0

I am using ranger within spacemacs. One useful feature an explorer in windows (directory opus) I used has, is that by pressing keys it automatically starts to filter files with names corresponding to the keys.

Is there a way to use helms fuzzy search as the default mode inside ranger windows, which then filters the files and directories according to the fuzzy input and to be able to toggle the mode off when desired?

6
  • Is helm-find-file the command you're looking for? I'm not sure if there is a helm fuzzy search mode, but if you wanted helm-find-file to be called immediately upon entering ranger you could add it as a hook to ranger via (add-hook 'ranger-mode-hook (lambda () (call-interactively #'helm-find-files))). ` Dec 16, 2019 at 22:21
  • Thank you for the tip. Is there also a way to switch it off for the current buffer with some shortcut, btw. how could one implement it? A strange problem which occurs, is that upon clicking on pdf files an unpredictabe behavior happens, they usually don't open. But it seems this has to do with a ranger bug adressed here, in deer everything seems to work smoothly.
    – Rareform
    Dec 17, 2019 at 11:54
  • So what I suggested will work upon entering ranger. Do you want this behavior whenever you switch to a ranger buffer? Or only when you just opened ranger? Dec 17, 2019 at 14:56
  • I want it to work when switching to ranger buffer just like it does now with a possibility to quit it with some hotkey sequence (e.g. esc key), so then I can use usual ranger keybindings. I have to say that the already provided solution does the most demanded things in my question. I would accept the hook as a solution, but you would need to write it down, as I cannot accept a comment as an answer I guess.
    – Rareform
    Dec 17, 2019 at 16:39
  • To be precise right now it doesn't work when switching to a ranger buffer. The hook will only work when you enter ranger mode (in practice, when a new buffer is created after calling deer or ranger). It won't work when you switch from one buffer to an existing ranger buffer. For example, if you open ranger switch to another buffer and then switch back. You want this behavior too right? Dec 17, 2019 at 17:02

1 Answer 1

1

EDIT START

It is more reliable to add advice to ranger and deer to try to ensure that helm-find-files is always enabled when ranger and dired are called (as opposed to adding a hook to ranger-mode-hook which is only called once the buffer is created). This should fix the problem of helm-find-files sometimes not being called immediately.

(with-eval-after-load 'ranger
  (advice-add #'deer :after #'+enable-helm-find-files)
  (advice-add #'ranger :after #'+enable-helm-find-files))

EDIT END

activate from newly created ranger buffers

helm-find-files might be what you're looking for. You can add it as a hook to ranger-mode-hook. I recommend naming it as I did so (1) you can easily remove it and (2) the hooks contents are more readable.

(defun +call-helm-find-files ()
  (interactive)
  (call-interactively #'helm-find-files))

(add-hook 'ranger-mode-hook #'+call-helm-find-files)

system to switch buffers

Adding a hook to ranger-mode-hook does not answer your original question which was to enable fuzzy searching whenever you switch to a ranger buffer. Adding a hook will only work when ranger-mode is enabled. In practice, this means when you call ranger mode (M-x ranger or M-x deer) and ranger creates a brand new ranger buffer. However if you're switching from a buffer to an existing ranger buffer ranger-mode-hook will not be run and therefore helm-find-files will not be called.

To call helm-find-files upon switching to a ranger buffer and to do it in a thorough, not as hacky way, I would recommend adapting some of the code from doom-emacs. Currently, there is no hook that runs after switching a buffer. This code sets up such a hook. I adapted it here.

switch hook

(defvar +after-switch-to-buffer-hook nil
  "Hook run after switched to buffer.")

advice to switch-to-buffer

(defun +run-switch-buffer-hooks (orig-fn buffer-or-name &rest args)
  "Run ‘+after-switch-buffer-hook’."
  (if (or +inhibit-switch-buffer-hooks
          (eq (current-buffer) (get-buffer buffer-or-name))
          (and (eq orig-fn #'switch-to-buffer) (car args)))
      (apply orig-fn buffer-or-name args)
    (let ((+inhibit-switch-buffer-hooks t))
      (when-let (buffer (apply orig-fn buffer-or-name args))
        (with-current-buffer (if (windowp buffer)
                                 (window-buffer buffer)
                               buffer)
          (run-hooks '+after-switch-to-buffer-hook))
        buffer))))

advice to previous-buffer and next-buffer

(defun +run-prev-or-next-buffer-hooks (orig-fn &rest args)
  (if +inhibit-switch-buffer-hooks
      (apply orig-fn args)
    (let ((+inhibit-switch-buffer-hooks t))
      (when-let (buffer (apply orig-fn args))
        (with-current-buffer buffer
          (run-hooks '+after-switch-to-buffer-hook))
        buffer))))

inhibit switch-buffer hooks

(defvar +inhibit-switch-buffer-hooks nil
  "Letvar for inhibiting `+after-switch-buffer-hook'. Do not set this directly.")

toggle

I checked this code and it worked for me. But my checking was not exhaustive so I wrote this function so you can enable and disable the switch buffer hook.

(defvar +enable-switch-buffer-hooks nil
  "Whether to enable switch buffer hooks.")

(defun +toggle/switch-window-advice ()
  (interactive)
  (setq +enable-switch-buffer-hooks (not +enable-switch-buffer-hooks))
  (if +enable-switch-buffer-hooks
      (progn
        (message "disabled switch buffer hooks.")
        (advice-remove #'switch-to-buffer #'+run-switch-buffer-hooks)
        (advice-remove #'display-buffer #'+run-switch-buffer-hooks)
        (advice-remove #'switch-to-next-buffer #'+run-prev-or-next-buffer-hooks)
        (advice-remove #'switch-to-prev-buffer #'+run-prev-or-next-buffer-hooks))
    (message "enabled switch buffer hooks")
    (advice-add #'switch-to-buffer :around #'+run-switch-buffer-hooks)
    (advice-add #'display-buffer :around #'+run-switch-buffer-hooks)
    (advice-add #'switch-to-next-buffer :around #'+run-prev-or-next-buffer-hooks)
    (advice-add #'switch-to-prev-buffer :around #'+run-prev-or-next-buffer-hooks)))

disable all

In case something goes wrong, you can disable everything with this.

(defun +disable-helm-find-files-all ()
  "Disable the whole thing."
  (interactive)
  (setq +enable-switch-buffer-hooks nil)
  (+toggle/switch-window-advice)
  (remove-hook 'ranger-mode-hook #'+call-helm-find-files))

inhibited files

This list is for the buffers you disable with +toggle/find-file-inhibited.

(defvar +inhibited-find-file-buffers nil
  "List of ranger buffers that shouldn’t do ‘helm-find-files’ on switch.")

toggle inhibited

This is the toggling functionality you requested. You can call this while on a ranger buffer and that buffer will not trigger helm-find-files when you switch to it.

(defun +toggle/find-file-inhibited ()
  "Make current buffer not call ‘helm-find-files’."
  (interactive)
  (push (current-buffer) +inhibited-find-file-buffers))

activate helm-find-files when entering buffer

This is the hook to actually call helm-find-files. It checks to see if the current buffer is a ranger buffer and whether its not a member of those in +inhibited-find-file-buffers.

(defun +enable-helm-find-files ()
  "Enable ‘helm-find-files’ in ranger buffers."
  (when (and (eq major-mode 'ranger-mode)
             (not (member (current-buffer) +inhibited-find-file-buffers)))
    (call-interactively #'helm-find-files)))

(add-hook '+after-switch-to-buffer-hook #'+enable-helm-find-files)
5
  • One right ) in switch-window-advice is too many. The helm-find-files doesn't get activated immediately again after entering the ranger buffer (e.g. calling ranger while viewing pdf), but only after going up or down a folder. The newly created ranger buffers code works for ranger and deer, but the other one only for ranger. How can I edit the code, so that it works for the deer mode too? When I try to open a file (tex, pdf) with the search inside ranger nothing happens, except Making window-configuration-change-hook buffer-local while locally let-bound!, do you what the problem is?
    – Rareform
    Dec 18, 2019 at 14:45
  • Also, after I try to open a document in fuzzy mode in deer or ranger (via the newly created buffer code) I get the message *** changed on disk; really edit the buffer?. The problem is circumvented by pressing esc and going in usual ranger or deer mode and then opening the document.
    – Rareform
    Dec 18, 2019 at 16:31
  • Maybe my answer was too complex. I think you were happy with just the ranger-mode-hook solution. If you enable ranger-cleanup-eagerly it will simulate enabling them on buffer switching. I'll change my solution to this so that it's less buggy. Dec 18, 2019 at 16:40
  • Oh and I think the "changed on disk" thing is unrelated to this. I dont use helm, I'm not sure why it says that. Dec 18, 2019 at 16:44
  • I edited the code. Try using advice as I specified and let me know how it goes. It should guarantee helm-find-files whenever ranger or deer is called. Dec 18, 2019 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.