Open selected completion candidate in a split?

What happened?

I tried to ask it in Reddit as well but did not able to find answer, so repeating here now, my apologies!

In neovim telescope (fuzzy finder) once you search for file ctrl+v and ctrl+x allows to open file in vertical or horizontal split respectively.

Is it possible to have something similar in here for find-files and projectile-find-files. I do come across find-file-other-window but it always performs vertical split only.

Hey @dhruvinsh, the way of doing this largely depends on your completion module / method. For the one I am familiar with, vertico and more specifically, embark, you can add your file specific keybindings in the embark-file-map. You can find more info in embarks README.

With ivy I imagine you can change the ivy-minibuffer-map to similar effect, though I am not sure if it’s limited to files or not, so you ought to be a bit more careful for when you call the binding. I imagine is not that different for helm or ido but I’m not familar with them.

2 Likes

That was a great info. Yes my setup is default doom emacs that is vertico +icons. And looks like I need to do more reading on vertico and embark.

But if possible would be kind to just give me some example here.

Pressing RET invokes the “default action” of whatever command you’re using. For most file commands, that means opening the file in the current window.

However, all our completion frameworks (except for ido) support invoking an alternative action on the selected candidate(s):

  • For ivy, press C-o to be presented a list of alternative actions. This shows you how to add your own/change existing ones.

  • For vertico, press C-; (in invoke Embark). To add to these, bind new keys to the appropriate embark keymap (in this case, embark-file-map):

    ;; This allows you to delete the selected file with 
    ;; C-; x for file commands
    (map! :after embark
          :map embark-file-map
          "x" #'delete-file)
    

    or create your own.

  • For helm, press TAB. To add to it, you add them to the appropriate source, e.g. with helm-add-action-to-source, but I haven’t used Helm in years to recall the specifics. [1]

Hope that helps!


  1. …and I wouldn’t recommend folks use it anyway. ↩︎

2 Likes

@hlissner and @danilevy1212 Thank you for pointing me in right direction. And I have below code that does the job.

But (there is always one) after split my cursor is not automatically moving to new split, how can I make it so?

;; ref: https://www.reddit.com/r/emacs/comments/sbh6hi/how_to_define_my_own_embark_functionkeymap_in/
(defun cust/vsplit-file-open (file)
  (+evil/window-vsplit-and-follow)
  (find-file file))

(defun cust/split-file-open (file)
  (+evil/window-split-and-follow)
  (find-file file))

(map! :after embark
      :map embark-file-map
      "V" 'cust/vsplit-file-open
      "X" 'cust/split-file-open)

For the other user like me, how it works for me is, SPC p p to access project files then while in project if I want other files to be open in split windows SPC p f to do projectile-find-file search the file and then C-; to initiate embark and V or X to open in vertical or horizontal split.

@dhruvinsh Try keeping a reference to the current buffer so you can go back to it, like this:

(defun cust/vsplit-file-open (file)
  (let ((old-buffer (current-buffer)))
    (+evil/window-vsplit-and-follow)
    (find-file file)
    (other-buffer old-buffer)))

(defun cust/split-file-open (file)
  (let ((old-buffer (current-buffer)))
    (+evil/window-split-and-follow)
    (find-file file)
    (other-buffer old-buffer)))

(map! :after embark
      :map embark-file-map
      "V" 'cust/vsplit-file-open
      "X" 'cust/split-file-open)
1 Like

What you experience can be controlled by evil-split-window-below and evil-vsplit-window-right. For seeing how these settings behave, you could try these two functions (mapped to v and V in this example):

(defun cust/vsplit-file-open1 (f)
  (let ((evil-vsplit-window-right nil))
    (+evil/window-vsplit-and-follow)
    (find-file f)))

(defun cust/vsplit-file-open2 (f)
  (let ((evil-vsplit-window-right t))
    (+evil/window-vsplit-and-follow)
    (find-file f)))

(map! :after embark
      :map embark-file-map
      "V" #'cust/vsplit-file-open1
      "v" #'cust/vsplit-file-open2)

You can see that v puts your cursor in the new window while V does not. Please keep in mind that the v mapping is already in use, only use it if you don’t mind overriding its default value.

evil-split-window-below behaves the same afaik.

yes, this exactly what I needed. Thanks everyone for your help. My final code looks like below

(defun cust/vsplit-file-open (f)
  (let ((evil-vsplit-window-right t))
    (+evil/window-vsplit-and-follow)
    (find-file f)))

(defun cust/split-file-open (f)
  (let ((evil-split-window-below t))
    (+evil/window-split-and-follow)
    (find-file f)))

(map! :after embark
      :map embark-file-map
      "V" #'cust/vsplit-file-open
      "X" #'cust/split-file-open)
1 Like

Somehow I did not find any change in behavior. I was getting split windows but cursor wasn’t moving to the new one. But found other solution. Thank you for pointing me in the right direction.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.