ctrlf icon indicating copy to clipboard operation
ctrlf copied to clipboard

Request: Emulating macOS's Find Next/Previous Commands

Open overvale opened this issue 3 years ago • 2 comments

There are some very useful standard Mac finding commands/behaviors that I'd love to be able to emulate in ctrlf. The relevant commands (in almost any Mac app) can be found in the menubar under "Edit > Find":

Screen Shot 2021-02-09 at 10 17 15 AM
  • Find... — This is pretty much what ctrlf does, however the Mac doesn't start with an empty search, it starts with the last thing you searched for.

    This is possible to emulate with (ctrlf-forward 'fuzzy nil ctrlf--last-input). However, I have no idea if this is robust or a "bad idea" in some way.

    Also, it doesn't seem that ctrlf-backward allows for the initial-contents argument.

  • Find Next/Previous — This command jumps directly to the next/previous occurrence of your last search without activating the Find interface. This, admittedly, isn't all that different from typing C-s C-s but there are circumstances when jumping to the next occurrence without the find interface is nice, and faster since you don't need to exit the interface.

  • Use Selection For Find — This command simply uses the selected text for the next Find command. So you can select some text, type command-E, then command-G to jump to the next occurrence of that text (no find interface). Alternatively, you might want to select some text, hit command-E, and then call up the find interface with command-F so you can edit the search term.

    I don't know if this is the proper and complete way to do this, but it should be possible with something like:

(defun ctrlf-push-region-to-history ()
  (interactive)
  (if (use-region-p)
      (setq ctrlf--last-input (buffer-substring (region-beginning) (region-end)))
    (error "No active region")))

So my proposal is:

  • Provide a user-facing variable that makes ctrlf commands start with the last-input by default. Or perhaps alternate functions which do this.
  • Provide functions for jumping (forward and back) to the last-input without activating ctrlf.
  • Provide a function for pushing the region to last-input.

overvale avatar Feb 09 '21 19:02 overvale

These all seem like reasonable proposals. My thoughts:

  • I am not sure why initial-contents is not supported in ctrlf-backward; that feature was added in https://github.com/raxod502/ctrlf/pull/48. I suspect it would be straightforward to port.
  • Rather than ctrlf--last-input, you can use (car ctrlf-search-history). That should work better. (I am not sure your code for ctrlf-push-region-to-history would actually work, as I think ctrlf--last-input is reset to nil when starting a search.)

It might be best to start by seeing if you can implement these user commands using the existing CTRLF public interface, and then if others express interest in the same feature, we could add them to CTRLF.

raxod502 avatar Feb 19 '21 03:02 raxod502

I have sort of implemented this just with my configuration. There are two issues:

  1. there may be a bug in search-backward in that it isn't accepting a search query
  2. For some reason, ctrlf-mode-map has precedence over ctrlf-minibuffer-mode-map, so I don't get the "s-g" to go to next candidate to work
(use-package ctrlf
  :preface
  (defun bsp-ctrlf-region-forward ()
    (interactive)
    (if (use-region-p)
        (let ((beg (region-beginning))
              (end (region-end)))
          (deactivate-mark)
          (ctrlf-forward ctrlf-default-search-style nil
                       (buffer-substring-no-properties beg end)))
      (ctrlf-forward-default)))
  (defun bsp-ctrlf-search-last ()
    (interactive)
        (ctrlf-forward ctrlf-default-search-style nil
                        (car ctrlf-search-history)))
  (defun bsp-ctrlf-search-last-backward ()
    (interactive)
    (ctrlf-backward ctrlf-default-search-style nil
                    (car ctrlf-search-history)))
  :init
  (ctrlf-mode +1)
  :bind (:map ctrlf-mode-map
              ("s-f" . ctrlf-forward-default)
              ("s-F" . ctrlf-backward-default)
              ("s-g" . bsp-ctrlf-search-last)
              ("s-G" . bsp-ctrlf-search-last-backward)
              ("s-e" . bsp-ctrlf-region-forward)
              :map ctrlf-minibuffer-mode-map
              ("s-g" . ctrlf-forward-default)
              ("s-G" . ctrlf-backward-default)))

Edit: had pasted wrong version of code prior

powellb avatar Nov 23 '21 19:11 powellb