Sublime Forum

Quick escape from the "find" search field

#1

Coming from emacs, I miss being able to quickly escape the search box. The way ST is setup I have to type a key combination to close the search box after finding the word I was looking for, before going back to editing.

I have this dream-wish for behavior:

-> any keystroke after the first “find next” command, and other than the keyboard shortcut for “find next” or “find prev”, kills the search box, returns to the editor with the current found selection highlighted, and and passes the keystroke to the main editor <–

For example, I should be able to press my key command (ctrl-g in my case) for “find next” a few times until I reach the occurrence of the word I was looking for, then press left arrow, which would (a) kill the search box, and then (b) return to ST with the current occurrence highlighted, and © pass on “left arrow” to the main editor, which would move the cursor to the beginning of the highlighted word and undo the highlight, just as pressing the left arrow usually does when a word is highlighted with the cursor at the right-end of the word.

Can this be done? It would really be amazing…

1 Like

#2

For an auto-closing search box you can use incremental search (Ctrl+I, or via Find tab in the menu). For navigating to next occurrences you may use find-next command (F3 is the default key, or via Find tab in the menu).

It is not exactly what you wished for, but it will get you much closer to that.

Anyways, are you using Sublime with the default key bindings, or with some kind of vim/emacs mode?

The reason I’m asking is that in the default sublime you only need to press the ESC key in order to close the find-panel, and not a key combination. And I think you can set it to work that way in any mode you’d use, if you find this easier.

Also, as an emacs enthusiast you might be interested in this plugin for Sublime:
https://packagecontrol.io/packages/Emacs%20Pro%20Essentials

0 Likes

#3

Hi,

Just looked at incremental search—I see that it saves me 1 keystroke because it automatically grabs the first occurrence as opposed to having to press “find next” (ctrl+g for me) to get the first occurrence. Apart from that, I still have to press a key to close the panel (be it the return or escape key!) before going back to editing the currently selected occurrence.

In the meanwhile, I’ve gotten quite close to the functionality that I want (at least for the “left arrow” case) by adding the following to my key bindings:

  { "keys": ["left"], "command": "hide_panel", "context": [{"key": "panel", "operand": "find"}, {"key": "panel_has_focus"}] },

It does everything I want except pass the “left” command onto the main editor after the find panel is closed. But I’m sure this could be done? Then I could add the same functionality for “right” and “delete” and I would have the most important cases covered…

0 Likes

#4

Sorry; in the meanwhile, I’ve added this to my ST3/Packages/User .py file:

class CloseFindWindowAndGoLeftCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.run_command("hide_panel")
        self.view.run_command("move", { "by": "characters", "forward": "false" } )

And tried to couple it with this key binding:

{ "keys": ["left"], "command": "close_find_window_and_go_left", 
                           "context": [{"key": "panel", "operand": "find"}, 
                                             {"key": "panel_has_focus"}] },

…but nothing is happening anymore when I press “left”—the panel doesn’t close anymore. (At least the panel was closing with the previously mentioned key binding.)

0 Likes

#5

There are a couple of things going on here that are kicking you in the butt.

The hide_panel command is a WindowCommand and not a TextCommand, but a View can only execute TextCommand commands, so the attempt to close the panel fails because the command execution silently fails.

Also, and perhaps more importantly, the text input field in the find panel is itself a View, so the command that you’ve defined triggers on that view instead, which causes the cursor to move left in a panel that you can no longer see.

To get around the first problem, you need to ask the view what window it belongs to, and then tell the window to execute the hide_panel command. To get around the second problem,you need to ask the window what it thinks the current View is, which will tell you the view that you’re actually searching in, so that you can get that window to respond to the command.

That might look something like this:

import sublime, sublime_plugin

class CloseFindWindowAndGoLeftCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        # Capture the active file view in the current window
        file_view = self.view.window().active_view()

        # Tell the window to close the panel and the file view to move left
        self.view.window().run_command("hide_panel")
        file_view.run_command("move", { "by": "characters", "forward": False } )

Note also that if you’re working with incremental find, you need to use the panel name incremental_find instead of find in the key binding. Possibly you want to have both bindings in place so that it always works:

[
	{ 
		"keys": ["left"], 
		"command": "close_find_window_and_go_left", 
      	"context": [
	      	{"key": "panel", "operand": "incremental_find"}, 
      		{"key": "panel_has_focus"}
      	] 
    }
]
4 Likes

#6

There is also ctrl+d/alt+f3 to search without panel.

1 Like

#7

(@OdatNurd) Hi,

Thank you very much this works!

One thing I am still missing is how to do this with the “delete” key.

One problem is that the first time the “find” window is brought up, the “delete” key needs to be used to (possibly) delete the last contents of the panel, that are initially selected. So the idea would be that any press of delete after the first “find next” command would trigger a similar “CloseFindWindowAndPressDelete” command. But I guess this is getting a bit fancy…

More down to earth, I’ve just remapped “up” and “down” arrows to “find prev” and “find next”, which is practical because I don’t use the default up/down functionality to retrieve past search items very much. Still, if I could remap “shift up” and “shift down” to scroll through past search items (if the need should arise!) that would be nice. Please let me know if you know how to do this.

Thanks!

0 Likes

#8

@OdatNurd: Nevermind the up/down question; my own remapping to “find prev” / “find next” isn’t even working. (I had somehow confused myself into thinking it was working.)

@mg979: These keyboard shortcuts don’t work for me. Ctrl+d deletes the next character and alt+f3 brings up some kind of mission control thing. I’m on mac…

0 Likes

#9

The keyboard shortcut for Quick Add Next is Ctrl+D on Windows/Linux and Command+D on MacOS. When there’s no selection it selects the word under the cursor, and when there is text selected it finds and adds the next occurrence to the selection.

The keyboard shortcuts for Quick Find and Quick Find All are Ctrl+F3 and Alt+F3 respectively on Windows/Linux and Command+Alt+G and Command+Ctrl+G on MacOS. The first one jumps the cursor between occurrences of the text currently under the cursor while the second one selects all of them at once (check the status line for text that tells you how many selection regions they are).

These are both handy to quickly search for other instances of some text you’re already working with, but not really a substitute for e.g. incremental search to find unrelated text.

0 Likes

#10

Just FYI the aforementioned Emacs Pro Essentials plugin has a proper incremental search, with most of the emacs semantics. And a bunch of other emacs things. It might be more than you want though. But for incremental search it’s mostly the real deal, plus it has multi-cursor extensions.

0 Likes