GNU bug report logs - #76817
30.1; completion-preview and shell

Previous Next

Package: emacs;

Reported by: Rufus Segar <rhs <at> riseup.net>

Date: Fri, 7 Mar 2025 17:27:02 UTC

Severity: normal

Found in version 30.1

To reply to this bug, email your comments to 76817 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#76817; Package emacs. (Fri, 07 Mar 2025 17:27:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Rufus Segar <rhs <at> riseup.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 07 Mar 2025 17:27:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Rufus Segar <rhs <at> riseup.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.1; completion-preview and shell
Date: Fri, 07 Mar 2025 16:38:11 +0000
It appears that completion-preview-mode is not quite working as intended
with shell. When inserting path completions it inserts a trailing space.

An example will show why this is undesirable:

Say I want to complete path `~/foobar/baz'. I start with `cd ~/foob` and
completion-preview successfully completes the 'foobar' portion. However,
after I do completion-preview-insert I'm left with the following:

"cd ~/foobar/ "
             ^-- Notice the trailing space

This means that if I want to continue completing my path all the way to
'~/foobar/baz', I have to delete that trailing space. completion-preview
should not leave a trailing space, and if possible immediately continue
completing the path, so that in this case I'm given '~/foobar/baz' as my
next completion candidate and can simply call completion-preview-insert
again to get the full path.

P.S. I'm loving completion-preview-mode by the way, I can tell that a
lot of care was put into this mode. I'm looking forward to this issue
being resolved so that I can use it in my shell too.

=====

I have tested this with `emacs -q` and have observed the same behavior.
However, here is the auto-filled info from report-emacs-bug:

In GNU Emacs 30.1 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.48,
cairo version 1.18.2)
Windowing system distributor 'The X.Org Foundation', version 11.0.12101015
System Description: Arch Linux

Configured using:
 'configure --sysconfdir=/etc --prefix=/usr --libexecdir=/usr/lib
 --with-tree-sitter --localstatedir=/var --with-cairo
 --disable-build-details --with-harfbuzz --with-libsystemd
 --with-modules --with-x-toolkit=gtk3 'CFLAGS=-march=x86-64
 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=3
 -Wformat -Werror=format-security -fstack-clash-protection
 -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -g
 -ffile-prefix-map=/build/emacs/src=/usr/src/debug/emacs -flto=auto'
 'LDFLAGS=-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro
 -Wl,-z,now -Wl,-z,pack-relative-relocs -flto=auto''

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: mu4e:main

Minor modes in effect:
  mu4e-search-minor-mode: t
  mu4e-update-minor-mode: t
  mu4e-context-minor-mode: t
  mu4e-modeline-mode: t
  erc-track-mode: t
  erc-track-minor-mode: t
  erc-ring-mode: t
  erc-netsplit-mode: t
  erc-menu-mode: t
  erc-match-mode: t
  erc-list-mode: t
  erc-irccontrols-mode: t
  erc-move-to-prompt-mode: t
  erc-readonly-mode: t
  erc-imenu-mode: t
  erc-pcomplete-mode: t
  erc-autojoin-mode: t
  erc-hl-nicks-mode: t
  erc-button-mode: t
  erc-fill-mode: t
  erc-stamp-mode: t
  erc-networks-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  emms-playing-time-display-mode: t
  emms-playing-time-mode: t
  hes-mode: t
  pdf-occur-global-minor-mode: t
  global-dired-hide-details-mode: t
  coterm-mode: t
  save-place-mode: t
  global-so-long-mode: t
  yas-global-mode: t
  yas-minor-mode: t
  eyebrowse-mode: t
  global-corfu-mode: t
  corfu-mode: t
  vertico-mode: t
  ednc-mode: t
  fortune-cookie-mode: t
  openwith-mode: t
  global-page-break-lines-mode: t
  global-fish-completion-mode: t
  fish-completion-mode: t
  shx-global-mode: t
  recentf-mode: t
  winner-mode: t
  shackle-mode: t
  windmove-mode: t
  global-auto-revert-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  marginalia-mode: t
  global-completion-preview-mode: t
  exwm-randr-mode: t
  server-mode: t
  override-global-mode: t
  straight-use-package-mode: t
  straight-package-neutering-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  buffer-read-only: t
  size-indication-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  overwrite-mode: overwrite-mode-binary

Load-path shadows:
/home/vent/.emacs.d/straight/build/transient/transient hides /usr/share/emacs/30.1/lisp/transient
/home/vent/.emacs.d/straight/build/seq/seq hides /usr/share/emacs/30.1/lisp/emacs-lisp/seq
/home/vent/.emacs.d/straight/build/compat/compat hides /usr/share/emacs/30.1/lisp/emacs-lisp/compat
/home/vent/.emacs.d/straight/build/let-alist/let-alist hides /usr/share/emacs/30.1/lisp/emacs-lisp/let-alist

Features:
(shadow mail-extr org-mime-autoloads mu4e mu4e-org mu4e-notification
notifications mu4e-main smtpmail mu4e-view mu4e-mime-parts mu4e-headers
mu4e-thread mu4e-actions mu4e-compose mu4e-draft gnus-msg gnus-art mm-uu
mml2015 mm-view mml-smime smime gnutls dig gnus-sum gnus-group gnus-undo
gnus-start gnus-dbus gnus-cloud nnimap nnmail mail-source utf7 nnoo
gnus-spec gnus-int gnus-range gnus-win mu4e-search mu4e-lists
mu4e-bookmarks mu4e-mark mu4e-message flow-fill mu4e-contacts
mu4e-update mu4e-folders mu4e-context mu4e-query-items mu4e-server
mu4e-modeline mu4e-vars mu4e-helpers mu4e-config mu4e-window
mu4e-obsolete emacsbug erc-track erc-ring erc-netsplit erc-menu
erc-match erc-list erc-goodies erc-imenu erc-pcomplete erc-join
erc-hl-nicks-autoloads erc-hl-nicks erc-button erc-fill erc-stamp erc
erc-backend erc-networks erc-common erc-compat erc-loaddefs shortdoc
completion goto-addr view apropos cus-start pcmpl-x dts-mode vterm
vterm-module term/xterm xterm tabify man git-rebase format-all
language-id inheritenv vc-hg vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs
log-view bug-reference magit-extras face-remap magit-bookmark
magit-submodule magit-blame magit-stash magit-reflog magit-bisect
magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-tag magit-merge
magit-branch magit-reset magit-files magit-refs magit-status magit
magit-repos magit-apply magit-wip magit-log which-func magit-diff
smerge-mode git-commit log-edit pcvs-util add-log magit-core
magit-autorevert magit-margin magit-transient magit-process with-editor
magit-mode transient benchmark magit-git magit-base magit-section
cursor-sensor crm llama consult-imenu pulse network-stream
display-line-numbers transmission diary-lib diary-loaddefs calc-bin
calc-ext elfeed-show elfeed-search message sendmail rfc822 mml mml-sec
epa epg rfc6068 epg-config mm-decode mailabbrev gmm-utils mailheader
elfeed-csv elfeed elfeed-curl elfeed-log elfeed-db elfeed-lib xml-query
transpose-frame tramp-archive tramp-gvfs help-fns radix-tree
emms-idapi-browser emms-idapi emms-idapi-musicbrainz mm-bodies mm-encode
emms-mpris emms-librefm-stream emms-librefm-scrobbler
emms-playlist-limit emms-i18n emms-history emms-score emms-stream-info
emms-metaplaylist-mode emms-bookmarks emms-cue emms-mode-line-icon
emms-browser sort emms-volume emms-volume-sndioctl emms-volume-mixerctl
emms-volume-pulse emms-volume-amixer emms-playlist-sort emms-last-played
emms-player-xine emms-player-mpd emms-lyrics emms-url emms-streams
emms-show-all emms-tag-editor emms-tag-tracktag emms-mark emms-mode-line
emms-cache emms-info-native emms-info-native-spc emms-info-native-mp3
emms-info-native-ogg emms-info-native-opus emms-info-native-flac
emms-info-native-vorbis bindat emms-info-exiftool emms-info-tinytag
emms-info-metaflac emms-info-opusinfo emms-info-ogginfo
emms-info-mp3info emms-playlist-mode emms-player-vlc emms-player-mpv
emms-playing-time emms-info emms-later-do emms-player-mplayer
emms-player-simple emms-source-playlist emms-source-file locate
emms-setup emms emms-compat dired-subtree dired-hacks-utils hl-line
tramp-cmds tramp-cache time-stamp ace-window avy yank-media misearch
multi-isearch pcmpl-git pcmpl-unix mule-util vc-git zig-mode
rainbow-delimiters subword-mode-expansions cap-words superword subword
highlight-escape-sequences highlight-numbers parent-mode
highlight-function-calls derived init.el pdf-occur tablist
tablist-filter semantic/wisent/comp semantic/wisent
semantic/wisent/wisent pdf-isearch let-alist pdf-misc pdf-tools package
url-handlers cus-edit cus-load pdf-view jka-compr pdf-cache pdf-info tq
pdf-util pdf-macs dired+ dired-aux dired+-autoloads image-dired
image-dired-tags image-dired-external image-dired-util image-mode
dired-collapse-autoloads f-autoloads dired-subtree-autoloads
dired-hacks-utils-autoloads dired-x dired dired-loaddefs exif coterm
term disp-table ehelp projectile grep ibuf-ext saveplace tramp-sh
so-long yasnippet-snippets-autoloads yasnippet-snippets yasnippet
eyebrowse corfu vertico gptel-autoloads elcord-autoloads ednc
ednc-autoloads cheat-sh-autoloads hackernews-autoloads eww url-queue shr
pixel-fill kinsoku url-file svg mm-url gnus nnheader gnus-util
mail-utils range w3m-autoloads browse-url ix grapnel ix-autoloads
grapnel-autoloads image+ image-file image-converter image+-autoloads
fortune-cookie fortune-cookie-autoloads elfeed-autoloads
transmission-autoloads openwith openwith-autoloads pdf-tools-autoloads
let-alist-autoloads tablist-autoloads emms-autoloads whitespace
smart-mode-line rich-minority smart-mode-line-autoloads
rich-minority-autoloads fancy-battery battery fancy-battery-autoloads
rainbow-delimiters-autoloads highlight-function-calls-autoloads
highlight-numbers-autoloads parent-mode-autoloads
highlight-escape-sequences-autoloads page-break-lines
page-break-lines-autoloads tramp trampver tramp-integration
tramp-message tramp-compat parse-time iso8601 tramp-loaddefs proced
exec-path-from-shell exec-path-from-shell-autoloads vterm-autoloads
coterm-autoloads xterm-color xterm-color-autoloads fish-completion
em-cmpl em-dirs esh-mode esh-var esh-cmd esh-ext esh-opt esh-proc esh-io
esh-arg esh-module esh-module-loaddefs esh-util files-x
fish-completion-autoloads bash-completion shx shx-autoloads embark-org
embark-consult embark ffap embark-consult-autoloads consult bookmark
markdown-mode color org-clock dbus xml ox-odt ox-latex ox-icalendar
ox-html table ox-ascii ox-publish ox org-attach org-habit org-agenda
the-org-mode-expansions org-element org-persist xdg org-id org-refile
org-element-ast inline avl-tree generator org ob ob-tangle ob-ref ob-lob
ob-table ob-exp org-macro org-src sh-script smie treesit executable
ob-comint org-pcomplete org-list org-footnote org-faces org-entities
time-date noutline outline ob-emacs-lisp ob-core ob-eval org-cycle
org-table ol org-fold org-fold-core org-keys oc org-loaddefs cal-menu
calendar cal-loaddefs org-version org-compat org-macs format-spec shell
pcomplete bash-completion-autoloads caml-mode-autoloads
ledger-mode-autoloads groovy-mode-autoloads tidal-autoloads
qt-pro-mode-autoloads bitbake-autoloads mmm-mode-autoloads
dockerfile-mode-autoloads yaml-mode-autoloads nix-mode-autoloads
glsl-mode-autoloads crontab-mode-autoloads kconfig-mode-autoloads
dts-mode-autoloads meson-mode-autoloads web-mode-autoloads
markdown-mode-autoloads haskell-mode-autoloads go-mode-autoloads
rust-mode-autoloads reformatter zig-mode-autoloads reformatter-autoloads
cc-mode-expansions cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles
cc-align cc-engine cc-vars cc-defs calc calc-loaddefs rect calc-macs
recentf tree-widget wid-edit winner shackle trace cl-print
shackle-autoloads windmove ace-window-autoloads avy-autoloads
ace-jump-mode advice cl ace-jump-mode-autoloads
transpose-frame-autoloads ibuffer ibuffer-loaddefs projectile-autoloads
eyebrowse-autoloads realgud-autoloads realgud-recursive-autoloads
test-simple-autoloads loc-changes-autoloads load-relative-autoloads
string-inflection-autoloads define-word nxml-mode-expansions rng-nxml
rng-valid rng-loc rng-uri rng-parse nxml-parse rng-match rng-dt rng-util
rng-pttrn nxml-ns nxml-mode nxml-outln nxml-rap html-mode-expansions
sgml-mode facemenu dom nxml-util nxml-enc xmltok url-http url url-proxy
url-privacy url-expand url-methods url-history mailcap url-auth
mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr
url-cookie generate-lisp-file url-domsuf url-gw nsm puny
define-word-autoloads semantic/util-modes semantic/util semantic
semantic/tag semantic/lex semantic/fw mode-local cedet unfill
unfill-autoloads expand-region text-mode-expansions er-basic-expansions
expand-region-core expand-region-custom expand-region-autoloads
autorevert format-all-autoloads language-id-autoloads
inheritenv-autoloads yasnippet-autoloads vc vc-dispatcher
magit-autoloads with-editor-autoloads transient-autoloads
magit-section-autoloads llama-autoloads ztree-autoloads undo-tree queue
undo-tree-autoloads queue-autoloads finder-inf dumb-jump popup dash s
dumb-jump-autoloads popup-autoloads dash-autoloads s-autoloads flyspell
ispell eglot external-completion jsonrpc xref flymake thingatpt project
seq-25 diff diff-mode track-changes ert pp ewoc debug backtrace
find-func filenotify compile text-property-search comint ansi-osc
ansi-color ring pcase url-util url-parse auth-source password-cache json
map url-vars imenu corfu-autoloads embark-autoloads consult-autoloads
ido vertico-autoloads orderless orderless-autoloads marginalia
marginalia-autoloads completion-preview exwm-randr xcb-randr exwm
exwm-input xcb-keysyms xcb-xkb exwm-manage exwm-floating xcb-cursor
xcb-render exwm-layout exwm-workspace exwm-core xcb-ewmh xcb-icccm xcb
xcb-xproto xcb-types xcb-debug eieio eieio-core server exwm-autoloads
xelb-autoloads comp comp-cstr warnings icons comp-run comp-common rx
zenbers-theme edmacro kmacro byte-opt diminish diminish-autoloads
use-package-ensure-system-package system-packages
system-packages-autoloads use-package use-package-ensure
use-package-delight use-package-diminish use-package-bind-key bind-key
easy-mmode no-littering compat no-littering-autoloads compat-autoloads
info seq-autoloads straight-autoloads straight subr-x cl-macs gv
cl-extra help-mode cl-seq use-package-core cl-loaddefs cl-lib bytecomp
byte-compile rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt
fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode
register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo gtk x-toolkit xinput2 x multi-tty move-toolbar
make-network-process native-compile emacs)

Memory information:
((conses 16 3809548 759425) (symbols 48 164178 17)
 (strings 32 958145 441164) (string-bytes 1 32828844)
 (vectors 16 191288) (vector-slots 8 3097097 245251)
 (floats 8 7839 8996) (intervals 56 87736 9154) (buffers 992 100))

-- 
Thanks,
~Rufus




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76817; Package emacs. (Fri, 07 Mar 2025 18:48:02 GMT) Full text and rfc822 format available.

Message #8 received at 76817 <at> debbugs.gnu.org (full text, mbox):

From: Eshel Yaron <me <at> eshelyaron.com>
To: Rufus Segar <rhs <at> riseup.net>
Cc: 76817 <at> debbugs.gnu.org
Subject: Re: bug#76817: 30.1; completion-preview and shell
Date: Fri, 07 Mar 2025 19:47:09 +0100
Hi Rufus,

Rufus Segar <rhs <at> riseup.net> writes:

> It appears that completion-preview-mode is not quite working as intended
> with shell. When inserting path completions it inserts a trailing space.

The trailing space comes from the :exit-function that the completion
backend specifies.  completion-preview-mode calls that :exit-function
when you insert a completion suggestion, so in that sense it does work
as intended.

Of course, I agree that this trailing space is undesirable for exactly
the reason you describe below.  You can disable it, as I do, by setting
either pcomplete-termination-string or pcomplete-exit-function.  Do you
get a better behavior with (setq pcomplete-termination-string "") ?

> An example will show why this is undesirable:
>
> Say I want to complete path `~/foobar/baz'. I start with `cd ~/foob` and
> completion-preview successfully completes the 'foobar' portion. However,
> after I do completion-preview-insert I'm left with the following:
>
> "cd ~/foobar/ "
>              ^-- Notice the trailing space
>
> This means that if I want to continue completing my path all the way to
> '~/foobar/baz', I have to delete that trailing space. completion-preview
> should not leave a trailing space, and if possible immediately continue
> completing the path, so that in this case I'm given '~/foobar/baz' as my
> next completion candidate and can simply call completion-preview-insert
> again to get the full path.
>
> P.S. I'm loving completion-preview-mode by the way, I can tell that a
> lot of care was put into this mode. I'm looking forward to this issue
> being resolved so that I can use it in my shell too.

Thanks!

Eshel




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76817; Package emacs. (Fri, 14 Mar 2025 17:01:02 GMT) Full text and rfc822 format available.

Message #11 received at 76817 <at> debbugs.gnu.org (full text, mbox):

From: Eshel Yaron <me <at> eshelyaron.com>
To: Rufus Segar <rhs <at> riseup.net>
Cc: 76817 <at> debbugs.gnu.org
Subject: Re: bug#76817: 30.1; completion-preview and shell
Date: Fri, 14 Mar 2025 17:59:58 +0100
[ Resending with the mailing list back in CC. ]

Hi Rufus,

Rufus Segar <rhs <at> riseup.net> writes:

> Hey Eshel,
>
>> Of course, I agree that this trailing space is undesirable for exactly
>> the reason you describe below.  You can disable it, as I do, by setting
>> either pcomplete-termination-string or pcomplete-exit-function.  Do you
>> get a better behavior with (setq pcomplete-termination-string "") ?
>
> Thanks! I added a hook to comint-mode to (setq pcomplete-termination-string "")
> and this has resolved the issue for me. Its working great now, so thanks again.

Great, thanks for confirming.

There's an alternative to setting pcomplete-termination-string directly,
which is to set comint-completion-addsuffix e.g. to nil.  Shell mode
consults this variable to and sets pcomplete-termination-string
accordingly, so if you set comint-completion-addsuffix once you don't
need to set pcomplete-termination-string via a hook.

I'd really like to make this work as you expect by default, so users
won't need this piece of configuration.  It's not hard to configure but
it's kind of an annoying gotcha...  It's mostly a matter of picking the
right place to tweak, since there are several intertwined components
that come into play.  For example, pcomplete-default-exit-function can
check if the completion ends with a directory separator (/), and if so
avoid adding pcomplete-termination-string.  I'll give it some thought,
and maybe someone who already gave it some thought will chime in too :)

>> The trailing space comes from the :exit-function that the completion
>> backend specifies.  completion-preview-mode calls that :exit-function
>> when you insert a completion suggestion, so in that sense it does work
>> as intended.
>
> I see. Interesting how it still inserts a trailing space after
> completing shell commands, even with the path completion fix described
> above. The trailing space is desirable here, so I ain't complaining,
> just curious.

Yeah, completion in Shell buffers is... involved.  In this case a
different :exit-function is in effect, which inserts a space regardless
of pcomplete-termination-string.  See shell--command-completion-data.


Regards,

Eshel




This bug report was last modified 29 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.