projectile icon indicating copy to clipboard operation
projectile copied to clipboard

Update command cache when editing the .dir-locals.el file

Open sfavazza opened this issue 2 years ago • 5 comments

Expected behavior

When editing a project .dir-locals.el (e.g. updating projectile-project-[install|test|run|etc..]-cmd) the projectile-*-cmd-map should be updated such that the first prompt on next invocation should be the latest from .dir-locals.el.

Actual behavior

  • after modifying a projectile command definition in .dir-locals.el
  • invoking the same command shows the last used command (before editing the configuration file)
  • since the first time the project is accessed and the .dir-locals.el read for the first time, any change to the dir-locals.el is not read anymore

Steps to reproduce the problem

  • create a .dir-locals.el file in your project, defining, say, projectile-project-test-cmd
  • open the project in Emacs
  • invoke projectile-test-project (the value read from the .dir-locals.el will be proposed)
  • open the .dir-locals.el buffer
    • modify the command
    • save the buffer
    • revert the buffer such that the changes are applied
  • try to invoke projectile-test-project again ==> the old version of the command is proposed

Environment & Version information

Projectile version information

Projectile 20230713.1023

Emacs version

GNU Emacs 28.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.24, cairo version 1.16.0) of 2023-03-10

Operating system

Linux 5.19.0-46-generic #47~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC

sfavazza avatar Sep 12 '23 10:09 sfavazza

@bbatsov any thoughts?

sfavazza avatar Oct 16 '23 08:10 sfavazza

I recall there was some command to force a re-read of dir-locals (e.g. (dir-locals-read-from-dir (dired-current-directory)), so using something like this might be a solution to your problem. Not sure if you have some different solution in mind.

bbatsov avatar Oct 16 '23 11:10 bbatsov

This won't solve the issue, because the problem is not with the dir-locals per-se, rather with the projectile cache. See the projectile-test-command case below:

(defun projectile-test-command (compile-dir)
  "Retrieve the test command for COMPILE-DIR.

The command is determined like this:

- first we check `projectile-test-cmd-map' for the last
test command that was invoked on the project

- then we check for `projectile-project-test-cmd' supplied
via .dir-locals.el

- finally we check for the default test command for a
project of that type"
  (or (gethash compile-dir projectile-test-cmd-map)
      projectile-project-test-cmd
      (projectile-default-test-command (projectile-project-type))))

Basically after the cache is initialized the dir-locals is not considered anymore. As a solution I was thinking the following:

  • record the modify time-stamp of the dir-locals
  • on following invocation of the same command the timestamp is checked to detect changes
  • if the actual is newer than the last saved, use it (this will automatically update the cache)
  • otherwise use the cache

This would require saving a timestamp (not a fun of this approach).

Otherwise projectile should add a function to the lisp-data-mode-hook (or the after-save-hook), to update projectile cache when a .dir-local.el buffer is saved.

Open to other suggestions as well :smiley:

I would be more than happy to open a merge-request if we agree on a solution.

sfavazza avatar Oct 22 '23 10:10 sfavazza

I guess a third approach would be a command that people can manually trigger to update the cache when needed, that they can optionally use as a hook function as you suggested. PR welcome!

bbatsov avatar Oct 23 '23 04:10 bbatsov