Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

cannot exit projectile-skel-dir-locals while keeping the variables already entered #1849

Open
st0nie opened this issue Jun 4, 2023 · 3 comments

Comments

@st0nie
Copy link

st0nie commented Jun 4, 2023

Expected behavior

When I enter an empty variable name, the template should exit and retain the previous input.

Projectile works well, but there seems to be no detailed documentation on how to properly use edit .dir-locals.el, I tried to use projectile-skel-dir-locals to edit it, but I can't exit the loop of input variables, if I press C-g or esc, my minibuffer will If I press C-g or esc, my minibuffer will close and the variables that have been entered before will disappear. I tried to exit the switch-case skeleton as in sh-mode by typing an empty string, but that doesn't work either.

I use vertico, and when I try to use a minimal configuration with only projectile, I also cannot exit the input loop of the skeleton correctly. This causes me to enter the input loop, press c-g to exit, and only the first input variable is saved, the rest of the variable input disappears.

What is the correct way to use projectile-skel-dir-locals, please help me out and thanks in advance!

The correct behavior should be like this

((nil . ((compile-command . "make -k"))

Actual behavior

((nil . ((compile-command . "make -k")
           ( .

Steps to reproduce the problem

M-x projectile-skel-dir-locals <cr>
c-file-style <cr>
"llvm.org" <cr>
M-x vertico-exit-input

Environment & Version information

Projectile version information

Projectile 20230317.1101

Emacs version

GNU Emacs 29.0.91 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38,
cairo version 1.17.8) of 2023-05-26

Operating system

E.g. Gentoo Linux 2.13

@st0nie st0nie changed the title Cannot exit projectile-skel-dir-locals while keeping the variables already entered cannot exit projectile-skel-dir-locals while keeping the variables already entered Jun 4, 2023
@neuhalje
Copy link

To add to that projectile-edit-dir-locals behaves similar, although M-x vertico-exit-input will also delete the fresh content (projectile 2.8.0).

@jaccarmac
Copy link
Contributor

Also observing this. I'm not familiar with the Emacs skeleton system, but want to dig into the interaction between it and Projectile's define-skeleton to discover the root cause.

@kotatsuyaki
Copy link

kotatsuyaki commented May 16, 2024

I found that Emacs 27.2 and before did not have this problem, while Emacs 28.1 and after

  • Clears out the whole skeleton on C-g at the prompt.
  • Keeps on looping even with an empty variable name.

Looking at the diff of skeleton.el between 27.2 and 28.1, the most significant change seems to be this commit that migrates it to lexical binding, but I'm not sure if that's the change that causes the issue.

Missing str in sub-skeleton?

(define-skeleton projectile-skel-dir-locals
  "Insert a .dir-locals.el template."
  nil
  "((nil . ("
  ; This sub-skeleton doesn't have a `str`?
  ("" '(projectile-skel-variable-cons) \n)
  resume:
  ")))")

One thing I noticed is that in the current implementation, the skeleton has a sub-skeleton without a str. On the Skeleton Language page on the Emacs manual, it's stated that a sub-skeleton must have a str (emphasis by myself):

skeleton
Subskeletons are inserted recursively, not once, but as often as the user enters something at the subskeletons interactor. Thus there must be a str in the subskeleton. They can also be used non-interactively, when prompt is a lisp-expression that returns successive list-elements.

The code of skeleton.el itself is too difficult for me to fully understand, so I'm not sure if this requirement stated on the manual is still the case.

I came up with a version of projectile-skel-dir-locals that, unlike the current implementation, has a str in the sub-skeleton. This version terminates properly on both empty variable name and empty value. It still wipes out the whole skeleton on C-g1, but terminating on empty variable name is good enough for me.

 (define-skeleton projectile-skel-dir-locals
   "Insert a .dir-locals.el template."
   nil
   "((nil . ("
-  ("" '(projectile-skel-variable-cons) \n)
+  ("Value: "
+   "("
+   (let ((var-name (projectile-read-variable)))
+                   (if (string-empty-p var-name)
+                       ;; Stop the sub-skeleton iteration on empty variable name.
+                       (signal 'quit t)
+                     var-name))
+   " . " str ")" \n)
   resume:
   ")))")

Footnotes

  1. python-skeleton-if also wipes out the whole skeleton on C-g starting from Emacs 28.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants