abo-abo / swiper

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!
https://oremacs.com/swiper/
2.32k stars 338 forks source link

File name completion overwrites already entered path in shell-mode #1755

Open vidagabor opened 6 years ago

vidagabor commented 6 years ago

Hi!

I have a long standing issue: in shell-mode, let's say there's /aa/bbb/cccc directory, and I want to complete this. If I enter "cd /aa/bbb" and I hit TAB, I get "cd /aabbb/" immediately. If I enter "cd /aa/bbb/" (there's a trailing /), and I hit TAB, the dropdown list appears which allows me to select from the candidates, which is "..", "cccc" and "." in this example. So after TAB, the already entered command switches to "cd /aa/b". If I go down and select "cccc" from the list, I get "cd /aa/bcccc". It varies how many characters of the already entered path is overwritten, but I couldn't figure out what it depends on.

If I toggle debug-on-quit, and hit ^G while the dropdown list is active, I get this back trace:

Debugger entered--Lisp error: (quit)
  read-from-minibuffer("(/aa/bbb/): " nil (keymap keymap (3 keymap (19 . ivy-rotate-sort) (1 . ivy-toggle-ignore) (15 . ivy-occur)) (67108903 . ivy-avy) (33554464 . ivy-restrict-to-matches) (15 . hydra-ivy/body) (22 . ivy-scroll-up-command) (prior . ivy-scroll-down-command) (next . ivy-scroll-up-command) (7 . minibuffer-keyboard-quit) (right . ivy-forward-char) (32 . self-insert-command) (18 . ivy-reverse-i-search) (19 . ivy-next-line-or-history) (remap keymap (describe-mode . ivy-help) (kill-ring-save . ivy-kill-ring-save) (kill-whole-line . ivy-kill-whole-line) (kill-line . ivy-kill-line) (scroll-down-command . ivy-scroll-down-command) (scroll-up-command . ivy-scroll-up-command) (end-of-buffer . ivy-end-of-buffer) (beginning-of-buffer . ivy-beginning-of-buffer) (kill-word . ivy-kill-word) (forward-char . ivy-forward-char) (delete-char . ivy-delete-char) (backward-kill-word . ivy-backward-kill-word) (backward-delete-char-untabify . ivy-backward-delete-char) (delete-backward-char . ivy-backward-delete-char) (previous-line . ivy-previous-line) (next-line . ivy-next-line)) (9 . ivy-partial-or-done) (10 . ivy-alt-done) (27 keymap (1 . ivy-read-action) (15 . ivy-dispatching-call) (111 . ivy-dispatching-done) (105 . ivy-insert-current) (106 . ivy-yank-word) (114 . ivy-toggle-regexp-quote) (16 . ivy-previous-line-and-call) (14 . ivy-next-line-and-call) (118 . ivy-scroll-down-command) (112 . ivy-previous-history-element) (110 . ivy-next-history-element) (10 . ivy-immediate-done) (13 . ivy-call)) (mouse-3 . ivy-mouse-dispatching-done) (mouse-1 . ivy-mouse-done) (down-mouse-1 . ignore) (13 . ivy-done)) nil ivy-history)
  ivy-read("(/aa/bbb/): " (#("../" 0 1 (font-lock-face completions-first-difference)) #("cccc/" 0 1 (font-lock-face completions-first-difference)) #("./" 0 1 (font-lock-face completions-first-difference))) :predicate nil :initial-input nil :sort t :action ivy-completion-in-region-action :unwind #f(compiled-function () #<bytecode 0x262bb59>) :caller ivy-completion-in-region)
  ivy-completion-in-region(#<marker at 668596 in shell @ /to:dc153fnd:/> 668604 #f(compiled-function (string pred action) #<bytecode 0x27767a5>) nil)
  completion-in-region(#<marker at 668596 in shell @ /to:dc153fnd:/> 668604 #f(compiled-function (string pred action) #<bytecode 0x27767a5>) nil)
  completion-at-point()
  funcall-interactively(completion-at-point)
  call-interactively(completion-at-point nil nil)
  command-execute(completion-at-point)

The buffer's name is "shell @ /to:dc153fnd:/" and the shell's prompt is "root@fnd01:/# ".

I'm using GNU Emacs 26.1 (build 1, x86_64-pc-linux-gnu, X toolkit, Xaw scroll bars) of 2018-06-13, and I'm using ivy 20180820.1526 installed via package.el.

I'd really appreciate any pointers how to debug this issue further, since I'm pretty sure I'm not the only one who uses Ivy like this, but seems that only I have this issue (for a long time, like at least half a year).

neosimsim commented 4 months ago

Having the same issue for a while.

plantarum commented 3 months ago

I just ran into this today, after using ivy for many years without issue.

To reproduce from emacs -Q, evaluate the following code:

(require 'package)
(setq package-load-list
      '((ivy t)))

(package-initialize)
(ivy-mode)
(shell)

This opens a shell. In my case, I have a directory ~/nextcloud/org. If I enter cd ~/next<TAB>, it completes to ~/nextcloud/. Pressing tab again offers me a vertical list of directories in ~/nextcloud/. When I select one, it is inserted a few spaces backwards. For example, if I select ~/nextcloud/org, after completion I have cd nextorg/.

GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.16.0) of 2024-07-02 Ivy installed from Melpa 2024-07-31: ivy-20240524.1139, Version: 0.14.2,

plantarum commented 3 months ago

The problem seems to occur in ivy-completion-in-region, which gets called from comint-dynamic-complete-filename, which calls completion-in-region:

https://github.com/abo-abo/swiper/blob/2a25a6fb5b081cb141c5eccac8ee58ab1feeb747/ivy.el#L2682-L2691

At this point, it looks like the length of the first match in the completion list ((car comps)) is deleted from the path to be completed. I don't understand the logic here, and presumably it's correct in other contexts. But in this situation it's clearly causing problems.

As a temporary fix, this resets the default completion-in-region-function value for shell-mode:

(defun tws-shell-mode-hook ()
  ;; to override ivy-mode, which provides a problematic
  ;; completion-in-region variation:
  (setq-local completion-in-region-function #'completion--in-region))

(add-hook 'shell-mode-hook 'tws-shell-mode-hook)
basil-conto commented 3 months ago

I just ran into this today, after using ivy for many years without issue.

Perhaps it was introduced by the following commit in Emacs 30?

At least that's when I noticed the issue in C-x p c (project-compile, which in turn delegates completion to comint-completion-at-point).

Highlight the suffix in Completions buffer in 'basic' style too 6b7ff60a5e7 2024-06-13 00:46:12 +0300

basil-conto commented 3 months ago

At first glance it looks like #3051 might be trying to address this issue; I'll try to dig deeper soon.