unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* 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-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  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 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: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 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-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-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 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-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-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-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-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: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  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-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-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  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 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-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-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-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

* 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 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-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-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-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-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  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 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 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 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 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 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 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-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-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-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 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-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-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

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).