mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-02 08:22:22 +00:00
Allow specifying the dir locals file to edit (Bug#66663)
* lisp/files-x.el (modify-dir-local-variable): Take a 5th optional argument, the filename of the dir locals file to modify. (read-dir-locals-file): New function. (add-dir-local-variable, delete-dir-local-variable) (copy-file-locals-to-dir-locals): Optionally read the filename to modify, and pass it to modify-dir-local-variable. * etc/NEWS: Announce the change. * doc/emacs/custom.texi (Directory Variables): Document the new functionality.
This commit is contained in:
parent
f39cd59ed4
commit
9be8011217
@ -1507,7 +1507,13 @@ mode or subdirectory, and for variable and value, and adds the
|
||||
entry defining the directory-local variable. @kbd{M-x
|
||||
delete-dir-local-variable} deletes an entry. @kbd{M-x
|
||||
copy-file-locals-to-dir-locals} copies the file-local variables in the
|
||||
current file into @file{.dir-locals.el}.
|
||||
current file into @file{.dir-locals.el}, or @file{.dir-locals-2.el} if
|
||||
that file is also present.
|
||||
|
||||
With a prefix argument, all three commands prompt for the file you
|
||||
want to modify. Although it doesn't have to exist, you must enter a
|
||||
valid filename, either @file{.dir-locals.el} or
|
||||
@file{.dir-locals-2.el}.
|
||||
|
||||
@findex dir-locals-set-class-variables
|
||||
@findex dir-locals-set-directory-class
|
||||
|
10
etc/NEWS
10
etc/NEWS
@ -187,6 +187,11 @@ right-aligned to is controlled by the new user option
|
||||
It can be used to add, remove and reorder functions that change
|
||||
the appearance of every tab on the tab bar.
|
||||
|
||||
+++
|
||||
** New optional argument for modifying directory local variables
|
||||
The commands 'add-dir-local-variable', 'delete-dir-local-variable' and
|
||||
'copy-file-locals-to-dir-locals' now take an optional prefix argument,
|
||||
to enter the file you want to modify.
|
||||
** Miscellaneous
|
||||
|
||||
---
|
||||
@ -1358,6 +1363,11 @@ Their 'noerror' arguments have no effect and are therefore obsolete.
|
||||
When supplied with ':default-language LANGUAGE', rules after it will
|
||||
default to use 'LANGUAGE'.
|
||||
|
||||
---
|
||||
** New optional argument to 'modify-dir-local-variable'
|
||||
A 5th argument, optional, has been added to
|
||||
'modify-dir-local-variable'. It can be used to specify which
|
||||
dir-locals file to modify.
|
||||
|
||||
* Changes in Emacs 30.1 on Non-Free Operating Systems
|
||||
|
||||
|
117
lisp/files-x.el
117
lisp/files-x.el
@ -31,6 +31,8 @@
|
||||
;;; Code:
|
||||
|
||||
(eval-when-compile (require 'subr-x)) ; for string-trim-right
|
||||
(declare-function dosified-file-name "dos-fns" (file-name))
|
||||
(declare-function project-root "project" (project))
|
||||
|
||||
|
||||
;;; Commands to add/delete file-local/directory-local variables.
|
||||
@ -410,7 +412,7 @@ then this function adds it."
|
||||
|
||||
(defvar auto-insert) ; from autoinsert.el
|
||||
|
||||
(defun modify-dir-local-variable (mode variable value op)
|
||||
(defun modify-dir-local-variable (mode variable value op &optional file)
|
||||
"Modify directory-local VARIABLE in .dir-locals.el depending on operation OP.
|
||||
|
||||
If OP is `add-or-replace' then delete all existing settings of
|
||||
@ -422,28 +424,37 @@ If .dir-locals.el was not found and OP is not `delete' then create
|
||||
this file in the current directory.
|
||||
|
||||
If OP is `delete' then delete all existing settings of VARIABLE
|
||||
from the MODE alist ignoring the input argument VALUE."
|
||||
from the MODE alist ignoring the input argument VALUE.
|
||||
|
||||
Optional argument FILE, when non-nil, specifies what file to modify. It
|
||||
should be an expanded filename."
|
||||
(catch 'exit
|
||||
(unless enable-local-variables
|
||||
(throw 'exit (message "Directory-local variables are disabled")))
|
||||
(let* ((dir-or-cache (and (buffer-file-name)
|
||||
(not (file-remote-p (buffer-file-name)))
|
||||
(dir-locals-find-file (buffer-file-name))))
|
||||
(variables-file
|
||||
;; If there are several .dir-locals, the user probably
|
||||
;; wants to edit the last one (the highest priority).
|
||||
(cond ((stringp dir-or-cache)
|
||||
(car (last (dir-locals--all-files dir-or-cache))))
|
||||
((consp dir-or-cache) ; result from cache
|
||||
;; If cache element has an mtime, assume it came
|
||||
;; from a file. Otherwise, assume it was set
|
||||
;; directly.
|
||||
(if (nth 2 dir-or-cache)
|
||||
(car (last (dir-locals--all-files (car dir-or-cache))))
|
||||
(cadr dir-or-cache)))
|
||||
;; Try to make a proper file-name.
|
||||
(t (expand-file-name dir-locals-file))))
|
||||
variables)
|
||||
(let ((variables-file
|
||||
(if (stringp file)
|
||||
file
|
||||
(let ((dir-or-cache
|
||||
(and (buffer-file-name)
|
||||
(not (file-remote-p (buffer-file-name)))
|
||||
(dir-locals-find-file (buffer-file-name)))))
|
||||
;; If there are several .dir-locals, the user probably
|
||||
;; wants to edit the last one (the highest priority).
|
||||
(cond
|
||||
((stringp dir-or-cache)
|
||||
(car (last (dir-locals--all-files dir-or-cache))))
|
||||
((consp dir-or-cache) ; result from cache
|
||||
;; If cache element has an mtime, assume it came
|
||||
;; from a file. Otherwise, assume it was set
|
||||
;; directly.
|
||||
(if (nth 2 dir-or-cache)
|
||||
(car (last (dir-locals--all-files (car dir-or-cache))))
|
||||
(cadr dir-or-cache)))
|
||||
;; Try to make a proper file-name.
|
||||
(t (expand-file-name (if (eq system-type 'ms-dos)
|
||||
(dosified-file-name dir-locals-file)
|
||||
dir-locals-file)))))))
|
||||
variables)
|
||||
;; I can't be bothered to handle this case right now.
|
||||
;; Dir locals were set directly from a class. You need to
|
||||
;; directly modify the class in dir-locals-class-alist.
|
||||
@ -527,33 +538,75 @@ from the MODE alist ignoring the input argument VALUE."
|
||||
(cdr mode-variables) "\n"))))
|
||||
variables "\n")))
|
||||
|
||||
(defun read-dir-locals-file ()
|
||||
"Read a dir-locals filename using completion.
|
||||
Intended to be used in the `interactive' spec of `add-dir-local-variable',
|
||||
`delete-dir-local-variable' and `copy-file-locals-to-dir-locals'.
|
||||
|
||||
Returns the filename, expanded."
|
||||
(let* ((pri dir-locals-file)
|
||||
(sec (replace-regexp-in-string ".el$" "-2.el" dir-locals-file))
|
||||
(dir (or (locate-dominating-file default-directory pri)
|
||||
(locate-dominating-file default-directory sec))))
|
||||
(expand-file-name
|
||||
(read-file-name
|
||||
"File: "
|
||||
(cond (dir)
|
||||
((when-let ((proj (and (featurep 'project) (project-current))))
|
||||
(project-root proj))))
|
||||
nil
|
||||
(lambda (fname)
|
||||
(member (file-name-nondirectory fname) (list pri sec)))
|
||||
dir-locals-file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun add-dir-local-variable (mode variable value)
|
||||
"Add directory-local VARIABLE with its VALUE and MODE to .dir-locals.el."
|
||||
(defun add-dir-local-variable (mode variable value &optional file)
|
||||
"Add directory-local VARIABLE with its VALUE and MODE to .dir-locals.el.
|
||||
|
||||
With a prefix argument, prompt for the file to modify.
|
||||
|
||||
When called from Lisp, FILE may be the expanded name of the dir-locals file
|
||||
where to add VARIABLE."
|
||||
(interactive
|
||||
(let (variable)
|
||||
(list
|
||||
(read-file-local-variable-mode)
|
||||
(setq variable (read-file-local-variable "Add directory-local variable"))
|
||||
(read-file-local-variable-value variable))))
|
||||
(modify-dir-local-variable mode variable value 'add-or-replace))
|
||||
(read-file-local-variable-value variable)
|
||||
(when current-prefix-arg
|
||||
(read-dir-locals-file)))))
|
||||
(modify-dir-local-variable mode variable value 'add-or-replace file))
|
||||
|
||||
;;;###autoload
|
||||
(defun delete-dir-local-variable (mode variable)
|
||||
"Delete all MODE settings of file-local VARIABLE from .dir-locals.el."
|
||||
(defun delete-dir-local-variable (mode variable &optional file)
|
||||
"Delete all MODE settings of dir-local VARIABLE from .dir-locals.el.
|
||||
|
||||
With a prefix argument, prompt for the file to modify.
|
||||
|
||||
When called from Lisp, FILE may be the expanded name of the dir-locals file
|
||||
from where to delete VARIABLE."
|
||||
(interactive
|
||||
(list
|
||||
(read-file-local-variable-mode)
|
||||
(read-file-local-variable "Delete directory-local variable")))
|
||||
(modify-dir-local-variable mode variable nil 'delete))
|
||||
(read-file-local-variable "Delete directory-local variable")
|
||||
(when current-prefix-arg
|
||||
(read-dir-locals-file))))
|
||||
(modify-dir-local-variable mode variable nil 'delete file))
|
||||
|
||||
;;;###autoload
|
||||
(defun copy-file-locals-to-dir-locals ()
|
||||
"Copy file-local variables to .dir-locals.el."
|
||||
(interactive)
|
||||
(defun copy-file-locals-to-dir-locals (&optional file)
|
||||
"Copy file-local variables to .dir-locals.el.
|
||||
|
||||
With a prefix argument, prompt for the file to modify.
|
||||
|
||||
When called from Lisp, FILE may be the expanded name of the dir-locals file
|
||||
where to copy the file-local variables."
|
||||
(interactive
|
||||
(list (when current-prefix-arg
|
||||
(read-dir-locals-file))))
|
||||
(dolist (elt file-local-variables-alist)
|
||||
(unless (assq (car elt) dir-local-variables-alist)
|
||||
(add-dir-local-variable major-mode (car elt) (cdr elt)))))
|
||||
(add-dir-local-variable major-mode (car elt) (cdr elt) file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun copy-dir-locals-to-file-locals ()
|
||||
|
Loading…
Reference in New Issue
Block a user