Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Company deletes asterisks in Eshell Mode #218

Closed
fehmud opened this issue Nov 3, 2014 · 13 comments
Closed

Company deletes asterisks in Eshell Mode #218

fehmud opened this issue Nov 3, 2014 · 13 comments

Comments

@fehmud
Copy link

fehmud commented Nov 3, 2014

Hello,

Company deletes asterisks entered in Eshell Mode. This problem does not happen with Shell Mode.

To reproduce:

  • emacs -Q
  • (add-to-list 'load-path "/path/to/company")
  • (require 'company)
  • (global-company-mode)
  • M-x eshell
  • type an asterisk

Software:

  • Company 0.8.7
  • Emacs 24.4

Thanks for your assistance.

@dgutov
Copy link
Member

dgutov commented Nov 3, 2014

Do you see the same behavior if you type M-x completion-at-point, without enabling company-mode?

I see a different thing happen: no asterisks disappear, but both company-mode and completion-at-point raise an error after asterisks. Like this:

Debugger entered--Lisp error: (wrong-type-argument stringp ("/adb:" "/bin/" "/boot/" "/cdrom/" "/dev/" "/etc/" "/fcp:" "/ftp:" "/git:" "/home/" "/initrd.img" "/initrd.img.old" "/krlogin:" "/ksu:" "/lib/" "/lib32/" "/lib64/" "/lost+found/" "/media/" "/mnt/" "/nc:" "/opt/" "/plink:" "/plinkx:" "/proc/" "/pscp:" "/psftp:" "/rcp:" "/remcp:" "/remsh:" "/root/" "/rsh:" "/rsync:" "/run/" "/sbin/" "/scp:" "/scpx:" "/smb:" "/srv/" "/ssh:" "/sshx:" "/su:" "/sudo:" "/sys/" "/telnet:" "/tmp/" "/usr/" "/var/" "/vmlinuz" "/vmlinuz.old"))
  file-name-directory(("/adb:" "/bin/" "/boot/" "/cdrom/" "/dev/" "/etc/" "/fcp:" "/ftp:" "/git:" "/home/" "/initrd.img" "/initrd.img.old" "/krlogin:" "/ksu:" "/lib/" "/lib32/" "/lib64/" "/lost+found/" "/media/" "/mnt/" "/nc:" "/opt/" "/plink:" "/plinkx:" "/proc/" "/pscp:" "/psftp:" "/rcp:" "/remcp:" "/remsh:" "/root/" "/rsh:" "/rsync:" "/run/" "/sbin/" "/scp:" "/scpx:" "/smb:" "/srv/" "/ssh:" "/sshx:" "/su:" "/sudo:" "/sys/" "/telnet:" "/tmp/" "/usr/" "/var/" "/vmlinuz" "/vmlinuz.old"))
  eshell-complete-commands-list()
  #[0 "\300 \207" [eshell-complete-commands-list] 1 "\n\n(fn)"]()
  pcomplete--here(#[0 "\300 \207" [eshell-complete-commands-list] 1 "\n\n(fn)"] nil nil nil)
  #[0 "\300\301\302\211\211$\207" [pcomplete--here #[0 "\300 \207" [eshell-complete-commands-list] 1 "\n\n(fn)"] nil] 5 "\n\n(fn)"]()
  #[0 "\306�!\2053
...

I guess it gets interpreted as file path, and file paths disallow unescaped asterisks (..?).

@fehmud
Copy link
Author

fehmud commented Nov 3, 2014

Thanks for your quick reply.

No errors here. Yes, M-x completion-at-point deletes the asterisk, but here it shows a completion window. Or, if I type a prefix that is long enough to have only one possible completion, and I append an asterisk, the successful completion deletes the asterisk. Therefore, it seems that this problem is caused by company-mode relying on completion-at-point.

@fehmud
Copy link
Author

fehmud commented Nov 3, 2014

But -- also -- completion-at-point is meant to be called on-demand, therefore users can choose whether to trigger the completion of wildcards or not. On the other hand, Company always calls completion-at-point automatically, and users are left with no choice. Maybe Company should not be enabled by default in shells?

@dgutov
Copy link
Member

dgutov commented Nov 3, 2014

Yes, M-x completion-at-point does that, but here it shows a completion window.

Okay, I can reproduce that now, in a bare Emacs session. Will have to see what customization of mine makes that behavior different.

completion-at-point is meant to be called on-demand, therefore users can choose whether to trigger the completion of wildcards or not.

Still, I see no possible benefit in replacing * with nothing. What might that mean in completion terms?

completion-at-point also adds a space, like I have pointed out in another issue.

Can you describe the exact sequence of commands (and the context) that makes it do that (in a comment, in the other issue)? That's the one thing I haven't been able to reproduce (specifically, with completion-at-point and directory paths in eshell).

@fehmud
Copy link
Author

fehmud commented Nov 4, 2014

Still, I see no possible benefit in replacing * with nothing. What might that mean in completion terms?

It means that the entire pattern with wildcards will eventually be replaced with the full completion.

Without Company, M-x completion-at-point deletes the wildcard but then shows a list of completions that match the pattern with wildcards that the user has entered. If only one completion is possible, completion-at-point inserts it directly and echoes Sole completion. However -- at least in Eshell Mode -- completion-at-point seems buggy because if the pattern has some characters before the asterisk, then the asterisk gets deleted but no completion is shown.

Can you describe the exact sequence of commands (and the context) that makes it do that (in a comment, in the other issue)? That's the one thing I haven't been able to reproduce (specifically, with completion-at-point and directory paths in eshell).

I have noticed that Eshell Mode binds TAB to eshell-pcomplete instead of completion-at-point (like Shell Mode does), and eshell-pcomplete does not insert an extra space. Anyway, to reproduce the problem of the extra space with completion-at-point (Emacs 24.4 on GNU/Linux):

  • emacs -Q
  • M-x eshell
  • type * in the Eshell buffer, followed by M-x completion-at-point
  • select a completion

Thanks for your assistance.

@fehmud
Copy link
Author

fehmud commented Nov 4, 2014

Anyway, both completion-at-point and eshell-pcomplete don't seem suitable for Company, because they have the side effect of changing the content of the buffer, and doing so automatically confuses the user.

Maybe Company could provide an option to exclude some major modes when calling global-company-mode, and by default such option would include shell modes.

@dgutov
Copy link
Member

dgutov commented Nov 5, 2014

It means that the entire pattern with wildcards will eventually be replaced with the full completion.

But that doesn't happen with any other prefix, even though they would also be "eventually replaced".

So, http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18951. Let's wait for the response.

And BTW, my original problem was http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18950.

@shlomiv
Copy link

shlomiv commented Sep 14, 2016

I experience the same thing, asterisks gets deleted in eshell when company-mode is enabled.

It has been some time since anything happened in this issue, any fixes or workarounds?

@quigonjeff
Copy link

I'm using spacemacs, and I have the same problem. Any solution or workaround?

@dgutov
Copy link
Member

dgutov commented Jan 30, 2017

@quigonjeff None that I'm aware of. You might be better off commenting on the Emacs bug report directly.

@dakra
Copy link

dakra commented Nov 2, 2017

I commented on the Emacs bug report and got a potential fix.

If someone wants to test it, just eval:

(defun pcomplete-parse-arguments (&optional expand-p)
  "Parse the command line arguments.  Most completions need this info."
  (let ((results (funcall pcomplete-parse-arguments-function)))
    (when results
      (setq pcomplete-args (or (car results) (list ""))
	    pcomplete-begins (or (cdr results) (list (point)))
	    pcomplete-last (1- (length pcomplete-args))
	    pcomplete-index 0
	    pcomplete-stub (pcomplete-arg 'last))
      (let ((begin (pcomplete-begin 'last)))
	(if (and (listp pcomplete-stub) ;??
		 (not pcomplete-expand-only-p))
	    (let* ((completions pcomplete-stub) ;??
		   (common-stub (car completions))
		   (c completions)
		   (len (length common-stub)))
	      (while (and c (> len 0))
		(while (and (> len 0)
			    (not (string=
				  (substring common-stub 0 len)
				  (substring (car c) 0
					     (min (length (car c))
						  len)))))
		  (setq len (1- len)))
		(setq c (cdr c)))
	      (setq pcomplete-stub (substring common-stub 0 len)
		    pcomplete-autolist t)
	      (when (and begin (> len 0) (not pcomplete-show-list))
		(delete-region begin (point))
		(pcomplete-insert-entry "" pcomplete-stub))
	      (throw 'pcomplete-completions completions))
	  (when expand-p
	    (if (stringp pcomplete-stub)
		(when begin
		  (delete-region begin (point))
		  (insert-and-inherit pcomplete-stub))
	      (if (and (listp pcomplete-stub)
		       pcomplete-expand-only-p)
		  ;; this is for the benefit of `pcomplete-expand'
		  (setq pcomplete-last-completion-length (- (point) begin)
			pcomplete-current-completions pcomplete-stub)
		(error "Cannot expand argument"))))
	  (if pcomplete-expand-only-p
	      (throw 'pcompleted t)
	    pcomplete-args))))))

and see if it fixes the problem and/or breaks something else.

@gopar
Copy link

gopar commented Dec 23, 2017

@dakra tested snippet out. Can confirm it works \o/

@dakra
Copy link

dakra commented Dec 23, 2017

@gopar nice.
jFYI, the fix is already included in Emacs26+ which is just around the corner :)

@dgutov dgutov closed this as completed Feb 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants