1

I use interactive mode with Ivy and Dired for interactively creating new files, like so:

(evil-local-set-key 'normal (kbd "t") (lambda (file)
                                      (interactive "Ftouch ")
                                      (let ((target_exists (file-directory-p file))
                                            (target_dir (file-name-directory file)))
                                        (unless target_exists
                                          (make-directory target_dir t))
                                        (with-temp-buffer
                                          (append-to-file (point-min)
                                                        (point-max)
                                                        file))
                                        (revert-buffer)
                                        (dired target_dir))

It works fine. The problem is that the / key always automatically completes what I am currently hovering in the completion list. Please take a look at the following GIF:

https://gfycat.com/parallelscratchyhuman

When I type . A M /, interactive mode will automatically complete it to ".AMD/", which is not my intention.

What I want to do is get rid of this "completion" behavior of / to not disturb what I am typing, i.e. pressing / only outputs the literal / character and nothing else.

0

After reading the documentation and the source code of ivy, I think there is no way to disable the effect of / elegantly. I may be wrong, those who are interested in the question can see the function ivy--update-minibuffer which calls ivy--magic-file-slash to autocomplete directory by / if only one directory matched the input string.

Workaround

Simply disable the function which triggers the directory completion, i.e ivy--magic-file-slash. (Not a great idea, because it is a "private" function of ivy.)

First, define an advice function doing nothing.

(defun disable-function (oldfun &rest args))

Then, replace your interactive snippet by this one:

(interactive
     (let ((file))
       (advice-add #'ivy--magic-file-slash :around #'disable-function)
       (setq file (read-file-name "touch ")) 
       (advice-remove #'ivy--magic-file-slash #'disable-function)
       (list file)))

The code above disables the effect of / before prompting for a filename (exactly as (interactive "Ftouch ") do) and then enable it again / in case you need it in another context.

You will need to press C-j manually to complete existing directories. For instance in your example, if you want to touch the file .AMD/Dir1/file.txt, you will need to press C-j after that .AMD is selected as a candidate, so that the completion of its subdirectories will be possible.

Old (wrong) answer:

I think you are looking for the keybinding C-M-j (ivy-immediate-done, see the documentation).

Exits with the current input instead of the current candidate (like other commands).

3
  • That is not the solution I'm looking for. To be clearer, I want to keep typing without having my input be disturbed by / 's behavior. I've updated the description to match that. – resolritter Aug 8 '20 at 20:20
  • @resolritter I see. And you want to touch a file even if its directory doesn't exist (as in your example .AM/) ? – Firmin Martin Aug 8 '20 at 20:28
  • Yes. If the path does not exist yet, I'll have some function recursively create the path and handle that case. Do you think it'd be better to have another mapping for creating the path? I think /'s function can already be simulated well enough with narrowing + Tab, which is my ideal usage pattern. – resolritter Aug 8 '20 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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