bling / fzf.el

A front-end for fzf
GNU General Public License v3.0
369 stars 50 forks source link

suggest to add a `fzf-find-in-buffer` command #94

Closed LiuYinCarl closed 1 year ago

LiuYinCarl commented 1 year ago

In the last few months,I fork the project and add a command fzf-find-in-buffer to fast find the pattern line and jump to it, the command works well and helped me read code faster, so I think maybe can add it to fzf.el.

image

image

the code can find in here. https://github.com/bling/fzf.el/commit/fa2306f6fa8398cc61cf4d983e94f979cd5356b9

(defun fzf-with-command-and-args (command action &optional fzf-append-args directory)
  (interactive)
  (if command
      (let
          ((process-environment (cons (concat "FZF_DEFAULT_COMMAND=" command "") process-environment))
           (args (if fzf-append-args
                    (concat fzf/args " " fzf-append-args)
                    fzf/args)))
        (fzf/start directory action args))
    (fzf/start directory action)))

(defun fzf/action-goto-line (target)
  (let ((parts (split-string (string-trim-left target) " ")))
    (goto-line (string-to-number (nth 0 parts)))))

;;;###autoload
(defun fzf-find-in-buffer ()
  "Exact search in current buffer."
  (interactive)
  (fzf-with-command-and-args (concat "cat -n " buffer-file-name " | tac")
            #'fzf/action-goto-line
        "--exact"))
pierre-rouleau commented 1 year ago

Hi @LiuYinCarl, that looks like a nice addition!

With the current state of the code, you would have to modify it slightly to the following:

;; Internal helper function                                                                                                                                                                                                                                                                       
(defun fzf--with-command-and-args (command action &optional fzf-append-args directory)
  (if command
      (let
          ((process-environment (cons
                                 (concat "FZF_DEFAULT_COMMAND=" command "")
                                 process-environment))
           (args (if fzf-append-args
                     (concat fzf/args " " fzf-append-args)
                   fzf/args)))
        (fzf--start directory action args))
    (fzf--start directory action)))

(defun fzf--action-goto-line (target)
  (let ((parts (split-string (string-trim-left target) " ")))
    (goto-char (point-min))
    (forward-line (1- (string-to-number (nth 0 parts))))))

;;;###autoload                                                                                                                                                                                                                                                                                    
(defun fzf-find-in-buffer ()
  "Exact search in current buffer."
  (interactive)
  (let ((fzf--target-validator (fzf--use-validator
                                (function fzf--pass-through))))
    (fzf--with-command-and-args (concat "cat -n " buffer-file-name " | tac")
                                (function fzf--action-goto-line)
                                "--exact")))

I tested the above code applied over the latest in main and it works fine.

The changes are made to allow overriding of a validator, in case we find ways to do special post processing, and to conform to the naming convention changes done recently. The code is also updated to ensure it byte compiles cleanly. I renamed the interactive form from the internal function.

You can either grab the latest code, update it with the above and publish a PR with it or I can do it for you. Let me know the way you want to proceed.

LiuYinCarl commented 1 year ago

@pierre-rouleau Thanks for your nice review and advice.

Actually I am a novice with elisp, the fzf-find-in-buffer actuall has some limitations in this version, so I want to discuss with you before publish a PR.

  1. I use cat to provide the input of fzf which limits the buffer must be a real file in disk, if can provide the buffer contents to fzf directly will be better.
  2. I use tac just because cat -n filename | fzf will make the contents of the buffer reversed, but for a very big file it may degrade the user experience.

I want to fix these limitations but have no good idea, If you have any suggestion about the limitations, it will make the effect and speed of fzf-find-in-buffer better.

pierre-rouleau commented 1 year ago

@LiuYinCarl , well, the easiest thing to do is to publish it and see how it goes. Both limitations you identified are real limitations. But if you submit now, and identify these as limitations, we'll all see them and if me or someone else has a solution then the diff will show what needs to be done and the diff itself will provide good information for the community. So I would go ahead with what you have now and identify your known limitations. One step at a time.

pierre-rouleau commented 1 year ago

Also note that the commands are Unix specific... Eventually we might want to support other commands for other OSes. But again, one step at a time

LiuYinCarl commented 1 year ago

@pierre-rouleau You are right! Would you please publish a PR for fzf-find-in-buffer because my current environment does not allow me to submit a git push. But if you have no time now, I will do it tomorow.

pierre-rouleau commented 1 year ago

@LiuYinCarl , no problem I'll do it soon.

pierre-rouleau commented 1 year ago

@LiuYinCarl the code was merged in. You may want to confirm all is OK and close the issue. Thanks!

LiuYinCarl commented 1 year ago

@pierre-rouleau Thanks for your help.