mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2026-09-10 07:46:51 -04:00
Delete empty local-variable block ad prop line
Delete local variable block or prop line when it became empty after deleting a variable. (Bug#81516) * lisp/files-x.el (modify-file-local-variable) (modify-file-local-variable-prop-line): Delete empty block or prop-line. * test/lisp/files-x-tests.el (files-x-test-add-file-local-variable) (files-x-test-add-file-local-variable-prop-line) (files-x-test-delete-file-local-variable) (files-x-test-delete-file-local-variable-prop-line): New tests.
This commit is contained in:
parent
fb6ad8aa78
commit
8b8aa7ced6
|
|
@ -201,7 +201,8 @@ the user how to make the new value take effect."
|
|||
(match-beginning 0)))
|
||||
(suffix (buffer-substring (point) (line-end-position)))
|
||||
(prefix-re (concat "^" (regexp-quote prefix)))
|
||||
(suffix-re (concat (regexp-quote suffix) "$")))
|
||||
(suffix-re (concat (regexp-quote suffix) "$"))
|
||||
(deleted nil))
|
||||
|
||||
;; Find or add missing "End:".
|
||||
(forward-line 1)
|
||||
|
|
@ -224,7 +225,17 @@ the user how to make the new value take effect."
|
|||
(while (re-search-forward
|
||||
(format "%s%S:.*%s" prefix-re variable suffix-re) end t)
|
||||
(delete-region (match-beginning 0) (1+ (match-end 0)))
|
||||
(setq replaced-pos (point)))))
|
||||
(setq replaced-pos (point)
|
||||
deleted t))
|
||||
;; Delete empty local variables block.
|
||||
(when (and (eq op 'delete) deleted (= beg end))
|
||||
(save-excursion
|
||||
(delete-region (progn (goto-char beg)
|
||||
(forward-line -1)
|
||||
(point))
|
||||
(progn (goto-char end)
|
||||
(forward-line 1)
|
||||
(point)))))))
|
||||
|
||||
;; Add a new variable/value pair. Add `mode' to the start, add new
|
||||
;; variable to the end, and add a replaced variable to its last location.
|
||||
|
|
@ -295,7 +306,7 @@ from the -*- line ignoring the input argument VALUE.
|
|||
If optional variable INTERACTIVE is non-nil, display a message telling
|
||||
the user how to make the new value take effect."
|
||||
(catch 'exit
|
||||
(let ((beg (point)) end replaced-pos)
|
||||
(let ((beg (point)) end replaced-pos deleted)
|
||||
(unless enable-local-variables
|
||||
(throw 'exit (message "File-local variables are disabled")))
|
||||
|
||||
|
|
@ -357,6 +368,7 @@ the user how to make the new value take effect."
|
|||
;; Replace or delete MODENAME
|
||||
(progn
|
||||
(when (member op '(add-or-replace delete))
|
||||
(setq deleted t)
|
||||
(delete-region (match-beginning 1) (match-end 1)))
|
||||
(when (eq op 'add-or-replace)
|
||||
(goto-char (match-beginning 1))
|
||||
|
|
@ -387,7 +399,8 @@ the user how to make the new value take effect."
|
|||
(skip-chars-forward " \t;")
|
||||
(when (eq key variable)
|
||||
(delete-region (match-beginning 0) (point))
|
||||
(setq replaced-pos (point)))))))
|
||||
(setq replaced-pos (point)
|
||||
deleted t))))))
|
||||
;; Add a new variable/value pair. Add `mode' to the start, add new
|
||||
;; variable to the end, and add a replaced variable to its last location.
|
||||
(when (eq op 'add-or-replace)
|
||||
|
|
@ -406,6 +419,28 @@ the user how to make the new value take effect."
|
|||
(insert (format "%S: %S;" variable value))
|
||||
(unless (eq (char-after) ?\s) (insert " ")))))
|
||||
|
||||
;; Delete empty prop-line.
|
||||
(when (and (eq op 'delete) deleted (= beg end))
|
||||
(save-excursion
|
||||
;; First delete -*- -*-
|
||||
(delete-region
|
||||
(progn
|
||||
(goto-char beg)
|
||||
(search-backward "-*-" (line-beginning-position))
|
||||
(point))
|
||||
(progn
|
||||
(goto-char end)
|
||||
(search-forward "-*-" (line-end-position))
|
||||
(point)))
|
||||
;; And then delete line if comment is empty.
|
||||
(goto-char (line-beginning-position))
|
||||
(when (looking-at-p
|
||||
(concat
|
||||
"^[ \t]*\\(?:" (regexp-quote (or comment-start ";"))
|
||||
"\\)+[ \t]*" (regexp-quote (or comment-end ""))
|
||||
"[ \t]*$"))
|
||||
(delete-region (point) (progn (forward-line 1) (point))))))
|
||||
|
||||
(when interactive
|
||||
(modify-file-local-variable-message variable value op)))))
|
||||
|
||||
|
|
|
|||
|
|
@ -638,5 +638,194 @@ or `executable-find', their default value must be used nonetheless."
|
|||
`(connection-local-profile-alist ',clpa now)
|
||||
`(connection-local-criteria-alist ',clca now)))))
|
||||
|
||||
(ert-deftest files-x-test-add-file-local-variable ()
|
||||
"Test adding and replacing file local variables."
|
||||
;; Simple adding
|
||||
(with-temp-buffer
|
||||
(add-file-local-variable 'foo 1)
|
||||
(add-file-local-variable 'bar 2)
|
||||
(should (equal (buffer-string)
|
||||
"\n;; Local Variables:\n;; foo: 1\n;; bar: 2\n;; End:\n")))
|
||||
;; Adding in c-mode
|
||||
(with-temp-buffer
|
||||
(c-mode)
|
||||
(setq-local comment-start "/* " comment-end " */")
|
||||
(add-file-local-variable 'foo 1)
|
||||
(add-file-local-variable 'bar 2)
|
||||
(should (equal (buffer-string)
|
||||
(concat "\n/* Local Variables: */\n"
|
||||
"/* foo: 1 */\n"
|
||||
"/* bar: 2 */\n"
|
||||
"/* End: */\n"))))
|
||||
;; Replacing
|
||||
(with-temp-buffer
|
||||
(add-file-local-variable 'foo 1)
|
||||
(add-file-local-variable 'bar 2)
|
||||
(add-file-local-variable 'foo t)
|
||||
(add-file-local-variable 'bar nil)
|
||||
(should (equal (buffer-string)
|
||||
"\n;; Local Variables:\n;; foo: t\n;; bar: nil\n;; End:\n")))
|
||||
;; Replacing with prefix/suffix
|
||||
(with-temp-buffer
|
||||
(insert ";; PRE Local Variables: SUF\n"
|
||||
";; PRE foo: t SUF\n"
|
||||
";; PRE bar: nil SUF\n"
|
||||
";; PRE End: SUF\n")
|
||||
(add-file-local-variable 'foo t)
|
||||
(add-file-local-variable 'bar nil)
|
||||
(should (equal (buffer-string)
|
||||
(concat ";; PRE Local Variables: SUF\n"
|
||||
";; PRE foo: t SUF\n"
|
||||
";; PRE bar: nil SUF\n"
|
||||
";; PRE End: SUF\n")))))
|
||||
|
||||
(ert-deftest files-x-test-delete-file-local-variable ()
|
||||
"Test deleting file local variables."
|
||||
;; Simple deleting
|
||||
(with-temp-buffer
|
||||
(setq-local comment-start ";;" comment-end "")
|
||||
(insert "BEFORE\n"
|
||||
";; Local Variables:\n"
|
||||
";; foo: t\n"
|
||||
";; bar: nil\n"
|
||||
";; End:\n"
|
||||
"AFTER")
|
||||
(delete-file-local-variable 'foo)
|
||||
(should (equal (buffer-string)
|
||||
(concat "BEFORE\n"
|
||||
";; Local Variables:\n"
|
||||
";; bar: nil\n"
|
||||
";; End:\n"
|
||||
"AFTER")))
|
||||
(delete-file-local-variable 'bar)
|
||||
(should (equal (buffer-string) "BEFORE\nAFTER")))
|
||||
;; Deleting in c-mode
|
||||
(with-temp-buffer
|
||||
(c-mode)
|
||||
(setq-local comment-start "/* " comment-end " */")
|
||||
(insert "BEFORE\n"
|
||||
"/* Local Variables: */\n"
|
||||
"/* foo: t */\n"
|
||||
"/* bar: nil */\n"
|
||||
"/* End: */\n"
|
||||
"AFTER")
|
||||
(delete-file-local-variable 'foo)
|
||||
(should (equal (buffer-string)
|
||||
(concat "BEFORE\n"
|
||||
"/* Local Variables: */\n"
|
||||
"/* bar: nil */\n"
|
||||
"/* End: */\n"
|
||||
"AFTER")))
|
||||
(delete-file-local-variable 'bar)
|
||||
(should (equal (buffer-string) "BEFORE\nAFTER")))
|
||||
;; Ensure that other blocks are untouched
|
||||
(with-temp-buffer
|
||||
(setq-local comment-start ";;" comment-end "")
|
||||
(insert ";; Local Variables:\n"
|
||||
";; foo: t\n"
|
||||
";; End:\n"
|
||||
";; Local Variables:\n"
|
||||
";; PRESERVE\n"
|
||||
";; End:\n")
|
||||
(delete-file-local-variable 'foo)
|
||||
(should (equal (buffer-string)
|
||||
";; Local Variables:\n;; PRESERVE\n;; End:\n")))
|
||||
;; Deleting with prefix/suffix
|
||||
(with-temp-buffer
|
||||
(setq-local comment-start ";;" comment-end "")
|
||||
(insert "BEFORE\n"
|
||||
";; PRE Local Variables: SUF\n"
|
||||
";; PRE foo: t SUF\n"
|
||||
";; PRE bar: nil SUF\n"
|
||||
";; PRE End: SUF\n"
|
||||
"AFTER")
|
||||
(delete-file-local-variable 'foo)
|
||||
(should (equal (buffer-string)
|
||||
(concat "BEFORE\n"
|
||||
";; PRE Local Variables: SUF\n"
|
||||
";; PRE bar: nil SUF\n"
|
||||
";; PRE End: SUF\n"
|
||||
"AFTER")))
|
||||
(delete-file-local-variable 'bar)
|
||||
(should (equal (buffer-string) "BEFORE\nAFTER"))))
|
||||
|
||||
(ert-deftest files-x-test-add-file-local-variable-prop-line ()
|
||||
"Test adding and replacing file local variables in the prop-line."
|
||||
;; Simple adding
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(add-file-local-variable-prop-line 'foo 1)
|
||||
(add-file-local-variable-prop-line 'bar 2)
|
||||
(should (equal (buffer-string) ";; -*- foo: 1; bar: 2; -*-\n")))
|
||||
;; Adding in c-mode
|
||||
(with-temp-buffer
|
||||
(c-mode)
|
||||
(setq-local comment-start "/* " comment-end " */")
|
||||
(add-file-local-variable-prop-line 'foo 1)
|
||||
(add-file-local-variable-prop-line 'bar 2)
|
||||
(should (equal (buffer-string) "/* -*- foo: 1; bar: 2; -*- */\n")))
|
||||
;; Adding to mode variable
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(insert ";; -*- org-mode -*-\n")
|
||||
(add-file-local-variable-prop-line 'foo 1)
|
||||
(should (equal (buffer-string) ";; -*- mode: org-mode; foo: 1; -*-\n")))
|
||||
;; Simple replacing
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(add-file-local-variable-prop-line 'foo 1)
|
||||
(add-file-local-variable-prop-line 'bar 2)
|
||||
(add-file-local-variable-prop-line 'foo t)
|
||||
(add-file-local-variable-prop-line 'bar nil)
|
||||
(should (equal (buffer-string) ";; -*- foo: t; bar: nil; -*-\n")))
|
||||
;; Replacing with prefix/suffix
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(insert ";; PRE -*- foo: 1; bar: 2; -*- SUF\n")
|
||||
(add-file-local-variable-prop-line 'foo t)
|
||||
(add-file-local-variable-prop-line 'bar nil)
|
||||
(should (equal (buffer-string)
|
||||
";; PRE -*- foo: t; bar: nil; -*- SUF\n"))))
|
||||
|
||||
(ert-deftest files-x-test-delete-file-local-variable-prop-line ()
|
||||
"Test deleting file local variables in prop-line."
|
||||
;; Simple deleting
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(insert ";; -*- foo: t; bar: nil -*-\n")
|
||||
(delete-file-local-variable-prop-line 'foo)
|
||||
(should (equal (buffer-string) ";; -*- bar: nil -*-\n"))
|
||||
(delete-file-local-variable-prop-line 'bar)
|
||||
(should (equal (buffer-string) "")))
|
||||
;; Deleting mode variable
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(insert ";; -*- org-mode -*-\n")
|
||||
(delete-file-local-variable-prop-line 'mode)
|
||||
(should (equal (buffer-string) "")))
|
||||
;; Deleting in c-mode
|
||||
(with-temp-buffer
|
||||
(c-mode)
|
||||
(setq-local comment-start "/* " comment-end " */")
|
||||
(insert "/* -*- foo: t; bar: nil -*- */\n")
|
||||
(delete-file-local-variable-prop-line 'foo)
|
||||
(should (equal (buffer-string) "/* -*- bar: nil -*- */\n"))
|
||||
(delete-file-local-variable-prop-line 'bar)
|
||||
(should (equal (buffer-string) "")))
|
||||
;; Ensure that other prop lines are untouched
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(insert ";; -*- foo: t -*-\n;; -*- -*-")
|
||||
(delete-file-local-variable-prop-line 'foo)
|
||||
(should (equal (buffer-string) ";; -*- -*-")))
|
||||
;; Deleting with prefix/suffix
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(insert ";; PRE -*- foo: t; bar: nil -*- SUF\n")
|
||||
(delete-file-local-variable-prop-line 'foo)
|
||||
(should (equal (buffer-string) ";; PRE -*- bar: nil -*- SUF\n"))
|
||||
(delete-file-local-variable-prop-line 'bar)
|
||||
(should (equal (buffer-string) ";; PRE SUF\n"))))
|
||||
|
||||
(provide 'files-x-tests)
|
||||
;;; files-x-tests.el ends here
|
||||
|
|
|
|||
Loading…
Reference in a new issue