* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands @ 2023-05-22 16:27 Spencer Baugh 2023-05-22 17:51 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-05-22 16:27 UTC (permalink / raw) To: 63648 1. (setq project-switch-use-entire-map t) 2. C-x p p some/project RET 3. At the prompt, C-x C-j 4. Errors with: project-switch-project: Wrong type argument: commandp, 1 Desired behavior: commands should run with default-directory of the project-root. So C-x C-j should open dired in the project root. I specifically ran into this when doing C-x p p some/project RET C-x v + because I wanted to immediately pull that project. Intuitively it made sense to me that that should work, it would be nice if it did actually work. (Tangential further thought: I wonder if we could make C-x p work as a prefix for all commands automatically, so for example C-x p C-x C-j would open the project root, C-x p M-& would run a shell command in the root, etc. That would be neat.) In GNU Emacs 29.0.90 (build 3, x86_64-pc-linux-gnu, X toolkit, cairo version 1.15.12, Xaw scroll bars) of 2023-05-17 built on igm-qws-u22796a Repository revision: 4d08492296c2a6d2910f2b740c2d2508275458fc Repository branch: emacs-29 Windowing system distributor 'The X.Org Foundation', version 11.0.12011000 System Description: CentOS Linux 7 (Core) Configured using: 'configure --with-x-toolkit=lucid --with-gif=ifavailable' Configured features: CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS X11 XDBE XIM XINPUT2 XPM LUCID ZLIB Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: Messages Minor modes in effect: jane-fe-minor-mode: t editorconfig-mode: t which-function-mode: t global-git-commit-mode: t magit-auto-revert-mode: t shell-dirtrack-mode: t windmove-mode: t savehist-mode: t save-place-mode: t tooltip-mode: t global-eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tab-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t context-menu-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t buffer-read-only: t line-number-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/project hides /home/sbaugh/.emacs.d/elpa/project-0.9.8/project /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/xref hides /home/sbaugh/.emacs.d/elpa/xref-1.6.3/xref /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/csharp-mode hides /home/sbaugh/src/emacs/emacs-29/lisp/progmodes/csharp-mode /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/xref hides /home/sbaugh/src/emacs/emacs-29/lisp/progmodes/xref /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/project hides /home/sbaugh/src/emacs/emacs-29/lisp/progmodes/project /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/eldoc hides /home/sbaugh/src/emacs/emacs-29/lisp/emacs-lisp/eldoc /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/auctex/lpath hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/dictionary/lpath /home/sbaugh/src/emacs/emacs-29/lisp/net/dictionary hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/dictionary/dictionary /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/caml-font hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/ocaml/caml-font /home/sbaugh/src/emacs/emacs-29/lisp/org/org-version hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-version /home/sbaugh/src/emacs/emacs-29/lisp/org/org-loaddefs hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-loaddefs /home/sbaugh/src/emacs/emacs-29/lisp/org/org-keys hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-keys /home/sbaugh/src/emacs/emacs-29/lisp/org/ol hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-perl hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-perl /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-core hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-core /home/sbaugh/src/emacs/emacs-29/lisp/org/ox hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-rmail hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-rmail /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-octave hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-octave /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-comint hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-comint /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-w3m hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-w3m /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-org hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-org /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-texinfo hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-texinfo /home/sbaugh/src/emacs/emacs-29/lisp/org/org-inlinetask hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-inlinetask /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-mhe hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-mhe /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-ocaml hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-ocaml /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-clojure hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-clojure /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-publish hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-publish /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-irc hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-irc /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-calc hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-calc /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-odt hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-odt /home/sbaugh/src/emacs/emacs-29/lisp/org/org-id hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-id /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-gnus hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-gnus /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-matlab hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-matlab /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-icalendar hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-icalendar /home/sbaugh/src/emacs/emacs-29/lisp/org/org-footnote hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-footnote /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-bibtex hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-bibtex /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-lisp hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-lisp /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-C hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-C /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-org hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-org /home/sbaugh/src/emacs/emacs-29/lisp/org/org-indent hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-indent /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-info hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-info /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-maxima hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-maxima /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-awk hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-awk /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-man hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-man /home/sbaugh/src/emacs/emacs-29/lisp/org/org-goto hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-goto /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-md hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-md /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-eshell hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-eshell /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-lua hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-lua /home/sbaugh/src/emacs/emacs-29/lisp/org/org-habit hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-habit /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-R hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-R /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-eww hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-eww /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-makefile hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-makefile /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-latex hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-latex /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-docview hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-docview /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-lob hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-lob /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-beamer hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-beamer /home/sbaugh/src/emacs/emacs-29/lisp/org/org-faces hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-faces /home/sbaugh/src/emacs/emacs-29/lisp/org/ob hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-html hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-html /home/sbaugh/src/emacs/emacs-29/lisp/org/org-feed hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-feed /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-bbdb hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ol-bbdb /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-lilypond hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-lilypond /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-ascii hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ox-ascii /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-latex hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-latex /home/sbaugh/src/emacs/emacs-29/lisp/org/org hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-tangle hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-tangle /home/sbaugh/src/emacs/emacs-29/lisp/org/org-tempo hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-tempo /home/sbaugh/src/emacs/emacs-29/lisp/org/org-duration hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-duration /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-sqlite hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-sqlite /home/sbaugh/src/emacs/emacs-29/lisp/org/org-entities hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-entities /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-table hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-table /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-js hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-js /home/sbaugh/src/emacs/emacs-29/lisp/org/org-table hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-table /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-sql hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-sql /home/sbaugh/src/emacs/emacs-29/lisp/org/org-timer hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-timer /home/sbaugh/src/emacs/emacs-29/lisp/org/org-element hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-element /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-java hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-java /home/sbaugh/src/emacs/emacs-29/lisp/org/org-ctags hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-ctags /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-shell hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-shell /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-groovy hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-groovy /home/sbaugh/src/emacs/emacs-29/lisp/org/org-src hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-src /home/sbaugh/src/emacs/emacs-29/lisp/org/org-datetree hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-datetree /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-haskell hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-haskell /home/sbaugh/src/emacs/emacs-29/lisp/org/org-plot hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-plot /home/sbaugh/src/emacs/emacs-29/lisp/org/org-compat hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-compat /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-screen hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-screen /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-fortran hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-fortran /home/sbaugh/src/emacs/emacs-29/lisp/org/org-protocol hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-protocol /home/sbaugh/src/emacs/emacs-29/lisp/org/org-crypt hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-crypt /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-sed hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-sed /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-gnuplot hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-gnuplot /home/sbaugh/src/emacs/emacs-29/lisp/org/org-pcomplete hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-pcomplete /home/sbaugh/src/emacs/emacs-29/lisp/org/org-colview hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-colview /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-scheme hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-scheme /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-forth hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-forth /home/sbaugh/src/emacs/emacs-29/lisp/org/org-num hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-num /home/sbaugh/src/emacs/emacs-29/lisp/org/org-clock hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-clock /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-exp hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-exp /home/sbaugh/src/emacs/emacs-29/lisp/org/org-mouse hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-mouse /home/sbaugh/src/emacs/emacs-29/lisp/org/org-capture hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-capture /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-sass hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-sass /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-eval hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-eval /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-ref hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-ref /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-emacs-lisp hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-emacs-lisp /home/sbaugh/src/emacs/emacs-29/lisp/org/org-mobile hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-mobile /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-ruby hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-ruby /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-eshell hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-eshell /home/sbaugh/src/emacs/emacs-29/lisp/org/org-lint hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-lint /home/sbaugh/src/emacs/emacs-29/lisp/org/org-agenda hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-agenda /home/sbaugh/src/emacs/emacs-29/lisp/org/org-macro hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-macro /home/sbaugh/src/emacs/emacs-29/lisp/org/org-attach-git hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-attach-git /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-processing hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-processing /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-css hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-css /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-dot hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-dot /home/sbaugh/src/emacs/emacs-29/lisp/org/org-list hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-list /home/sbaugh/src/emacs/emacs-29/lisp/org/org-macs hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-macs /home/sbaugh/src/emacs/emacs-29/lisp/org/org-attach hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-attach /home/sbaugh/src/emacs/emacs-29/lisp/org/org-archive hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/org-archive /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-python hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-python /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-plantuml hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-plantuml /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-ditaa hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/lisp/ob-ditaa /home/sbaugh/src/emacs/emacs-29/lisp/org/ob-julia hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/contrib/lisp/ob-julia /home/sbaugh/src/emacs/emacs-29/lisp/org/ol-man hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/contrib/lisp/ol-man /home/sbaugh/src/emacs/emacs-29/lisp/org/ox-koma-letter hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/org/contrib/lisp/ox-koma-letter /home/sbaugh/.emacs.d/elpa/dash-2.19.1/dash hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/dash/dash /home/sbaugh/.emacs.d/elpa/dash-2.19.1/dash-functional hides /usr/local/home/sbaugh/workspaces/fe-47828/+share+/app/emacs/elisp/contrib/dash/dash-functional Features: (shadow sort mail-extr emacsbug cl-print cus-start cal-iso org-datetree dired-aux vc-git vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs log-view ediff ediff-merg ediff-mult ediff-wind ediff-diff ediff-help ediff-init ediff-util pulse shortdoc help-fns radix-tree misearch multi-isearch tabify org-capture sh-script treesit grep find-dired executable vc-fe org-element org-persist org-id org-refile avl-tree generator oc-basic ol-eww eww xdg url-queue mm-url ol-rmail ol-mhe ol-irc ol-info ol-gnus nnselect gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig gnus-sum shr pixel-fill kinsoku url-file svg dom gnus-group gnus-undo gnus-start gnus-dbus dbus xml gnus-cloud nnimap nnmail mail-source utf7 nnoo gnus-spec gnus-int gnus-range gnus-win gnus nnheader range ol-docview doc-view jka-compr image-mode exif ol-bibtex bibtex ol-bbdb ol-w3m ol-doi org-link-doi goto-addr cus-edit cus-load wid-edit vc-hg vc-dir vc vc-dispatcher tramp tramp-loaddefs trampver tramp-integration tramp-compat parse-time iso8601 ls-lisp jane-project ffap jane-merlin merlin-imenu merlin-xref merlin-cap merlin jane-async-merlin jane-completion jane-common jane-fe-project xref jane-fe-menu ecaml_plugin linum view gopcaml magit-bookmark bookmark image+ advice image-file image-converter editorconfig editorconfig-core editorconfig-core-handle editorconfig-fnmatch whitespace jane-auto-modes vba-mode markdown-mode color jane jane-micro-features jane-diff unified-test-mode shell-file core core-buffer core-error core-util ert pp ewoc debug backtrace jane-sexp jane-ocaml jane-tuareg-theme tuareg tuareg-compat tuareg-opam skeleton flymake-proc flymake warnings thingatpt smie caml-types caml-help caml-emacs find-file compile jane-cr jane-align jane-deprecated jane-smerge gnu-elpa-keyring-update jane-ocp-indent ocp-indent cl jane-util ob-shell page-ext dired-x magit-extras project magit-submodule magit-obsolete 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 imenu magit-diff smerge-mode diff diff-mode git-commit log-edit message sendmail yank-media puny dired dired-loaddefs rfc822 mml mml-sec epa epg rfc6068 epg-config gnus-util text-property-search mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils mailheader pcvs-util add-log magit-core magit-autorevert autorevert filenotify magit-margin magit-transient magit-process with-editor shell server magit-mode transient edmacro kmacro magit-git magit-section magit-utils crm dash cl-extra help-mode windmove org ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-src ob-comint org-pcomplete pcomplete org-list org-footnote org-faces org-entities time-date noutline outline icons ob-emacs-lisp ob-core ob-eval org-cycle org-table ol rx org-fold org-fold-core org-keys oc org-loaddefs find-func cal-menu calendar cal-loaddefs org-version org-compat org-macs format-spec gdb-mi bindat gud comint easy-mmode files-x derived ansi-osc ansi-color ring vundo pcase cyberpunk-theme savehist saveplace project-autoloads vundo-autoloads magit-autoloads xref-autoloads csv-mode-autoloads magit-section-autoloads cyberpunk-theme-autoloads url-http-ntlm-autoloads url-auth git-commit-autoloads with-editor-autoloads finder-inf info dash-autoloads vc-hgcmd-autoloads package browse-url url url-proxy url-privacy url-expand url-methods url-history url-cookie generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib 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 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 dynamic-setting system-font-setting font-render-setting cairo x-toolkit xinput2 x multi-tty make-network-process emacs) Memory information: ((conses 16 650875 91874) (symbols 48 45890 12) (strings 32 164696 16344) (string-bytes 1 5817957) (vectors 16 83175) (vector-slots 8 1714092 170471) (floats 8 577 249) (intervals 56 9811 200) (buffers 976 43) (heap 1024 690393 127136)) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-22 16:27 bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands Spencer Baugh @ 2023-05-22 17:51 ` Juri Linkov 2023-05-24 1:14 ` Dmitry Gutov 2023-05-24 14:55 ` Spencer Baugh 0 siblings, 2 replies; 109+ messages in thread From: Juri Linkov @ 2023-05-22 17:51 UTC (permalink / raw) To: Spencer Baugh; +Cc: 63648 > 1. (setq project-switch-use-entire-map t) > 2. C-x p p some/project RET > 3. At the prompt, C-x C-j > 4. Errors with: > project-switch-project: Wrong type argument: commandp, 1 > > Desired behavior: commands should run with default-directory of the > project-root. So C-x C-j should open dired in the project root. > > I specifically ran into this when doing > C-x p p some/project RET C-x v + > > because I wanted to immediately pull that project. Intuitively it made > sense to me that that should work, it would be nice if it did actually > work. This should be possible to implement by using 'set-transient-map'. > (Tangential further thought: I wonder if we could make C-x p work as a > prefix for all commands automatically, so for example C-x p C-x C-j > would open the project root, C-x p M-& would run a shell command in the > root, etc. That would be neat.) IOW, like 'C-x p p' but without asking for another project. Doable as well. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-22 17:51 ` Juri Linkov @ 2023-05-24 1:14 ` Dmitry Gutov 2023-05-24 6:20 ` Juri Linkov 2023-05-24 14:55 ` Spencer Baugh 1 sibling, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-05-24 1:14 UTC (permalink / raw) To: Juri Linkov, Spencer Baugh; +Cc: 63648 On 22/05/2023 20:51, Juri Linkov wrote: >> 1. (setq project-switch-use-entire-map t) >> 2. C-x p p some/project RET >> 3. At the prompt, C-x C-j >> 4. Errors with: >> project-switch-project: Wrong type argument: commandp, 1 >> >> Desired behavior: commands should run with default-directory of the >> project-root. So C-x C-j should open dired in the project root. >> >> I specifically ran into this when doing >> C-x p p some/project RET C-x v + >> >> because I wanted to immediately pull that project. Intuitively it made >> sense to me that that should work, it would be nice if it did actually >> work. > This should be possible to implement by using 'set-transient-map'. > >> (Tangential further thought: I wonder if we could make C-x p work as a >> prefix for all commands automatically, so for example C-x p C-x C-j >> would open the project root, C-x p M-& would run a shell command in the >> root, etc. That would be neat.) > IOW, like 'C-x p p' but without asking for another project. Doable as well. That sounds like a cool potential addition, just we all need to keep in mind that not every command will be 100% compatible with the approach. One example is the bug#58784 where changing default-directory made project-switch-to-buffer behave incorrectly. Maybe there are some less subtle examples as well. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 1:14 ` Dmitry Gutov @ 2023-05-24 6:20 ` Juri Linkov 2023-05-24 15:46 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-05-24 6:20 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648 >>> C-x p p some/project RET C-x v + >>> >>> because I wanted to immediately pull that project. Intuitively it made >>> sense to me that that should work, it would be nice if it did actually >>> work. >> This should be possible to implement by using 'set-transient-map'. >> >>> (Tangential further thought: I wonder if we could make C-x p work as a >>> prefix for all commands automatically, so for example C-x p C-x C-j >>> would open the project root, C-x p M-& would run a shell command in the >>> root, etc. That would be neat.) >> IOW, like 'C-x p p' but without asking for another project. Doable as well. > > That sounds like a cool potential addition, just we all need to keep in > mind that not every command will be 100% compatible with the approach. Why not every command? For example, 100% commands are compatible with 'C-x t t.' > One example is the bug#58784 where changing default-directory made > project-switch-to-buffer behave incorrectly. Maybe there are some less > subtle examples as well. 'display-buffer-override-next-command' already solved these problems. So a similar function could remember 'project-current-directory-override' for the next command. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 6:20 ` Juri Linkov @ 2023-05-24 15:46 ` Dmitry Gutov 2023-05-24 16:20 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-05-24 15:46 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648 On 24/05/2023 09:20, Juri Linkov wrote: >>>> C-x p p some/project RET C-x v + >>>> >>>> because I wanted to immediately pull that project. Intuitively it made >>>> sense to me that that should work, it would be nice if it did actually >>>> work. >>> This should be possible to implement by using 'set-transient-map'. >>> >>>> (Tangential further thought: I wonder if we could make C-x p work as a >>>> prefix for all commands automatically, so for example C-x p C-x C-j >>>> would open the project root, C-x p M-& would run a shell command in the >>>> root, etc. That would be neat.) >>> IOW, like 'C-x p p' but without asking for another project. Doable as well. >> >> That sounds like a cool potential addition, just we all need to keep in >> mind that not every command will be 100% compatible with the approach. > > Why not every command? For example, 100% commands are compatible with > 'C-x t t.' > >> One example is the bug#58784 where changing default-directory made >> project-switch-to-buffer behave incorrectly. Maybe there are some less >> subtle examples as well. > > 'display-buffer-override-next-command' already solved these problems. > So a similar function could remember 'project-current-directory-override' > for the next command. But we were talking about "regular" commands, right? Those don't know anything about project-current-directory-override. So we'd bind default-directory, and that's where the problem could come from. Hopefully, only in rare cases, though. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 15:46 ` Dmitry Gutov @ 2023-05-24 16:20 ` Juri Linkov 2023-05-24 17:37 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-05-24 16:20 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648 >>>>> C-x p p some/project RET C-x v + >>>>> >>>>> because I wanted to immediately pull that project. Intuitively it made >>>>> sense to me that that should work, it would be nice if it did actually >>>>> work. >>>> This should be possible to implement by using 'set-transient-map'. >>>> >>>>> (Tangential further thought: I wonder if we could make C-x p work as a >>>>> prefix for all commands automatically, so for example C-x p C-x C-j >>>>> would open the project root, C-x p M-& would run a shell command in the >>>>> root, etc. That would be neat.) >>>> IOW, like 'C-x p p' but without asking for another project. Doable as well. >>> >>> That sounds like a cool potential addition, just we all need to keep in >>> mind that not every command will be 100% compatible with the approach. >> Why not every command? For example, 100% commands are compatible with >> 'C-x t t.' >> >>> One example is the bug#58784 where changing default-directory made >>> project-switch-to-buffer behave incorrectly. Maybe there are some less >>> subtle examples as well. >> 'display-buffer-override-next-command' already solved these problems. >> So a similar function could remember 'project-current-directory-override' >> for the next command. > > But we were talking about "regular" commands, right? Those don't know > anything about project-current-directory-override. Any command indeed. They should use the temporarily set default-directory. > So we'd bind default-directory, and that's where the problem could come > from. Hopefully, only in rare cases, though. Naturally, this needs more testing. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 16:20 ` Juri Linkov @ 2023-05-24 17:37 ` Juri Linkov 2023-05-24 17:44 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-05-24 17:37 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648 >>> So a similar function could remember 'project-current-directory-override' >>> for the next command. >> >> But we were talking about "regular" commands, right? Those don't know >> anything about project-current-directory-override. > > Any command indeed. They should use the temporarily set default-directory. Actually, instead of 'project-current-directory-override' I meant 'default-directory'. But probably this is impossible to do because of these restrictions: 1. the current buffer should remain the same for the next command; 2. the buffer-local value of 'default-directory' should remain the same; 3. the next command should have a new value of 'default-directory'. I see no way to satisfy all these requirements. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 17:37 ` Juri Linkov @ 2023-05-24 17:44 ` Juri Linkov 2023-06-01 16:05 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-05-24 17:44 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648 >>>> So a similar function could remember 'project-current-directory-override' >>>> for the next command. >>> >>> But we were talking about "regular" commands, right? Those don't know >>> anything about project-current-directory-override. >> >> Any command indeed. They should use the temporarily set default-directory. > > Actually, instead of 'project-current-directory-override' I meant > 'default-directory'. But probably this is impossible to do > because of these restrictions: > > 1. the current buffer should remain the same for the next command; > 2. the buffer-local value of 'default-directory' should remain the same; > 3. the next command should have a new value of 'default-directory'. > > I see no way to satisfy all these requirements. Except adding a variable like 'project-current-directory-override' somewhere inside 'command_loop_1'. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 17:44 ` Juri Linkov @ 2023-06-01 16:05 ` Juri Linkov 2023-06-02 1:40 ` Dmitry Gutov ` (2 more replies) 0 siblings, 3 replies; 109+ messages in thread From: Juri Linkov @ 2023-06-01 16:05 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648 [-- Attachment #1: Type: text/plain, Size: 823 bytes --] >> 1. the current buffer should remain the same for the next command; >> 2. the buffer-local value of 'default-directory' should remain the same; >> 3. the next command should have a new value of 'default-directory'. >> >> I see no way to satisfy all these requirements. > > Except adding a variable like 'project-current-directory-override' > somewhere inside 'command_loop_1'. And indeed with the following patch replacing the current definition of 'project-switch-project' with just: (defun project-switch-project (dir) (interactive (list (funcall project-prompter))) (setq next-default-directory dir)) 'C-x p p (select project ...) RET M-& pwd RET' confirms that the command runs in the selected project directory. Whereas the original buffer keeps its previous buffer-local value of 'default-directory'. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: next-default-directory.patch --] [-- Type: text/x-diff, Size: 1374 bytes --] diff --git a/src/buffer.c b/src/buffer.c index 0c46b201586..ca81db21894 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5360,6 +5360,10 @@ syms_of_buffer (void) these names start with `/' or `~' and end with `/'. To interactively change the default directory, use command `cd'. */); + DEFVAR_LISP ("next-default-directory", Vnext_default_directory, + doc: /* Default directory for the next command. */); + Vnext_default_directory = Qnil; + DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function), Qnil, doc: /* Function called (if non-nil) to perform auto-fill. diff --git a/src/keyboard.c b/src/keyboard.c index 14c55666768..dfe939750c9 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1500,7 +1500,19 @@ command_loop_1 (void) update_redisplay_ticks (0, NULL); display_working_on_window_p = false; + Lisp_Object next_dir = Vnext_default_directory; + specpdl_ref count = SPECPDL_INDEX (); + if (!NILP (next_dir)) + specbind (Qdefault_directory, next_dir); + call1 (Qcommand_execute, Vthis_command); + + if (!NILP (next_dir)) + { + unbind_to (count, Qnil); + Vnext_default_directory = Qnil; + } + display_working_on_window_p = false; #ifdef HAVE_WINDOW_SYSTEM ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-01 16:05 ` Juri Linkov @ 2023-06-02 1:40 ` Dmitry Gutov 2023-06-02 6:40 ` Juri Linkov 2023-06-02 12:46 ` Eli Zaretskii 2023-06-02 6:32 ` Eli Zaretskii 2023-06-02 17:07 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2 siblings, 2 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-06-02 1:40 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648 On 01/06/2023 19:05, Juri Linkov wrote: >>> 1. the current buffer should remain the same for the next command; >>> 2. the buffer-local value of 'default-directory' should remain the same; >>> 3. the next command should have a new value of 'default-directory'. >>> >>> I see no way to satisfy all these requirements. >> >> Except adding a variable like 'project-current-directory-override' >> somewhere inside 'command_loop_1'. > > And indeed with the following patch replacing the current definition of > 'project-switch-project' with just: > > (defun project-switch-project (dir) > (interactive (list (funcall project-prompter))) > (setq next-default-directory dir)) Note that we'd need to keep the previous implementation for a number of years anyway, to retain compatibility with older emacsen. > 'C-x p p (select project ...) RET M-& pwd RET' confirms that > the command runs in the selected project directory. > Whereas the original buffer keeps its previous buffer-local value > of 'default-directory'. I suggest you bring up this feature addition on emacs-devel, or otherwise wait for a review from Eli, at least. It's not a big addition, but it's a distinct new feature (the next-default-directory var). ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 1:40 ` Dmitry Gutov @ 2023-06-02 6:40 ` Juri Linkov 2023-06-03 1:30 ` Dmitry Gutov 2023-08-10 11:56 ` sbaugh 2023-06-02 12:46 ` Eli Zaretskii 1 sibling, 2 replies; 109+ messages in thread From: Juri Linkov @ 2023-06-02 6:40 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648 >>>> 1. the current buffer should remain the same for the next command; >>>> 2. the buffer-local value of 'default-directory' should remain the same; >>>> 3. the next command should have a new value of 'default-directory'. >>>> >>>> I see no way to satisfy all these requirements. >>> >>> Except adding a variable like 'project-current-directory-override' >>> somewhere inside 'command_loop_1'. >> And indeed with the following patch replacing the current definition of >> 'project-switch-project' with just: >> (defun project-switch-project (dir) >> (interactive (list (funcall project-prompter))) >> (setq next-default-directory dir)) > > Note that we'd need to keep the previous implementation for a number of > years anyway, to retain compatibility with older emacsen. Then some version-depending condition could be added. >> 'C-x p p (select project ...) RET M-& pwd RET' confirms that >> the command runs in the selected project directory. >> Whereas the original buffer keeps its previous buffer-local value >> of 'default-directory'. > > I suggest you bring up this feature addition on emacs-devel, or otherwise > wait for a review from Eli, at least. > > It's not a big addition, but it's a distinct new feature (the > next-default-directory var). Indeed, such code addition better to be discussed on emacs-devel. But first need to ensure that it works with 'C-x p p'. Currently it works with keys from the global map such as 'C-x p p M-& pwd RET', but not with keys from 'project-prefix-map', e.g. 'C-x p p f'. Maybe in addition to (setq next-default-directory dir) also need to use 'set-transient-map' with 'project-prefix-map'. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 6:40 ` Juri Linkov @ 2023-06-03 1:30 ` Dmitry Gutov 2023-08-10 11:56 ` sbaugh 1 sibling, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-06-03 1:30 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648 On 02/06/2023 09:40, Juri Linkov wrote: > Indeed, such code addition better to be discussed on emacs-devel. > But first need to ensure that it works with 'C-x p p'. > Currently it works with keys from the global map such as > 'C-x p p M-& pwd RET', but not with keys from 'project-prefix-map', e.g. > 'C-x p p f'. Maybe in addition to (setq next-default-directory dir) > also need to use 'set-transient-map' with 'project-prefix-map'. Here's another question: will we be able to reimplement the current behavior? Meaning, first of all, having a loop where the user is asked to use some existing binding from the menu, or from the keymap, but when a key is typed which does not correspond to some existing command, we ask again and again until the user chooses some existing one, or pressed C-g. 'set-transient-map' seems like a viable approach, but it will only let the user try once, right? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 6:40 ` Juri Linkov 2023-06-03 1:30 ` Dmitry Gutov @ 2023-08-10 11:56 ` sbaugh 2023-08-23 13:53 ` Spencer Baugh 1 sibling, 1 reply; 109+ messages in thread From: sbaugh @ 2023-08-10 11:56 UTC (permalink / raw) To: Juri Linkov; +Cc: Dmitry Gutov, 63648, Spencer Baugh Juri Linkov <juri@linkov.net> writes: >>>>> 1. the current buffer should remain the same for the next command; >>>>> 2. the buffer-local value of 'default-directory' should remain the same; >>>>> 3. the next command should have a new value of 'default-directory'. >>>>> >>>>> I see no way to satisfy all these requirements. >>>> >>>> Except adding a variable like 'project-current-directory-override' >>>> somewhere inside 'command_loop_1'. >>> And indeed with the following patch replacing the current definition of >>> 'project-switch-project' with just: >>> (defun project-switch-project (dir) >>> (interactive (list (funcall project-prompter))) >>> (setq next-default-directory dir)) >> >> Note that we'd need to keep the previous implementation for a number of >> years anyway, to retain compatibility with older emacsen. > > Then some version-depending condition could be added. > >>> 'C-x p p (select project ...) RET M-& pwd RET' confirms that >>> the command runs in the selected project directory. >>> Whereas the original buffer keeps its previous buffer-local value >>> of 'default-directory'. >> >> I suggest you bring up this feature addition on emacs-devel, or otherwise >> wait for a review from Eli, at least. >> >> It's not a big addition, but it's a distinct new feature (the >> next-default-directory var). > > Indeed, such code addition better to be discussed on emacs-devel. Did this end up being discussed on emacs-devel? I am still quite interested in this feature. > But first need to ensure that it works with 'C-x p p'. > Currently it works with keys from the global map such as > 'C-x p p M-& pwd RET', but not with keys from 'project-prefix-map', e.g. > 'C-x p p f'. Maybe in addition to (setq next-default-directory dir) > also need to use 'set-transient-map' with 'project-prefix-map'. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-10 11:56 ` sbaugh @ 2023-08-23 13:53 ` Spencer Baugh 2023-08-23 17:54 ` Juri Linkov 2023-08-28 22:44 ` Dmitry Gutov 0 siblings, 2 replies; 109+ messages in thread From: Spencer Baugh @ 2023-08-23 13:53 UTC (permalink / raw) To: sbaugh; +Cc: Dmitry Gutov, 63648, Juri Linkov sbaugh@catern.com writes: > Juri Linkov <juri@linkov.net> writes: > >>>>>> 1. the current buffer should remain the same for the next command; >>>>>> 2. the buffer-local value of 'default-directory' should remain the same; >>>>>> 3. the next command should have a new value of 'default-directory'. >>>>>> >>>>>> I see no way to satisfy all these requirements. >>>>> >>>>> Except adding a variable like 'project-current-directory-override' >>>>> somewhere inside 'command_loop_1'. >>>> And indeed with the following patch replacing the current definition of >>>> 'project-switch-project' with just: >>>> (defun project-switch-project (dir) >>>> (interactive (list (funcall project-prompter))) >>>> (setq next-default-directory dir)) >>> >>> Note that we'd need to keep the previous implementation for a number of >>> years anyway, to retain compatibility with older emacsen. >> >> Then some version-depending condition could be added. >> >>>> 'C-x p p (select project ...) RET M-& pwd RET' confirms that >>>> the command runs in the selected project directory. >>>> Whereas the original buffer keeps its previous buffer-local value >>>> of 'default-directory'. >>> >>> I suggest you bring up this feature addition on emacs-devel, or otherwise >>> wait for a review from Eli, at least. >>> >>> It's not a big addition, but it's a distinct new feature (the >>> next-default-directory var). >> >> Indeed, such code addition better to be discussed on emacs-devel. > > Did this end up being discussed on emacs-devel? I am still quite > interested in this feature. Oh, another thought (which maybe should be discussed on emacs-devel): maybe we don't need to make this specific next-default-directory var. Instead, maybe what we want is a way to bind a dynamic variable *without* changing the buffer-local value. It would shadow the existing binding, but if we explicitly switched buffer we'd get back to the old value. So we'd have: (special-let ((default-directory newval)) (assert default-directory newval)) and (special-let ((default-directory newval)) (set-buffer (current-buffer)) (assert default-directory oldval)) Ignore any complexities of implementing this and any complexities of the semantics which I haven't covered. If we had this, would it work as an alternative to next-default-directory? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-23 13:53 ` Spencer Baugh @ 2023-08-23 17:54 ` Juri Linkov 2023-08-29 20:36 ` Spencer Baugh 2023-08-29 20:40 ` Dmitry Gutov 2023-08-28 22:44 ` Dmitry Gutov 1 sibling, 2 replies; 109+ messages in thread From: Juri Linkov @ 2023-08-23 17:54 UTC (permalink / raw) To: Spencer Baugh; +Cc: sbaugh, 63648, Dmitry Gutov >>>> I suggest you bring up this feature addition on emacs-devel, or otherwise >>>> wait for a review from Eli, at least. >>>> >>>> It's not a big addition, but it's a distinct new feature (the >>>> next-default-directory var). >>> >>> Indeed, such code addition better to be discussed on emacs-devel. >> >> Did this end up being discussed on emacs-devel? I am still quite >> interested in this feature. > > Oh, another thought (which maybe should be discussed on emacs-devel): > maybe we don't need to make this specific next-default-directory var. > > Instead, maybe what we want is a way to bind a dynamic variable > *without* changing the buffer-local value. It would shadow the existing > binding, but if we explicitly switched buffer we'd get back to the old > value. So we'd have: > > (special-let ((default-directory newval)) > (assert default-directory newval)) > > and > > (special-let ((default-directory newval)) > (set-buffer (current-buffer)) > (assert default-directory oldval)) > > Ignore any complexities of implementing this and any complexities of the > semantics which I haven't covered. If we had this, would it work as an > alternative to next-default-directory? There is no code where to bind a dynamic variable, because its value should be available for the next command in the command loop. If you agree there is no other way to implement this than next-default-directory, then I could bring up the discussion on emacs-devel. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-23 17:54 ` Juri Linkov @ 2023-08-29 20:36 ` Spencer Baugh 2023-08-29 20:40 ` Dmitry Gutov 1 sibling, 0 replies; 109+ messages in thread From: Spencer Baugh @ 2023-08-29 20:36 UTC (permalink / raw) To: Juri Linkov; +Cc: sbaugh, 63648, Dmitry Gutov Juri Linkov <juri@linkov.net> writes: >>>>> I suggest you bring up this feature addition on emacs-devel, or otherwise >>>>> wait for a review from Eli, at least. >>>>> >>>>> It's not a big addition, but it's a distinct new feature (the >>>>> next-default-directory var). >>>> >>>> Indeed, such code addition better to be discussed on emacs-devel. >>> >>> Did this end up being discussed on emacs-devel? I am still quite >>> interested in this feature. >> >> Oh, another thought (which maybe should be discussed on emacs-devel): >> maybe we don't need to make this specific next-default-directory var. >> >> Instead, maybe what we want is a way to bind a dynamic variable >> *without* changing the buffer-local value. It would shadow the existing >> binding, but if we explicitly switched buffer we'd get back to the old >> value. So we'd have: >> >> (special-let ((default-directory newval)) >> (assert default-directory newval)) >> >> and >> >> (special-let ((default-directory newval)) >> (set-buffer (current-buffer)) >> (assert default-directory oldval)) >> >> Ignore any complexities of implementing this and any complexities of the >> semantics which I haven't covered. If we had this, would it work as an >> alternative to next-default-directory? > > There is no code where to bind a dynamic variable, because its value > should be available for the next command in the command loop. Oh, that's true. (I guess maybe we could add a way to do that, and other prefix commands could work that way too. But that would be a big effort - and worth talking about on emacs-devel) > If you agree there is no other way to implement this than next-default-directory, > then I could bring up the discussion on emacs-devel. Yes, seems like that's the only way. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-23 17:54 ` Juri Linkov 2023-08-29 20:36 ` Spencer Baugh @ 2023-08-29 20:40 ` Dmitry Gutov 2023-08-29 21:47 ` Spencer Baugh 2023-08-30 16:27 ` Juri Linkov 1 sibling, 2 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-08-29 20:40 UTC (permalink / raw) To: Juri Linkov, Spencer Baugh; +Cc: sbaugh, 63648 [-- Attachment #1: Type: text/plain, Size: 1031 bytes --] Sorry for the possible duplicate, but it seems this message didn't reach the bug tracker, or other recipients. Resending contents below. On 23/08/2023 20:54, Juri Linkov wrote: > There is no code where to bind a dynamic variable, because its value > should be available for the next command in the command loop. > If you agree there is no other way to implement this than next-default-directory, > then I could bring up the discussion on emacs-devel. Before we dive into all that, why not try advice on 'command-execute'? For the PoC code at least. It's in Lisp since 2013. The comment in its body does say "Called directly from the C code", but I'm not sure if that has any direct implications for us. This attached piece of code implements the project-switch-project as you outlined. Does it work well for you/others? Careful when testing or modifying: a typo can break the command loop (and thus the session). To me it seems a little too bare-bones, lacking the instructive hints project-switch-project currently has. [-- Attachment #2: next-dd.el --] [-- Type: text/x-emacs-lisp, Size: 387 bytes --] (defvar project--next-dd nil) (defun project--with-next-dd (fun &rest args) (advice-remove 'command-execute #'project--with-next-dd) (let ((default-directory project--next-dd)) (apply fun args))) (defun project-switch-project (dir) (interactive (list (funcall project-prompter))) (setq project--next-dd dir) (advice-add 'command-execute :around #'project--with-next-dd)) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-29 20:40 ` Dmitry Gutov @ 2023-08-29 21:47 ` Spencer Baugh 2023-08-29 22:32 ` Dmitry Gutov 2023-08-30 16:27 ` Juri Linkov 1 sibling, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-08-29 21:47 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > Sorry for the possible duplicate, but it seems this message didn't > reach the bug tracker, or other recipients. Resending contents below. > > On 23/08/2023 20:54, Juri Linkov wrote: >> There is no code where to bind a dynamic variable, because its value >> should be available for the next command in the command loop. >> If you agree there is no other way to implement this than next-default-directory, >> then I could bring up the discussion on emacs-devel. > > Before we dive into all that, why not try advice on 'command-execute'? > For the PoC code at least. It's in Lisp since 2013. > > The comment in its body does say "Called directly from the C code", > but I'm not sure if that has any direct implications for us. > > This attached piece of code implements the project-switch-project as > you outlined. Does it work well for you/others? Careful when testing > or modifying: a typo can break the command loop (and thus the > session). > > To me it seems a little too bare-bones, lacking the instructive hints > project-switch-project currently has. Nice! One thing at least to make it not quite so bare-bones is: (defun project-switch-project (dir) (interactive (list (funcall project-prompter))) (setq project--next-dd dir) (advice-add 'command-execute :around #'project--with-next-dd) (message "Run next command in project %s..." (project-name (project-current nil dir)))) which matches other-window-prefix. Will try running with this for a while and see how it goes. (I'm already missing the short form of project-find-files, but maybe I'll get used to it... or maybe we should remap C-x C-f to project-find-files while in this prefix, or something wacky like that) > (defvar project--next-dd nil) > > (defun project--with-next-dd (fun &rest args) > (advice-remove 'command-execute #'project--with-next-dd) > (let ((default-directory project--next-dd)) > (apply fun args))) > > (defun project-switch-project (dir) > (interactive (list (funcall project-prompter))) > (setq project--next-dd dir) > (advice-add 'command-execute :around #'project--with-next-dd)) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-29 21:47 ` Spencer Baugh @ 2023-08-29 22:32 ` Dmitry Gutov 0 siblings, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-08-29 22:32 UTC (permalink / raw) To: Spencer Baugh; +Cc: sbaugh, 63648, Juri Linkov On 30/08/2023 00:47, Spencer Baugh wrote: > Nice! > > One thing at least to make it not quite so bare-bones is: > > (defun project-switch-project (dir) > (interactive (list (funcall project-prompter))) > (setq project--next-dd dir) > (advice-add 'command-execute :around #'project--with-next-dd) > (message "Run next command in project %s..." (project-name (project-current nil dir)))) > > which matches other-window-prefix. Definitely an improvement, but still -- any such message is likely soon overridden by the prefix echo (e.g. "C-x p-"). > Will try running with this for a while and see how it goes. (I'm > already missing the short form of project-find-files, but maybe I'll get > used to it... or maybe we should remap C-x C-f to project-find-files > while in this prefix, or something wacky like that) It could also use set-transient-map to set up a given map (e.g. one with the fast keys), and for the rest fall back to global commands. Note that our current project-switch-project impl could also be augmented to do that. Anyway, please test it out and see how you like it, and whatever improvements come to mind. In either case, we can add a new command (rather than replacing project-switch-project). E.g. call it project-switch-for-next-command. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-29 20:40 ` Dmitry Gutov 2023-08-29 21:47 ` Spencer Baugh @ 2023-08-30 16:27 ` Juri Linkov 2023-08-31 2:01 ` Dmitry Gutov 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-08-30 16:27 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 973 bytes --] >> There is no code where to bind a dynamic variable, because its value >> should be available for the next command in the command loop. >> If you agree there is no other way to implement this than next-default-directory, >> then I could bring up the discussion on emacs-devel. > > Before we dive into all that, why not try advice on 'command-execute'? For > the PoC code at least. It's in Lisp since 2013. Thanks for bringing up 'command-execute'. I forgot it was moved from C to Lisp, so the change is simpler and not needed to discuss on emacs-devel. Then advice on 'command-execute' will be required to support older Emacs versions in project.el. But for Emacs 30 I modified my previous patch, and the next version is below: > The comment in its body does say "Called directly from the C code", but I'm > not sure if that has any direct implications for us. Also interesting how 'command-execute' handles 'debug-on-next-call' similar to 'next-default-directory'. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: next-default-directory.patch --] [-- Type: text/x-diff, Size: 11333 bytes --] diff --git a/lisp/simple.el b/lisp/simple.el index 05a3c4b93d6..ff665111a5d 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2752,6 +2752,9 @@ oclosure-interactive-form (let ((if (cconv--interactive-helper--if f))) `(interactive ,(if (functionp if) `(funcall ',if) if)))) +(defvar next-default-directory nil + "Default directory for the next command.") + (defun command-execute (cmd &optional record-flag keys special) ;; BEWARE: Called directly from the C code. "Execute CMD as an editor command. @@ -2803,7 +2806,11 @@ command-execute (execute-kbd-macro final prefixarg)) (t ;; Pass `cmd' rather than `final', for the backtrace's sake. - (prog1 (call-interactively cmd record-flag keys) + (prog1 (if next-default-directory + (let ((default-directory next-default-directory)) + (prog1 (call-interactively cmd record-flag keys) + (setq next-default-directory nil))) + (call-interactively cmd record-flag keys)) (when-let ((info (and (symbolp cmd) (not (get cmd 'command-execute-obsolete-warned)) diff --git a/lisp/window.el b/lisp/window.el index b9b032c33e9..006531ab017 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9122,7 +9114,8 @@ display-buffer-override-next-command (> (minibuffer-depth) minibuffer-depth) ;; But don't remove immediately after ;; adding the hook by the same command below. - (eq this-command command)) + (eq this-command command) + (eq this-command 'project-switch-project)) (funcall exitfun)))) ;; Call post-function after the next command finishes (bug#49057). (add-hook 'post-command-hook postfun) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 7aaf7a9f9fb..f87bb750e23 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -193,9 +193,10 @@ project-find-functions 'project-current-directory-override "29.1") -(defvar project-current-directory-override nil - "Value to use instead of `default-directory' when detecting the project. -When it is non-nil, `project-current' will always skip prompting too.") +(define-obsolete-variable-alias + 'project-current-directory-override + 'next-default-directory + "30.1") (defcustom project-prompter #'project-prompt-project-dir "Function to call to prompt for a project. @@ -227,12 +228,11 @@ project-current See the doc string of `project-find-functions' for the general form of the project instance object." - (unless directory (setq directory (or project-current-directory-override - default-directory))) + (unless directory (setq directory default-directory)) (let ((pr (project--find-in-directory directory))) (cond (pr) - ((unless project-current-directory-override + ((unless next-default-directory maybe-prompt) (setq directory (funcall project-prompter) pr (project--find-in-directory directory)))) @@ -846,8 +846,8 @@ project-prefix-map ;;;###autoload (define-key ctl-x-map "p" project-prefix-map) -;; We can't have these place-specific maps inherit from -;; project-prefix-map because project--other-place-command needs to +;; Maybe we can have these place-specific maps inherit from +;; project-prefix-map because set-transient-map maybe needs to ;; know which map the key binding came from, as if it came from one of ;; these maps, we don't want to set display-buffer-overriding-action @@ -863,16 +863,6 @@ project-other-frame-map map) "Keymap for project commands that display buffers in other frames.") -(defun project--other-place-command (action &optional map) - (let* ((key (read-key-sequence-vector nil t)) - (place-cmd (lookup-key map key)) - (generic-cmd (lookup-key project-prefix-map key)) - (switch-to-buffer-obey-display-actions t) - (display-buffer-overriding-action (unless place-cmd action))) - (if-let ((cmd (or place-cmd generic-cmd))) - (call-interactively cmd) - (user-error "%s is undefined" (key-description key))))) - ;;;###autoload (defun project-other-window-command () "Run project command, displaying resultant buffer in another window. @@ -882,9 +872,10 @@ project-other-window-command \\{project-prefix-map} \\{project-other-window-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-window) - (inhibit-same-window . t)) - project-other-window-map)) + (let ((inhibit-message t)) (other-window-prefix)) + (message "Display next project command buffer in a new window...") + (set-transient-map (make-composed-keymap project-prefix-map + project-other-window-map))) ;;;###autoload (define-key ctl-x-4-map "p" #'project-other-window-command) @@ -897,8 +888,10 @@ project-other-frame-command \\{project-prefix-map} \\{project-other-frame-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-frame)) - project-other-frame-map)) + (let ((inhibit-message t)) (other-frame-prefix)) + (message "Display next project command buffer in a new frame...") + (set-transient-map (make-composed-keymap project-prefix-map + project-other-frame-map))) ;;;###autoload (define-key ctl-x-5-map "p" #'project-other-frame-command) @@ -910,7 +903,9 @@ project-other-tab-command \\{project-prefix-map}" (interactive) - (project--other-place-command '((display-buffer-in-new-tab)))) + (let ((inhibit-message t)) (other-tab-prefix)) + (message "Display next project command buffer in a new tab...") + (set-transient-map project-prefix-map)) ;;;###autoload (when (bound-and-true-p tab-prefix-map) @@ -993,13 +988,13 @@ project--find-default-from "Ensure FILENAME is in PROJECT. Usually, just return FILENAME. But if -`project-current-directory-override' is set, adjust it to be +`next-default-directory' is set, adjust it to be relative to PROJECT instead. This supports using a relative file name from the current buffer when switching projects with `project-switch-project' and then using a command like `project-find-file'." - (if-let (filename-proj (and project-current-directory-override + (if-let (filename-proj (and next-default-directory (project-current nil default-directory))) ;; file-name-concat requires Emacs 28+ (concat (file-name-as-directory (project-root project)) @@ -1893,16 +1888,17 @@ project-switch-commands (character :tag "Explicit key")))) (symbol :tag "Single command"))) -(defcustom project-switch-use-entire-map nil - "Whether `project-switch-project' will use the entire `project-prefix-map'. -If nil, `project-switch-project' will only recognize commands -listed in `project-switch-commands', and will signal an error -when other commands are invoked. If this is non-nil, all the -keys in `project-prefix-map' are valid even if they aren't -listed in the dispatch menu produced from `project-switch-commands'." - :type 'boolean - :group 'project - :version "28.1") +;; OBSOLETE? +;; (defcustom project-switch-use-entire-map nil +;; "Whether `project-switch-project' will use the entire `project-prefix-map'. +;; If nil, `project-switch-project' will only recognize commands +;; listed in `project-switch-commands', and will signal an error +;; when other commands are invoked. If this is non-nil, all the +;; keys in `project-prefix-map' are valid even if they aren't +;; listed in the dispatch menu produced from `project-switch-commands'." +;; :type 'boolean +;; :group 'project +;; :version "28.1") (defcustom project-key-prompt-style (if (facep 'help-key-binding) t @@ -1938,39 +1934,6 @@ project--keymap-prompt project-switch-commands " ")) -(defun project--switch-project-command () - (let* ((commands-menu - (mapcar - (lambda (row) - (if (characterp (car row)) - ;; Deprecated format. - ;; XXX: Add a warning about it? - (reverse row) - row)) - project-switch-commands)) - (commands-map - (let ((temp-map (make-sparse-keymap))) - (set-keymap-parent temp-map project-prefix-map) - (dolist (row commands-menu temp-map) - (when-let ((cmd (nth 0 row)) - (keychar (nth 2 row))) - (define-key temp-map (vector keychar) cmd))))) - command) - (while (not command) - (let* ((overriding-local-map commands-map) - (choice (read-key-sequence (project--keymap-prompt)))) - (when (setq command (lookup-key commands-map choice)) - (unless (or project-switch-use-entire-map - (assq command commands-menu)) - ;; TODO: Add some hint to the prompt, like "key not - ;; recognized" or something. - (setq command nil))) - (let ((global-command (lookup-key (current-global-map) choice))) - (when (memq global-command - '(keyboard-quit keyboard-escape-quit)) - (call-interactively global-command))))) - command)) - ;;;###autoload (defun project-switch-project (dir) "\"Switch\" to another project by running an Emacs command. @@ -1980,11 +1943,18 @@ project-switch-project When called in a program, it will use the project corresponding to directory DIR." (interactive (list (funcall project-prompter))) - (let ((command (if (symbolp project-switch-commands) - project-switch-commands - (project--switch-project-command)))) - (let ((project-current-directory-override dir)) - (call-interactively command)))) + (if (symbolp project-switch-commands) + (let ((default-directory dir)) + (call-interactively project-switch-commands)) + (let* ((echofun (lambda () "[switch-project]")) + (postfun (lambda () (remove-hook + 'prefix-command-echo-keystrokes-functions + echofun)))) + (setq next-default-directory dir) + (message (project--keymap-prompt)) + (add-hook 'prefix-command-echo-keystrokes-functions echofun) + (prefix-command-preserve-state) + (set-transient-map project-prefix-map nil postfun)))) ;;;###autoload (defun project-uniquify-dirname-transform (dirname) diff --git a/test/lisp/progmodes/project-tests.el b/test/lisp/progmodes/project-tests.el index 5a206b67db1..bc8c0553f40 100644 --- a/test/lisp/progmodes/project-tests.el +++ b/test/lisp/progmodes/project-tests.el @@ -41,7 +41,7 @@ project/quoted-directory (skip-unless (executable-find "grep")) (ert-with-temp-directory directory (let ((default-directory directory) - (project-current-directory-override t) + (next-default-directory directory) (project-find-functions nil) (project-list-file (expand-file-name "projects" directory)) ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-30 16:27 ` Juri Linkov @ 2023-08-31 2:01 ` Dmitry Gutov 2023-08-31 6:47 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-08-31 2:01 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 30/08/2023 19:27, Juri Linkov wrote: >>> There is no code where to bind a dynamic variable, because its value >>> should be available for the next command in the command loop. >>> If you agree there is no other way to implement this than next-default-directory, >>> then I could bring up the discussion on emacs-devel. >> Before we dive into all that, why not try advice on 'command-execute'? For >> the PoC code at least. It's in Lisp since 2013. > Thanks for bringing up 'command-execute'. I forgot it was moved from C to Lisp, > so the change is simpler and not needed to discuss on emacs-devel. Then advice > on 'command-execute' will be required to support older Emacs versions in project.el. > But for Emacs 30 I modified my previous patch, and the next version is below: > >> The comment in its body does say "Called directly from the C code", but I'm >> not sure if that has any direct implications for us. > Also interesting how 'command-execute' handles 'debug-on-next-call' > similar to 'next-default-directory'. I've tried the patch a little bit, some more impressions: - Unfortunately, using default-directory instead of the specialized variable which we added lately (project-current-directory-override) brings back the bug it was added for: https://debbugs.gnu.org/58784. The switch to a different design didn't fix the problem of the temporary binding for d-d in the buffer which is current when the command is executed. So adding the next-default-directory variable might not be the best idea after all. But the advice thingy can set a binding for any variable, including the *-override one. - I also managed to get into some transient state where some chars were doing one thing (their usual bindings), and some - invoked project commands instead, with no apparent method of quitting that state. Maybe I'll document it next time I see it. - Using (project--keymap-prompt) for just a message call is cute, but I personally like the "guardrails": if I accidentally type a wrong char when choosing the command, I won't have to choose the other project again. This is debatable, but both modes of operation are probably worth keeping available (opinions welcome). - Either way, with method with the advice should be useful for other things, like project--other-place-command. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-31 2:01 ` Dmitry Gutov @ 2023-08-31 6:47 ` Juri Linkov 2023-08-31 11:13 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-08-31 6:47 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh > I've tried the patch a little bit, some more impressions: > > - Unfortunately, using default-directory instead of the specialized > variable which we added lately (project-current-directory-override) > brings back the bug it was added for: https://debbugs.gnu.org/58784. The > switch to a different design didn't fix the problem of the temporary > binding for d-d in the buffer which is current when the command is > executed. So adding the next-default-directory variable might not be the > best idea after all. But the advice thingy can set a binding for any > variable, including the *-override one. I didn't test yet the cases from bug#58784. So this might require more changes. > - I also managed to get into some transient state where some chars were > doing one thing (their usual bindings), and some - invoked project > commands instead, with no apparent method of quitting that state. Maybe > I'll document it next time I see it. It would be nice to have a reproducible test case. But indeed chars in the project map invoke the project commands, and all other chars fall back to local/global keybindings. > - Using (project--keymap-prompt) for just a message call is cute, but > I personally like the "guardrails": if I accidentally type a wrong char > when choosing the command, I won't have to choose the other project > again. This is debatable, but both modes of operation are probably worth > keeping available (opinions welcome). This is easy to do with something like in 'y-or-n-p-map'. > - Either way, with method with the advice should be useful for other > things, like project--other-place-command. It's not recommended to use advice in the core packages, maybe only for providing backward-compatibility with older versions. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-31 6:47 ` Juri Linkov @ 2023-08-31 11:13 ` Dmitry Gutov 2023-08-31 16:36 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-08-31 11:13 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 31/08/2023 09:47, Juri Linkov wrote: >> I've tried the patch a little bit, some more impressions: >> >> - Unfortunately, using default-directory instead of the specialized >> variable which we added lately (project-current-directory-override) >> brings back the bug it was added for: https://debbugs.gnu.org/58784. The >> switch to a different design didn't fix the problem of the temporary >> binding for d-d in the buffer which is current when the command is >> executed. So adding the next-default-directory variable might not be the >> best idea after all. But the advice thingy can set a binding for any >> variable, including the *-override one. > > I didn't test yet the cases from bug#58784. So this might require more changes. We tried to make the default-directory binding work with a couple of different changes - it didn't work out. >> - I also managed to get into some transient state where some chars were >> doing one thing (their usual bindings), and some - invoked project >> commands instead, with no apparent method of quitting that state. Maybe >> I'll document it next time I see it. > > It would be nice to have a reproducible test case. > But indeed chars in the project map invoke the project commands, > and all other chars fall back to local/global keybindings. > >> - Using (project--keymap-prompt) for just a message call is cute, but >> I personally like the "guardrails": if I accidentally type a wrong char >> when choosing the command, I won't have to choose the other project >> again. This is debatable, but both modes of operation are probably worth >> keeping available (opinions welcome). > > This is easy to do with something like in 'y-or-n-p-map'. With setting that (or similar) keymap as a transient keymap? >> - Either way, with method with the advice should be useful for other >> things, like project--other-place-command. > > It's not recommended to use advice in the core packages, > maybe only for providing backward-compatibility with older versions. Sure, but it should also be permissible when there is no other way to do a thing. OTOH, if we're talking about new features in core, we could have a next-command-variables-alist, where we'd bind any variables that we would want. A general question regarding this approach, for me, is: is a "prefix command" a real command? And would they "swallow" these prepared variable bindings too early? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-31 11:13 ` Dmitry Gutov @ 2023-08-31 16:36 ` Juri Linkov 2023-09-01 1:11 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-08-31 16:36 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >>> - Unfortunately, using default-directory instead of the specialized >>> variable which we added lately (project-current-directory-override) >>> brings back the bug it was added for: https://debbugs.gnu.org/58784. The >>> switch to a different design didn't fix the problem of the temporary >>> binding for d-d in the buffer which is current when the command is >>> executed. So adding the next-default-directory variable might not be the >>> best idea after all. But the advice thingy can set a binding for any >>> variable, including the *-override one. >> I didn't test yet the cases from bug#58784. So this might require more >> changes. > > We tried to make the default-directory binding work with a couple of > different changes - it didn't work out. The problem is that let-binding overrides the buffer-local value: ``` (let ((default-directory "/tmp/")) (list default-directory (buffer-local-value 'default-directory (current-buffer)))) => ("/tmp/" "/tmp/") ``` Here is the shortest test case: 'C-x p p C-b' shows buffers from two projects when using let-binding for default-directory, because 'project-buffers' relies on (buffer-local-value 'default-directory buf) This could be fixed by adding special-handling of the default-directory for the current buffer in 'project-buffers'. >>> - I also managed to get into some transient state where some chars were >>> doing one thing (their usual bindings), and some - invoked project >>> commands instead, with no apparent method of quitting that state. Maybe >>> I'll document it next time I see it. >> It would be nice to have a reproducible test case. >> But indeed chars in the project map invoke the project commands, >> and all other chars fall back to local/global keybindings. >> >>> - Using (project--keymap-prompt) for just a message call is cute, but >>> I personally like the "guardrails": if I accidentally type a wrong char >>> when choosing the command, I won't have to choose the other project >>> again. This is debatable, but both modes of operation are probably worth >>> keeping available (opinions welcome). >> This is easy to do with something like in 'y-or-n-p-map'. > > With setting that (or similar) keymap as a transient keymap? Something like this. >>> - Either way, with method with the advice should be useful for other >>> things, like project--other-place-command. >> It's not recommended to use advice in the core packages, >> maybe only for providing backward-compatibility with older versions. > > Sure, but it should also be permissible when there is no other way to do > a thing. > > OTOH, if we're talking about new features in core, we could have > a next-command-variables-alist, where we'd bind any variables that we would > want. Such generalization could be added later. > A general question regarding this approach, for me, is: is a "prefix > command" a real command? It's a real command that prepares some transient values for the next command. Most existing prefix commands have no problems because they modify global values. But 'default-directory' is the first buffer-local variable used for the next command, therefore it requires special-handling. Too bad that 'default-directory' is not a function. > And would they "swallow" these prepared variable bindings too early? The scope of the modified variable depends on concrete needs. For example, set-transient-map restores its old value in pre-command-hook, but display-buffer-override-next-command does this in post-command-hook. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-31 16:36 ` Juri Linkov @ 2023-09-01 1:11 ` Dmitry Gutov 2023-09-01 6:46 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-01 1:11 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 31/08/2023 19:36, Juri Linkov wrote: >>>> - Unfortunately, using default-directory instead of the specialized >>>> variable which we added lately (project-current-directory-override) >>>> brings back the bug it was added for: https://debbugs.gnu.org/58784. The >>>> switch to a different design didn't fix the problem of the temporary >>>> binding for d-d in the buffer which is current when the command is >>>> executed. So adding the next-default-directory variable might not be the >>>> best idea after all. But the advice thingy can set a binding for any >>>> variable, including the *-override one. >>> I didn't test yet the cases from bug#58784. So this might require more >>> changes. >> >> We tried to make the default-directory binding work with a couple of >> different changes - it didn't work out. > > The problem is that let-binding overrides the buffer-local value: Yep. > ``` > (let ((default-directory "/tmp/")) > (list default-directory > (buffer-local-value 'default-directory (current-buffer)))) > => ("/tmp/" "/tmp/") > ``` > > Here is the shortest test case: 'C-x p p C-b' shows buffers > from two projects when using let-binding for default-directory, > because 'project-buffers' relies on > > (buffer-local-value 'default-directory buf) > > This could be fixed by adding special-handling of the default-directory > for the current buffer in 'project-buffers'. What kind of special handling? The "real" buffer-local value is hidden until the "let" exists, the global value is nil, and if the buffer is not a file-visiting one, there is no other file name to test against. Finally, whatever special handling we invent, would have to be mirrored by all subsequent new commands (built-in and third-party) which look up the value of default-directory. Especially project-related ones. How to popularize that knowledge, would be the next question for whatever solution we invent. >> A general question regarding this approach, for me, is: is a "prefix >> command" a real command? > > It's a real command that prepares some transient values for the next command. > Most existing prefix commands have no problems because they modify global > values. But 'default-directory' is the first buffer-local variable > used for the next command, therefore it requires special-handling. > Too bad that 'default-directory' is not a function. I suppose the new code could check against some property or dynamic var to distinguish prefix commands from "terminal" ones. >> And would they "swallow" these prepared variable bindings too early? > > The scope of the modified variable depends on concrete needs. > For example, set-transient-map restores its old value in pre-command-hook, > but display-buffer-override-next-command does this in post-command-hook. That can also work - though the odds of getting into an unrecoverable state (such as one I described) would be higher. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-01 1:11 ` Dmitry Gutov @ 2023-09-01 6:46 ` Juri Linkov 2023-09-01 9:53 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-01 6:46 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >> (let ((default-directory "/tmp/")) >> (list default-directory >> (buffer-local-value 'default-directory (current-buffer)))) >> => ("/tmp/" "/tmp/") >> Here is the shortest test case: 'C-x p p C-b' shows buffers >> from two projects when using let-binding for default-directory, >> because 'project-buffers' relies on >> (buffer-local-value 'default-directory buf) >> This could be fixed by adding special-handling of the default-directory >> for the current buffer in 'project-buffers'. > > What kind of special handling? The "real" buffer-local value is hidden > until the "let" exists, the global value is nil, and if the buffer is not > a file-visiting one, there is no other file name to test against. Additional buffer-local variable like 'buffer-default-directory' could help. Or additional global variable 'global-default-directory'. Or even using the global value of the existing variable 'default-directory'. > Finally, whatever special handling we invent, would have to be mirrored by > all subsequent new commands (built-in and third-party) which look up the > value of default-directory. Especially project-related ones. How to > popularize that knowledge, would be the next question for whatever solution > we invent. Hopefully there should be not much trouble such as in 'project-buffers'. >>> A general question regarding this approach, for me, is: is a "prefix >>> command" a real command? >> It's a real command that prepares some transient values for the next >> command. >> Most existing prefix commands have no problems because they modify global >> values. But 'default-directory' is the first buffer-local variable >> used for the next command, therefore it requires special-handling. >> Too bad that 'default-directory' is not a function. > > I suppose the new code could check against some property or dynamic var to > distinguish prefix commands from "terminal" ones. Currently I see no need for this. >>> And would they "swallow" these prepared variable bindings too early? >> The scope of the modified variable depends on concrete needs. >> For example, set-transient-map restores its old value in pre-command-hook, >> but display-buffer-override-next-command does this in post-command-hook. > > That can also work - though the odds of getting into an unrecoverable state > (such as one I described) would be higher. This is strange, no one reported an unrecoverable state for set-transient-map. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-01 6:46 ` Juri Linkov @ 2023-09-01 9:53 ` Dmitry Gutov 2023-09-01 15:59 ` Spencer Baugh 2023-09-10 15:30 ` Juri Linkov 0 siblings, 2 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-09-01 9:53 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 01/09/2023 09:46, Juri Linkov wrote: >>> (let ((default-directory "/tmp/")) >>> (list default-directory >>> (buffer-local-value 'default-directory (current-buffer)))) >>> => ("/tmp/""/tmp/") >>> Here is the shortest test case: 'C-x p p C-b' shows buffers >>> from two projects when using let-binding for default-directory, >>> because 'project-buffers' relies on >>> (buffer-local-value 'default-directory buf) >>> This could be fixed by adding special-handling of the default-directory >>> for the current buffer in 'project-buffers'. >> What kind of special handling? The "real" buffer-local value is hidden >> until the "let" exists, the global value is nil, and if the buffer is not >> a file-visiting one, there is no other file name to test against. > Additional buffer-local variable like 'buffer-default-directory' could help. > Or additional global variable 'global-default-directory'. Or even > using the global value of the existing variable 'default-directory'. What code would use it instead of the local value of default-directory? Only project-related code? Or other code as well? If it's the former, we have an existing variable in the project package. If the latter, we'd need some formal description of those usage rules to proceed. >> Finally, whatever special handling we invent, would have to be mirrored by >> all subsequent new commands (built-in and third-party) which look up the >> value of default-directory. Especially project-related ones. How to >> popularize that knowledge, would be the next question for whatever solution >> we invent. > Hopefully there should be not much trouble such as in 'project-buffers'. I think there exists a class of commands (existing and potential ones) that would use default-directory with exact same purpose and expectations. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-01 9:53 ` Dmitry Gutov @ 2023-09-01 15:59 ` Spencer Baugh 2023-09-02 1:47 ` Dmitry Gutov 2023-09-03 17:11 ` Juri Linkov 2023-09-10 15:30 ` Juri Linkov 1 sibling, 2 replies; 109+ messages in thread From: Spencer Baugh @ 2023-09-01 15:59 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > On 01/09/2023 09:46, Juri Linkov wrote: >>>> (let ((default-directory "/tmp/")) >>>> (list default-directory >>>> (buffer-local-value 'default-directory (current-buffer)))) >>>> => ("/tmp/""/tmp/") >>>> Here is the shortest test case: 'C-x p p C-b' shows buffers >>>> from two projects when using let-binding for default-directory, >>>> because 'project-buffers' relies on >>>> (buffer-local-value 'default-directory buf) >>>> This could be fixed by adding special-handling of the default-directory >>>> for the current buffer in 'project-buffers'. >>> What kind of special handling? The "real" buffer-local value is hidden >>> until the "let" exists, the global value is nil, and if the buffer is not >>> a file-visiting one, there is no other file name to test against. >> Additional buffer-local variable like 'buffer-default-directory' could help. >> Or additional global variable 'global-default-directory'. Or even >> using the global value of the existing variable 'default-directory'. > > What code would use it instead of the local value of > default-directory? Only project-related code? Or other code as well? > If it's the former, we have an existing variable in the project > package. If the latter, we'd need some formal description of those > usage rules to proceed. > >>> Finally, whatever special handling we invent, would have to be mirrored by >>> all subsequent new commands (built-in and third-party) which look up the >>> value of default-directory. Especially project-related ones. How to >>> popularize that knowledge, would be the next question for whatever solution >>> we invent. >> Hopefully there should be not much trouble such as in 'project-buffers'. > > I think there exists a class of commands (existing and potential ones) > that would use default-directory with exact same purpose and > expectations. Thinking about it, I guess there's (roughly) two classes of commands which want different things from default-directory, classes 1 and 2: 1. wants whatever the current value of default-directory is (and gets this by just using default-directory as a variable) 2. wants the value of default-directory for some specific buffer X (and gets this either with buffer-local-value or by using with-current-buffer) If we could change 1 without changing 2, then we'd be happy. This gets back to my earlier suggestion, that we have some way of binding a variable which does not change the buffer-local value. Supporting that would require fairly deep changes in C of course. (But actually, maybe it would be useful for Lisp threads? In fact, maybe Lisp threads already support this? Because when you're in a thread and you bind default-directory, you don't want that to affect any other threads, you only want it to affect code running directly under you.) --- Anyway, I'm coming around to the idea that actually the "changing the local value of default-directory" problem isn't that big of a deal. We can do something special for project-buffers, and that would make things work OK with the next-default-directory approach, and if we run into further problems in the future, we'll rethink at that time. Maybe with more time running with the code, we will come up with something new and clever. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-01 15:59 ` Spencer Baugh @ 2023-09-02 1:47 ` Dmitry Gutov 2023-09-03 17:11 ` Juri Linkov 1 sibling, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-09-02 1:47 UTC (permalink / raw) To: Spencer Baugh; +Cc: sbaugh, 63648, Juri Linkov On 01/09/2023 18:59, Spencer Baugh wrote: >>> Hopefully there should be not much trouble such as in 'project-buffers'. >> >> I think there exists a class of commands (existing and potential ones) >> that would use default-directory with exact same purpose and >> expectations. > > Thinking about it, I guess there's (roughly) two classes of commands > which want different things from default-directory, classes 1 and 2: > > 1. wants whatever the current value of default-directory is (and gets > this by just using default-directory as a variable) > > 2. wants the value of default-directory for some specific buffer X (and > gets this either with buffer-local-value or by using > with-current-buffer) > > If we could change 1 without changing 2, then we'd be happy. Yes, maybe. > This gets back to my earlier suggestion, that we have some way of > binding a variable which does not change the buffer-local value. > Supporting that would require fairly deep changes in C of course. > > (But actually, maybe it would be useful for Lisp threads? In fact, > maybe Lisp threads already support this? Because when you're in a > thread and you bind default-directory, you don't want that to affect any > other threads, you only want it to affect code running directly under > you.) It might be useful, sure. But as for how reasonable would be to have such a primitive, I'd rather defer to our language gurus (a question on emacs-devel would be a good idea). > Anyway, I'm coming around to the idea that actually the "changing the > local value of default-directory" problem isn't that big of a deal. We > can do something special for project-buffers, and that would make things > work OK with the next-default-directory approach, and if we run into > further problems in the future, we'll rethink at that time. > > Maybe with more time running with the code, we will come up with > something new and clever. It's a minor problem, but we've already went through two rounds on bug#58784 (first finding one solution, then a problem with it, and ending up with project-current-directory-override). I'd rather not throw out a solution that covers the known edge cases too eagerly. So I don't like an idea of a "special fix" in project-buffers, but if anyone has a specific patch to show, please go ahead. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-01 15:59 ` Spencer Baugh 2023-09-02 1:47 ` Dmitry Gutov @ 2023-09-03 17:11 ` Juri Linkov 2023-09-11 20:16 ` Spencer Baugh 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-03 17:11 UTC (permalink / raw) To: Spencer Baugh; +Cc: Dmitry Gutov, 63648, sbaugh > Thinking about it, I guess there's (roughly) two classes of commands > which want different things from default-directory, classes 1 and 2: > > 1. wants whatever the current value of default-directory is (and gets > this by just using default-directory as a variable) > > 2. wants the value of default-directory for some specific buffer X (and > gets this either with buffer-local-value or by using > with-current-buffer) > > If we could change 1 without changing 2, then we'd be happy. I think we can't solve this logical paradox because it contains self-contradictory requirements. Here is the command that illustrates this paradox. What should this command print? C-x p p ... C-h v default-directory RET Like Schrödinger's cat, it belongs simultaneously to both classes: 1. wants to print the new value of default-directory because 'C-h v' is the next command for which the value of default-directory was explicitly set. 2. wants to print the original value of default-directory because 'C-h v' was invoked in the buffer where the value of default-directory should stay unchanged. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-03 17:11 ` Juri Linkov @ 2023-09-11 20:16 ` Spencer Baugh 2023-09-12 6:55 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-09-11 20:16 UTC (permalink / raw) To: Juri Linkov; +Cc: Dmitry Gutov, 63648, sbaugh Juri Linkov <juri@linkov.net> writes: >> Thinking about it, I guess there's (roughly) two classes of commands >> which want different things from default-directory, classes 1 and 2: >> >> 1. wants whatever the current value of default-directory is (and gets >> this by just using default-directory as a variable) >> >> 2. wants the value of default-directory for some specific buffer X (and >> gets this either with buffer-local-value or by using >> with-current-buffer) >> >> If we could change 1 without changing 2, then we'd be happy. > > I think we can't solve this logical paradox because it contains > self-contradictory requirements. Here is the command that > illustrates this paradox. What should this command print? > > C-x p p ... C-h v default-directory RET > > Like Schrödinger's cat, it belongs simultaneously to both classes: > > 1. wants to print the new value of default-directory > because 'C-h v' is the next command for which > the value of default-directory was explicitly set. > > 2. wants to print the original value of default-directory > because 'C-h v' was invoked in the buffer where > the value of default-directory should stay unchanged. I would argue that it's in class 1. Or at least, it would make sense for C-h v to print the new value. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-11 20:16 ` Spencer Baugh @ 2023-09-12 6:55 ` Juri Linkov 0 siblings, 0 replies; 109+ messages in thread From: Juri Linkov @ 2023-09-12 6:55 UTC (permalink / raw) To: Spencer Baugh; +Cc: Dmitry Gutov, 63648, sbaugh >> 1. wants to print the new value of default-directory >> because 'C-h v' is the next command for which >> the value of default-directory was explicitly set. >> >> 2. wants to print the original value of default-directory >> because 'C-h v' was invoked in the buffer where >> the value of default-directory should stay unchanged. > > I would argue that it's in class 1. Or at least, it would make sense > for C-h v to print the new value. I agree. And the latest patch does this. It prints the new value on 'C-x p p ... C-h v'. Then you can type 'g' and it reverts to the original value. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-01 9:53 ` Dmitry Gutov 2023-09-01 15:59 ` Spencer Baugh @ 2023-09-10 15:30 ` Juri Linkov 2023-09-12 23:47 ` Dmitry Gutov 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-10 15:30 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 1475 bytes --] >>>> This could be fixed by adding special-handling of the default-directory >>>> for the current buffer in 'project-buffers'. >>> What kind of special handling? The "real" buffer-local value is hidden >>> until the "let" exists, the global value is nil, and if the buffer is not >>> a file-visiting one, there is no other file name to test against. >> Additional buffer-local variable like 'buffer-default-directory' could help. >> Or additional global variable 'global-default-directory'. Or even >> using the global value of the existing variable 'default-directory'. > > What code would use it instead of the local value of default-directory? > Only project-related code? Or other code as well? If it's the former, we > have an existing variable in the project package. If the latter, we'd need > some formal description of those usage rules to proceed. The former. So given all the considered constraints we have to admit there is a possibility that some rare non-project command that checks default-directory in all buffers might get a wrong value for one buffer when it's called immediately after 'C-x p p'. OTOH, such a reasonable compromise can help us fix other bugs such as bug#65558. So here is a complete tested patch that maintains backward-compatibility with older versions, and is localized to project.el without the need to discuss more fundamental changes on emacs-devel, and handles 100% of known cases such as reported in bug#58784, bug#63829, etc. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: other-project-prefix.patch --] [-- Type: text/x-diff, Size: 9449 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 2e6ae89a443..257c0da4264 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -197,6 +197,19 @@ project-current-directory-override "Value to use instead of `default-directory' when detecting the project. When it is non-nil, `project-current' will always skip prompting too.") +(make-obsolete-variable + 'project-current-directory-override + 'project-current-directory-old + "30.1") + +(defvar-local project-current-directory-old nil + "Value to use instead of `default-directory' when detecting the project. +For the next command after switching the project, this buffer-local +variable contains the original value of `default-directory'. +Whereas the buffer-local `default-directory' is temporarily set +to the root directory of the switched project. +When it is non-nil, `project-current' will always skip prompting too.") + (defcustom project-prompter #'project-prompt-project-dir "Function to call to prompt for a project. Called with no arguments and should return a project root dir." @@ -232,7 +245,8 @@ project-current (let ((pr (project--find-in-directory directory))) (cond (pr) - ((unless project-current-directory-override + ((unless (or project-current-directory-override + project-current-directory-old) maybe-prompt) (setq directory (funcall project-prompter) pr (project--find-in-directory directory)))) @@ -397,8 +411,10 @@ project-buffers (let ((root (expand-file-name (file-name-as-directory (project-root project)))) bufs) (dolist (buf (buffer-list)) - (when (string-prefix-p root (expand-file-name - (buffer-local-value 'default-directory buf))) + (when (string-prefix-p + root (expand-file-name + (or (buffer-local-value 'project-current-directory-old buf) + (buffer-local-value 'default-directory buf)))) (push buf bufs))) (nreverse bufs))) @@ -813,7 +829,9 @@ project-buffers dd bufs) (dolist (buf (buffer-list)) - (setq dd (expand-file-name (buffer-local-value 'default-directory buf))) + (setq dd (expand-file-name + (or (buffer-local-value 'project-current-directory-old buf) + (buffer-local-value 'default-directory buf)))) (when (and (string-prefix-p root dd) (not (cl-find-if (lambda (module) (string-prefix-p module dd)) modules))) @@ -842,7 +860,9 @@ project-prefix-map (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) - (define-key map "p" 'project-switch-project) + (define-key map "p" (if (< emacs-major-version 30) + 'project-switch-project + 'other-project-prefix)) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) @@ -889,10 +909,16 @@ project-other-window-command \\{project-prefix-map} \\{project-other-window-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-window) - (inhibit-same-window . t)) - project-other-window-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-window) + (inhibit-same-window . t)) + project-other-window-map) + (let ((inhibit-message t)) (other-window-prefix)) + (message "Display next project command buffer in a new window...") + (set-transient-map (make-composed-keymap project-prefix-map + project-other-window-map)))) +;; TODO: maybe rename to project-other-window-prefix ;;;###autoload (define-key ctl-x-4-map "p" #'project-other-window-command) ;;;###autoload @@ -904,8 +930,13 @@ project-other-frame-command \\{project-prefix-map} \\{project-other-frame-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-frame)) - project-other-frame-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-frame)) + project-other-frame-map) + (let ((inhibit-message t)) (other-frame-prefix)) + (message "Display next project command buffer in a new frame...") + (set-transient-map (make-composed-keymap project-prefix-map + project-other-frame-map)))) ;;;###autoload (define-key ctl-x-5-map "p" #'project-other-frame-command) @@ -917,7 +948,11 @@ project-other-tab-command \\{project-prefix-map}" (interactive) - (project--other-place-command '((display-buffer-in-new-tab)))) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-in-new-tab))) + (let ((inhibit-message t)) (other-tab-prefix)) + (message "Display next project command buffer in a new tab...") + (set-transient-map project-prefix-map))) ;;;###autoload (when (bound-and-true-p tab-prefix-map) @@ -1000,14 +1035,16 @@ project--find-default-from "Ensure FILENAME is in PROJECT. Usually, just return FILENAME. But if -`project-current-directory-override' is set, adjust it to be +`project-current-directory-old' is set, adjust it to be relative to PROJECT instead. This supports using a relative file name from the current buffer when switching projects with `project-switch-project' and then using a command like `project-find-file'." - (if-let (filename-proj (and project-current-directory-override - (project-current nil default-directory))) + (if-let (filename-proj (or (and project-current-directory-override + (project-current nil default-directory)) + (and project-current-directory-old + (project-current nil project-current-directory-old)))) ;; file-name-concat requires Emacs 28+ (concat (file-name-as-directory (project-root project)) (file-relative-name filename (project-root filename-proj))) @@ -1993,6 +2030,50 @@ project-switch-project (let ((project-current-directory-override dir)) (call-interactively command)))) +;;;###autoload +(defun other-project-prefix (dir) + "\"Switch\" to another project before running an Emacs command. +The available commands are presented as a dispatch menu +made from `project-switch-commands'. + +When called in a program, it will use the project corresponding +to directory DIR." + (interactive (list (funcall project-prompter))) + (if (symbolp project-switch-commands) + (let* ((project-current-directory-old default-directory) + (default-directory dir)) + (call-interactively project-switch-commands)) + (prefix-command-preserve-state) + (letrec ((minibuffer-depth (minibuffer-depth)) + (command this-command) + (old-buffer (current-buffer)) + (echofun (lambda () "[switch-project]")) + (postfun + (lambda () + (unless (or (eq this-command command) + (> (minibuffer-depth) minibuffer-depth)) + (remove-hook 'post-command-hook postfun) + (remove-hook 'prefix-command-echo-keystrokes-functions + echofun) + (when (buffer-live-p old-buffer) + (with-current-buffer old-buffer + (when project-current-directory-old + (setq-local default-directory project-current-directory-old) + (kill-local-variable 'project-current-directory-old)))))))) + (add-hook 'post-command-hook postfun) + (add-hook 'prefix-command-echo-keystrokes-functions echofun) + (setq-local project-current-directory-old default-directory) + (setq-local default-directory dir) + (message (project--keymap-prompt)) + (let ((commands-map + (let ((temp-map (make-sparse-keymap))) + (set-keymap-parent temp-map project-prefix-map) + (dolist (row project-switch-commands temp-map) + (when-let ((cmd (nth 0 row)) + (keychar (nth 2 row))) + (define-key temp-map (vector keychar) cmd)))))) + (set-transient-map commands-map))))) + ;;;###autoload (defun project-uniquify-dirname-transform (dirname) "Uniquify name of directory DIRNAME using `project-name', if in a project. diff --git a/lisp/window.el b/lisp/window.el index b9b032c33e9..b67b3dced9c 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9122,7 +9114,8 @@ display-buffer-override-next-command (> (minibuffer-depth) minibuffer-depth) ;; But don't remove immediately after ;; adding the hook by the same command below. - (eq this-command command)) + (eq this-command command) + (eq this-command 'other-project-prefix)) (funcall exitfun)))) ;; Call post-function after the next command finishes (bug#49057). (add-hook 'post-command-hook postfun) ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-10 15:30 ` Juri Linkov @ 2023-09-12 23:47 ` Dmitry Gutov 2023-09-13 6:47 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-12 23:47 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh Hi Juri, On 10/09/2023 18:30, Juri Linkov wrote: > So here is a complete tested patch that maintains backward-compatibility > with older versions, and is localized to project.el without the need to > discuss more fundamental changes on emacs-devel, and handles 100% of > known cases such as reported in bug#58784, bug#63829, etc. It sounds like a possibly concise solution, but I'm still wrapping my head around it. > +(make-obsolete-variable > + 'project-current-directory-override > + 'project-current-directory-old > + "30.1") Aren't those variables sufficiently different that making one an alias for another would confuse things? > +(defvar-local project-current-directory-old nil > + "Value to use instead of `default-directory' when detecting the project. > +For the next command after switching the project, this buffer-local > +variable contains the original value of `default-directory'. > +Whereas the buffer-local `default-directory' is temporarily set > +to the root directory of the switched project. > +When it is non-nil, `project-current' will always skip prompting too.") The docstring is valuable, but I wonder how it looks to somebody from the outside trying to write code that would use it. > + (or (buffer-local-value 'project-current-directory-old buf) > + (buffer-local-value 'default-directory buf)))) ... > + (or (buffer-local-value 'project-current-directory-old buf) > + (buffer-local-value 'default-directory buf)))) So, this part looks like what we would be paying for this solution: any code looking to decide whether a buffer "belongs" to the project, would have to reproduce this exact expression. Wouldn't it? > + (setq-local project-current-directory-old default-directory) > + (setq-local default-directory dir) Could you explain: if we can just set these here and then clean up in postfun, couldn't we likewise set (and then later clean up) the value of project-current-directory-override? > - (eq this-command command)) > + (eq this-command command) > + (eq this-command 'other-project-prefix)) Did this part of the patch get in by accident? If it's "localized to project.el". Or do we have further plans to "generalize" that place somehow? Just making sure. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-12 23:47 ` Dmitry Gutov @ 2023-09-13 6:47 ` Juri Linkov 2023-09-18 0:12 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-13 6:47 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >> So here is a complete tested patch that maintains backward-compatibility >> with older versions, and is localized to project.el without the need to >> discuss more fundamental changes on emacs-devel, and handles 100% of >> known cases such as reported in bug#58784, bug#63829, etc. > > It sounds like a possibly concise solution, but I'm still wrapping my head > around it. > >> +(make-obsolete-variable >> + 'project-current-directory-override >> + 'project-current-directory-old >> + "30.1") > > Aren't those variables sufficiently different that making one an alias for > another would confuse things? Indeed, during development I mistakenly made one an alias for another with 'define-obsolete-variable-alias', and this broke both variables. So I replaced it with 'make-obsolete-variable' that doesn't make an alias. It just designates it as obsolete to show the intention to remove it in later versions. >> +(defvar-local project-current-directory-old nil >> + "Value to use instead of `default-directory' when detecting the project. >> +For the next command after switching the project, this buffer-local >> +variable contains the original value of `default-directory'. >> +Whereas the buffer-local `default-directory' is temporarily set >> +to the root directory of the switched project. >> +When it is non-nil, `project-current' will always skip prompting too.") > > The docstring is valuable, but I wonder how it looks to somebody from the > outside trying to write code that would use it. I don't believe that someone might want to use this variable in more commands than the current project commands that rely on 'project-buffers'. But we could add a few more lines with explanations for them too. >> + (or (buffer-local-value 'project-current-directory-old buf) >> + (buffer-local-value 'default-directory buf)))) > ... >> + (or (buffer-local-value 'project-current-directory-old buf) >> + (buffer-local-value 'default-directory buf)))) > > So, this part looks like what we would be paying for this solution: any > code looking to decide whether a buffer "belongs" to the project, would > have to reproduce this exact expression. Wouldn't it? Then maybe this code should be moved to a separate function? >> + (setq-local project-current-directory-old default-directory) >> + (setq-local default-directory dir) > > Could you explain: if we can just set these here and then clean up in > postfun, couldn't we likewise set (and then later clean up) the value of > project-current-directory-override? We need to set 'default-directory' to support non-project commands. I already started to use this feature, and it becomes indispensable. For example, the most often used commands are vc commands such as 'C-x p p C-x v L' to see a vc log in another project, and 'C-x p p C-x v d' to open vc-dir, etc. >> - (eq this-command command)) >> + (eq this-command command) >> + (eq this-command 'other-project-prefix)) > > Did this part of the patch get in by accident? If it's "localized to > project.el". Or do we have further plans to "generalize" that place > somehow? Just making sure. This part is optional and could be generalized later. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-13 6:47 ` Juri Linkov @ 2023-09-18 0:12 ` Dmitry Gutov 2023-09-18 6:51 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-18 0:12 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh Sorry about the wait. On 13/09/2023 09:47, Juri Linkov wrote: >>> So here is a complete tested patch that maintains backward-compatibility >>> with older versions, and is localized to project.el without the need to >>> discuss more fundamental changes on emacs-devel, and handles 100% of >>> known cases such as reported in bug#58784, bug#63829, etc. >> It sounds like a possibly concise solution, but I'm still wrapping my head >> around it. >> >>> +(make-obsolete-variable >>> + 'project-current-directory-override >>> + 'project-current-directory-old >>> + "30.1") >> Aren't those variables sufficiently different that making one an alias for >> another would confuse things? > Indeed, during development I mistakenly made one an alias for another > with 'define-obsolete-variable-alias', and this broke both variables. > So I replaced it with 'make-obsolete-variable' that doesn't make an alias. > It just designates it as obsolete to show the intention to remove it > in later versions. I suppose that would make us liable to support it for a version or two? >>> + (setq-local project-current-directory-old default-directory) >>> + (setq-local default-directory dir) >> Could you explain: if we can just set these here and then clean up in >> postfun, couldn't we likewise set (and then later clean up) the value of >> project-current-directory-override? > We need to set 'default-directory' to support non-project commands. > I already started to use this feature, and it becomes indispensable. > For example, the most often used commands are vc commands such as > 'C-x p p C-x v L' to see a vc log in another project, and > 'C-x p p C-x v d' to open vc-dir, etc. All right, so we also want to support non-project commands. And you wanted to use a common approach for both. What if we handle them differently, though? For "project" commands (those that internally call project-current) we can set one variable, and for the rest -- alter default-directory. Then restore the previous value in post-command. The detection of "project commands" could work like this: - Is it in one of the special maps? E.g. in project-prefix-map. Or maybe it's in project-switch-commands. - Does the function name start with 'project-'? - Finally, for user-defined commands we could also introduce a property 'project-command-p', although the distinction between using project-current-directory-override vs default-directory will not be important for every such command, so maybe being this thorough is not too important. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-18 0:12 ` Dmitry Gutov @ 2023-09-18 6:51 ` Juri Linkov 2023-09-18 11:00 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-18 6:51 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >> 'C-x p p C-x v L' to see a vc log in another project, and >> 'C-x p p C-x v d' to open vc-dir, etc. > > All right, so we also want to support non-project commands. And you wanted > to use a common approach for both. > > What if we handle them differently, though? For "project" commands (those > that internally call project-current) we can set one variable, and for the > rest -- alter default-directory. Then restore the previous value in > post-command. > > The detection of "project commands" could work like this: > > - Is it in one of the special maps? E.g. in project-prefix-map. Or maybe > it's in project-switch-commands. > - Does the function name start with 'project-'? > - Finally, for user-defined commands we could also introduce a property > 'project-command-p', although the distinction between using > project-current-directory-override vs default-directory will not be > important for every such command, so maybe being this thorough is not too > important. Sorry, I don't understand how 'C-x p p' could read the user's mind whether the user afterwards will type a key for a project command or a non-project command? And depending on user's intention will either set project-current-directory-override or default-directory. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-18 6:51 ` Juri Linkov @ 2023-09-18 11:00 ` Dmitry Gutov 2023-09-18 13:56 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-18 11:00 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 18/09/2023 09:51, Juri Linkov wrote: >>> 'C-x p p C-x v L' to see a vc log in another project, and >>> 'C-x p p C-x v d' to open vc-dir, etc. >> All right, so we also want to support non-project commands. And you wanted >> to use a common approach for both. >> >> What if we handle them differently, though? For "project" commands (those >> that internally call project-current) we can set one variable, and for the >> rest -- alter default-directory. Then restore the previous value in >> post-command. >> >> The detection of "project commands" could work like this: >> >> - Is it in one of the special maps? E.g. in project-prefix-map. Or maybe >> it's in project-switch-commands. >> - Does the function name start with 'project-'? >> - Finally, for user-defined commands we could also introduce a property >> 'project-command-p', although the distinction between using >> project-current-directory-override vs default-directory will not be >> important for every such command, so maybe being this thorough is not too >> important. > Sorry, I don't understand how 'C-x p p' could read the user's mind > whether the user afterwards will type a key for a project command > or a non-project command? And depending on user's intention will > either set project-current-directory-override or default-directory. Ah, I forgot that in the general case we don't read the sequence, find the command and do the thing. We leave the event loop up to Emacs. What about pre-command-hook? this-command will already be set by then. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-18 11:00 ` Dmitry Gutov @ 2023-09-18 13:56 ` Dmitry Gutov 2023-09-19 17:57 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-18 13:56 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 18/09/2023 14:00, Dmitry Gutov wrote: > On 18/09/2023 09:51, Juri Linkov wrote: >>>> 'C-x p p C-x v L' to see a vc log in another project, and >>>> 'C-x p p C-x v d' to open vc-dir, etc. >>> All right, so we also want to support non-project commands. And you >>> wanted >>> to use a common approach for both. >>> >>> What if we handle them differently, though? For "project" commands >>> (those >>> that internally call project-current) we can set one variable, and >>> for the >>> rest -- alter default-directory. Then restore the previous value in >>> post-command. >>> >>> The detection of "project commands" could work like this: >>> >>> - Is it in one of the special maps? E.g. in project-prefix-map. Or maybe >>> it's in project-switch-commands. >>> - Does the function name start with 'project-'? >>> - Finally, for user-defined commands we could also introduce a property >>> 'project-command-p', although the distinction between using >>> project-current-directory-override vs default-directory will not be >>> important for every such command, so maybe being this thorough is >>> not too >>> important. >> Sorry, I don't understand how 'C-x p p' could read the user's mind >> whether the user afterwards will type a key for a project command >> or a non-project command? And depending on user's intention will >> either set project-current-directory-override or default-directory. > > Ah, I forgot that in the general case we don't read the sequence, find > the command and do the thing. We leave the event loop up to Emacs. > > What about pre-command-hook? this-command will already be set by then. And we should consider whether other-project-prefix should entirely subsume project-switch-project. Or they should remain separate commands. E.g. would people who customized project-switch-commands to a symbol be okay with not being able to use the other functionality of other-project-prefix? Or what about the variable project-switch-use-entire-map? I'm not sure about dropping it, at least without notifying about that in the UI somehow. Finally, the current patch drops the loop, so if the user types the wrong key, they will need to repeat the command and choose the project again. So perhaps the simplest incremental change is to add other-project-prefix which will work with "regular" commands and keep project-switch-project for project commands (whether it will support "project" commands as well, can be optional). The downside is that it will require a different key binding (or for the user to redefine the current one), so I'm open to discussing all the questions above. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-18 13:56 ` Dmitry Gutov @ 2023-09-19 17:57 ` Juri Linkov 2023-09-20 0:39 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-19 17:57 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh > And we should consider whether other-project-prefix should entirely subsume > project-switch-project. Or they should remain separate commands. We could leave project-switch-project unobsoleted indefinitely for users who might prefer it, and users can bind it to C-x p p. > E.g. would people who customized project-switch-commands to a symbol be > okay with not being able to use the other functionality of > other-project-prefix? Symbolic project-switch-commands is supported by other-project-prefix. > Or what about the variable project-switch-use-entire-map? I'm not sure > about dropping it, at least without notifying about that in the UI somehow. project-switch-use-entire-map could be handled in other-project-prefix. But is this really needed? I can't imagine why anyone might want to disable keys from project-prefix-map. > Finally, the current patch drops the loop, so if the user types the wrong > key, they will need to repeat the command and choose the project again. Indeed, the loop now is the command loop, and maybe it's possible to write a hack to set a catch-all in set-transient-map that is not finished until a key in the map is typed. But as with any command, if the user types a wrong key sequence, then need to type it again. I do this all the time with mistakenly typed keys. I don't see why project keys are the exception. > So perhaps the simplest incremental change is to add other-project-prefix > which will work with "regular" commands and keep project-switch-project for > project commands (whether it will support "project" commands as well, can > be optional). > > The downside is that it will require a different key binding (or for the > user to redefine the current one), so I'm open to discussing all the > questions above. A different key binding for the commands that do the same thing? Only because the new command uses the command loop? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-19 17:57 ` Juri Linkov @ 2023-09-20 0:39 ` Dmitry Gutov 2023-09-20 17:10 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-20 0:39 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 19/09/2023 20:57, Juri Linkov wrote: >> And we should consider whether other-project-prefix should entirely subsume >> project-switch-project. Or they should remain separate commands. > > We could leave project-switch-project unobsoleted indefinitely > for users who might prefer it, and users can bind it to C-x p p. Or we keep the easier-to-use command on 'C-x p p', and the more experienced users would rebind that to 'other-project-prefix', when they learn how to use it. >> E.g. would people who customized project-switch-commands to a symbol be >> okay with not being able to use the other functionality of >> other-project-prefix? > > Symbolic project-switch-commands is supported by other-project-prefix. Yes, and that could be a problem: if I as a user want 'C-x p p' to always run 'project-find-file', for example (in the other project), but I also want to be able to sometimes call 'M-x other-project-prefix' (or use a custom binding) to run an arbitrary command in the other project. >> Or what about the variable project-switch-use-entire-map? I'm not sure >> about dropping it, at least without notifying about that in the UI somehow. > > project-switch-use-entire-map could be handled in other-project-prefix. > But is this really needed? I can't imagine why anyone might want > to disable keys from project-prefix-map. I think if project-switch-use-entire-map is still wanted, we should just keep these commands separate (the same logic as in the previous paragraph). Why not remove that option? Consider the current UI (which looks almost the same in your latest patch): user types 'C-x p p', chooses the project and then sees the prompt which only offers the options from project-switch-commands. They are not informed that any other keys could be used too. So if we were to change the default behavior, I think this UI/prompt needs to change, at the very least. Do we want to drop the whole "choose a command from the list" thing? Will that be an improvement overall, for most users? If you think so, I suppose we should make a poll somewhere. >> Finally, the current patch drops the loop, so if the user types the wrong >> key, they will need to repeat the command and choose the project again. > > Indeed, the loop now is the command loop, and maybe it's possible to > write a hack to set a catch-all in set-transient-map that is not > finished until a key in the map is typed. But as with any command, > if the user types a wrong key sequence, then need to type it again. > I do this all the time with mistakenly typed keys. I don't see why > project keys are the exception. Maybe because in the middle of it all you have interacted with Emacs to choose the other project, and that can be a significant amount of typing? I suppose, if it worked the other way (first choose the command, and then the project), it would make more sense to not care about having the user repeat the command sequence. >> So perhaps the simplest incremental change is to add other-project-prefix >> which will work with "regular" commands and keep project-switch-project for >> project commands (whether it will support "project" commands as well, can >> be optional). >> >> The downside is that it will require a different key binding (or for the >> user to redefine the current one), so I'm open to discussing all the >> questions above. > > A different key binding for the commands that do the same thing? > Only because the new command uses the command loop? project-switch-project would continue to show the menu with commands, only work with them by default, and obey project-switch-use-entire-map, which, when set to t, would enable other commands from the project keymap, but only them. All accessible via one character binding. And when project-switch-commands is set to a symbol, it would only invoke that one command without additional prompting. other-project-prefix would accept all commands but require full key sequence for the invoked command. Would it add shortcuts to the commands from the project keymap? Possibly. Any ideas how to inform the user about that? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-20 0:39 ` Dmitry Gutov @ 2023-09-20 17:10 ` Juri Linkov 2023-09-21 1:16 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-20 17:10 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >>> And we should consider whether other-project-prefix should entirely subsume >>> project-switch-project. Or they should remain separate commands. >> We could leave project-switch-project unobsoleted indefinitely >> for users who might prefer it, and users can bind it to C-x p p. > > Or we keep the easier-to-use command on 'C-x p p', and the more experienced > users would rebind that to 'other-project-prefix', when they learn how to > use it. Or vice versa. >>> E.g. would people who customized project-switch-commands to a symbol be >>> okay with not being able to use the other functionality of >>> other-project-prefix? >> Symbolic project-switch-commands is supported by other-project-prefix. > > Yes, and that could be a problem: if I as a user want 'C-x p p' to always > run 'project-find-file', for example (in the other project), but I also > want to be able to sometimes call 'M-x other-project-prefix' (or use > a custom binding) to run an arbitrary command in the other project. With other-project-prefix, users can run 'project-find-file' in another project with just: ``` (defun other-project-find-file () (interactive) (call-interactively 'other-project-prefix) (call-interactively 'project-find-file)) ``` >>> Or what about the variable project-switch-use-entire-map? I'm not sure >>> about dropping it, at least without notifying about that in the UI somehow. >> project-switch-use-entire-map could be handled in other-project-prefix. >> But is this really needed? I can't imagine why anyone might want >> to disable keys from project-prefix-map. > > I think if project-switch-use-entire-map is still wanted, we should just > keep these commands separate (the same logic as in the previous paragraph). No problem, project-switch-use-entire-map can be easily supported in other-project-prefix. > Why not remove that option? Consider the current UI (which looks almost the > same in your latest patch): user types 'C-x p p', chooses the project and > then sees the prompt which only offers the options from > project-switch-commands. They are not informed that any other keys could be > used too. So if we were to change the default behavior, I think this > UI/prompt needs to change, at the very least. Agreed, a better prompt needed. Maybe with the standard C-h key for help. > Do we want to drop the whole "choose a command from the list" thing? Will > that be an improvement overall, for most users? If you think so, I suppose > we should make a poll somewhere. Maybe this short menu is not much needed. OTOH, it doesn't cause distraction. >>> Finally, the current patch drops the loop, so if the user types the wrong >>> key, they will need to repeat the command and choose the project again. >> Indeed, the loop now is the command loop, and maybe it's possible to >> write a hack to set a catch-all in set-transient-map that is not >> finished until a key in the map is typed. But as with any command, >> if the user types a wrong key sequence, then need to type it again. >> I do this all the time with mistakenly typed keys. I don't see why >> project keys are the exception. > > Maybe because in the middle of it all you have interacted with Emacs to > choose the other project, and that can be a significant amount of typing? Then for repeating the previously selected project it will be in the history: 'C-x p p M-p'. > I suppose, if it worked the other way (first choose the command, and then > the project), it would make more sense to not care about having the user > repeat the command sequence. Like it does when typed e.g. 'C-x p f' in a non-project directory? >>> So perhaps the simplest incremental change is to add other-project-prefix >>> which will work with "regular" commands and keep project-switch-project for >>> project commands (whether it will support "project" commands as well, can >>> be optional). >>> >>> The downside is that it will require a different key binding (or for the >>> user to redefine the current one), so I'm open to discussing all the >>> questions above. >> A different key binding for the commands that do the same thing? >> Only because the new command uses the command loop? > > project-switch-project would continue to show the menu with commands, only > work with them by default, and obey project-switch-use-entire-map, which, > when set to t, would enable other commands from the project keymap, but > only them. All accessible via one character binding. And when > project-switch-commands is set to a symbol, it would only invoke that one > command without additional prompting. > > other-project-prefix would accept all commands but require full key > sequence for the invoked command. And also other-project-prefix will fix such bugs as bug#65558. > Would it add shortcuts to the commands from the project keymap? > Possibly. Any ideas how to inform the user about that? By a different prompt? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-20 17:10 ` Juri Linkov @ 2023-09-21 1:16 ` Dmitry Gutov 2023-09-21 6:58 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-09-21 1:16 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 20/09/2023 20:10, Juri Linkov wrote: >>>> And we should consider whether other-project-prefix should entirely subsume >>>> project-switch-project. Or they should remain separate commands. >>> We could leave project-switch-project unobsoleted indefinitely >>> for users who might prefer it, and users can bind it to C-x p p. >> >> Or we keep the easier-to-use command on 'C-x p p', and the more experienced >> users would rebind that to 'other-project-prefix', when they learn how to >> use it. > > Or vice versa. Yes. >>>> E.g. would people who customized project-switch-commands to a symbol be >>>> okay with not being able to use the other functionality of >>>> other-project-prefix? >>> Symbolic project-switch-commands is supported by other-project-prefix. >> >> Yes, and that could be a problem: if I as a user want 'C-x p p' to always >> run 'project-find-file', for example (in the other project), but I also >> want to be able to sometimes call 'M-x other-project-prefix' (or use >> a custom binding) to run an arbitrary command in the other project. > > With other-project-prefix, users can run 'project-find-file' > in another project with just: > > ``` > (defun other-project-find-file () > (interactive) > (call-interactively 'other-project-prefix) > (call-interactively 'project-find-file)) > ``` Right... but they'd have to define a custom function for any such command. I think the idea behind 'other-project-prefix' is that one wouldn't have to. >>>> Or what about the variable project-switch-use-entire-map? I'm not sure >>>> about dropping it, at least without notifying about that in the UI somehow. >>> project-switch-use-entire-map could be handled in other-project-prefix. >>> But is this really needed? I can't imagine why anyone might want >>> to disable keys from project-prefix-map. >> >> I think if project-switch-use-entire-map is still wanted, we should just >> keep these commands separate (the same logic as in the previous paragraph). > > No problem, project-switch-use-entire-map can be easily supported in > other-project-prefix. I'm not saying it's hard to support it there. But it could make the command less useful. >> Why not remove that option? Consider the current UI (which looks almost the >> same in your latest patch): user types 'C-x p p', chooses the project and >> then sees the prompt which only offers the options from >> project-switch-commands. They are not informed that any other keys could be >> used too. So if we were to change the default behavior, I think this >> UI/prompt needs to change, at the very least. > > Agreed, a better prompt needed. Maybe with the standard C-h key for help. Some short version initially, and perhaps a more expanded if the user hits 'C-h'. >> Do we want to drop the whole "choose a command from the list" thing? Will >> that be an improvement overall, for most users? If you think so, I suppose >> we should make a poll somewhere. > > Maybe this short menu is not much needed. OTOH, it doesn't cause distraction. I think some menu, or an explanation, anything, is better than nothing. >>>> Finally, the current patch drops the loop, so if the user types the wrong >>>> key, they will need to repeat the command and choose the project again. >>> Indeed, the loop now is the command loop, and maybe it's possible to >>> write a hack to set a catch-all in set-transient-map that is not >>> finished until a key in the map is typed. But as with any command, >>> if the user types a wrong key sequence, then need to type it again. >>> I do this all the time with mistakenly typed keys. I don't see why >>> project keys are the exception. >> >> Maybe because in the middle of it all you have interacted with Emacs to >> choose the other project, and that can be a significant amount of typing? > > Then for repeating the previously selected project it will be in the history: > 'C-x p p M-p'. Fair point. Still, that's more typing and required one to remember/know about M-p. >> I suppose, if it worked the other way (first choose the command, and then >> the project), it would make more sense to not care about having the user >> repeat the command sequence. > > Like it does when typed e.g. 'C-x p f' in a non-project directory? Yep. >>> A different key binding for the commands that do the same thing? >>> Only because the new command uses the command loop? >> >> project-switch-project would continue to show the menu with commands, only >> work with them by default, and obey project-switch-use-entire-map, which, >> when set to t, would enable other commands from the project keymap, but >> only them. All accessible via one character binding. And when >> project-switch-commands is set to a symbol, it would only invoke that one >> command without additional prompting. >> >> other-project-prefix would accept all commands but require full key >> sequence for the invoked command. > > And also other-project-prefix will fix such bugs as bug#65558. > >> Would it add shortcuts to the commands from the project keymap? >> Possibly. Any ideas how to inform the user about that? > > By a different prompt? Probably. Would you like to propose one? So that I have something to compare to, and have something specific to put to the vote as well. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-21 1:16 ` Dmitry Gutov @ 2023-09-21 6:58 ` Juri Linkov 2023-09-22 15:52 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-09-21 6:58 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 4829 bytes --] >>>>> E.g. would people who customized project-switch-commands to a symbol be >>>>> okay with not being able to use the other functionality of >>>>> other-project-prefix? >>>> Symbolic project-switch-commands is supported by other-project-prefix. >>> >>> Yes, and that could be a problem: if I as a user want 'C-x p p' to always >>> run 'project-find-file', for example (in the other project), but I also >>> want to be able to sometimes call 'M-x other-project-prefix' (or use >>> a custom binding) to run an arbitrary command in the other project. >> With other-project-prefix, users can run 'project-find-file' >> in another project with just: >> ``` >> (defun other-project-find-file () >> (interactive) >> (call-interactively 'other-project-prefix) >> (call-interactively 'project-find-file)) >> ``` > > Right... but they'd have to define a custom function for any such > command. I think the idea behind 'other-project-prefix' is that one > wouldn't have to. Only one custom function. Or they can just bind the most used command to the most easily typed key RET. >>>>> Or what about the variable project-switch-use-entire-map? I'm not sure >>>>> about dropping it, at least without notifying about that in the UI somehow. >>>> project-switch-use-entire-map could be handled in other-project-prefix. >>>> But is this really needed? I can't imagine why anyone might want >>>> to disable keys from project-prefix-map. >>> >>> I think if project-switch-use-entire-map is still wanted, we should just >>> keep these commands separate (the same logic as in the previous paragraph). >> No problem, project-switch-use-entire-map can be easily supported in >> other-project-prefix. > > I'm not saying it's hard to support it there. But it could make the command > less useful. When all global keybindings are available, it's strange to remove keys from project-prefix-map. But ok, the patch below supports project-switch-use-entire-map. >>> Why not remove that option? Consider the current UI (which looks almost the >>> same in your latest patch): user types 'C-x p p', chooses the project and >>> then sees the prompt which only offers the options from >>> project-switch-commands. They are not informed that any other keys could be >>> used too. So if we were to change the default behavior, I think this >>> UI/prompt needs to change, at the very least. >> Agreed, a better prompt needed. Maybe with the standard C-h key for >> help. > > Some short version initially, and perhaps a more expanded if the user hits > 'C-h'. I tried to use 'help-form' in a new patch, but actually 'C-h' is quite useless when not using the ad-hoc loop as e.g. in y-or-n-p that forces to type a limited set of keys. >>>>> Finally, the current patch drops the loop, so if the user types the wrong >>>>> key, they will need to repeat the command and choose the project again. >>>> Indeed, the loop now is the command loop, and maybe it's possible to >>>> write a hack to set a catch-all in set-transient-map that is not >>>> finished until a key in the map is typed. But as with any command, >>>> if the user types a wrong key sequence, then need to type it again. >>>> I do this all the time with mistakenly typed keys. I don't see why >>>> project keys are the exception. >>> >>> Maybe because in the middle of it all you have interacted with Emacs to >>> choose the other project, and that can be a significant amount of typing? >> Then for repeating the previously selected project it will be in the >> history: >> 'C-x p p M-p'. > > Fair point. Still, that's more typing and required one to remember/know > about M-p. If 'project-prompt-project-dir' remembered the selected directory like 'project-current' does, then would be possible to repeat with: 'C-x p p M-n'. >>>> A different key binding for the commands that do the same thing? >>>> Only because the new command uses the command loop? >>> >>> project-switch-project would continue to show the menu with commands, only >>> work with them by default, and obey project-switch-use-entire-map, which, >>> when set to t, would enable other commands from the project keymap, but >>> only them. All accessible via one character binding. And when >>> project-switch-commands is set to a symbol, it would only invoke that one >>> command without additional prompting. >>> >>> other-project-prefix would accept all commands but require full key >>> sequence for the invoked command. >> And also other-project-prefix will fix such bugs as bug#65558. >> >>> Would it add shortcuts to the commands from the project keymap? >>> Possibly. Any ideas how to inform the user about that? >> By a different prompt? > > Probably. Would you like to propose one? So that I have something to > compare to, and have something specific to put to the vote as well. Ok, something like this: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: project-default-directory.patch --] [-- Type: text/x-diff, Size: 9146 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 2e6ae89a443..6d5664c0e98 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -197,6 +197,14 @@ project-current-directory-override "Value to use instead of `default-directory' when detecting the project. When it is non-nil, `project-current' will always skip prompting too.") +(defvar-local project-default-directory nil + "Value to use instead of `default-directory' when detecting the project. +For the next command after switching the project, this buffer-local +variable contains the original value of `default-directory'. +Whereas the buffer-local `default-directory' is temporarily set +to the root directory of the switched project. +When it is non-nil, `project-current' will always skip prompting too.") + (defcustom project-prompter #'project-prompt-project-dir "Function to call to prompt for a project. Called with no arguments and should return a project root dir." @@ -232,7 +240,8 @@ project-current (let ((pr (project--find-in-directory directory))) (cond (pr) - ((unless project-current-directory-override + ((unless (or project-current-directory-override + project-default-directory) maybe-prompt) (setq directory (funcall project-prompter) pr (project--find-in-directory directory)))) @@ -397,8 +406,10 @@ project-buffers (let ((root (expand-file-name (file-name-as-directory (project-root project)))) bufs) (dolist (buf (buffer-list)) - (when (string-prefix-p root (expand-file-name - (buffer-local-value 'default-directory buf))) + (when (string-prefix-p + root (expand-file-name + (or (buffer-local-value 'project-default-directory buf) + (buffer-local-value 'default-directory buf)))) (push buf bufs))) (nreverse bufs))) @@ -813,7 +824,9 @@ project-buffers dd bufs) (dolist (buf (buffer-list)) - (setq dd (expand-file-name (buffer-local-value 'default-directory buf))) + (setq dd (expand-file-name + (or (buffer-local-value 'project-default-directory buf) + (buffer-local-value 'default-directory buf)))) (when (and (string-prefix-p root dd) (not (cl-find-if (lambda (module) (string-prefix-p module dd)) modules))) @@ -842,7 +855,9 @@ project-prefix-map (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) - (define-key map "p" 'project-switch-project) + (define-key map "p" (if (< emacs-major-version 30) + 'project-switch-project + 'other-project-prefix)) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) @@ -889,10 +904,16 @@ project-other-window-command \\{project-prefix-map} \\{project-other-window-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-window) - (inhibit-same-window . t)) - project-other-window-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-window) + (inhibit-same-window . t)) + project-other-window-map) + (let ((inhibit-message t)) (other-window-prefix)) + (message "Display next project command buffer in a new window...") + (set-transient-map (make-composed-keymap project-prefix-map + project-other-window-map)))) +;; TODO: maybe rename to project-other-window-prefix ;;;###autoload (define-key ctl-x-4-map "p" #'project-other-window-command) ;;;###autoload @@ -904,8 +925,13 @@ project-other-frame-command \\{project-prefix-map} \\{project-other-frame-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-frame)) - project-other-frame-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-frame)) + project-other-frame-map) + (let ((inhibit-message t)) (other-frame-prefix)) + (message "Display next project command buffer in a new frame...") + (set-transient-map (make-composed-keymap project-prefix-map + project-other-frame-map)))) ;;;###autoload (define-key ctl-x-5-map "p" #'project-other-frame-command) @@ -917,7 +943,11 @@ project-other-tab-command \\{project-prefix-map}" (interactive) - (project--other-place-command '((display-buffer-in-new-tab)))) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-in-new-tab))) + (let ((inhibit-message t)) (other-tab-prefix)) + (message "Display next project command buffer in a new tab...") + (set-transient-map project-prefix-map))) ;;;###autoload (when (bound-and-true-p tab-prefix-map) @@ -1000,14 +1030,16 @@ project--find-default-from "Ensure FILENAME is in PROJECT. Usually, just return FILENAME. But if -`project-current-directory-override' is set, adjust it to be +`project-default-directory' is set, adjust it to be relative to PROJECT instead. This supports using a relative file name from the current buffer when switching projects with `project-switch-project' and then using a command like `project-find-file'." - (if-let (filename-proj (and project-current-directory-override - (project-current nil default-directory))) + (if-let (filename-proj (or (and project-current-directory-override + (project-current nil default-directory)) + (and project-default-directory + (project-current nil project-default-directory)))) ;; file-name-concat requires Emacs 28+ (concat (file-name-as-directory (project-root project)) (file-relative-name filename (project-root filename-proj))) @@ -1993,6 +2025,60 @@ project-switch-project (let ((project-current-directory-override dir)) (call-interactively command)))) +;;;###autoload +(defun other-project-prefix (dir) + "\"Switch\" to another project before running an Emacs command. +The available commands are presented as a dispatch menu +made from `project-switch-commands'. + +When called in a program, it will use the project corresponding +to directory DIR." + (interactive (list (funcall project-prompter))) + (if (symbolp project-switch-commands) + (let* ((project-default-directory default-directory) + (default-directory dir)) + (call-interactively project-switch-commands)) + (prefix-command-preserve-state) + (letrec ((minibuffer-depth (minibuffer-depth)) + (command this-command) + (old-buffer (current-buffer)) + (echofun (lambda () "[switch-project]")) + (postfun + (lambda () + (unless (or (eq this-command command) + (> (minibuffer-depth) minibuffer-depth)) + (remove-hook 'post-command-hook postfun) + (remove-hook 'prefix-command-echo-keystrokes-functions + echofun) + (when (buffer-live-p old-buffer) + (with-current-buffer old-buffer + (when project-default-directory + (setq-local default-directory project-default-directory) + (kill-local-variable 'project-default-directory)))))))) + (add-hook 'post-command-hook postfun) + (add-hook 'prefix-command-echo-keystrokes-functions echofun) + (setq-local project-default-directory default-directory) + (setq-local default-directory dir) + (message (concat (project--keymap-prompt) " or any global key.")) + (let ((map (make-sparse-keymap))) + (if project-switch-use-entire-map + (set-keymap-parent map project-prefix-map) + (dolist (row project-switch-commands map) + (when-let* ((cmd (nth 0 row)) + (key (nth 2 row)) + (keychar (if key (vector key) + (where-is-internal + cmd (list project-prefix-map) t)))) + (define-key map keychar cmd)))) + (define-key map (vector help-char) + (lambda () + (interactive) + (let ((help-form "\ +You can use any global keybinding.")) + (help-form-show)))) + ;; Should return exitfun from set-transient-map + (set-transient-map map))))) + ;;;###autoload (defun project-uniquify-dirname-transform (dirname) "Uniquify name of directory DIRNAME using `project-name', if in a project. ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-21 6:58 ` Juri Linkov @ 2023-09-22 15:52 ` Juri Linkov 2023-10-19 0:42 ` Dmitry Gutov 2023-10-21 13:14 ` sbaugh 0 siblings, 2 replies; 109+ messages in thread From: Juri Linkov @ 2023-09-22 15:52 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 737 bytes --] >> Probably. Would you like to propose one? So that I have something to >> compare to, and have something specific to put to the vote as well. > > Ok, something like this: Here is a more tested patch. It supports these cases: (setq project-switch-use-entire-map t) C-x p p C-b - should not include current buffer in the list of another project (bug#58784) C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) C-x p p C-x d - should visit another project's root (bug#63648) The same with frames: C-x 5 p p C-b C-x 5 p p f M-n C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) C-x 5 p p C-x d [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: project-default-directory.patch --] [-- Type: text/x-diff, Size: 9407 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 2e6ae89a443..9faacbe3512 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -197,6 +197,14 @@ project-current-directory-override "Value to use instead of `default-directory' when detecting the project. When it is non-nil, `project-current' will always skip prompting too.") +(defvar-local project-default-directory nil + "Value to use instead of `default-directory' when detecting the project. +For the next command after switching the project, this buffer-local +variable contains the original value of `default-directory'. +Whereas the buffer-local `default-directory' is temporarily set +to the root directory of the switched project. +When it is non-nil, `project-current' will always skip prompting too.") + (defcustom project-prompter #'project-prompt-project-dir "Function to call to prompt for a project. Called with no arguments and should return a project root dir." @@ -232,7 +240,8 @@ project-current (let ((pr (project--find-in-directory directory))) (cond (pr) - ((unless project-current-directory-override + ((unless (or project-current-directory-override + project-default-directory) maybe-prompt) (setq directory (funcall project-prompter) pr (project--find-in-directory directory)))) @@ -397,8 +406,10 @@ project-buffers (let ((root (expand-file-name (file-name-as-directory (project-root project)))) bufs) (dolist (buf (buffer-list)) - (when (string-prefix-p root (expand-file-name - (buffer-local-value 'default-directory buf))) + (when (string-prefix-p + root (expand-file-name + (or (buffer-local-value 'project-default-directory buf) + (buffer-local-value 'default-directory buf)))) (push buf bufs))) (nreverse bufs))) @@ -813,7 +824,9 @@ project-buffers dd bufs) (dolist (buf (buffer-list)) - (setq dd (expand-file-name (buffer-local-value 'default-directory buf))) + (setq dd (expand-file-name + (or (buffer-local-value 'project-default-directory buf) + (buffer-local-value 'default-directory buf)))) (when (and (string-prefix-p root dd) (not (cl-find-if (lambda (module) (string-prefix-p module dd)) modules))) @@ -842,7 +855,9 @@ project-prefix-map (define-key map "c" 'project-compile) (define-key map "e" 'project-eshell) (define-key map "k" 'project-kill-buffers) - (define-key map "p" 'project-switch-project) + (define-key map "p" (if (< emacs-major-version 30) + 'project-switch-project + 'other-project-prefix)) (define-key map "g" 'project-find-regexp) (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) @@ -889,10 +904,18 @@ project-other-window-command \\{project-prefix-map} \\{project-other-window-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-window) - (inhibit-same-window . t)) - project-other-window-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-window) + (inhibit-same-window . t)) + project-other-window-map) + (prefix-command-preserve-state) + (let ((inhibit-message t)) (other-window-prefix)) + (message "Display next project command buffer in a new window...") + ;; Should return exitfun from set-transient-map + (set-transient-map (make-composed-keymap project-prefix-map + project-other-window-map)))) +;; TODO: maybe rename to project-other-window-prefix ;;;###autoload (define-key ctl-x-4-map "p" #'project-other-window-command) ;;;###autoload @@ -904,8 +927,15 @@ project-other-frame-command \\{project-prefix-map} \\{project-other-frame-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-frame)) - project-other-frame-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-frame)) + project-other-frame-map) + (prefix-command-preserve-state) + (let ((inhibit-message t)) (other-frame-prefix)) + (message "Display next project command buffer in a new frame...") + ;; Should return exitfun from set-transient-map + (set-transient-map (make-composed-keymap project-prefix-map + project-other-frame-map)))) ;;;###autoload (define-key ctl-x-5-map "p" #'project-other-frame-command) @@ -917,7 +947,13 @@ project-other-tab-command \\{project-prefix-map}" (interactive) - (project--other-place-command '((display-buffer-in-new-tab)))) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-in-new-tab))) + (prefix-command-preserve-state) + (let ((inhibit-message t)) (other-tab-prefix)) + (message "Display next project command buffer in a new tab...") + ;; Should return exitfun from set-transient-map + (set-transient-map project-prefix-map))) ;;;###autoload (when (bound-and-true-p tab-prefix-map) @@ -1000,14 +1036,16 @@ project--find-default-from "Ensure FILENAME is in PROJECT. Usually, just return FILENAME. But if -`project-current-directory-override' is set, adjust it to be +`project-default-directory' is set, adjust it to be relative to PROJECT instead. This supports using a relative file name from the current buffer when switching projects with `project-switch-project' and then using a command like `project-find-file'." - (if-let (filename-proj (and project-current-directory-override - (project-current nil default-directory))) + (if-let (filename-proj (or (and project-current-directory-override + (project-current nil default-directory)) + (and project-default-directory + (project-current nil project-default-directory)))) ;; file-name-concat requires Emacs 28+ (concat (file-name-as-directory (project-root project)) (file-relative-name filename (project-root filename-proj))) @@ -1993,6 +2031,60 @@ project-switch-project (let ((project-current-directory-override dir)) (call-interactively command)))) +;;;###autoload +(defun other-project-prefix (dir) + "\"Switch\" to another project before running an Emacs command. +The available commands are presented as a dispatch menu +made from `project-switch-commands'. + +When called in a program, it will use the project corresponding +to directory DIR." + (interactive (list (funcall project-prompter))) + (if (symbolp project-switch-commands) + (let* ((project-default-directory default-directory) + (default-directory dir)) + (call-interactively project-switch-commands)) + (prefix-command-preserve-state) + (letrec ((minibuffer-depth (minibuffer-depth)) + (command this-command) + (old-buffer (current-buffer)) + (echofun (lambda () "[switch-project]")) + (postfun + (lambda () + (unless (or (eq this-command command) + (> (minibuffer-depth) minibuffer-depth)) + (remove-hook 'post-command-hook postfun) + (remove-hook 'prefix-command-echo-keystrokes-functions + echofun) + (when (buffer-live-p old-buffer) + (with-current-buffer old-buffer + (when project-default-directory + (setq-local default-directory project-default-directory) + (kill-local-variable 'project-default-directory)))))))) + (add-hook 'post-command-hook postfun) + (add-hook 'prefix-command-echo-keystrokes-functions echofun) + (setq-local project-default-directory default-directory) + (setq-local default-directory dir) + (message (concat (project--keymap-prompt) " or any global key.")) + (let ((map (make-sparse-keymap))) + (if project-switch-use-entire-map + (set-keymap-parent map project-prefix-map) + (dolist (row project-switch-commands map) + (when-let* ((cmd (nth 0 row)) + (key (if (nth 2 row) + (vector (nth 2 row)) + (where-is-internal + cmd (list project-prefix-map) t)))) + (define-key map key cmd)))) + (define-key map (vector help-char) + (lambda () + (interactive) + (let ((help-form "\ +You can use any global keybinding.")) + (help-form-show)))) + ;; Should return exitfun from set-transient-map + (set-transient-map map))))) + ;;;###autoload (defun project-uniquify-dirname-transform (dirname) "Uniquify name of directory DIRNAME using `project-name', if in a project. ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-22 15:52 ` Juri Linkov @ 2023-10-19 0:42 ` Dmitry Gutov 2023-10-19 4:46 ` Eli Zaretskii ` (3 more replies) 2023-10-21 13:14 ` sbaugh 1 sibling, 4 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 0:42 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 2435 bytes --] Hi Juri, On 22/09/2023 18:52, Juri Linkov wrote: >>> Probably. Would you like to propose one? So that I have something to >>> compare to, and have something specific to put to the vote as well. >> >> Ok, something like this: > > Here is a more tested patch. It supports these cases: > > (setq project-switch-use-entire-map t) > > C-x p p C-b - should not include current buffer in the list of another project (bug#58784) > C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) > C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) > C-x p p C-x d - should visit another project's root (bug#63648) > > The same with frames: > > C-x 5 p p C-b > C-x 5 p p f M-n > C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) > C-x 5 p p C-x d Thank you. Especially for the list. But I think we still haven't reached a decision whether the "loop until correct key is pressed" behavior is useful. I tried to think how to fit the above requirements into the existing model, and it seems to require a new command, and an additional key being pressed sometimes, for explicitness. The attached patch also includes your fix for bug#65558, which seems orthogonal to our dilemma, and could probably be installed separately. It could be dry-ed up a little, though. Anyway, with the attached counter-proposal, the list looks like this: C-x p p C-b - works when project-switch-use-entire-map=t C-x p p f M-n - always works C-u C-x p p f - same C-x p p C-x d - the key sequence is 'C-x p p o C-x d' With frames: C-x 5 p p C-b - works when project-switch-use-entire-map=t C-x 5 p p f M-n - always works C-u C-x 5 p p f emoji TAB - same (thanks to your fix, included) C-x 5 p p C-x d - the key sequence is 'C-x 5 C-x p p o C-x d' The user could add project-list-buffers (or project-switch-to-buffer) to project-switch-commands, though, and then project-switch-use-entire-map won't be needed. Either way's fine. To sum up, that does require pressing an extra key to use commands outside of project-prefix-map, but OTOH that key is shown right in the commands menu. And one doesn't have to (setq project-switch-use-entire-map t) to use it, though that doesn't hurt either. And the meaning of project-switch-use-entire-map remains as it currently is: expand the set of keys to the whole project-prefix-map, but not to all local and global ones. WDYT? [-- Attachment #2: project-other-command.diff --] [-- Type: text/x-patch, Size: 4325 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index b9ecb770e60..764d31387e0 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -847,6 +847,7 @@ project-prefix-map (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) + (define-key map "o" 'project-other-command) (define-key map "\C-b" 'project-list-buffers) map) "Keymap for project commands.") @@ -889,10 +890,18 @@ project-other-window-command \\{project-prefix-map} \\{project-other-window-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-window) - (inhibit-same-window . t)) - project-other-window-map)) - + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-window) + (inhibit-same-window . t)) + project-other-window-map) + (prefix-command-preserve-state) + (let ((inhibit-message t)) (other-window-prefix)) + (message "Display next project command buffer in a new window...") + ;; Should return exitfun from set-transient-map + (set-transient-map (make-composed-keymap project-prefix-map + project-other-window-map)))) + +;; TODO: maybe rename to project-other-window-prefix ;;;###autoload (define-key ctl-x-4-map "p" #'project-other-window-command) ;;;###autoload @@ -904,8 +913,15 @@ project-other-frame-command \\{project-prefix-map} \\{project-other-frame-map}" (interactive) - (project--other-place-command '((display-buffer-pop-up-frame)) - project-other-frame-map)) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-pop-up-frame)) + project-other-frame-map) + (prefix-command-preserve-state) + (let ((inhibit-message t)) (other-frame-prefix)) + (message "Display next project command buffer in a new frame...") + ;; Should return exitfun from set-transient-map + (set-transient-map (make-composed-keymap project-prefix-map + project-other-frame-map)))) ;;;###autoload (define-key ctl-x-5-map "p" #'project-other-frame-command) @@ -917,7 +933,13 @@ project-other-tab-command \\{project-prefix-map}" (interactive) - (project--other-place-command '((display-buffer-in-new-tab)))) + (if (< emacs-major-version 30) + (project--other-place-command '((display-buffer-in-new-tab))) + (prefix-command-preserve-state) + (let ((inhibit-message t)) (other-tab-prefix)) + (message "Display next project command buffer in a new tab...") + ;; Should return exitfun from set-transient-map + (set-transient-map project-prefix-map))) ;;;###autoload (when (bound-and-true-p tab-prefix-map) @@ -1796,6 +1818,19 @@ project-execute-extended-command (let ((default-directory (project-root (project-current t)))) (call-interactively #'execute-extended-command))) +;;;###autoload +(defun project-other-command () + "Run command with `default-directory' set to the current project root." + (interactive) + (let* ((pr (project-current t)) + (prefix-command-echo-keystrokes-functions + (cons (lambda () (format "[execute in %s]" (project-root pr))) + prefix-command-echo-keystrokes-functions)) + (command (key-binding (read-key-sequence "") t))) + (let ((default-directory (project-root pr))) + (and command + (call-interactively command))))) + (defun project-remember-projects-under (dir &optional recursive) "Index all projects below a directory DIR. If RECURSIVE is non-nil, recurse into all subdirectories to find @@ -1874,7 +1909,8 @@ project-switch-commands (project-find-regexp "Find regexp") (project-find-dir "Find directory") (project-vc-dir "VC-Dir") - (project-eshell "Eshell")) + (project-eshell "Eshell") + (project-other-command "Other")) "Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 0:42 ` Dmitry Gutov @ 2023-10-19 4:46 ` Eli Zaretskii 2023-10-19 6:43 ` Juri Linkov 2023-10-19 9:46 ` Dmitry Gutov 2023-10-19 12:22 ` sbaugh ` (2 subsequent siblings) 3 siblings, 2 replies; 109+ messages in thread From: Eli Zaretskii @ 2023-10-19 4:46 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, sbaugh, 63648, juri > Cc: Spencer Baugh <sbaugh@janestreet.com>, 63648@debbugs.gnu.org, > sbaugh@catern.com > Date: Thu, 19 Oct 2023 03:42:24 +0300 > From: Dmitry Gutov <dmitry@gutov.dev> > > +;;;###autoload > +(defun project-other-command () > + "Run command with `default-directory' set to the current project root." I very much hope you will find a better name for this command. The "other" part seems to be out of place here, at least as far as the doc string is considered. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 4:46 ` Eli Zaretskii @ 2023-10-19 6:43 ` Juri Linkov 2023-10-19 7:51 ` Eli Zaretskii 2023-10-19 9:46 ` Dmitry Gutov 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-19 6:43 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Dmitry Gutov, sbaugh, 63648, sbaugh >> +(defun project-other-command () >> + "Run command with `default-directory' set to the current project root." > > I very much hope you will find a better name for this command. The > "other" part seems to be out of place here, at least as far as the doc > string is considered. The prefix 'other-' would make sense for consistency with 'other-window-...', etc. But when the prefix is 'project-' then the function name doesn't need to contain the word "other". ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 6:43 ` Juri Linkov @ 2023-10-19 7:51 ` Eli Zaretskii 0 siblings, 0 replies; 109+ messages in thread From: Eli Zaretskii @ 2023-10-19 7:51 UTC (permalink / raw) To: Juri Linkov; +Cc: dmitry, sbaugh, 63648, sbaugh > From: Juri Linkov <juri@linkov.net> > Cc: Dmitry Gutov <dmitry@gutov.dev>, sbaugh@janestreet.com, > 63648@debbugs.gnu.org, sbaugh@catern.com > Date: Thu, 19 Oct 2023 09:43:42 +0300 > > >> +(defun project-other-command () > >> + "Run command with `default-directory' set to the current project root." > > > > I very much hope you will find a better name for this command. The > > "other" part seems to be out of place here, at least as far as the doc > > string is considered. > > The prefix 'other-' would make sense for consistency with 'other-window-...', etc. How is it consistent with "other-window" commands? More accurately, what is this "other" thing that makes the "other" part in the command name relevant? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 4:46 ` Eli Zaretskii 2023-10-19 6:43 ` Juri Linkov @ 2023-10-19 9:46 ` Dmitry Gutov 2023-10-19 11:05 ` Eli Zaretskii 1 sibling, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 9:46 UTC (permalink / raw) To: Eli Zaretskii; +Cc: sbaugh, sbaugh, 63648, juri On 19/10/2023 07:46, Eli Zaretskii wrote: >> Cc: Spencer Baugh<sbaugh@janestreet.com>,63648@debbugs.gnu.org, >> sbaugh@catern.com >> Date: Thu, 19 Oct 2023 03:42:24 +0300 >> From: Dmitry Gutov<dmitry@gutov.dev> >> >> +;;;###autoload >> +(defun project-other-command () >> + "Run command with `default-directory' set to the current project root." > I very much hope you will find a better name for this command. The > "other" part seems to be out of place here, at least as far as the doc > string is considered. The intended meaning was "execute any other command in project", that is any other than those that are already present in project-prefix-map. It also matches the "o" binding, which is very conveniently positioned. But I'm not at all married to the name, better ideas welcome. project-any-command project-prefix-command project-execute-command [as opposed to extended command? which reads the command name] project-execute-other-command project-execute-in-root ... your suggestions here ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 9:46 ` Dmitry Gutov @ 2023-10-19 11:05 ` Eli Zaretskii 2023-10-19 11:34 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Eli Zaretskii @ 2023-10-19 11:05 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, sbaugh, 63648, juri > Date: Thu, 19 Oct 2023 12:46:53 +0300 > Cc: juri@linkov.net, sbaugh@janestreet.com, 63648@debbugs.gnu.org, > sbaugh@catern.com > From: Dmitry Gutov <dmitry@gutov.dev> > > On 19/10/2023 07:46, Eli Zaretskii wrote: > >> Cc: Spencer Baugh<sbaugh@janestreet.com>,63648@debbugs.gnu.org, > >> sbaugh@catern.com > >> Date: Thu, 19 Oct 2023 03:42:24 +0300 > >> From: Dmitry Gutov<dmitry@gutov.dev> > >> > >> +;;;###autoload > >> +(defun project-other-command () > >> + "Run command with `default-directory' set to the current project root." > > I very much hope you will find a better name for this command. The > > "other" part seems to be out of place here, at least as far as the doc > > string is considered. > > The intended meaning was "execute any other command in project", that is > any other than those that are already present in project-prefix-map. It > also matches the "o" binding, which is very conveniently positioned. > > But I'm not at all married to the name, better ideas welcome. > > project-any-command This one looks like a good name to me. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 11:05 ` Eli Zaretskii @ 2023-10-19 11:34 ` Dmitry Gutov 0 siblings, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 11:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: sbaugh, sbaugh, 63648, juri On 19/10/2023 14:05, Eli Zaretskii wrote: >> Date: Thu, 19 Oct 2023 12:46:53 +0300 >> Cc:juri@linkov.net,sbaugh@janestreet.com,63648@debbugs.gnu.org, >> sbaugh@catern.com >> From: Dmitry Gutov<dmitry@gutov.dev> >> >> On 19/10/2023 07:46, Eli Zaretskii wrote: >>>> Cc: Spencer Baugh<sbaugh@janestreet.com>,63648@debbugs.gnu.org, >>>> sbaugh@catern.com >>>> Date: Thu, 19 Oct 2023 03:42:24 +0300 >>>> From: Dmitry Gutov<dmitry@gutov.dev> >>>> >>>> +;;;###autoload >>>> +(defun project-other-command () >>>> + "Run command with `default-directory' set to the current project root." >>> I very much hope you will find a better name for this command. The >>> "other" part seems to be out of place here, at least as far as the doc >>> string is considered. >> The intended meaning was "execute any other command in project", that is >> any other than those that are already present in project-prefix-map. It >> also matches the "o" binding, which is very conveniently positioned. >> >> But I'm not at all married to the name, better ideas welcome. >> >> project-any-command > This one looks like a good name to me. Works for me. I'll be waiting for the feedback on the rest of the proposed change. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 0:42 ` Dmitry Gutov 2023-10-19 4:46 ` Eli Zaretskii @ 2023-10-19 12:22 ` sbaugh 2023-10-19 12:49 ` Dmitry Gutov 2023-10-19 17:56 ` Juri Linkov 2023-10-21 13:27 ` sbaugh 3 siblings, 1 reply; 109+ messages in thread From: sbaugh @ 2023-10-19 12:22 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > Hi Juri, > > On 22/09/2023 18:52, Juri Linkov wrote: >>>> Probably. Would you like to propose one? So that I have something to >>>> compare to, and have something specific to put to the vote as well. >>> >>> Ok, something like this: >> Here is a more tested patch. It supports these cases: >> (setq project-switch-use-entire-map t) >> C-x p p C-b - should not include current buffer in the list of >> another project (bug#58784) >> C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) >> C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) >> C-x p p C-x d - should visit another project's root (bug#63648) >> The same with frames: >> C-x 5 p p C-b >> C-x 5 p p f M-n >> C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) >> C-x 5 p p C-x d > > Thank you. Especially for the list. > > But I think we still haven't reached a decision whether the "loop > until correct key is pressed" behavior is useful. > > I tried to think how to fit the above requirements into the existing > model, and it seems to require a new command, and an additional key > being pressed sometimes, for explicitness. > > The attached patch also includes your fix for bug#65558, which seems > orthogonal to our dilemma, and could probably be installed > separately. It could be dry-ed up a little, though. > > Anyway, with the attached counter-proposal, the list looks like this: > > C-x p p C-b - works when project-switch-use-entire-map=t > C-x p p f M-n - always works > C-u C-x p p f - same > C-x p p C-x d - the key sequence is 'C-x p p o C-x d' > > With frames: > > C-x 5 p p C-b - works when project-switch-use-entire-map=t > C-x 5 p p f M-n - always works > C-u C-x 5 p p f emoji TAB - same (thanks to your fix, included) > C-x 5 p p C-x d - the key sequence is 'C-x 5 C-x p p o C-x d' > > The user could add project-list-buffers (or project-switch-to-buffer) > to project-switch-commands, though, and then > project-switch-use-entire-map won't be needed. Either way's fine. > > To sum up, that does require pressing an extra key to use commands > outside of project-prefix-map, but OTOH that key is shown right in the > commands menu. And one doesn't have to (setq > project-switch-use-entire-map t) to use it, though that doesn't hurt > either. > > And the meaning of project-switch-use-entire-map remains as it > currently is: expand the set of keys to the whole project-prefix-map, > but not to all local and global ones. > > WDYT? Hm, I personally think having to hit the extra "o" is undesirable. I'm not sure whether "C-x p p o" would be an improvement over the current state of the world: you can already hit "C-x p p D" to run project-dired, so you end up in dired at the root of the project, and then run whatever command you like with default-directory=project-root. The main downside of C-x p p D is that it necessarily switches buffers, which I often don't want. Solving that would be nice, but it would be nice to also get a shorter keybinding out of it. Actually, this gives me an idea. What if we embraced having C-x p p switch buffers? What if we had a new command which jumps you to some new "project status buffer", whose default-directory=project-root, and which has single-letter bindings for the current project-prefix commands? Similar to vc-dir. We could probably find some useful information to display in that buffer, too, like a header which extracts the status from the project's compilation buffer, or a list of the buffers in the project. If we replaced C-x p p with this command, then that would avoid all our issues with default-directory and command loops and so on, by just biting the bullet and switching buffers. Although, maybe we can get the best of both worlds by having C-x p p just temporarily switch buffer? It can do (with-current-buffer (project-status) ...) plus resolving keybindings as if they were typed in the project-status buffer. That seems pretty elegant to me and resolves a lot of complexities without giving up anything. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 12:22 ` sbaugh @ 2023-10-19 12:49 ` Dmitry Gutov 2023-10-19 14:00 ` Spencer Baugh 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 12:49 UTC (permalink / raw) To: sbaugh; +Cc: Spencer Baugh, 63648, Juri Linkov On 19/10/2023 15:22, sbaugh@catern.com wrote: > Dmitry Gutov <dmitry@gutov.dev> writes: >> Hi Juri, >> >> On 22/09/2023 18:52, Juri Linkov wrote: >>>>> Probably. Would you like to propose one? So that I have something to >>>>> compare to, and have something specific to put to the vote as well. >>>> >>>> Ok, something like this: >>> Here is a more tested patch. It supports these cases: >>> (setq project-switch-use-entire-map t) >>> C-x p p C-b - should not include current buffer in the list of >>> another project (bug#58784) >>> C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) >>> C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) >>> C-x p p C-x d - should visit another project's root (bug#63648) >>> The same with frames: >>> C-x 5 p p C-b >>> C-x 5 p p f M-n >>> C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) >>> C-x 5 p p C-x d >> >> Thank you. Especially for the list. >> >> But I think we still haven't reached a decision whether the "loop >> until correct key is pressed" behavior is useful. >> >> I tried to think how to fit the above requirements into the existing >> model, and it seems to require a new command, and an additional key >> being pressed sometimes, for explicitness. >> >> The attached patch also includes your fix for bug#65558, which seems >> orthogonal to our dilemma, and could probably be installed >> separately. It could be dry-ed up a little, though. >> >> Anyway, with the attached counter-proposal, the list looks like this: >> >> C-x p p C-b - works when project-switch-use-entire-map=t >> C-x p p f M-n - always works >> C-u C-x p p f - same >> C-x p p C-x d - the key sequence is 'C-x p p o C-x d' >> >> With frames: >> >> C-x 5 p p C-b - works when project-switch-use-entire-map=t >> C-x 5 p p f M-n - always works >> C-u C-x 5 p p f emoji TAB - same (thanks to your fix, included) >> C-x 5 p p C-x d - the key sequence is 'C-x 5 C-x p p o C-x d' >> >> The user could add project-list-buffers (or project-switch-to-buffer) >> to project-switch-commands, though, and then >> project-switch-use-entire-map won't be needed. Either way's fine. >> >> To sum up, that does require pressing an extra key to use commands >> outside of project-prefix-map, but OTOH that key is shown right in the >> commands menu. And one doesn't have to (setq >> project-switch-use-entire-map t) to use it, though that doesn't hurt >> either. >> >> And the meaning of project-switch-use-entire-map remains as it >> currently is: expand the set of keys to the whole project-prefix-map, >> but not to all local and global ones. >> >> WDYT? > > Hm, I personally think having to hit the extra "o" is undesirable. I'm > not sure whether "C-x p p o" would be an improvement over the current > state of the world: you can already hit "C-x p p D" to run > project-dired, so you end up in dired at the root of the project, and > then run whatever command you like with default-directory=project-root. It makes this capability apparent, and it's still one fewer keystroke (and 'o' is close to 'p', too). > The main downside of C-x p p D is that it necessarily switches buffers, > which I often don't want. Solving that would be nice, but it would be > nice to also get a shorter keybinding out of it. > > Actually, this gives me an idea. What if we embraced having C-x p p > switch buffers? What if we had a new command which jumps you to some > new "project status buffer", whose default-directory=project-root, and > which has single-letter bindings for the current project-prefix > commands? Similar to vc-dir. We could probably find some useful > information to display in that buffer, too, like a header which extracts > the status from the project's compilation buffer, or a list of the > buffers in the project. I'm totally on board with adding such command, except I'm not sure if we will give away the 'C-x p p' binding to it. But as far as calling the "next" command, both project-vc-dir and project-dired currently satisfy your condition, right? > If we replaced C-x p p with this command, then that would avoid all our > issues with default-directory and command loops and so on, by just > biting the bullet and switching buffers. Except when one wants to call a command that takes the current buffer into account. And/or its contents in particular (e.g. file name at point). > Although, maybe we can get the best of both worlds by having C-x p p > just temporarily switch buffer? It can do (with-current-buffer > (project-status) ...) plus resolving keybindings as if they were typed > in the project-status buffer. That seems pretty elegant to me and > resolves a lot of complexities without giving up anything. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem caused by a similar approach in the implementation. OTOH, https://debbugs.gnu.org/cgi/bugreport.cgi?bug=58784 probably doesn't apply (most of the time; unless the projects are nested or whatever). ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 12:49 ` Dmitry Gutov @ 2023-10-19 14:00 ` Spencer Baugh 2023-10-19 17:17 ` Dmitry Gutov 2023-10-19 18:03 ` Juri Linkov 0 siblings, 2 replies; 109+ messages in thread From: Spencer Baugh @ 2023-10-19 14:00 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > On 19/10/2023 15:22, sbaugh@catern.com wrote: >> Hm, I personally think having to hit the extra "o" is undesirable. >> I'm >> not sure whether "C-x p p o" would be an improvement over the current >> state of the world: you can already hit "C-x p p D" to run >> project-dired, so you end up in dired at the root of the project, and >> then run whatever command you like with default-directory=project-root. > > It makes this capability apparent, and it's still one fewer keystroke > (and 'o' is close to 'p', too). One fewer keystroke? Oh, since one has to hit shift to type D... there's equivalently C-x p p v, then, which is the same length in keystrokes. >> The main downside of C-x p p D is that it necessarily switches buffers, >> which I often don't want. Solving that would be nice, but it would be >> nice to also get a shorter keybinding out of it. >> Actually, this gives me an idea. What if we embraced having C-x p p >> switch buffers? What if we had a new command which jumps you to some >> new "project status buffer", whose default-directory=project-root, and >> which has single-letter bindings for the current project-prefix >> commands? Similar to vc-dir. We could probably find some useful >> information to display in that buffer, too, like a header which extracts >> the status from the project's compilation buffer, or a list of the >> buffers in the project. > > I'm totally on board with adding such command, except I'm not sure if > we will give away the 'C-x p p' binding to it. But as far as calling > the "next" command, both project-vc-dir and project-dired currently > satisfy your condition, right? Yes. Although project-vc-dir and project-dired don't provide a nice solution for how to implement the C-x p p single key bindings. With the project-status buffer, if it had the single-key bindings, then we would just say "C-x p p resolves keybindings as they would be resolved in project-status". BTW, a more tangential idea: a list-projects command and associated *Project List* buffer would be nice. With: - a list of all remembered projects, with some details about each one - you can hit RET to open a project's project-status - with something (a post-command-hook?) which updates default-directory so that it matches the project at point, so commands you run operate on that project (e.g. find-file) - and the same single key bindings that are in project-prefix-map (maybe C-x p RET should be the binding to open project-status in general) This would be a nice complement to project-switch-project: list-projects and project-switch-project would be like list-buffers and switch-to-buffer. (The combination of list-projects and project-status buffers would basically be a port of what we have internally at Jane Street. While I'm saying that, I should mention also our equivalent of project-switch-project: when passed a prefix argument, all our equivalent-to-project-* commands will prompt for a project. This is not a great solution though, it doesn't scale well since every command needs to be aware of this prefix argument. The C-x p p design of a separate command which overrides the project for the next command is much better, and once we get a good design I plan to tell our users to start using C-x p p for our internal commands instead of passing the prefix argument.) >> If we replaced C-x p p with this command, then that would avoid all our >> issues with default-directory and command loops and so on, by just >> biting the bullet and switching buffers. > > Except when one wants to call a command that takes the current buffer > into account. And/or its contents in particular (e.g. file name at > point). > >> Although, maybe we can get the best of both worlds by having C-x p p >> just temporarily switch buffer? It can do (with-current-buffer >> (project-status) ...) plus resolving keybindings as if they were typed >> in the project-status buffer. That seems pretty elegant to me and >> resolves a lot of complexities without giving up anything. > > https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem > caused by a similar approach in the implementation. OTOH, I was thinking we'd solve both this specific problem and the general case by just saving the current buffer in a project-old-buffer variable so that project-aware commands could go back and grab stuff from it. It does mean that project-unaware commands can't both operate in a different project and on the current buffer. Is there ever a place we actually want that though? > https://debbugs.gnu.org/cgi/bugreport.cgi?bug=58784 probably doesn't > apply (most of the time; unless the projects are nested or whatever). Indeed. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 14:00 ` Spencer Baugh @ 2023-10-19 17:17 ` Dmitry Gutov 2023-10-19 19:30 ` Spencer Baugh 2023-10-19 18:03 ` Juri Linkov 1 sibling, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 17:17 UTC (permalink / raw) To: Spencer Baugh; +Cc: sbaugh, 63648, Juri Linkov On 19/10/2023 17:00, Spencer Baugh wrote: >> It makes this capability apparent, and it's still one fewer keystroke >> (and 'o' is close to 'p', too). > > One fewer keystroke? Oh, since one has to hit shift to type > D... there's equivalently C-x p p v, then, which is the same length in > keystrokes. 'C-x p p v' is a bit farther, but close enough indeed. >>> The main downside of C-x p p D is that it necessarily switches buffers, >>> which I often don't want. Solving that would be nice, but it would be >>> nice to also get a shorter keybinding out of it. >>> Actually, this gives me an idea. What if we embraced having C-x p p >>> switch buffers? What if we had a new command which jumps you to some >>> new "project status buffer", whose default-directory=project-root, and >>> which has single-letter bindings for the current project-prefix >>> commands? Similar to vc-dir. We could probably find some useful >>> information to display in that buffer, too, like a header which extracts >>> the status from the project's compilation buffer, or a list of the >>> buffers in the project. >> >> I'm totally on board with adding such command, except I'm not sure if >> we will give away the 'C-x p p' binding to it. But as far as calling >> the "next" command, both project-vc-dir and project-dired currently >> satisfy your condition, right? > > Yes. Although project-vc-dir and project-dired don't provide a nice > solution for how to implement the C-x p p single key bindings. With the > project-status buffer, if it had the single-key bindings, then we would > just say "C-x p p resolves keybindings as they would be resolved in > project-status". Hmm... if the goal is to just have 'C-x p p' resolve the short key bindings, then (setq project-switch-use-entire-map t) gets you all the way there, doesn't it? So the question is, do you need to be able to use non-project commands (like in the title of this report), and how often? If it's not very often (which would reflect my experience), then pressing 'o' once in a while should be a small price to pay. BTW, when project-switch-use-entire-map is non-nil, we should probably display something informative to the user (e.g. some abbreviated list of all the bindings in project-prefix-map?), so that the users don't mistake the the meaning of the option, and see at least some of the keys they can press at that point, instead of the incorrect command menu. > BTW, a more tangential idea: a list-projects command and associated > *Project List* buffer would be nice. With: > > - a list of all remembered projects, with some details about each one > - you can hit RET to open a project's project-status > - with something (a post-command-hook?) which updates default-directory > so that it matches the project at point, so commands you run operate > on that project (e.g. find-file) > - and the same single key bindings that are in project-prefix-map > (maybe C-x p RET should be the binding to open project-status in general) > > This would be a nice complement to project-switch-project: list-projects > and project-switch-project would be like list-buffers and > switch-to-buffer. That reminds me of bug#63896. And I suppose some pieces could be reused between these views. Speaking of 'list-projects', though, I wonder what we could display for a project by default, aside from its root dir (abbreviated) and the number of open buffers. > (The combination of list-projects and project-status buffers would > basically be a port of what we have internally at Jane Street. While > I'm saying that, I should mention also our equivalent of > project-switch-project: when passed a prefix argument, all our > equivalent-to-project-* commands will prompt for a project. This is not > a great solution though, it doesn't scale well since every command needs > to be aware of this prefix argument. The C-x p p design of a separate > command which overrides the project for the next command is much better, > and once we get a good design I plan to tell our users to start using > C-x p p for our internal commands instead of passing the prefix > argument.) > >>> If we replaced C-x p p with this command, then that would avoid all our >>> issues with default-directory and command loops and so on, by just >>> biting the bullet and switching buffers. >> >> Except when one wants to call a command that takes the current buffer >> into account. And/or its contents in particular (e.g. file name at >> point). >> >>> Although, maybe we can get the best of both worlds by having C-x p p >>> just temporarily switch buffer? It can do (with-current-buffer >>> (project-status) ...) plus resolving keybindings as if they were typed >>> in the project-status buffer. That seems pretty elegant to me and >>> resolves a lot of complexities without giving up anything. >> >> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem >> caused by a similar approach in the implementation. OTOH, > > I was thinking we'd solve both this specific problem and the general > case by just saving the current buffer in a project-old-buffer variable > so that project-aware commands could go back and grab stuff from it. I suppose they could, but then we support using them all (?) already with project-switch-use-entire-map. When one has custom commands, the user would probably add them to project-prefix-map too. > It does mean that project-unaware commands can't both operate in a > different project and on the current buffer. Is there ever a place we > actually want that though? From where I'm standing, we've already passed into the "does anybody need this" territory. But people can write their own commands, or install packages, and apparently sometimes combine them with projects with advanced invocations. I'm happy to try optimizing different workflows, but it's probably at least equally important to make sure the new additions are consistent and predictable (meaning, it's easy to tell in advance whether something is going to work or not), and hopefully somewhat discoverable too. The latter probably means that we cannot make just any global key sequence work in the *Project List* buffer (or e.g. have 'M-x gnus' start in a different directory depending on which line point current is on). But we might have a binding for a prefix command which would make sure the next one is run within the project room as its default-directory. Binding 'project-any-command' (or a variation of it) to 'o' seems natural in there too. Do you disagree? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 17:17 ` Dmitry Gutov @ 2023-10-19 19:30 ` Spencer Baugh 2023-10-19 23:25 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-10-19 19:30 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > On 19/10/2023 17:00, Spencer Baugh wrote: >>>> The main downside of C-x p p D is that it necessarily switches buffers, >>>> which I often don't want. Solving that would be nice, but it would be >>>> nice to also get a shorter keybinding out of it. >>>> Actually, this gives me an idea. What if we embraced having C-x p p >>>> switch buffers? What if we had a new command which jumps you to some >>>> new "project status buffer", whose default-directory=project-root, and >>>> which has single-letter bindings for the current project-prefix >>>> commands? Similar to vc-dir. We could probably find some useful >>>> information to display in that buffer, too, like a header which extracts >>>> the status from the project's compilation buffer, or a list of the >>>> buffers in the project. >>> >>> I'm totally on board with adding such command, except I'm not sure if >>> we will give away the 'C-x p p' binding to it. But as far as calling >>> the "next" command, both project-vc-dir and project-dired currently >>> satisfy your condition, right? >> Yes. Although project-vc-dir and project-dired don't provide a nice >> solution for how to implement the C-x p p single key bindings. With the >> project-status buffer, if it had the single-key bindings, then we would >> just say "C-x p p resolves keybindings as they would be resolved in >> project-status". > > Hmm... if the goal is to just have 'C-x p p' resolve the short key > bindings, then (setq project-switch-use-entire-map t) gets you all the > way there, doesn't it? To be clear, this was just a comment about how project-status would help us on the implementation side of single-key bindings. I still > So the question is, do you need to be able to use non-project commands > (like in the title of this report), and how often? > > If it's not very often (which would reflect my experience), then > pressing 'o' once in a while should be a small price to pay. I personally use non-project commands quite frequently through C-x p p D Some things I run sometimes: - find-file (if I just want to find a file from the root rather than with project-find-file) - vc-pull - vc-root-diff - various internal commands to access code review or check the build status > BTW, when project-switch-use-entire-map is non-nil, we should probably > display something informative to the user (e.g. some abbreviated list > of all the bindings in project-prefix-map?), so that the users don't > mistake the the meaning of the option, and see at least some of the > keys they can press at that point, instead of the incorrect command > menu. True. Automatically generating this would be kind of like which-key. >> BTW, a more tangential idea: a list-projects command and associated >> *Project List* buffer would be nice. With: >> - a list of all remembered projects, with some details about each >> one >> - you can hit RET to open a project's project-status >> - with something (a post-command-hook?) which updates default-directory >> so that it matches the project at point, so commands you run operate >> on that project (e.g. find-file) >> - and the same single key bindings that are in project-prefix-map >> (maybe C-x p RET should be the binding to open project-status in general) >> This would be a nice complement to project-switch-project: >> list-projects >> and project-switch-project would be like list-buffers and >> switch-to-buffer. > > That reminds me of bug#63896. And I suppose some pieces could be > reused between these views. Indeed. They're two perspectives on the same data. The main reason for bug#63896 though is to get the benefits of seeing the data that project-list presents, and then be able to run a command in an arbitrary > Speaking of 'list-projects', though, I wonder what we could display > for a project by default, aside from its root dir (abbreviated) and > the number of open buffers. Some possibilities: - The project type (or the vc type if it's a vc project?) - Maybe some vc information; whether the working tree is dirty? - The current number of warnings/errors in the *compilation* buffer for that project if any; I implemented that for bug#63896 and it's pretty easy >> (The combination of list-projects and project-status buffers would >> basically be a port of what we have internally at Jane Street. While >> I'm saying that, I should mention also our equivalent of >> project-switch-project: when passed a prefix argument, all our >> equivalent-to-project-* commands will prompt for a project. This is not >> a great solution though, it doesn't scale well since every command needs >> to be aware of this prefix argument. The C-x p p design of a separate >> command which overrides the project for the next command is much better, >> and once we get a good design I plan to tell our users to start using >> C-x p p for our internal commands instead of passing the prefix >> argument.) >> >>>> If we replaced C-x p p with this command, then that would avoid all our >>>> issues with default-directory and command loops and so on, by just >>>> biting the bullet and switching buffers. >>> >>> Except when one wants to call a command that takes the current buffer >>> into account. And/or its contents in particular (e.g. file name at >>> point). >>> >>>> Although, maybe we can get the best of both worlds by having C-x p p >>>> just temporarily switch buffer? It can do (with-current-buffer >>>> (project-status) ...) plus resolving keybindings as if they were typed >>>> in the project-status buffer. That seems pretty elegant to me and >>>> resolves a lot of complexities without giving up anything. >>> >>> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem >>> caused by a similar approach in the implementation. OTOH, >> I was thinking we'd solve both this specific problem and the general >> case by just saving the current buffer in a project-old-buffer variable >> so that project-aware commands could go back and grab stuff from it. > > I suppose they could, but then we support using them all (?) already > with project-switch-use-entire-map. When one has custom commands, the > user would probably add them to project-prefix-map too. Er, I'm not sure I understand. Let me clarify: The "specific problem and the general case" that I was referring to is the problem with some implementations of project-switch-project where the buffer changes when we use project-switch-project, meaning we can't grab stuff from the current buffer. And we could solve that by just saving the buffer in a project-specific variable. >> It does mean that project-unaware commands can't both operate in a >> different project and on the current buffer. Is there ever a place we >> actually want that though? > > From where I'm standing, we've already passed into the "does anybody > need this" territory. But people can write their own commands, or > install packages, and apparently sometimes combine them with projects > with advanced invocations. > > I'm happy to try optimizing different workflows, but it's probably at > least equally important to make sure the new additions are consistent > and predictable (meaning, it's easy to tell in advance whether > something is going to work or not), and hopefully somewhat > discoverable too. I agree of course. > The latter probably means that we cannot make just any global key > sequence work in the *Project List* buffer (or e.g. have 'M-x gnus' > start in a different directory depending on which line point current > is on). But we might have a binding for a prefix command which would > make sure the next one is run within the project room as its > default-directory. Binding 'project-any-command' (or a variation of > it) to 'o' seems natural in there too. Do you disagree? Hm, I think changing default-directory in project-list based on point is very discoverable. Let me explain why: When you hit "g" in the project-list buffer, I expect that it would operate on the project at point. That seems obvious and unobjectionable. So users will be used to being able to operate on different projects based on the value of point. And it is (in my experience) a straightforward extension from that to running arbitrary commands on different projects based on the value of point. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 19:30 ` Spencer Baugh @ 2023-10-19 23:25 ` Dmitry Gutov 2023-10-21 16:09 ` Spencer Baugh 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 23:25 UTC (permalink / raw) To: Spencer Baugh; +Cc: sbaugh, 63648, Juri Linkov On 19/10/2023 22:30, Spencer Baugh wrote: >>>> I'm totally on board with adding such command, except I'm not sure if >>>> we will give away the 'C-x p p' binding to it. But as far as calling >>>> the "next" command, both project-vc-dir and project-dired currently >>>> satisfy your condition, right? >>> Yes. Although project-vc-dir and project-dired don't provide a nice >>> solution for how to implement the C-x p p single key bindings. With the >>> project-status buffer, if it had the single-key bindings, then we would >>> just say "C-x p p resolves keybindings as they would be resolved in >>> project-status". >> >> Hmm... if the goal is to just have 'C-x p p' resolve the short key >> bindings, then (setq project-switch-use-entire-map t) gets you all the >> way there, doesn't it? > > To be clear, this was just a comment about how project-status would help > us on the implementation side of single-key bindings. I still <paragraph unfinished> >> So the question is, do you need to be able to use non-project commands >> (like in the title of this report), and how often? >> >> If it's not very often (which would reflect my experience), then >> pressing 'o' once in a while should be a small price to pay. > > I personally use non-project commands quite frequently through C-x p p D > > Some things I run sometimes: > - find-file (if I just want to find a file from the root rather than > with project-find-file) > - vc-pull > - vc-root-diff > - various internal commands to access code review or check the build > status I guess 'find-file' could also be a command that could use the buffer text under point. Apparently, not in your usage, but in someone else's. >> BTW, when project-switch-use-entire-map is non-nil, we should probably >> display something informative to the user (e.g. some abbreviated list >> of all the bindings in project-prefix-map?), so that the users don't >> mistake the the meaning of the option, and see at least some of the >> keys they can press at that point, instead of the incorrect command >> menu. > > True. > > Automatically generating this would be kind of like which-key. I pushed a version of this to master, but one that looks more like read-multiple-choice. Reimplementing which-key would be too much, and unfortunately I don't see a way to integrate it when available either. >> Speaking of 'list-projects', though, I wonder what we could display >> for a project by default, aside from its root dir (abbreviated) and >> the number of open buffers. > > Some possibilities: > - The project type (or the vc type if it's a vc project?) > - Maybe some vc information; whether the working tree is dirty? > - The current number of warnings/errors in the *compilation* buffer for > that project if any; I implemented that for bug#63896 and it's > pretty easy These first two sound like they call for addition of more generic functions that describe a project. Though it seems like they'd be hard to explain in terms of other project backends. Maybe we could instead say "VCS responsible for project root" and "VCS short status". Anyway, both good ideas. Regarding warnings/compilations, like I said in the other bug, it does sound nice when the integration works, but the info will be empty for a lot of users. >>>>> Although, maybe we can get the best of both worlds by having C-x p p >>>>> just temporarily switch buffer? It can do (with-current-buffer >>>>> (project-status) ...) plus resolving keybindings as if they were typed >>>>> in the project-status buffer. That seems pretty elegant to me and >>>>> resolves a lot of complexities without giving up anything. >>>> >>>> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem >>>> caused by a similar approach in the implementation. OTOH, >>> I was thinking we'd solve both this specific problem and the general >>> case by just saving the current buffer in a project-old-buffer variable >>> so that project-aware commands could go back and grab stuff from it. >> >> I suppose they could, but then we support using them all (?) already >> with project-switch-use-entire-map. When one has custom commands, the >> user would probably add them to project-prefix-map too. > > Er, I'm not sure I understand. Let me clarify: The "specific problem > and the general case" that I was referring to is the problem with some > implementations of project-switch-project where the buffer changes when > we use project-switch-project, meaning we can't grab stuff from the > current buffer. And we could solve that by just saving the buffer in a > project-specific variable. Which only project-aware commands would be able to take advantage of. >> The latter probably means that we cannot make just any global key >> sequence work in the *Project List* buffer (or e.g. have 'M-x gnus' >> start in a different directory depending on which line point current >> is on). But we might have a binding for a prefix command which would >> make sure the next one is run within the project room as its >> default-directory. Binding 'project-any-command' (or a variation of >> it) to 'o' seems natural in there too. Do you disagree? > > Hm, I think changing default-directory in project-list based on point is > very discoverable. Let me explain why: When you hit "g" in the > project-list buffer, I expect that it would operate on the project at > point. That seems obvious and unobjectionable. So users will be used > to being able to operate on different projects based on the value of > point. And it is (in my experience) a straightforward extension from > that to running arbitrary commands on different projects based on the > value of point. 'g' is probably fine. 'f' and the rest of such keys too. Though 'n' and, more importantly, 'p' will likely have different expectations. What if the user presses 'C-x o' while this buffer is current (and point is on one of the projects)? Or 'C-x C-s'? Would we dispatch every key sequence through our custom prefix command while this buffer is current? I can't think of an particularly damaging example right now, but the concept feels moderately dangerous. Buuut... simply changing default-directory buffer-locally in post-command hook based on what is under point might be fine. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 23:25 ` Dmitry Gutov @ 2023-10-21 16:09 ` Spencer Baugh 2023-10-21 18:43 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-10-21 16:09 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > On 19/10/2023 22:30, Spencer Baugh wrote: >>>>> I'm totally on board with adding such command, except I'm not sure if >>>>> we will give away the 'C-x p p' binding to it. But as far as calling >>>>> the "next" command, both project-vc-dir and project-dired currently >>>>> satisfy your condition, right? >>>> Yes. Although project-vc-dir and project-dired don't provide a nice >>>> solution for how to implement the C-x p p single key bindings. With the >>>> project-status buffer, if it had the single-key bindings, then we would >>>> just say "C-x p p resolves keybindings as they would be resolved in >>>> project-status". >>> >>> Hmm... if the goal is to just have 'C-x p p' resolve the short key >>> bindings, then (setq project-switch-use-entire-map t) gets you all the >>> way there, doesn't it? >> To be clear, this was just a comment about how project-status would >> help >> us on the implementation side of single-key bindings. I still > > <paragraph unfinished> I don't remember how I was going to finish it :) Anyway, the point is moot now, since I'm persuaded that "C-x p p resolves keybindings as they would be resolved in project-status" doesn't work because of the buffer change. >>> BTW, when project-switch-use-entire-map is non-nil, we should probably >>> display something informative to the user (e.g. some abbreviated list >>> of all the bindings in project-prefix-map?), so that the users don't >>> mistake the the meaning of the option, and see at least some of the >>> keys they can press at that point, instead of the incorrect command >>> menu. >> True. >> Automatically generating this would be kind of like which-key. > > I pushed a version of this to master, but one that looks more like > read-multiple-choice. Reimplementing which-key would be too much, and > unfortunately I don't see a way to integrate it when available either. which-key is in GNU ELPA. So possibly it could be brought into core, if we're finding that we need it. Does that seem plausible? I could bring it up on emacs-devel, since I think which-key would be an excellent addition to core for other reasons too. >>> The latter probably means that we cannot make just any global key >>> sequence work in the *Project List* buffer (or e.g. have 'M-x gnus' >>> start in a different directory depending on which line point current >>> is on). But we might have a binding for a prefix command which would >>> make sure the next one is run within the project room as its >>> default-directory. Binding 'project-any-command' (or a variation of >>> it) to 'o' seems natural in there too. Do you disagree? >> Hm, I think changing default-directory in project-list based on >> point is >> very discoverable. Let me explain why: When you hit "g" in the >> project-list buffer, I expect that it would operate on the project at >> point. That seems obvious and unobjectionable. So users will be used >> to being able to operate on different projects based on the value of >> point. And it is (in my experience) a straightforward extension from >> that to running arbitrary commands on different projects based on the >> value of point. > > 'g' is probably fine. 'f' and the rest of such keys too. Though 'n' > and, more importantly, 'p' will likely have different expectations. Yes, I was thinking we'd have 'n' and 'p' do next/previous-line. 'n' is unused and 'p' is probably not necessary: you can just do C-s instead, or possibly (if we set it up) use imenu, M-g i. Possibly we should avoid using C-x p n, to reserve 'n' for this. (Or maybe C-x p n could be something that is also not necessary in the project-list buffer... maybe C-x p n could run project-list? Maybe it could be called project-navigate?) > What if the user presses 'C-x o' while this buffer is current (and > point is on one of the projects)? Or 'C-x C-s'? Would we dispatch > every key sequence through our custom prefix command while this buffer > is current? > > I can't think of an particularly damaging example right now, but the > concept feels moderately dangerous. Oh, certainly not! That does sound quite dangerous and complicated and I have no idea how it would work. > Buuut... simply changing default-directory buffer-locally in > post-command hook based on what is under point might be fine. Yes, that's what I had in mind. This is much simpler than other-project-prefix. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-21 16:09 ` Spencer Baugh @ 2023-10-21 18:43 ` Dmitry Gutov 0 siblings, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-10-21 18:43 UTC (permalink / raw) To: Spencer Baugh; +Cc: sbaugh, 63648, Juri Linkov On 21/10/2023 19:09, Spencer Baugh wrote: >>>> BTW, when project-switch-use-entire-map is non-nil, we should probably >>>> display something informative to the user (e.g. some abbreviated list >>>> of all the bindings in project-prefix-map?), so that the users don't >>>> mistake the the meaning of the option, and see at least some of the >>>> keys they can press at that point, instead of the incorrect command >>>> menu. >>> True. >>> Automatically generating this would be kind of like which-key. >> >> I pushed a version of this to master, but one that looks more like >> read-multiple-choice. Reimplementing which-key would be too much, and >> unfortunately I don't see a way to integrate it when available either. > > which-key is in GNU ELPA. So possibly it could be brought into core, if > we're finding that we need it. Does that seem plausible? I could bring > it up on emacs-devel, since I think which-key would be an excellent > addition to core for other reasons too. Even if it were here, I'm not sure what the integration would look like, code-wise. >>>> The latter probably means that we cannot make just any global key >>>> sequence work in the *Project List* buffer (or e.g. have 'M-x gnus' >>>> start in a different directory depending on which line point current >>>> is on). But we might have a binding for a prefix command which would >>>> make sure the next one is run within the project room as its >>>> default-directory. Binding 'project-any-command' (or a variation of >>>> it) to 'o' seems natural in there too. Do you disagree? >>> Hm, I think changing default-directory in project-list based on >>> point is >>> very discoverable. Let me explain why: When you hit "g" in the >>> project-list buffer, I expect that it would operate on the project at >>> point. That seems obvious and unobjectionable. So users will be used >>> to being able to operate on different projects based on the value of >>> point. And it is (in my experience) a straightforward extension from >>> that to running arbitrary commands on different projects based on the >>> value of point. >> >> 'g' is probably fine. 'f' and the rest of such keys too. Though 'n' >> and, more importantly, 'p' will likely have different expectations. > > Yes, I was thinking we'd have 'n' and 'p' do next/previous-line. 'n' is > unused and 'p' is probably not necessary: you can just do C-s instead, > or possibly (if we set it up) use imenu, M-g i. > > Possibly we should avoid using C-x p n, to reserve 'n' for this. (Or > maybe C-x p n could be something that is also not necessary in the > project-list buffer... maybe C-x p n could run project-list? Maybe it > could be called project-navigate?) The latter -- sure, probably. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 14:00 ` Spencer Baugh 2023-10-19 17:17 ` Dmitry Gutov @ 2023-10-19 18:03 ` Juri Linkov 2023-10-19 19:38 ` Spencer Baugh 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-19 18:03 UTC (permalink / raw) To: Spencer Baugh; +Cc: Dmitry Gutov, 63648, sbaugh >> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem >> caused by a similar approach in the implementation. OTOH, > > I was thinking we'd solve both this specific problem and the general > case by just saving the current buffer in a project-old-buffer variable > so that project-aware commands could go back and grab stuff from it. > > It does mean that project-unaware commands can't both operate in a > different project and on the current buffer. Is there ever a place we > actually want that though? For example, 'C-x p p M-x rgrep RET' would need to read a word under point as the default value. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 18:03 ` Juri Linkov @ 2023-10-19 19:38 ` Spencer Baugh 0 siblings, 0 replies; 109+ messages in thread From: Spencer Baugh @ 2023-10-19 19:38 UTC (permalink / raw) To: Juri Linkov; +Cc: Dmitry Gutov, 63648, sbaugh Juri Linkov <juri@linkov.net> writes: >>> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63829 was a problem >>> caused by a similar approach in the implementation. OTOH, >> >> I was thinking we'd solve both this specific problem and the general >> case by just saving the current buffer in a project-old-buffer variable >> so that project-aware commands could go back and grab stuff from it. >> >> It does mean that project-unaware commands can't both operate in a >> different project and on the current buffer. Is there ever a place we >> actually want that though? > > For example, 'C-x p p M-x rgrep RET' would need to read a word under point > as the default value. Argh. Aaargh. OK, I guess that is definitely a test case that we want to work. So nevermind about the idea of having project-switch-project just switch to a project-status buffer. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 0:42 ` Dmitry Gutov 2023-10-19 4:46 ` Eli Zaretskii 2023-10-19 12:22 ` sbaugh @ 2023-10-19 17:56 ` Juri Linkov 2023-10-19 22:39 ` Dmitry Gutov 2023-10-21 13:27 ` sbaugh 3 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-19 17:56 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh > C-x p p C-x d - the key sequence is 'C-x p p o C-x d' BTW, with (setq project-switch-use-entire-map t) I accidentally typed 'C-x p p C-x d' that should ignore 'C-x' and read a directory with 'd', it fails with: (wrong-type-argument commandp 1) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 17:56 ` Juri Linkov @ 2023-10-19 22:39 ` Dmitry Gutov 2023-10-20 6:44 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-19 22:39 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 19/10/2023 20:56, Juri Linkov wrote: >> C-x p p C-x d - the key sequence is 'C-x p p o C-x d' > BTW, with (setq project-switch-use-entire-map t) > I accidentally typed 'C-x p p C-x d' that should ignore 'C-x' > and read a directory with 'd', it fails with: > > (wrong-type-argument commandp 1) Thanks, see the commit e1708697122 I just pushed. It should fix this, print the available keys from the whole keymap (when enabled), and echo mistakes as well. In a fairly bare way, but this should make the feature what I'd call usable. I also tried the variant with printing all the command names beside the keys, but even with ^project- stripped, they didn't fit on one line. 'C-x d' will result in a warning echo, though, instead of just using 'd'. If you really prefer that, try experimenting with the below addition, but I'm wary of edge cases, since we want to keep supporting sub-maps like in bug#47620. It also might feel a little too "magical" now that there are more details printed (it also doesn't handle extremes like 'C-c C-x C-c' still). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 0d6539113cc..90b61609c45 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -2003,7 +2003,9 @@ project--switch-project-command (help-key-description choice nil))))) (setq choice (read-key-sequence (concat "Choose: " prompt))) (when (setq command (lookup-key commands-map choice)) - (when (numberp command) (setq command nil)) + (when (numberp command) + (setq command + (lookup-key commands-map (substring choice command)))) (unless (or project-switch-use-entire-map (assq command commands-menu)) ;; TODO: Add some hint to the prompt, like "key not ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 22:39 ` Dmitry Gutov @ 2023-10-20 6:44 ` Juri Linkov 2023-10-20 19:25 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-20 6:44 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh > 'C-x d' will result in a warning echo, though, instead of just using > 'd'. If you really prefer that, try experimenting with the below addition, > but I'm wary of edge cases, since we want to keep supporting sub-maps like > in bug#47620. It also might feel a little too "magical" now that there are > more details printed (it also doesn't handle extremes like 'C-c C-x C-c' > still). > > @@ -2003,7 +2003,9 @@ project--switch-project-command > (help-key-description choice > nil))))) > (setq choice (read-key-sequence (concat "Choose: " prompt))) > (when (setq command (lookup-key commands-map choice)) > - (when (numberp command) (setq command nil)) > + (when (numberp command) > + (setq command > + (lookup-key commands-map (substring choice command)))) Wow, it works nicely for 'C-x p p C-x d'. But strange it fails for 'C-x p p C-x v d' with the same error: (wrong-type-argument commandp 1) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-20 6:44 ` Juri Linkov @ 2023-10-20 19:25 ` Dmitry Gutov 2023-10-23 6:58 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-20 19:25 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 20/10/2023 09:44, Juri Linkov wrote: >> 'C-x d' will result in a warning echo, though, instead of just using >> 'd'. If you really prefer that, try experimenting with the below addition, >> but I'm wary of edge cases, since we want to keep supporting sub-maps like >> in bug#47620. It also might feel a little too "magical" now that there are >> more details printed (it also doesn't handle extremes like 'C-c C-x C-c' >> still). >> >> @@ -2003,7 +2003,9 @@ project--switch-project-command >> (help-key-description choice >> nil))))) >> (setq choice (read-key-sequence (concat "Choose: " prompt))) >> (when (setq command (lookup-key commands-map choice)) >> - (when (numberp command) (setq command nil)) >> + (when (numberp command) >> + (setq command >> + (lookup-key commands-map (substring choice command)))) > Wow, it works nicely for 'C-x p p C-x d'. > But strange it fails for 'C-x p p C-x v d' > with the same error: > > (wrong-type-argument commandp 1) That's because (lookup-key ... "vd") also returns 1. I haven't been able to find a solution that works like we would expect. The most trivial would be to loop cutting off invalid prefixes, but then we end up with 'd', not 'v'. That's probably not what you want. Ideally, 'read-key-sequence' would stop at the user pressing 'v' and return "^Xv", then the rest would work out okay. But I haven't managed to have it do that, even when using overriding-terminal-local-map and temporarily altering the global map. My experimental patch is below, you can try tweaking it. And overall I'm not sure it's a constructive approach because you might have been going for 'C-x v d' (where the 'v' translation is correct), but you might have been going for 'C-x v D' or 'C-x v v' instead, very different commands. It might be better to report unknown key sequence and let the user make an explicit choice, like it works now. Depends on whether you notice the key sequence echoing while doing that input. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fda1081eb62..09d7e1025ca 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1983,7 +1983,6 @@ project--switch-project-command project-switch-commands)) (commands-map (let ((temp-map (make-sparse-keymap))) - (set-keymap-parent temp-map project-prefix-map) (dolist (row commands-menu temp-map) (when-let ((cmd (nth 0 row)) (keychar (nth 2 row))) @@ -1991,7 +1990,15 @@ project--switch-project-command command choice) (while (not command) - (let* ((overriding-local-map commands-map) + (let* ((map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map (if project-switch-use-entire-map + project-prefix-map + commands-map)) + (define-key map "\e\e\e" 'keyboard-escape-quit) + (define-key map "\C-g" 'keyboard-quit) + map)) + (overriding-terminal-local-map map) (prompt (if project-switch-use-entire-map (project--keymap-prompt) (project--menu-prompt)))) @@ -2001,16 +2008,20 @@ project--switch-project-command (propertize "Unrecognized input" 'face 'warning) (help-key-description choice nil))))) - (setq choice (read-key-sequence (concat "Choose: " prompt))) - (when (setq command (lookup-key commands-map choice)) - (when (numberp command) (setq command nil)) + (unwind-protect + (progn + (use-global-map map) + (setq choice (read-key-sequence (concat "Choose: " prompt) nil t nil t))) + (use-global-map global-map)) + (when (setq command (lookup-key map choice)) + (while (numberp command) + (setq choice (substring choice command)) + (setq command (lookup-key map choice))) + (when (memq command '(keyboard-quit keyboard-escape-quit)) + (call-interactively command)) (unless (or project-switch-use-entire-map (assq command commands-menu)) - (setq command nil))) - (let ((global-command (lookup-key (current-global-map) choice))) - (when (memq global-command - '(keyboard-quit keyboard-escape-quit)) - (call-interactively global-command))))) + (setq command nil))))) (message nil) command)) ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-20 19:25 ` Dmitry Gutov @ 2023-10-23 6:58 ` Juri Linkov 2023-10-23 17:24 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-23 6:58 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >> Wow, it works nicely for 'C-x p p C-x d'. >> But strange it fails for 'C-x p p C-x v d' >> with the same error: >> (wrong-type-argument commandp 1) > > That's because (lookup-key ... "vd") also returns 1. > > I haven't been able to find a solution that works like we would expect. The > most trivial would be to loop cutting off invalid prefixes, but then we end > up with 'd', not 'v'. That's probably not what you want. > > Ideally, 'read-key-sequence' would stop at the user pressing 'v' and return > "^Xv", then the rest would work out okay. But I haven't managed to have it > do that, even when using overriding-terminal-local-map and temporarily > altering the global map. My experimental patch is below, you can try > tweaking it. Now can't type 'C-x p p C-x v d' completely because 'C-x p p C-x v' opens vc-dir after typing 'v'. > And overall I'm not sure it's a constructive approach because you might > have been going for 'C-x v d' (where the 'v' translation is correct), but > you might have been going for 'C-x v D' or 'C-x v v' instead, very > different commands. It might be better to report unknown key sequence and > let the user make an explicit choice, like it works now. Depends on whether > you notice the key sequence echoing while doing that input. Maybe adding a new option 'project-switch-use-global-map' would help? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-23 6:58 ` Juri Linkov @ 2023-10-23 17:24 ` Dmitry Gutov 2023-10-23 17:34 ` Juri Linkov 2023-10-25 16:53 ` Juri Linkov 0 siblings, 2 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-10-23 17:24 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 1986 bytes --] On 23/10/2023 09:58, Juri Linkov wrote: >>> Wow, it works nicely for 'C-x p p C-x d'. >>> But strange it fails for 'C-x p p C-x v d' >>> with the same error: >>> (wrong-type-argument commandp 1) >> >> That's because (lookup-key ... "vd") also returns 1. >> >> I haven't been able to find a solution that works like we would expect. The >> most trivial would be to loop cutting off invalid prefixes, but then we end >> up with 'd', not 'v'. That's probably not what you want. >> >> Ideally, 'read-key-sequence' would stop at the user pressing 'v' and return >> "^Xv", then the rest would work out okay. But I haven't managed to have it >> do that, even when using overriding-terminal-local-map and temporarily >> altering the global map. My experimental patch is below, you can try >> tweaking it. > > Now can't type 'C-x p p C-x v d' completely because > 'C-x p p C-x v' opens vc-dir after typing 'v'. Huh. That actually works for me now, after I ran 'make' and restarted. But I thought you wanted this? 'C-x v d' ends with vc-dir, so if 'C-x p p C-x v' opens vc-dir, then isn't this what you expected? Anyway, the resulting UI is fairly counter-intuitive. >> And overall I'm not sure it's a constructive approach because you might >> have been going for 'C-x v d' (where the 'v' translation is correct), but >> you might have been going for 'C-x v D' or 'C-x v v' instead, very >> different commands. It might be better to report unknown key sequence and >> let the user make an explicit choice, like it works now. Depends on whether >> you notice the key sequence echoing while doing that input. > > Maybe adding a new option 'project-switch-use-global-map' would help? Try the attached, it's another iteration on the latest patch (prefix-command-echo-keystrokes-functions doesn't seem to work reliably in this context). Try it together with (setq project-switch-commands 'project-any-command) Also see the "Variation" in the comment (it allows for short bindings). [-- Attachment #2: project-other-command-v3.diff --] [-- Type: text/x-patch, Size: 2653 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fda1081eb62..6fffa92d71f 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -847,6 +847,7 @@ project-prefix-map (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) + (define-key map "o" 'project-any-command) (define-key map "\C-b" 'project-list-buffers) map) "Keymap for project commands.") @@ -1813,6 +1814,37 @@ project-execute-extended-command (let ((default-directory (project-root (project-current t)))) (call-interactively #'execute-extended-command))) +;;;###autoload +(defun project-any-command () + "Run the next command in the current project. +If the command is in `project-prefix-map', it gets passed that +info with `project-current-directory-override'. Otherwise, +`default-directory' is temporarily set to the current project's +root." + (interactive) + (let* ((pr (project-current t)) + ;; Variation: could be a separate command, or an option. + ;; (command (let ((overriding-local-map project-prefix-map)) + ;; (key-binding (read-key-sequence + ;; (format "[execute in %s]:" (project-root pr))) + ;; t))) + (command (key-binding (read-key-sequence + (format "[execute in %s]:" (project-root pr))) + t)) + (root (project-root pr)) + found) + (when command + ;; We could also check the command name against "\\`project-", + ;; and/or (get command 'project-command). + (map-keymap + (lambda (_evt cmd) (if (eq cmd command) (setq found t))) + project-prefix-map) + (if found + (let ((project-current-directory-override root)) + (call-interactively command)) + (let ((default-directory root)) + (call-interactively command)))))) + (defun project-remember-projects-under (dir &optional recursive) "Index all projects below a directory DIR. If RECURSIVE is non-nil, recurse into all subdirectories to find @@ -1891,7 +1923,8 @@ project-switch-commands (project-find-regexp "Find regexp") (project-find-dir "Find directory") (project-vc-dir "VC-Dir") - (project-eshell "Eshell")) + (project-eshell "Eshell") + (project-any-command "Other")) "Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-23 17:24 ` Dmitry Gutov @ 2023-10-23 17:34 ` Juri Linkov 2023-10-23 17:36 ` Dmitry Gutov 2023-10-25 16:53 ` Juri Linkov 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-23 17:34 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >> Now can't type 'C-x p p C-x v d' completely because >> 'C-x p p C-x v' opens vc-dir after typing 'v'. > > Huh. That actually works for me now, after I ran 'make' and restarted. > > But I thought you wanted this? 'C-x v d' ends with vc-dir, so if 'C-x > p p C-x v' opens vc-dir, then isn't this what you expected? Then can't use other vc commands like 'C-x p p C-x v L' >> Maybe adding a new option 'project-switch-use-global-map' would help? > > Try the attached, it's another iteration on the latest patch > (prefix-command-echo-keystrokes-functions doesn't seem to work reliably in > this context). Try it together with > > (setq project-switch-commands 'project-any-command) > > Also see the "Variation" in the comment (it allows for short bindings). I tried it out but don't like that it requires an additional key 'o'. I believe it should be possible to add a new option 'project-switch-use-global-map' (or a new value 'global' for existing 'project-switch-use-entire-map') that will combine 'project-prefix-map' with global-map before reading a key sequence. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-23 17:34 ` Juri Linkov @ 2023-10-23 17:36 ` Dmitry Gutov 2023-10-23 18:42 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-23 17:36 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 23/10/2023 20:34, Juri Linkov wrote: >>> Maybe adding a new option 'project-switch-use-global-map' would help? >> Try the attached, it's another iteration on the latest patch >> (prefix-command-echo-keystrokes-functions doesn't seem to work reliably in >> this context). Try it together with >> >> (setq project-switch-commands 'project-any-command) >> >> Also see the "Variation" in the comment (it allows for short bindings). > I tried it out but don't like that it requires an additional key 'o'. > > I believe it should be possible to add a new option > 'project-switch-use-global-map' (or a new value 'global' for existing > 'project-switch-use-entire-map') that will combine 'project-prefix-map' > with global-map before reading a key sequence. Have you tried it together with (setq project-switch-commands 'project-any-command) ? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-23 17:36 ` Dmitry Gutov @ 2023-10-23 18:42 ` Juri Linkov 2023-10-23 18:49 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-23 18:42 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >>>> Maybe adding a new option 'project-switch-use-global-map' would help? >>> Try the attached, it's another iteration on the latest patch >>> (prefix-command-echo-keystrokes-functions doesn't seem to work reliably in >>> this context). Try it together with >>> >>> (setq project-switch-commands 'project-any-command) >>> >>> Also see the "Variation" in the comment (it allows for short bindings). >> I tried it out but don't like that it requires an additional key 'o'. >> I believe it should be possible to add a new option >> 'project-switch-use-global-map' (or a new value 'global' for existing >> 'project-switch-use-entire-map') that will combine 'project-prefix-map' >> with global-map before reading a key sequence. > > Have you tried it together with > > (setq project-switch-commands 'project-any-command) > > ? It doesn't allow using short keys from 'project-prefix-map'. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-23 18:42 ` Juri Linkov @ 2023-10-23 18:49 ` Dmitry Gutov 0 siblings, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-10-23 18:49 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 23/10/2023 21:42, Juri Linkov wrote: >>>>> Maybe adding a new option 'project-switch-use-global-map' would help? >>>> Try the attached, it's another iteration on the latest patch >>>> (prefix-command-echo-keystrokes-functions doesn't seem to work reliably in >>>> this context). Try it together with >>>> >>>> (setq project-switch-commands 'project-any-command) >>>> >>>> Also see the "Variation" in the comment (it allows for short bindings). >>> I tried it out but don't like that it requires an additional key 'o'. >>> I believe it should be possible to add a new option >>> 'project-switch-use-global-map' (or a new value 'global' for existing >>> 'project-switch-use-entire-map') that will combine 'project-prefix-map' >>> with global-map before reading a key sequence. >> Have you tried it together with >> >> (setq project-switch-commands 'project-any-command) >> >> ? > It doesn't allow using short keys from 'project-prefix-map'. As per the GGGP email, see the "Variation" in the comment. Uncomment it, comment out the next binding (for the same variable), and re-evaluate. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-23 17:24 ` Dmitry Gutov 2023-10-23 17:34 ` Juri Linkov @ 2023-10-25 16:53 ` Juri Linkov 2023-10-25 22:26 ` Dmitry Gutov 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-25 16:53 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh > + ;; Variation: could be a separate command, or an option. > + ;; (command (let ((overriding-local-map project-prefix-map)) > + ;; (key-binding (read-key-sequence > + ;; (format "[execute in %s]:" (project-root pr))) > + ;; t))) Thanks, it works nicely. Any reason not to use this by default? > + (if found > + (let ((project-current-directory-override root)) > + (call-interactively command)) > + (let ((default-directory root)) > + (call-interactively command)))))) Not sure why need to let-bind project-current-directory-override here. It seems to work with and without it. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-25 16:53 ` Juri Linkov @ 2023-10-25 22:26 ` Dmitry Gutov 2023-10-27 6:50 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-25 22:26 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 2063 bytes --] On 25/10/2023 19:53, Juri Linkov wrote: >> + ;; Variation: could be a separate command, or an option. >> + ;; (command (let ((overriding-local-map project-prefix-map)) >> + ;; (key-binding (read-key-sequence >> + ;; (format "[execute in %s]:" (project-root pr))) >> + ;; t))) > > Thanks, it works nicely. > Any reason not to use this by default? Nothing critical, but it might not fit the expectations without additional instructions in the prompt, or it can be unnecessary if the user had reached this command through 'C-x p o'. In the latter case there is also a small chance that the user had set up some advanced sub-maps inside project-prefix-map which would shadow some global bindings. So maybe a separate command is best. Please see how you like the attached new version together with (setq project-switch-commands #'project-prefix-or-any-command) I'm not sure about project-prefix-or-any-command's prompt, though (phrasing feels awkward). Improvements welcome. >> + (if found >> + (let ((project-current-directory-override root)) >> + (call-interactively command)) >> + (let ((default-directory root)) >> + (call-interactively command)))))) > > Not sure why need to let-bind project-current-directory-override here. > It seems to work with and without it. You mean with found=nil? Indeed, rebinding project-current-directory-override instead of just doing that with default-directory is critical for only a small subset of commands (such as project-switch-buffer or bug#58784). So this will be a 99% solution that, however, leads to more straightforward code. BTW, let me know if you prefer the "prefix command" style from your last patch for this command. My main sticking point with it was the change of logic used to indicate a different project root, but it can just as well be transplanted there. So if the prefix command approach is better for some scenarios, we can switch to it. [-- Attachment #2: project-other-command-v4.diff --] [-- Type: text/x-patch, Size: 3102 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fda1081eb62..360137e67bb 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -847,6 +847,7 @@ project-prefix-map (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) + (define-key map "o" 'project-any-command) (define-key map "\C-b" 'project-list-buffers) map) "Keymap for project commands.") @@ -1813,6 +1814,50 @@ project-execute-extended-command (let ((default-directory (project-root (project-current t)))) (call-interactively #'execute-extended-command))) +;;;###autoload +(defun project-any-command (&optional overriding-map prompt-format) + "Run the next command in the current project. +If the command is in `project-prefix-map', it gets passed that +info with `project-current-directory-override'. Otherwise, +`default-directory' is temporarily set to the current project's +root. + +If OVERRIDING-MAP is non-nil, it will be used as +`overriding-local-map' to provide shorter bindings from that map +which will take priority over the global ones." + (interactive) + (let* ((pr (project-current t)) + (prompt-format (or prompt-format "[execute in %s]:")) + (command (let ((overriding-local-map overriding-map)) + (key-binding (read-key-sequence + (format prompt-format (project-root pr))) + t))) + (root (project-root pr)) + found) + (when command + ;; We could also check the command name against "\\`project-", + ;; and/or (get command 'project-command). + (map-keymap + (lambda (_evt cmd) (if (eq cmd command) (setq found t))) + project-prefix-map) + (if found + (let ((project-current-directory-override root)) + (call-interactively command)) + (let ((default-directory root)) + (call-interactively command)))))) + +;;;###autoload +(defun project-prefix-or-any-command () + "Run the next command in the current project. +Works like `project-any-command', but also mixes in the shorter +bindings from `project-prefix-map'." + (interactive) + (project-any-command project-prefix-map + (concat + "[in %s] Press " + (project--keymap-prompt) + " or other:"))) + (defun project-remember-projects-under (dir &optional recursive) "Index all projects below a directory DIR. If RECURSIVE is non-nil, recurse into all subdirectories to find @@ -1891,7 +1936,8 @@ project-switch-commands (project-find-regexp "Find regexp") (project-find-dir "Find directory") (project-vc-dir "VC-Dir") - (project-eshell "Eshell")) + (project-eshell "Eshell") + (project-any-command "Other")) "Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-25 22:26 ` Dmitry Gutov @ 2023-10-27 6:50 ` Juri Linkov 2023-10-27 9:38 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-27 6:50 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >>> + ;; Variation: could be a separate command, or an option. >>> + ;; (command (let ((overriding-local-map project-prefix-map)) >>> + ;; (key-binding (read-key-sequence >>> + ;; (format "[execute in %s]:" (project-root pr))) >>> + ;; t))) >> Thanks, it works nicely. >> Any reason not to use this by default? > > Nothing critical, but it might not fit the expectations without additional > instructions in the prompt, or it can be unnecessary if the user had > reached this command through 'C-x p o'. Indeed, this is needed only for 'C-x p p' that supports the global map. > In the latter case there is also a small chance that the user had set up > some advanced sub-maps inside project-prefix-map which would shadow some > global bindings. So maybe a separate command is best. Please see how you > like the attached new version together with > > (setq project-switch-commands #'project-prefix-or-any-command) A separate command that is not used anywhere looks strange. Why not a simple option like 'project-switch-use-entire-map'? > I'm not sure about project-prefix-or-any-command's prompt, though (phrasing > feels awkward). Improvements welcome. I'm not a fan of the long prompt especially that wraps to the second line. > BTW, let me know if you prefer the "prefix command" style from your last > patch for this command. My main sticking point with it was the change of > logic used to indicate a different project root, but it can just as well be > transplanted there. So if the prefix command approach is better for some > scenarios, we can switch to it. Also I'm not a fan of ad-hoc reimplementation of the command loop with read-key-sequence and call-interactively. In my last patch this is avoided by using post-command-hook and set-transient-map. OTOH, since migrating from the former to the latter makes code more complicated, I'm fine with dropping my last patch as long as the former still can do everything that was supported by the latter. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-27 6:50 ` Juri Linkov @ 2023-10-27 9:38 ` Dmitry Gutov 2023-10-28 16:56 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-10-27 9:38 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 27/10/2023 09:50, Juri Linkov wrote: >>>> + ;; Variation: could be a separate command, or an option. >>>> + ;; (command (let ((overriding-local-map project-prefix-map)) >>>> + ;; (key-binding (read-key-sequence >>>> + ;; (format "[execute in %s]:" (project-root pr))) >>>> + ;; t))) >>> Thanks, it works nicely. >>> Any reason not to use this by default? >> >> Nothing critical, but it might not fit the expectations without additional >> instructions in the prompt, or it can be unnecessary if the user had >> reached this command through 'C-x p o'. > > Indeed, this is needed only for 'C-x p p' that supports the global map. > >> In the latter case there is also a small chance that the user had set up >> some advanced sub-maps inside project-prefix-map which would shadow some >> global bindings. So maybe a separate command is best. Please see how you >> like the attached new version together with >> >> (setq project-switch-commands #'project-prefix-or-any-command) > > A separate command that is not used anywhere looks strange. > Why not a simple option like 'project-switch-use-entire-map'? You would still need to change project-switch-commands, right? Or what would the option be called? >> I'm not sure about project-prefix-or-any-command's prompt, though (phrasing >> feels awkward). Improvements welcome. > > I'm not a fan of the long prompt especially that wraps to the second line. It didn't wrap for me. But if it's too long, how would you like it changed? Remove everything? Just keep [executing in ...]? >> BTW, let me know if you prefer the "prefix command" style from your last >> patch for this command. My main sticking point with it was the change of >> logic used to indicate a different project root, but it can just as well be >> transplanted there. So if the prefix command approach is better for some >> scenarios, we can switch to it. > > Also I'm not a fan of ad-hoc reimplementation of the command loop > with read-key-sequence and call-interactively. In my last patch > this is avoided by using post-command-hook and set-transient-map. > OTOH, since migrating from the former to the latter makes code > more complicated, I'm fine with dropping my last patch as long as > the former still can do everything that was supported by the latter. It shouldn't be hard to migrate in either direction, as long as the logic to choose which variable to modify is the same. This approach (with read-key-sequence, etc) looks a little shorter, but if any problems crop up, this is changeable. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-27 9:38 ` Dmitry Gutov @ 2023-10-28 16:56 ` Juri Linkov 2023-11-01 21:12 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-10-28 16:56 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >>>>> + ;; Variation: could be a separate command, or an option. >>>>> + ;; (command (let ((overriding-local-map project-prefix-map)) >>>>> + ;; (key-binding (read-key-sequence >>>>> + ;; (format "[execute in %s]:" (project-root pr))) >>>>> + ;; t))) >>>> Thanks, it works nicely. >>>> Any reason not to use this by default? >>> >>> Nothing critical, but it might not fit the expectations without additional >>> instructions in the prompt, or it can be unnecessary if the user had >>> reached this command through 'C-x p o'. >> Indeed, this is needed only for 'C-x p p' that supports the global map. >> >>> In the latter case there is also a small chance that the user had set up >>> some advanced sub-maps inside project-prefix-map which would shadow some >>> global bindings. So maybe a separate command is best. Please see how you >>> like the attached new version together with >>> >>> (setq project-switch-commands #'project-prefix-or-any-command) >> A separate command that is not used anywhere looks strange. >> Why not a simple option like 'project-switch-use-entire-map'? > > You would still need to change project-switch-commands, right? Or what > would the option be called? I expected 'project-switch-use-global-map' to be used by 'project--switch-project-command' without the need to customize 'project-switch-commands'. >>> I'm not sure about project-prefix-or-any-command's prompt, though (phrasing >>> feels awkward). Improvements welcome. >> I'm not a fan of the long prompt especially that wraps to the second >> line. > > It didn't wrap for me. Because the length depends on the deepness of the project root. > But if it's too long, how would you like it changed? > Remove everything? Just keep [executing in ...]? I'd prefer keeping only [executing in ...] because it's useful to confirm in which directory the command will be executed. But all available keys are usually useless except in such modes as help-quick for novices. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-28 16:56 ` Juri Linkov @ 2023-11-01 21:12 ` Dmitry Gutov 2023-11-02 17:20 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-11-01 21:12 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh [-- Attachment #1: Type: text/plain, Size: 2624 bytes --] On 28/10/2023 19:56, Juri Linkov wrote: >>>>>> + ;; Variation: could be a separate command, or an option. >>>>>> + ;; (command (let ((overriding-local-map project-prefix-map)) >>>>>> + ;; (key-binding (read-key-sequence >>>>>> + ;; (format "[execute in %s]:" (project-root pr))) >>>>>> + ;; t))) >>>>> Thanks, it works nicely. >>>>> Any reason not to use this by default? >>>> >>>> Nothing critical, but it might not fit the expectations without additional >>>> instructions in the prompt, or it can be unnecessary if the user had >>>> reached this command through 'C-x p o'. >>> Indeed, this is needed only for 'C-x p p' that supports the global map. >>> >>>> In the latter case there is also a small chance that the user had set up >>>> some advanced sub-maps inside project-prefix-map which would shadow some >>>> global bindings. So maybe a separate command is best. Please see how you >>>> like the attached new version together with >>>> >>>> (setq project-switch-commands #'project-prefix-or-any-command) >>> A separate command that is not used anywhere looks strange. >>> Why not a simple option like 'project-switch-use-entire-map'? >> >> You would still need to change project-switch-commands, right? Or what >> would the option be called? > > I expected 'project-switch-use-global-map' to be used > by 'project--switch-project-command' without the need > to customize 'project-switch-commands'. How about this, then? project-switch-use-global-map is obsoleted, all variations are accessible through customizing project-switch-commands. Should have better discoverability for project-prefix-or-any-command than simply having it included. >>>> I'm not sure about project-prefix-or-any-command's prompt, though (phrasing >>>> feels awkward). Improvements welcome. >>> I'm not a fan of the long prompt especially that wraps to the second >>> line. >> >> It didn't wrap for me. > > Because the length depends on the deepness of the project root. > >> But if it's too long, how would you like it changed? >> Remove everything? Just keep [executing in ...]? > > I'd prefer keeping only [executing in ...] because it's useful > to confirm in which directory the command will be executed. > But all available keys are usually useless except in such modes > as help-quick for novices. I don't like having a prompt that requires prior knowledge to use, but fair enough, let's just use [executing in ...] for now. Perhaps someone will suggest an alternative later. The new revision is attached, have a look. [-- Attachment #2: project-other-command-v5.diff --] [-- Type: text/x-patch, Size: 7003 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 57d9d8e99ab..9186af663cb 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -855,6 +855,7 @@ project-prefix-map (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) + (define-key map "o" 'project-any-command) (define-key map "\C-b" 'project-list-buffers) map) "Keymap for project commands.") @@ -1817,6 +1818,46 @@ project-execute-extended-command (let ((default-directory (project-root (project-current t)))) (call-interactively #'execute-extended-command))) +;;;###autoload +(defun project-any-command (&optional overriding-map prompt-format) + "Run the next command in the current project. +If the command is in `project-prefix-map', it gets passed that +info with `project-current-directory-override'. Otherwise, +`default-directory' is temporarily set to the current project's +root. + +If OVERRIDING-MAP is non-nil, it will be used as +`overriding-local-map' to provide shorter bindings from that map +which will take priority over the global ones." + (interactive) + (let* ((pr (project-current t)) + (prompt-format (or prompt-format "[execute in %s]:")) + (command (let ((overriding-local-map overriding-map)) + (key-binding (read-key-sequence + (format prompt-format (project-root pr))) + t))) + (root (project-root pr)) + found) + (when command + ;; We could also check the command name against "\\`project-", + ;; and/or (get command 'project-command). + (map-keymap + (lambda (_evt cmd) (if (eq cmd command) (setq found t))) + project-prefix-map) + (if found + (let ((project-current-directory-override root)) + (call-interactively command)) + (let ((default-directory root)) + (call-interactively command)))))) + +;;;###autoload +(defun project-prefix-or-any-command () + "Run the next command in the current project. +Works like `project-any-command', but also mixes in the shorter +bindings from `project-prefix-map'." + (interactive) + (project-any-command project-prefix-map "[execute in %s]:")) + (defun project-remember-projects-under (dir &optional recursive) "Index all projects below a directory DIR. If RECURSIVE is non-nil, recurse into all subdirectories to find @@ -1895,7 +1936,8 @@ project-switch-commands (project-find-regexp "Find regexp") (project-find-dir "Find directory") (project-vc-dir "VC-Dir") - (project-eshell "Eshell")) + (project-eshell "Eshell") + (project-any-command "Other")) "Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. @@ -1907,7 +1949,17 @@ project-switch-commands key is looked up in that map. The value can also be a symbol, the name of the command to be -invoked immediately without any dispatch menu." +invoked immediately without any dispatch menu. + +Or it can be one of two special symbols: + +`short-keys' means the dispatch menu will feature all the +one-character bindings from `project-prefix-map'. The prompt +will loop until one of those characters is pressed. + +`short-or-any' means that the dispatch will accept either a +short key from the above map, or any global binding not shadowed +by the above keys." :version "28.1" :group 'project :package-version '(project . "0.6.0") @@ -1919,7 +1971,9 @@ project-switch-commands (choice :tag "Key to press" (const :tag "Infer from the keymap" nil) (character :tag "Explicit key")))) - (symbol :tag "Single command"))) + (symbol :tag "Single command") + (const :tag "Use short keys from `project-prefix-map'" short-keys) + (const :tag "Use short keys and global bindings" short-or-any))) (defcustom project-switch-use-entire-map nil "Whether `project-switch-project' will use the entire `project-prefix-map'. @@ -1932,6 +1986,13 @@ project-switch-use-entire-map :group 'project :version "28.1") +(make-obsolete-variable + 'project-switch-use-entire-map + (format-message + "set `project-switch-commands' to the value `short-keys' instead.") + "30.1" + 'set) + (defcustom project-key-prompt-style (if (facep 'help-key-binding) t 'brackets) @@ -1984,7 +2045,8 @@ project--switch-project-command ;; XXX: Add a warning about it? (reverse row) row)) - project-switch-commands)) + (and (listp project-switch-commands) + project-switch-commands))) (commands-map (let ((temp-map (make-sparse-keymap))) (set-keymap-parent temp-map project-prefix-map) @@ -1992,11 +2054,13 @@ project--switch-project-command (when-let ((cmd (nth 0 row)) (keychar (nth 2 row))) (define-key temp-map (vector keychar) cmd))))) + (use-all-short-keys (or project-switch-use-entire-map + (eq project-switch-commands 'short-keys))) command choice) (while (not command) (let* ((overriding-local-map commands-map) - (prompt (if project-switch-use-entire-map + (prompt (if use-all-short-keys (project--keymap-prompt) (project--menu-prompt)))) (when choice @@ -2008,7 +2072,7 @@ project--switch-project-command (setq choice (read-key-sequence (concat "Choose: " prompt))) (when (setq command (lookup-key commands-map choice)) (when (numberp command) (setq command nil)) - (unless (or project-switch-use-entire-map + (unless (or use-all-short-keys (assq command commands-menu)) (setq command nil))) (let ((global-command (lookup-key (current-global-map) choice))) @@ -2027,9 +2091,14 @@ project-switch-project When called in a program, it will use the project corresponding to directory DIR." (interactive (list (funcall project-prompter))) - (let ((command (if (symbolp project-switch-commands) - project-switch-commands - (project--switch-project-command))) + (let ((command + (cond + ((eq project-switch-commands 'short-or-any) + #'project-prefix-or-any-command) + ((and (symbolp project-switch-commands) + (not (eq project-switch-commands 'short-keys))) + project-switch-commands) + (t (project--switch-project-command)))) (buffer (current-buffer))) (unwind-protect (progn ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-11-01 21:12 ` Dmitry Gutov @ 2023-11-02 17:20 ` Juri Linkov 2023-11-02 21:33 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-11-02 17:20 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh > How about this, then? > > project-switch-use-global-map is obsoleted, all variations are accessible > through customizing project-switch-commands. Should have better > discoverability for project-prefix-or-any-command than simply having it > included. I don't know, it's extra trouble for users to migrate from the obsoleted project-switch-use-entire-map. But maybe ok. > I don't like having a prompt that requires prior knowledge to use, but fair > enough, let's just use [executing in ...] for now. Perhaps someone will > suggest an alternative later. > > The new revision is attached, have a look. Thanks, tried, it works nicely. One minor question is why project-prefix-or-any-command is a command. Would anyone want to bind it in project-prefix-map, like project-any-command that makes sense to run commands in root. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-11-02 17:20 ` Juri Linkov @ 2023-11-02 21:33 ` Dmitry Gutov 2023-11-04 17:28 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-11-02 21:33 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 02/11/2023 19:20, Juri Linkov wrote: >> How about this, then? >> >> project-switch-use-global-map is obsoleted, all variations are accessible >> through customizing project-switch-commands. Should have better >> discoverability for project-prefix-or-any-command than simply having it >> included. > > I don't know, it's extra trouble for users to migrate > from the obsoleted project-switch-use-entire-map. > But maybe ok. I couldn't find a better alternative to keep the behavior compatible. Either we have the user customize an existing var (this was the option where they'd set project-switch-commands to `project-prefix-or-any-command', which you didn't like), or we would add a yet another custom var which would, conceptually, conflict with the two existing ones. Unifying all three alternatives in one option seems like the logical choice. >> I don't like having a prompt that requires prior knowledge to use, but fair >> enough, let's just use [executing in ...] for now. Perhaps someone will >> suggest an alternative later. >> >> The new revision is attached, have a look. > > Thanks, tried, it works nicely. > > One minor question is why project-prefix-or-any-command > is a command. Would anyone want to bind it in project-prefix-map, > like project-any-command that makes sense to run commands in root. It's done this way basically for the ease and brevity of implementation. But someone could also advise it, or copy and do their own alternative, e.g. changing the prompt. Hopefully having this piece of behavior so localized will make it easier to grok for future contributors as well. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-11-02 21:33 ` Dmitry Gutov @ 2023-11-04 17:28 ` Juri Linkov 2023-11-05 0:55 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-11-04 17:28 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >>> How about this, then? >>> >>> project-switch-use-global-map is obsoleted, all variations are accessible >>> through customizing project-switch-commands. Should have better >>> discoverability for project-prefix-or-any-command than simply having it >>> included. >> I don't know, it's extra trouble for users to migrate >> from the obsoleted project-switch-use-entire-map. >> But maybe ok. > > I couldn't find a better alternative to keep the behavior compatible. > > Either we have the user customize an existing var (this was the option > where they'd set project-switch-commands to > `project-prefix-or-any-command', which you didn't like), or we would add > a yet another custom var which would, conceptually, conflict with the two > existing ones. I don't dislike it. I proposed a new option project-switch-use-global-map. But when project-switch-commands should be customized instead of new option, then I'd prefer to use function names like `project-prefix-or-any-command' instead of symbols `short-or-any' and `short-keys'. > Unifying all three alternatives in one option seems like the logical choice. To avoid obsoleting `project-switch-use-entire-map', `short-keys' could be removed. Then `short-or-any' could be replaced by `project-prefix-or-any-command'. This will introduce minimal changes. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-11-04 17:28 ` Juri Linkov @ 2023-11-05 0:55 ` Dmitry Gutov 2023-11-06 7:16 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-11-05 0:55 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648, sbaugh On 04/11/2023 19:28, Juri Linkov wrote: >>>> How about this, then? >>>> >>>> project-switch-use-global-map is obsoleted, all variations are accessible >>>> through customizing project-switch-commands. Should have better >>>> discoverability for project-prefix-or-any-command than simply having it >>>> included. >>> I don't know, it's extra trouble for users to migrate >>> from the obsoleted project-switch-use-entire-map. >>> But maybe ok. >> >> I couldn't find a better alternative to keep the behavior compatible. >> >> Either we have the user customize an existing var (this was the option >> where they'd set project-switch-commands to >> `project-prefix-or-any-command', which you didn't like), or we would add >> a yet another custom var which would, conceptually, conflict with the two >> existing ones. > > I don't dislike it. Very good. > I proposed a new option project-switch-use-global-map. I didn't know how the reconcile the existence of both project-switch-use-entire-map and project-switch-use-global-map. Saying in both docstrings that one takes priority over the other (and possibly repeating that in the doc for project-switch-commands) would be awkward. > But when project-switch-commands should be customized instead of new option, > then I'd prefer to use function names like `project-prefix-or-any-command' > instead of symbols `short-or-any' and `short-keys'. > >> Unifying all three alternatives in one option seems like the logical choice. > > To avoid obsoleting `project-switch-use-entire-map', `short-keys' > could be removed. Then `short-or-any' could be replaced by > `project-prefix-or-any-command'. This will introduce minimal changes. All right, that sounds like a mix between v4 and v5. I've pushed 41e801fea1c to master, please take a look. In the future, perhaps we'd want to obsolete the option project-switch-use-entire-map anyway, replacing it with a separate command to be used in the same way as the newly-added one. But for now the change is maximally backward-compatible. I'm still not sure personally about the prompt in project-prefix-or-any-command (short and not differentiating from project-any-command), but let's see what others think and propose later. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-11-05 0:55 ` Dmitry Gutov @ 2023-11-06 7:16 ` Juri Linkov 2023-11-06 22:49 ` Dmitry Gutov 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-11-06 7:16 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, sbaugh >> I proposed a new option project-switch-use-global-map. > > I didn't know how the reconcile the existence of both > project-switch-use-entire-map and project-switch-use-global-map. Saying in > both docstrings that one takes priority over the other (and possibly > repeating that in the doc for project-switch-commands) would be awkward. Then another variant would be to allow a new value 'global' in the existing 'project-switch-use-entire-map'. >> But when project-switch-commands should be customized instead of new option, >> then I'd prefer to use function names like `project-prefix-or-any-command' >> instead of symbols `short-or-any' and `short-keys'. >> >>> Unifying all three alternatives in one option seems like the logical choice. >> To avoid obsoleting `project-switch-use-entire-map', `short-keys' >> could be removed. Then `short-or-any' could be replaced by >> `project-prefix-or-any-command'. This will introduce minimal changes. > > All right, that sounds like a mix between v4 and v5. > > I've pushed 41e801fea1c to master, please take a look. Thanks, I tested and it works great. > In the future, perhaps we'd want to obsolete the option > project-switch-use-entire-map anyway, replacing it with a separate command > to be used in the same way as the newly-added one. But for now the change > is maximally backward-compatible. Indeed, this is the safest change for now. More changes either will bring trouble to users requiring to migrate from the obsolete variable, or will make code more complicated. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-11-06 7:16 ` Juri Linkov @ 2023-11-06 22:49 ` Dmitry Gutov 0 siblings, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-11-06 22:49 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648-done, sbaugh On 06/11/2023 09:16, Juri Linkov wrote: >>> I proposed a new option project-switch-use-global-map. >> >> I didn't know how the reconcile the existence of both >> project-switch-use-entire-map and project-switch-use-global-map. Saying in >> both docstrings that one takes priority over the other (and possibly >> repeating that in the doc for project-switch-commands) would be awkward. > > Then another variant would be to allow a new value 'global' > in the existing 'project-switch-use-entire-map'. Ah indeed. That could also look sensible. >>> But when project-switch-commands should be customized instead of new option, >>> then I'd prefer to use function names like `project-prefix-or-any-command' >>> instead of symbols `short-or-any' and `short-keys'. >>> >>>> Unifying all three alternatives in one option seems like the logical choice. >>> To avoid obsoleting `project-switch-use-entire-map', `short-keys' >>> could be removed. Then `short-or-any' could be replaced by >>> `project-prefix-or-any-command'. This will introduce minimal changes. >> >> All right, that sounds like a mix between v4 and v5. >> >> I've pushed 41e801fea1c to master, please take a look. > > Thanks, I tested and it works great. > >> In the future, perhaps we'd want to obsolete the option >> project-switch-use-entire-map anyway, replacing it with a separate command >> to be used in the same way as the newly-added one. But for now the change >> is maximally backward-compatible. > > Indeed, this is the safest change for now. More changes either will > bring trouble to users requiring to migrate from the obsolete variable, > or will make code more complicated. I guess it's time to close this bug? Thank you all for participation, and thanks for testing. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-19 0:42 ` Dmitry Gutov ` (2 preceding siblings ...) 2023-10-19 17:56 ` Juri Linkov @ 2023-10-21 13:27 ` sbaugh 2023-10-21 18:41 ` Dmitry Gutov 3 siblings, 1 reply; 109+ messages in thread From: sbaugh @ 2023-10-21 13:27 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Spencer Baugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > Hi Juri, > > On 22/09/2023 18:52, Juri Linkov wrote: >>>> Probably. Would you like to propose one? So that I have something to >>>> compare to, and have something specific to put to the vote as well. >>> >>> Ok, something like this: >> Here is a more tested patch. It supports these cases: >> (setq project-switch-use-entire-map t) >> C-x p p C-b - should not include current buffer in the list of >> another project (bug#58784) >> C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) >> C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) >> C-x p p C-x d - should visit another project's root (bug#63648) >> The same with frames: >> C-x 5 p p C-b >> C-x 5 p p f M-n >> C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) >> C-x 5 p p C-x d > > Thank you. Especially for the list. > > But I think we still haven't reached a decision whether the "loop > until correct key is pressed" behavior is useful. > > I tried to think how to fit the above requirements into the existing > model, and it seems to require a new command, and an additional key > being pressed sometimes, for explicitness. > > The attached patch also includes your fix for bug#65558, which seems > orthogonal to our dilemma, and could probably be installed > separately. It could be dry-ed up a little, though. > > Anyway, with the attached counter-proposal, the list looks like this: > > C-x p p C-b - works when project-switch-use-entire-map=t > C-x p p f M-n - always works > C-u C-x p p f - same > C-x p p C-x d - the key sequence is 'C-x p p o C-x d' > > With frames: > > C-x 5 p p C-b - works when project-switch-use-entire-map=t > C-x 5 p p f M-n - always works > C-u C-x 5 p p f emoji TAB - same (thanks to your fix, included) > C-x 5 p p C-x d - the key sequence is 'C-x 5 C-x p p o C-x d' > > The user could add project-list-buffers (or project-switch-to-buffer) > to project-switch-commands, though, and then > project-switch-use-entire-map won't be needed. Either way's fine. > > To sum up, that does require pressing an extra key to use commands > outside of project-prefix-map, but OTOH that key is shown right in the > commands menu. And one doesn't have to (setq > project-switch-use-entire-map t) to use it, though that doesn't hurt > either. Two thoughts: 1. Maybe C-x p o should also exist, which runs the subsequent command in project-root. (Although I think it would be better if C-x p magically let you type any binding after C-x p, and the command would run in project-root, as I pondered much earlier in this thread. But that's a lot harder...) 2. Maybe C-x p p should have both `o` (on by default even without project-switch-use-entire-map) and the no-extra-key version (needs to be explicitly turned on, possibly by project-switch-use-entire-map) Although, I plan to turn the no-extra-key version on for all my users anyway. The one extra key is a real cost if you're doing this frequently. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-10-21 13:27 ` sbaugh @ 2023-10-21 18:41 ` Dmitry Gutov 0 siblings, 0 replies; 109+ messages in thread From: Dmitry Gutov @ 2023-10-21 18:41 UTC (permalink / raw) To: sbaugh; +Cc: Spencer Baugh, 63648, Juri Linkov [-- Attachment #1: Type: text/plain, Size: 3369 bytes --] On 21/10/2023 16:27, sbaugh@catern.com wrote: > Dmitry Gutov <dmitry@gutov.dev> writes: >> Hi Juri, >> >> On 22/09/2023 18:52, Juri Linkov wrote: >>>>> Probably. Would you like to propose one? So that I have something to >>>>> compare to, and have something specific to put to the vote as well. >>>> >>>> Ok, something like this: >>> Here is a more tested patch. It supports these cases: >>> (setq project-switch-use-entire-map t) >>> C-x p p C-b - should not include current buffer in the list of >>> another project (bug#58784) >>> C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) >>> C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) >>> C-x p p C-x d - should visit another project's root (bug#63648) >>> The same with frames: >>> C-x 5 p p C-b >>> C-x 5 p p f M-n >>> C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) >>> C-x 5 p p C-x d >> >> Thank you. Especially for the list. >> >> But I think we still haven't reached a decision whether the "loop >> until correct key is pressed" behavior is useful. >> >> I tried to think how to fit the above requirements into the existing >> model, and it seems to require a new command, and an additional key >> being pressed sometimes, for explicitness. >> >> The attached patch also includes your fix for bug#65558, which seems >> orthogonal to our dilemma, and could probably be installed >> separately. It could be dry-ed up a little, though. >> >> Anyway, with the attached counter-proposal, the list looks like this: >> >> C-x p p C-b - works when project-switch-use-entire-map=t >> C-x p p f M-n - always works >> C-u C-x p p f - same >> C-x p p C-x d - the key sequence is 'C-x p p o C-x d' >> >> With frames: >> >> C-x 5 p p C-b - works when project-switch-use-entire-map=t >> C-x 5 p p f M-n - always works >> C-u C-x 5 p p f emoji TAB - same (thanks to your fix, included) >> C-x 5 p p C-x d - the key sequence is 'C-x 5 C-x p p o C-x d' >> >> The user could add project-list-buffers (or project-switch-to-buffer) >> to project-switch-commands, though, and then >> project-switch-use-entire-map won't be needed. Either way's fine. >> >> To sum up, that does require pressing an extra key to use commands >> outside of project-prefix-map, but OTOH that key is shown right in the >> commands menu. And one doesn't have to (setq >> project-switch-use-entire-map t) to use it, though that doesn't hurt >> either. > > Two thoughts: > > 1. Maybe C-x p o should also exist, which runs the subsequent command in > project-root. (Although I think it would be better if C-x p > magically let you type any binding after C-x p, and the command would > run in project-root, as I pondered much earlier in this thread. But > that's a lot harder...) Then the 'C-x p p' binding wouldn't be available?... Anyway, try the attached updated patch. > 2. Maybe C-x p p should have both `o` (on by default even without > project-switch-use-entire-map) and the no-extra-key version (needs to > be explicitly turned on, possibly by project-switch-use-entire-map) The patch plus (setq project-switch-commands 'project-any-command) should do that for you. > Although, I plan to turn the no-extra-key version on for all my users > anyway. The one extra key is a real cost if you're doing this > frequently. [-- Attachment #2: project-other-command-v2.diff --] [-- Type: text/x-patch, Size: 2410 bytes --] diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fda1081eb62..2500acd3961 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -847,6 +847,7 @@ project-prefix-map (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) + (define-key map "o" 'project-any-command) (define-key map "\C-b" 'project-list-buffers) map) "Keymap for project commands.") @@ -1813,6 +1814,33 @@ project-execute-extended-command (let ((default-directory (project-root (project-current t)))) (call-interactively #'execute-extended-command))) +;;;###autoload +(defun project-any-command () + "Run the next command in the current project. +If the command is in `project-prefix-map', it gets passed that +info with `project-current-directory-override'. Otherwise, +`default-directory' is temporarily set to the current project's +root." + (interactive) + (let* ((pr (project-current t)) + (prefix-command-echo-keystrokes-functions + (cons (lambda () (format "[execute in %s]" (project-root pr))) + prefix-command-echo-keystrokes-functions)) + (command (key-binding (read-key-sequence "") t)) + (root (project-root pr)) + found) + (when command + ;; We could also check the command name against "\\`project-", + ;; and/or (get command 'project-command). + (map-keymap + (lambda (_evt cmd) (if (eq cmd command) (setq found t))) + project-prefix-map) + (if found + (let ((project-current-directory-override root)) + (call-interactively command)) + (let ((default-directory root)) + (call-interactively command)))))) + (defun project-remember-projects-under (dir &optional recursive) "Index all projects below a directory DIR. If RECURSIVE is non-nil, recurse into all subdirectories to find @@ -1891,7 +1919,8 @@ project-switch-commands (project-find-regexp "Find regexp") (project-find-dir "Find directory") (project-vc-dir "VC-Dir") - (project-eshell "Eshell")) + (project-eshell "Eshell") + (project-any-command "Other")) "Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-09-22 15:52 ` Juri Linkov 2023-10-19 0:42 ` Dmitry Gutov @ 2023-10-21 13:14 ` sbaugh 1 sibling, 0 replies; 109+ messages in thread From: sbaugh @ 2023-10-21 13:14 UTC (permalink / raw) To: Juri Linkov; +Cc: Dmitry Gutov, 63648, Spencer Baugh Juri Linkov <juri@linkov.net> writes: >>> Probably. Would you like to propose one? So that I have something to >>> compare to, and have something specific to put to the vote as well. >> >> Ok, something like this: > > Here is a more tested patch. It supports these cases: > > (setq project-switch-use-entire-map t) > > C-x p p C-b - should not include current buffer in the list of another project (bug#58784) > C-x p p f M-n - should fetch the right default file name (bug#58784, bug#63829) > C-u C-x p p f emoji TAB - should include ignored emoji-labels.el (bug#63648) > C-x p p C-x d - should visit another project's root (bug#63648) > > The same with frames: > > C-x 5 p p C-b > C-x 5 p p f M-n > C-u C-x 5 p p f emoji TAB - should not show completions in another frame (bug#65558) > C-x 5 p p C-x d I've only been testing it for a few days, but this patch seems perfect to me. It does everything I want. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-23 13:53 ` Spencer Baugh 2023-08-23 17:54 ` Juri Linkov @ 2023-08-28 22:44 ` Dmitry Gutov 2023-08-29 20:34 ` Spencer Baugh 1 sibling, 1 reply; 109+ messages in thread From: Dmitry Gutov @ 2023-08-28 22:44 UTC (permalink / raw) To: Spencer Baugh, sbaugh; +Cc: 63648, Juri Linkov On 23/08/2023 16:53, Spencer Baugh wrote: > Oh, another thought (which maybe should be discussed on emacs-devel): > maybe we don't need to make this specific next-default-directory var. > > Instead, maybe what we want is a way to bind a dynamic variable > *without* changing the buffer-local value. It would shadow the existing > binding, but if we explicitly switched buffer we'd get back to the old > value. So we'd have: > > (special-let ((default-directory newval)) > (assert default-directory newval)) > > and > > (special-let ((default-directory newval)) > (set-buffer (current-buffer)) > (assert default-directory oldval)) Where does the main logic run in this case? If we call set-buffer before the main logic is ran, the old value of dd will be used. If we call set-buffer after the main logic is ran, we could as well use plain 'let' because that's what it does: restores the previous values at the end (and we know that it doesn't suit our purpose). I was also considering rebinding the global value of dd instead, but that turned out to be even sillier, since any new buffer inherits the local value of this var from the previous buffer, the global one isn't used anywhere (or doesn't seem to be). (cl-letf (((default-value 'default-directory) "~/Documents/")) (with-temp-buffer (message "dv %s" (default-value 'default-directory)) (message "lv %s" default-directory))) So to make use of this, every relevant spot would have to look up the global value of this var manually. Might as well use the special var that we already have (...-override). ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-08-28 22:44 ` Dmitry Gutov @ 2023-08-29 20:34 ` Spencer Baugh 0 siblings, 0 replies; 109+ messages in thread From: Spencer Baugh @ 2023-08-29 20:34 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, Juri Linkov Dmitry Gutov <dmitry@gutov.dev> writes: > On 23/08/2023 16:53, Spencer Baugh wrote: >> Oh, another thought (which maybe should be discussed on emacs-devel): >> maybe we don't need to make this specific next-default-directory var. >> Instead, maybe what we want is a way to bind a dynamic variable >> *without* changing the buffer-local value. It would shadow the existing >> binding, but if we explicitly switched buffer we'd get back to the old >> value. So we'd have: >> (special-let ((default-directory newval)) >> (assert default-directory newval)) >> and >> (special-let ((default-directory newval)) >> (set-buffer (current-buffer)) >> (assert default-directory oldval)) > > Where does the main logic run in this case? > > If we call set-buffer before the main logic is ran, the old value of > dd will be used. > > If we call set-buffer after the main logic is ran, we could as well > use plain 'let' because that's what it does: restores the previous > values at the end (and we know that it doesn't suit our purpose). Sorry, I was unclear - our logic wouldn't use set-buffer at all, it's just that things would work fine if user code used set-buffer. So this would work: (project-current) ;; -> (vc . oldval) (special-let ((default-directory newval)) (project-current) ;; -> (vc . newval) (with-current-buffer (current-buffer) (project-current))) ;; -> (vc . oldval) (project-current) ;; -> (vc . newval) The actual logic of project-switch-project would be: (defun project-switch-project (dir) (interactive (list (funcall project-prompter))) (let ((command (if (symbolp project-switch-commands) project-switch-commands (project--switch-project-command)))) (special-let ((default-directory dir)) (call-interactively command)))) (well, as long as (project--switch-project-command) could support reading arbitrary commands) > I was also considering rebinding the global value of dd instead, but > that turned out to be even sillier, since any new buffer inherits the > local value of this var from the previous buffer, the global one isn't > used anywhere (or doesn't seem to be). > > (cl-letf (((default-value 'default-directory) "~/Documents/")) > (with-temp-buffer > (message "dv %s" (default-value 'default-directory)) > (message "lv %s" default-directory))) > > So to make use of this, every relevant spot would have to look up the > global value of this var manually. Might as well use the special var > that we already have (...-override). Sad! ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 1:40 ` Dmitry Gutov 2023-06-02 6:40 ` Juri Linkov @ 2023-06-02 12:46 ` Eli Zaretskii 2023-06-02 16:09 ` Juri Linkov 1 sibling, 1 reply; 109+ messages in thread From: Eli Zaretskii @ 2023-06-02 12:46 UTC (permalink / raw) To: Dmitry Gutov; +Cc: sbaugh, 63648, juri > Cc: Spencer Baugh <sbaugh@janestreet.com>, 63648@debbugs.gnu.org > Date: Fri, 2 Jun 2023 04:40:28 +0300 > From: Dmitry Gutov <dmitry@gutov.dev> > > > 'C-x p p (select project ...) RET M-& pwd RET' confirms that > > the command runs in the selected project directory. > > Whereas the original buffer keeps its previous buffer-local value > > of 'default-directory'. > > I suggest you bring up this feature addition on emacs-devel, or > otherwise wait for a review from Eli, at least. > > It's not a big addition, but it's a distinct new feature (the > next-default-directory var). I guess I wasn't following this discussion closely enough, because I don't understand why my review is being sought. Is this something proposed for the emacs-29 branch? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 12:46 ` Eli Zaretskii @ 2023-06-02 16:09 ` Juri Linkov 0 siblings, 0 replies; 109+ messages in thread From: Juri Linkov @ 2023-06-02 16:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Dmitry Gutov, 63648, sbaugh >> > 'C-x p p (select project ...) RET M-& pwd RET' confirms that >> > the command runs in the selected project directory. >> > Whereas the original buffer keeps its previous buffer-local value >> > of 'default-directory'. >> >> I suggest you bring up this feature addition on emacs-devel, or >> otherwise wait for a review from Eli, at least. >> >> It's not a big addition, but it's a distinct new feature (the >> next-default-directory var). > > I guess I wasn't following this discussion closely enough, because I > don't understand why my review is being sought. Is this something > proposed for the emacs-29 branch? Luckily this new feature is not for the emacs-29 branch. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-01 16:05 ` Juri Linkov 2023-06-02 1:40 ` Dmitry Gutov @ 2023-06-02 6:32 ` Eli Zaretskii 2023-06-02 6:55 ` Juri Linkov 2023-06-02 17:07 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2 siblings, 1 reply; 109+ messages in thread From: Eli Zaretskii @ 2023-06-02 6:32 UTC (permalink / raw) To: Juri Linkov, Stefan Monnier; +Cc: dmitry, 63648, sbaugh > Cc: Spencer Baugh <sbaugh@janestreet.com>, 63648@debbugs.gnu.org > From: Juri Linkov <juri@linkov.net> > Date: Thu, 01 Jun 2023 19:05:07 +0300 > > And indeed with the following patch replacing the current definition of > 'project-switch-project' with just: > > (defun project-switch-project (dir) > (interactive (list (funcall project-prompter))) > (setq next-default-directory dir)) > > 'C-x p p (select project ...) RET M-& pwd RET' confirms that > the command runs in the selected project directory. > Whereas the original buffer keeps its previous buffer-local value > of 'default-directory'. > > diff --git a/src/buffer.c b/src/buffer.c > index 0c46b201586..ca81db21894 100644 > --- a/src/buffer.c > +++ b/src/buffer.c > @@ -5360,6 +5360,10 @@ syms_of_buffer (void) > these names start with `/' or `~' and end with `/'. > To interactively change the default directory, use command `cd'. */); > > + DEFVAR_LISP ("next-default-directory", Vnext_default_directory, > + doc: /* Default directory for the next command. */); > + Vnext_default_directory = Qnil; > + > DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function), > Qnil, > doc: /* Function called (if non-nil) to perform auto-fill. > diff --git a/src/keyboard.c b/src/keyboard.c > index 14c55666768..dfe939750c9 100644 > --- a/src/keyboard.c > +++ b/src/keyboard.c > @@ -1500,7 +1500,19 @@ command_loop_1 (void) > update_redisplay_ticks (0, NULL); > display_working_on_window_p = false; > > + Lisp_Object next_dir = Vnext_default_directory; > + specpdl_ref count = SPECPDL_INDEX (); > + if (!NILP (next_dir)) > + specbind (Qdefault_directory, next_dir); > + > call1 (Qcommand_execute, Vthis_command); > + > + if (!NILP (next_dir)) > + { > + unbind_to (count, Qnil); > + Vnext_default_directory = Qnil; > + } > + > display_working_on_window_p = false; > > #ifdef HAVE_WINDOW_SYSTEM What will this do when a command is invoked via call-interactively? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 6:32 ` Eli Zaretskii @ 2023-06-02 6:55 ` Juri Linkov 2023-06-02 11:39 ` Eli Zaretskii 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-06-02 6:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dmitry, Stefan Monnier, 63648, sbaugh >> @@ -1500,7 +1500,19 @@ command_loop_1 (void) >> update_redisplay_ticks (0, NULL); >> display_working_on_window_p = false; >> >> + Lisp_Object next_dir = Vnext_default_directory; >> + specpdl_ref count = SPECPDL_INDEX (); >> + if (!NILP (next_dir)) >> + specbind (Qdefault_directory, next_dir); >> + >> call1 (Qcommand_execute, Vthis_command); >> + >> + if (!NILP (next_dir)) >> + { >> + unbind_to (count, Qnil); >> + Vnext_default_directory = Qnil; >> + } >> + > > What will this do when a command is invoked via call-interactively? This is intended only for commands called interactively. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 6:55 ` Juri Linkov @ 2023-06-02 11:39 ` Eli Zaretskii 2023-06-02 16:11 ` Juri Linkov 2023-06-05 6:53 ` Juri Linkov 0 siblings, 2 replies; 109+ messages in thread From: Eli Zaretskii @ 2023-06-02 11:39 UTC (permalink / raw) To: Juri Linkov; +Cc: dmitry, monnier, 63648, sbaugh > From: Juri Linkov <juri@linkov.net> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, dmitry@gutov.dev, > sbaugh@janestreet.com, 63648@debbugs.gnu.org > Date: Fri, 02 Jun 2023 09:55:36 +0300 > > >> @@ -1500,7 +1500,19 @@ command_loop_1 (void) > >> update_redisplay_ticks (0, NULL); > >> display_working_on_window_p = false; > >> > >> + Lisp_Object next_dir = Vnext_default_directory; > >> + specpdl_ref count = SPECPDL_INDEX (); > >> + if (!NILP (next_dir)) > >> + specbind (Qdefault_directory, next_dir); > >> + > >> call1 (Qcommand_execute, Vthis_command); > >> + > >> + if (!NILP (next_dir)) > >> + { > >> + unbind_to (count, Qnil); > >> + Vnext_default_directory = Qnil; > >> + } > >> + > > > > What will this do when a command is invoked via call-interactively? > > This is intended only for commands called interactively. Won't this violate some legitimate expectations? Namely, that invoking a command interactively and via call-interactively produces the same results? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 11:39 ` Eli Zaretskii @ 2023-06-02 16:11 ` Juri Linkov 2023-06-05 6:53 ` Juri Linkov 1 sibling, 0 replies; 109+ messages in thread From: Juri Linkov @ 2023-06-02 16:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dmitry, monnier, 63648, sbaugh >> >> @@ -1500,7 +1500,19 @@ command_loop_1 (void) >> >> update_redisplay_ticks (0, NULL); >> >> display_working_on_window_p = false; >> >> >> >> + Lisp_Object next_dir = Vnext_default_directory; >> >> + specpdl_ref count = SPECPDL_INDEX (); >> >> + if (!NILP (next_dir)) >> >> + specbind (Qdefault_directory, next_dir); >> >> + >> >> call1 (Qcommand_execute, Vthis_command); >> >> + >> >> + if (!NILP (next_dir)) >> >> + { >> >> + unbind_to (count, Qnil); >> >> + Vnext_default_directory = Qnil; >> >> + } >> >> + >> > >> > What will this do when a command is invoked via call-interactively? >> >> This is intended only for commands called interactively. > > Won't this violate some legitimate expectations? Namely, that > invoking a command interactively and via call-interactively produces > the same results? When needed this could be added to call-interactively as well if there is no common code to share between these two. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 11:39 ` Eli Zaretskii 2023-06-02 16:11 ` Juri Linkov @ 2023-06-05 6:53 ` Juri Linkov 1 sibling, 0 replies; 109+ messages in thread From: Juri Linkov @ 2023-06-05 6:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dmitry, monnier, 63648, sbaugh >> >> @@ -1500,7 +1500,19 @@ command_loop_1 (void) >> >> update_redisplay_ticks (0, NULL); >> >> display_working_on_window_p = false; >> >> >> >> + Lisp_Object next_dir = Vnext_default_directory; >> >> + specpdl_ref count = SPECPDL_INDEX (); >> >> + if (!NILP (next_dir)) >> >> + specbind (Qdefault_directory, next_dir); >> >> + >> >> call1 (Qcommand_execute, Vthis_command); >> >> + >> >> + if (!NILP (next_dir)) >> >> + { >> >> + unbind_to (count, Qnil); >> >> + Vnext_default_directory = Qnil; >> >> + } >> >> + >> > >> > What will this do when a command is invoked via call-interactively? >> >> This is intended only for commands called interactively. > > Won't this violate some legitimate expectations? Namely, that > invoking a command interactively and via call-interactively produces > the same results? Using 'let' for 'call-interactively' works expectedly in the recent patch: (if (symbolp project-switch-commands) (let ((default-directory dir)) (call-interactively project-switch-commands)) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-01 16:05 ` Juri Linkov 2023-06-02 1:40 ` Dmitry Gutov 2023-06-02 6:32 ` Eli Zaretskii @ 2023-06-02 17:07 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-06-05 6:50 ` Juri Linkov 2 siblings, 1 reply; 109+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-06-02 17:07 UTC (permalink / raw) To: Juri Linkov; +Cc: Dmitry Gutov, 63648, Spencer Baugh > And indeed with the following patch replacing the current definition of > 'project-switch-project' with just: > > (defun project-switch-project (dir) > (interactive (list (funcall project-prompter))) > (setq next-default-directory dir)) This would be a new "prefix command", like the `universal-argument`, `C-x RET c`, the `ofw-other-window`, vc-edit-next-command, `ofw-other-frame` from the `other-frame-window` package, and a few more. In order for this new prefix to interact correctly with those other ones, it should probably use `prefix-command-preserve-state` and it would be good to make it show some visual feedback via `prefix-command-echo-keystrokes-functions`. [ Side note: take my opinion with a grain of salt, because I can't understand why the above would Do The Right Thing wrt the command's docstring. ] Stefan ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 17:07 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-06-05 6:50 ` Juri Linkov 2023-06-05 14:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-06-05 6:50 UTC (permalink / raw) To: Stefan Monnier; +Cc: Dmitry Gutov, 63648, Spencer Baugh >> And indeed with the following patch replacing the current definition of >> 'project-switch-project' with just: >> >> (defun project-switch-project (dir) >> (interactive (list (funcall project-prompter))) >> (setq next-default-directory dir)) > > This would be a new "prefix command", like the `universal-argument`, > `C-x RET c`, the `ofw-other-window`, vc-edit-next-command, > `ofw-other-frame` from the `other-frame-window` package, and a few more. > > In order for this new prefix to interact correctly with those other > ones, it should probably use `prefix-command-preserve-state` and it > would be good to make it show some visual feedback via > `prefix-command-echo-keystrokes-functions`. Here is the same function turned into a prefix command, so it supports both cases: 1. 'C-x p p d' -- keys from project-prefix-map 2. 'C-x p p C-x d' -- global keybindings ``` (defun project-switch-project (dir) (interactive (list (funcall project-prompter))) (if (symbolp project-switch-commands) (let ((default-directory dir)) (call-interactively project-switch-commands)) (let* ((echofun (lambda () "[switch-project]")) (postfun (lambda () (remove-hook 'prefix-command-echo-keystrokes-functions echofun)))) (setq next-default-directory dir) (add-hook 'prefix-command-echo-keystrokes-functions echofun) (message (project--keymap-prompt)) (prefix-command-update) (set-transient-map project-prefix-map nil postfun)))) ``` If this is conceptually ok, then more customization could be ported from project--switch-project-command such as project-switch-use-entire-map. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-05 6:50 ` Juri Linkov @ 2023-06-05 14:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-06-05 16:31 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-06-05 14:44 UTC (permalink / raw) To: Juri Linkov; +Cc: Dmitry Gutov, 63648, Spencer Baugh Juri Linkov [2023-06-05 09:50:44] wrote: >>> And indeed with the following patch replacing the current definition of >>> 'project-switch-project' with just: >>> >>> (defun project-switch-project (dir) >>> (interactive (list (funcall project-prompter))) >>> (setq next-default-directory dir)) >> >> This would be a new "prefix command", like the `universal-argument`, >> `C-x RET c`, the `ofw-other-window`, vc-edit-next-command, >> `ofw-other-frame` from the `other-frame-window` package, and a few more. >> >> In order for this new prefix to interact correctly with those other >> ones, it should probably use `prefix-command-preserve-state` and it >> would be good to make it show some visual feedback via >> `prefix-command-echo-keystrokes-functions`. > > Here is the same function turned into a prefix command, > so it supports both cases: > > 1. 'C-x p p d' -- keys from project-prefix-map > 2. 'C-x p p C-x d' -- global keybindings > > ``` > (defun project-switch-project (dir) > (interactive (list (funcall project-prompter))) > (if (symbolp project-switch-commands) > (let ((default-directory dir)) > (call-interactively project-switch-commands)) > (let* ((echofun (lambda () "[switch-project]")) > (postfun (lambda () (remove-hook > 'prefix-command-echo-keystrokes-functions > echofun)))) > (setq next-default-directory dir) > (add-hook 'prefix-command-echo-keystrokes-functions echofun) > (message (project--keymap-prompt)) > (prefix-command-update) > (set-transient-map project-prefix-map nil postfun)))) > ``` I think you need to call `prefix-command-preserve-state` as well, so that the order of prefix commands doesn't matter (e.g. user can do `C-u C-x p` instead of `C-x p C-u`). [ Note: I'm still not really happy with the way prefix commands work. I can't remember what problems are still lurking, but IIRC interaction with minibuffer is a source of problems (e.g. prefix commands from before we entered the minibuffer can affect operations within the minibuffer and prefix commands from within the minibuffer can affect the behavior after exiting the minibuffer). I think last time I looked at it, I concluded that maybe it should be reimplemented such that the state is kept in a single object to which prefix commands can add/remove properties, and the minibuffer code would automatically suspend and then reinstall that state (and could emit a warning when throwing away "unused state", such as when leaving a minibuffer). ] > If this is conceptually ok, then more customization could be ported > from project--switch-project-command such as project-switch-use-entire-map. Looks OK to me [ modulo the fact that I don't really understand what this is doing (I don't understand the `project-switch-commands` bit, nor do I understand why a prefix command which temporarily changes the `default-directory` would be called `project-switch-project`). ] Stefan ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-05 14:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-06-05 16:31 ` Juri Linkov 0 siblings, 0 replies; 109+ messages in thread From: Juri Linkov @ 2023-06-05 16:31 UTC (permalink / raw) To: Stefan Monnier; +Cc: Dmitry Gutov, 63648, Spencer Baugh >> (prefix-command-update) > > I think you need to call `prefix-command-preserve-state` as well, so > that the order of prefix commands doesn't matter (e.g. user can do `C-u > C-x p` instead of `C-x p C-u`). I confirm that after replacing `prefix-command-update` with `prefix-command-preserve-state` (replacing since the latter calls the former), now `C-u C-x p p f lisp/international/emoji-labels.el` works ok (without C-u it can't find this non-registered file). > [ Note: I'm still not really happy with the way prefix commands work. > I can't remember what problems are still lurking, but IIRC interaction > with minibuffer is a source of problems (e.g. prefix commands from > before we entered the minibuffer can affect operations within the > minibuffer and prefix commands from within the minibuffer can affect > the behavior after exiting the minibuffer). I think last time > I looked at it, I concluded that maybe it should be reimplemented such > that the state is kept in a single object to which prefix commands can > add/remove properties, and the minibuffer code would automatically > suspend and then reinstall that state (and could emit a warning when > throwing away "unused state", such as when leaving a minibuffer). ] I tested this with such test command and there are no problems: ``` (defun test (arg1 arg2) (interactive (list (progn (message "%S" default-directory) (read-string "1: ") (message "%S" default-directory)) (progn (message "%S" default-directory) (read-string "2: ") (message "%S" default-directory)))) (message "%S" default-directory)) ``` `C-x p p M-x test RET` prints only the new directory. However, I found a problem with `C-x p 4 p`. To fix it, `project-other-window-command` should be completely rewritten to: ``` (defun project-other-window-command () (interactive) (other-window-prefix) (set-transient-map (make-composed-keymap project-prefix-map project-other-window-map))) ``` plus a small fix that I don't know how to generalize: ``` diff --git a/lisp/window.el b/lisp/window.el index ab7dd5ced12..52ba407d9c8 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9099,7 +9091,8 @@ display-buffer-override-next-command (> (minibuffer-depth) minibuffer-depth) ;; But don't remove immediately after ;; adding the hook by the same command below. - (eq this-command command)) + (eq this-command command) + (memq this-command '(other-project-prefix))) (funcall exitfun)))) ;; Call post-function after the next command finishes (bug#49057). (add-hook 'post-command-hook postfun) ``` Then everything works as before and even better. >> If this is conceptually ok, then more customization could be ported >> from project--switch-project-command such as project-switch-use-entire-map. > > Looks OK to me [ modulo the fact that I don't really understand what > this is doing (I don't understand the `project-switch-commands` bit, nor > do I understand why a prefix command which temporarily changes the > `default-directory` would be called `project-switch-project`). ] It's possible to create another general command that will read arbitrary directory, but this command is project-specific with `project-prompter`. `project-switch-project` really should be renamed to `other-project-prefix` like other similar prefix commands. Here is the latest version without much changes: ``` (defun other-project-prefix (dir) (interactive (list (funcall project-prompter))) (if (symbolp project-switch-commands) (let ((default-directory dir)) (call-interactively project-switch-commands)) (let* ((echofun (lambda () "[switch-project]")) (postfun (lambda () (remove-hook 'prefix-command-echo-keystrokes-functions echofun)))) (setq next-default-directory dir) (message (project--keymap-prompt)) (add-hook 'prefix-command-echo-keystrokes-functions echofun) (prefix-command-preserve-state) (set-transient-map project-prefix-map nil postfun)))) ``` ^ permalink raw reply related [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-22 17:51 ` Juri Linkov 2023-05-24 1:14 ` Dmitry Gutov @ 2023-05-24 14:55 ` Spencer Baugh 2023-05-24 16:24 ` Juri Linkov 1 sibling, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-05-24 14:55 UTC (permalink / raw) To: Juri Linkov; +Cc: 63648 Juri Linkov <juri@linkov.net> writes: >> (Tangential further thought: I wonder if we could make C-x p work as a >> prefix for all commands automatically, so for example C-x p C-x C-j >> would open the project root, C-x p M-& would run a shell command in the >> root, etc. That would be neat.) > > IOW, like 'C-x p p' but without asking for another project. Doable as well. I'm curious, how are you thinking this would be implemented? My thought was that C-x p would act as a prefix for any key sequence in this way, *but* also C-x p c and the other things currently in project-prefix-map would still be explicitly bound, so they can be looked up with describe-key. And also, C-x p C-h should still run describe-prefix-bindings. I don't know how one would achieve this... ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 14:55 ` Spencer Baugh @ 2023-05-24 16:24 ` Juri Linkov 2023-05-26 15:16 ` Spencer Baugh 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-05-24 16:24 UTC (permalink / raw) To: Spencer Baugh; +Cc: 63648 >>> (Tangential further thought: I wonder if we could make C-x p work as a >>> prefix for all commands automatically, so for example C-x p C-x C-j >>> would open the project root, C-x p M-& would run a shell command in the >>> root, etc. That would be neat.) >> >> IOW, like 'C-x p p' but without asking for another project. Doable as well. > > I'm curious, how are you thinking this would be implemented? My thought > was that C-x p would act as a prefix for any key sequence in this way, > *but* also C-x p c and the other things currently in project-prefix-map > would still be explicitly bound, so they can be looked up with > describe-key. And also, C-x p C-h should still run > describe-prefix-bindings. I don't know how one would achieve this... Probably this is not possible. What I meant is to bind 'C-x p' to a special command that uses 'set-transient-map'. But then such command could be bound to e.g. 'C-x p /' (with mnemonics "root") to set 'default-directory' to the project root for the next command. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-24 16:24 ` Juri Linkov @ 2023-05-26 15:16 ` Spencer Baugh 2023-05-30 17:48 ` Juri Linkov 0 siblings, 1 reply; 109+ messages in thread From: Spencer Baugh @ 2023-05-26 15:16 UTC (permalink / raw) To: Juri Linkov; +Cc: 63648 Juri Linkov <juri@linkov.net> writes: >>>> (Tangential further thought: I wonder if we could make C-x p work as a >>>> prefix for all commands automatically, so for example C-x p C-x C-j >>>> would open the project root, C-x p M-& would run a shell command in the >>>> root, etc. That would be neat.) >>> >>> IOW, like 'C-x p p' but without asking for another project. Doable as well. >> >> I'm curious, how are you thinking this would be implemented? My thought >> was that C-x p would act as a prefix for any key sequence in this way, >> *but* also C-x p c and the other things currently in project-prefix-map >> would still be explicitly bound, so they can be looked up with >> describe-key. And also, C-x p C-h should still run >> describe-prefix-bindings. I don't know how one would achieve this... > > Probably this is not possible. What I meant is to bind 'C-x p' > to a special command that uses 'set-transient-map'. But then such > command could be bound to e.g. 'C-x p /' (with mnemonics "root") > to set 'default-directory' to the project root for the next command. Yes, that would make sense. It would be nice if that kind of approach didn't hurt the self-documentation capabilities of Emacs. I have an idea for how to make it work, which might be generally useful: Maybe commands/keybindings could support marking themselves as "prefix" commands, such that when you run describe-key and enter the prefix key sequence, describe-key accepts another key sequence after you finish the prefix key sequence, and interprets it with the altered keymaps that would be created by the prefix. And then the help buffer would print the help for both commands. So then (describe-key (kbd "C-x p M-&")) would print help for both the new project-prefix command and async-shell-command. And also, (describe-key (kbd "C-x p c")) would print help for both project-prefix and project-compile, the latter being bound only by the transient created by C-x p. And also, describe-prefix-bindings would be taught to describe any additional bindings added by an explicitly marked prefix command. So C-x p C-h would print all the same bindings as it currently does. This probably wouldn't be worth it just for project.el, but it could allow another very cool change: We could turn C-x 4, C-x 5, and C-x t into prefixes like this, which behave like C-x 4 4, C-x 5 5, and C-x t t do today, and turn their current bindings into a transient. If we added this explicit support for "prefix" commands, we could maybe do this without losing any features or self-documenting abilities. So then, e.g., C-x 4 M-& would run async-shell-command in another window. One less key to hit would make that a lot more convenient IMO... Probably we wouldn't want to do that by default, but it could be a nice user customization. I'd like to turn it on myself... ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-26 15:16 ` Spencer Baugh @ 2023-05-30 17:48 ` Juri Linkov 2023-06-01 20:31 ` Spencer Baugh 0 siblings, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-05-30 17:48 UTC (permalink / raw) To: Spencer Baugh; +Cc: 63648 >>>>> (Tangential further thought: I wonder if we could make C-x p work >>>>> as a prefix for all commands automatically, so for example >>>>> C-x p C-x C-j would open the project root, I just noticed that 'C-x p C-x C-j' would open the parent directory of the project root, not the root itself, since 'C-x C-j' in the root jumps to its parent. > I have an idea for how to make it work, which might be generally useful: > > Maybe commands/keybindings could support marking themselves as "prefix" > commands, such that when you run describe-key and enter the prefix key > sequence, describe-key accepts another key sequence after you finish the > prefix key sequence, and interprets it with the altered keymaps that > would be created by the prefix. And then the help buffer would print > the help for both commands. > > So then (describe-key (kbd "C-x p M-&")) would print help for both the > new project-prefix command and async-shell-command. > > And also, (describe-key (kbd "C-x p c")) would print help for both > project-prefix and project-compile, the latter being bound only by the > transient created by C-x p. Before doing this for 'C-x p' and 'C-x 4' it's possible already to test this on the existing 'C-x p p' since currently (describe-key (kbd "C-x p p c")) fails to describe 'project-prefix-map'. And only prints help for 'project-switch-project' with (describe-key (kbd "C-x p p")) ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-05-30 17:48 ` Juri Linkov @ 2023-06-01 20:31 ` Spencer Baugh 2023-06-01 21:09 ` Drew Adams 2023-06-02 6:46 ` Juri Linkov 0 siblings, 2 replies; 109+ messages in thread From: Spencer Baugh @ 2023-06-01 20:31 UTC (permalink / raw) To: Juri Linkov; +Cc: 63648 Juri Linkov <juri@linkov.net> writes: >>>>>> (Tangential further thought: I wonder if we could make C-x p work >>>>>> as a prefix for all commands automatically, so for example >>>>>> C-x p C-x C-j would open the project root, > > I just noticed that 'C-x p C-x C-j' would open the parent directory > of the project root, not the root itself, since 'C-x C-j' in the root > jumps to its parent. Only in dired buffers. If not in dired, and not in a file-visiting buffer, it just goes to default-directory. That is kind of annoying for making C-x p p C-x C-j go to the root, though, because its behavior will depend on the current buffer... Maybe C-x p p can switch buffers before running the command? Or maybe we can just change how C-x C-j behaves so it works intuitively with C-x p p? ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-01 20:31 ` Spencer Baugh @ 2023-06-01 21:09 ` Drew Adams 2023-06-02 6:33 ` Eli Zaretskii 2023-06-02 6:46 ` Juri Linkov 1 sibling, 1 reply; 109+ messages in thread From: Drew Adams @ 2023-06-01 21:09 UTC (permalink / raw) To: Spencer Baugh, Juri Linkov; +Cc: 63648@debbugs.gnu.org > Or maybe we can just change how C-x C-j > behaves so it works intuitively with C-x p p? Please don't change C-x C-j. If you want to have another command that does whatever you want then do that. Bind that to whatever keys you like in a particular mode. But please don't change the behavior of `C-x C-j'. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-01 21:09 ` Drew Adams @ 2023-06-02 6:33 ` Eli Zaretskii 0 siblings, 0 replies; 109+ messages in thread From: Eli Zaretskii @ 2023-06-02 6:33 UTC (permalink / raw) To: Drew Adams; +Cc: sbaugh, 63648, juri > Cc: "63648@debbugs.gnu.org" <63648@debbugs.gnu.org> > From: Drew Adams <drew.adams@oracle.com> > Date: Thu, 1 Jun 2023 21:09:28 +0000 > > > Or maybe we can just change how C-x C-j > > behaves so it works intuitively with C-x p p? > > Please don't change C-x C-j. Don't worry, it won't change. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-01 20:31 ` Spencer Baugh 2023-06-01 21:09 ` Drew Adams @ 2023-06-02 6:46 ` Juri Linkov 2023-08-10 11:52 ` sbaugh 1 sibling, 1 reply; 109+ messages in thread From: Juri Linkov @ 2023-06-02 6:46 UTC (permalink / raw) To: Spencer Baugh; +Cc: 63648 >>>>>>> (Tangential further thought: I wonder if we could make C-x p work >>>>>>> as a prefix for all commands automatically, so for example >>>>>>> C-x p C-x C-j would open the project root, >> >> I just noticed that 'C-x p C-x C-j' would open the parent directory >> of the project root, not the root itself, since 'C-x C-j' in the root >> jumps to its parent. > > Only in dired buffers. If not in dired, and not in a file-visiting > buffer, it just goes to default-directory. You are right, I tried with the next-default-directory patch, and it works like you described. > That is kind of annoying for making C-x p p C-x C-j go to the root, > though, because its behavior will depend on the current buffer... Maybe > C-x p p can switch buffers before running the command? Alas, can't switch buffers because such commands as 'C-x p g' read the default value from the current buffer. > Or maybe we can just change how C-x C-j behaves so it works > intuitively with C-x p p? The problem is in 'C-x C-j'. In dired buffers it uses the value of 'dired-subdir-alist' instead of 'default-directory', so the patch with 'next-default-directory' doesn't help. ^ permalink raw reply [flat|nested] 109+ messages in thread
* bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands 2023-06-02 6:46 ` Juri Linkov @ 2023-08-10 11:52 ` sbaugh 0 siblings, 0 replies; 109+ messages in thread From: sbaugh @ 2023-08-10 11:52 UTC (permalink / raw) To: Juri Linkov; +Cc: Spencer Baugh, 63648 Juri Linkov <juri@linkov.net> writes: >>>>>>>> (Tangential further thought: I wonder if we could make C-x p work >>>>>>>> as a prefix for all commands automatically, so for example >>>>>>>> C-x p C-x C-j would open the project root, >>> >>> I just noticed that 'C-x p C-x C-j' would open the parent directory >>> of the project root, not the root itself, since 'C-x C-j' in the root >>> jumps to its parent. >> >> Only in dired buffers. If not in dired, and not in a file-visiting >> buffer, it just goes to default-directory. > > You are right, I tried with the next-default-directory patch, > and it works like you described. > >> That is kind of annoying for making C-x p p C-x C-j go to the root, >> though, because its behavior will depend on the current buffer... Maybe >> C-x p p can switch buffers before running the command? > > Alas, can't switch buffers because such commands as 'C-x p g' > read the default value from the current buffer. > >> Or maybe we can just change how C-x C-j behaves so it works >> intuitively with C-x p p? > > The problem is in 'C-x C-j'. In dired buffers it uses the value of > 'dired-subdir-alist' instead of 'default-directory', so the patch with > 'next-default-directory' doesn't help. Ah, I just realized this doesn't matter. C-x C-j isn't the right command to use. The right command to use is C-x d RET, that will have consistent behavior. ^ permalink raw reply [flat|nested] 109+ messages in thread
end of thread, other threads:[~2023-11-06 22:49 UTC | newest] Thread overview: 109+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-05-22 16:27 bug#63648: 29.0.90; project.el: with switch-use-entire-map, switch-project errors on non-project commands Spencer Baugh 2023-05-22 17:51 ` Juri Linkov 2023-05-24 1:14 ` Dmitry Gutov 2023-05-24 6:20 ` Juri Linkov 2023-05-24 15:46 ` Dmitry Gutov 2023-05-24 16:20 ` Juri Linkov 2023-05-24 17:37 ` Juri Linkov 2023-05-24 17:44 ` Juri Linkov 2023-06-01 16:05 ` Juri Linkov 2023-06-02 1:40 ` Dmitry Gutov 2023-06-02 6:40 ` Juri Linkov 2023-06-03 1:30 ` Dmitry Gutov 2023-08-10 11:56 ` sbaugh 2023-08-23 13:53 ` Spencer Baugh 2023-08-23 17:54 ` Juri Linkov 2023-08-29 20:36 ` Spencer Baugh 2023-08-29 20:40 ` Dmitry Gutov 2023-08-29 21:47 ` Spencer Baugh 2023-08-29 22:32 ` Dmitry Gutov 2023-08-30 16:27 ` Juri Linkov 2023-08-31 2:01 ` Dmitry Gutov 2023-08-31 6:47 ` Juri Linkov 2023-08-31 11:13 ` Dmitry Gutov 2023-08-31 16:36 ` Juri Linkov 2023-09-01 1:11 ` Dmitry Gutov 2023-09-01 6:46 ` Juri Linkov 2023-09-01 9:53 ` Dmitry Gutov 2023-09-01 15:59 ` Spencer Baugh 2023-09-02 1:47 ` Dmitry Gutov 2023-09-03 17:11 ` Juri Linkov 2023-09-11 20:16 ` Spencer Baugh 2023-09-12 6:55 ` Juri Linkov 2023-09-10 15:30 ` Juri Linkov 2023-09-12 23:47 ` Dmitry Gutov 2023-09-13 6:47 ` Juri Linkov 2023-09-18 0:12 ` Dmitry Gutov 2023-09-18 6:51 ` Juri Linkov 2023-09-18 11:00 ` Dmitry Gutov 2023-09-18 13:56 ` Dmitry Gutov 2023-09-19 17:57 ` Juri Linkov 2023-09-20 0:39 ` Dmitry Gutov 2023-09-20 17:10 ` Juri Linkov 2023-09-21 1:16 ` Dmitry Gutov 2023-09-21 6:58 ` Juri Linkov 2023-09-22 15:52 ` Juri Linkov 2023-10-19 0:42 ` Dmitry Gutov 2023-10-19 4:46 ` Eli Zaretskii 2023-10-19 6:43 ` Juri Linkov 2023-10-19 7:51 ` Eli Zaretskii 2023-10-19 9:46 ` Dmitry Gutov 2023-10-19 11:05 ` Eli Zaretskii 2023-10-19 11:34 ` Dmitry Gutov 2023-10-19 12:22 ` sbaugh 2023-10-19 12:49 ` Dmitry Gutov 2023-10-19 14:00 ` Spencer Baugh 2023-10-19 17:17 ` Dmitry Gutov 2023-10-19 19:30 ` Spencer Baugh 2023-10-19 23:25 ` Dmitry Gutov 2023-10-21 16:09 ` Spencer Baugh 2023-10-21 18:43 ` Dmitry Gutov 2023-10-19 18:03 ` Juri Linkov 2023-10-19 19:38 ` Spencer Baugh 2023-10-19 17:56 ` Juri Linkov 2023-10-19 22:39 ` Dmitry Gutov 2023-10-20 6:44 ` Juri Linkov 2023-10-20 19:25 ` Dmitry Gutov 2023-10-23 6:58 ` Juri Linkov 2023-10-23 17:24 ` Dmitry Gutov 2023-10-23 17:34 ` Juri Linkov 2023-10-23 17:36 ` Dmitry Gutov 2023-10-23 18:42 ` Juri Linkov 2023-10-23 18:49 ` Dmitry Gutov 2023-10-25 16:53 ` Juri Linkov 2023-10-25 22:26 ` Dmitry Gutov 2023-10-27 6:50 ` Juri Linkov 2023-10-27 9:38 ` Dmitry Gutov 2023-10-28 16:56 ` Juri Linkov 2023-11-01 21:12 ` Dmitry Gutov 2023-11-02 17:20 ` Juri Linkov 2023-11-02 21:33 ` Dmitry Gutov 2023-11-04 17:28 ` Juri Linkov 2023-11-05 0:55 ` Dmitry Gutov 2023-11-06 7:16 ` Juri Linkov 2023-11-06 22:49 ` Dmitry Gutov 2023-10-21 13:27 ` sbaugh 2023-10-21 18:41 ` Dmitry Gutov 2023-10-21 13:14 ` sbaugh 2023-08-28 22:44 ` Dmitry Gutov 2023-08-29 20:34 ` Spencer Baugh 2023-06-02 12:46 ` Eli Zaretskii 2023-06-02 16:09 ` Juri Linkov 2023-06-02 6:32 ` Eli Zaretskii 2023-06-02 6:55 ` Juri Linkov 2023-06-02 11:39 ` Eli Zaretskii 2023-06-02 16:11 ` Juri Linkov 2023-06-05 6:53 ` Juri Linkov 2023-06-02 17:07 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-06-05 6:50 ` Juri Linkov 2023-06-05 14:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-06-05 16:31 ` Juri Linkov 2023-05-24 14:55 ` Spencer Baugh 2023-05-24 16:24 ` Juri Linkov 2023-05-26 15:16 ` Spencer Baugh 2023-05-30 17:48 ` Juri Linkov 2023-06-01 20:31 ` Spencer Baugh 2023-06-01 21:09 ` Drew Adams 2023-06-02 6:33 ` Eli Zaretskii 2023-06-02 6:46 ` Juri Linkov 2023-08-10 11:52 ` sbaugh
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).