diff options
| author | João Távora | 2020-04-18 02:46:04 +0100 |
|---|---|---|
| committer | João Távora | 2020-05-01 12:11:10 +0100 |
| commit | 43fded12d544ab68f493142debc5b3e437317f35 (patch) | |
| tree | 19da109c5f240f97d80c8d73dc103e9fa64b19cc | |
| parent | 7fa3e754cb7af37b0c50f253e7dec2acd0275a8a (diff) | |
| download | emacs-43fded12d544ab68f493142debc5b3e437317f35.tar.gz emacs-43fded12d544ab68f493142debc5b3e437317f35.zip | |
Add lisp-data-mode for editing non-code Lisp data
Fixes: bug#40573
The new mode can be used stand-alone or inherited from by modes
intended to edit programs. The existing emacs-lisp-mode and lisp-mode
are examples.
Thanks to Juri Linkov and Basil L. Contovounesios for researching some
data files in Emacs that can be automatically set to use the new mode.
* lisp/files.el (auto-mode-alist): Add entry for ".dir-locals" and
".dir-locals-2"
* lisp/emacs-lisp/lisp-mode.el: (lisp-data-mode): New major mode.
(lisp-mode): Inherit from lisp-data-mode. Set special lisp-mode
stuff here.
* lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Inherit from
lisp-data-mode.
* lisp/bookmark.el (bookmark-insert-file-format-version-stamp):
Use lisp-data-mode.
* lisp/saveplace.el (save-place-alist-to-file): Use
lisp-data-mode.
* lisp/net/eww.el (eww-write-bookmarks): Use lisp-data-mode.
* lisp/net/nsm.el (nsm-write-settings): Use lisp-data-mode.
* lisp/net/tramp-cache.el (tramp-dump-connection-properties): Use
lisp-data-mode.
* etc/NEWS: Mention lisp-data-mode.
* doc/lispref/modes.texi (Example Major Modes): Update example.
| -rw-r--r-- | doc/lispref/modes.texi | 17 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/bookmark.el | 6 | ||||
| -rw-r--r-- | lisp/emacs-lisp/lisp-mode.el | 13 | ||||
| -rw-r--r-- | lisp/files.el | 7 | ||||
| -rw-r--r-- | lisp/net/eww.el | 2 | ||||
| -rw-r--r-- | lisp/net/nsm.el | 1 | ||||
| -rw-r--r-- | lisp/net/tramp-cache.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/elisp-mode.el | 27 | ||||
| -rw-r--r-- | lisp/saveplace.el | 2 |
10 files changed, 45 insertions, 38 deletions
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index fc68ee1b322..eaee56f0a32 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi | |||
| @@ -1352,19 +1352,11 @@ illustrate how these modes are written. | |||
| 1352 | @end smallexample | 1352 | @end smallexample |
| 1353 | 1353 | ||
| 1354 | The three modes for Lisp share much of their code. For instance, | 1354 | The three modes for Lisp share much of their code. For instance, |
| 1355 | each calls the following function to set various variables: | 1355 | Lisp mode and Emacs Lisp mode inherit from Lisp Data mode and Lisp |
| 1356 | 1356 | Interaction Mode inherits from Emacs Lisp mode. | |
| 1357 | @smallexample | ||
| 1358 | @group | ||
| 1359 | (defun lisp-mode-variables (&optional syntax keywords-case-insensitive elisp) | ||
| 1360 | (when syntax | ||
| 1361 | (set-syntax-table lisp-mode-syntax-table)) | ||
| 1362 | @dots{} | ||
| 1363 | @end group | ||
| 1364 | @end smallexample | ||
| 1365 | 1357 | ||
| 1366 | @noindent | 1358 | @noindent |
| 1367 | Amongst other things, this function sets up the @code{comment-start} | 1359 | Amongst other things, Lisp Data mode sets up the @code{comment-start} |
| 1368 | variable to handle Lisp comments: | 1360 | variable to handle Lisp comments: |
| 1369 | 1361 | ||
| 1370 | @smallexample | 1362 | @smallexample |
| @@ -1414,7 +1406,7 @@ Finally, here is the major mode command for Lisp mode: | |||
| 1414 | 1406 | ||
| 1415 | @smallexample | 1407 | @smallexample |
| 1416 | @group | 1408 | @group |
| 1417 | (define-derived-mode lisp-mode prog-mode "Lisp" | 1409 | (define-derived-mode lisp-mode lisp-data-mode "Lisp" |
| 1418 | "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp. | 1410 | "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp. |
| 1419 | Commands: | 1411 | Commands: |
| 1420 | Delete converts tabs to spaces as it moves back. | 1412 | Delete converts tabs to spaces as it moves back. |
| @@ -1425,7 +1417,6 @@ Note that `run-lisp' may be used either to start an inferior Lisp job | |||
| 1425 | or to switch back to an existing one." | 1417 | or to switch back to an existing one." |
| 1426 | @end group | 1418 | @end group |
| 1427 | @group | 1419 | @group |
| 1428 | (lisp-mode-variables nil t) | ||
| 1429 | (setq-local find-tag-default-function 'lisp-find-tag-default) | 1420 | (setq-local find-tag-default-function 'lisp-find-tag-default) |
| 1430 | (setq-local comment-start-skip | 1421 | (setq-local comment-start-skip |
| 1431 | "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") | 1422 | "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") |
| @@ -291,6 +291,12 @@ These new navigation commands are bound to 'n' and 'p' in | |||
| 291 | 291 | ||
| 292 | * New Modes and Packages in Emacs 28.1 | 292 | * New Modes and Packages in Emacs 28.1 |
| 293 | 293 | ||
| 294 | *** Lisp Data mode | ||
| 295 | The new command 'lisp-data-mode' enables a major mode for buffers | ||
| 296 | composed of Lisp symbolic expressions that do not form a computer | ||
| 297 | program. The '.dir-locals.el' file is automatically set to use this | ||
| 298 | mode, as are other data files produced by Emacs. | ||
| 299 | |||
| 294 | 300 | ||
| 295 | * Incompatible Editing Changes in Emacs 28.1 | 301 | * Incompatible Editing Changes in Emacs 28.1 |
| 296 | 302 | ||
diff --git a/lisp/bookmark.el b/lisp/bookmark.el index 720ad18c16f..f2384973e9c 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el | |||
| @@ -734,8 +734,10 @@ CODING is the symbol of the coding-system in which the file is encoded." | |||
| 734 | (if (memq (coding-system-base coding) '(undecided prefer-utf-8)) | 734 | (if (memq (coding-system-base coding) '(undecided prefer-utf-8)) |
| 735 | (setq coding 'utf-8-emacs)) | 735 | (setq coding 'utf-8-emacs)) |
| 736 | (insert | 736 | (insert |
| 737 | (format ";;;; Emacs Bookmark Format Version %d ;;;; -*- coding: %S -*-\n" | 737 | (format |
| 738 | bookmark-file-format-version (coding-system-base coding))) | 738 | ";;;; Emacs Bookmark Format Version %d\ |
| 739 | ;;;; -*- coding: %S mode: lisp-data -*-\n" | ||
| 740 | bookmark-file-format-version (coding-system-base coding))) | ||
| 739 | (insert ";;; This format is meant to be slightly human-readable;\n" | 741 | (insert ";;; This format is meant to be slightly human-readable;\n" |
| 740 | ";;; nevertheless, you probably don't want to edit it.\n" | 742 | ";;; nevertheless, you probably don't want to edit it.\n" |
| 741 | ";;; " | 743 | ";;; " |
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 98c44161ad0..7098a41f274 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el | |||
| @@ -611,6 +611,8 @@ Value for `adaptive-fill-function'." | |||
| 611 | ;; a single docstring. Let's fix it here. | 611 | ;; a single docstring. Let's fix it here. |
| 612 | (if (looking-at "\\s-+\"[^\n\"]+\"\\s-*$") "")) | 612 | (if (looking-at "\\s-+\"[^\n\"]+\"\\s-*$") "")) |
| 613 | 613 | ||
| 614 | ;; Maybe this should be discouraged/obsoleted and users should be | ||
| 615 | ;; encouraged to use `lisp-data-mode` instead. | ||
| 614 | (defun lisp-mode-variables (&optional lisp-syntax keywords-case-insensitive | 616 | (defun lisp-mode-variables (&optional lisp-syntax keywords-case-insensitive |
| 615 | elisp) | 617 | elisp) |
| 616 | "Common initialization routine for lisp modes. | 618 | "Common initialization routine for lisp modes. |
| @@ -658,6 +660,14 @@ font-lock keywords will not be case sensitive." | |||
| 658 | (setq-local electric-pair-skip-whitespace 'chomp) | 660 | (setq-local electric-pair-skip-whitespace 'chomp) |
| 659 | (setq-local electric-pair-open-newline-between-pairs nil)) | 661 | (setq-local electric-pair-open-newline-between-pairs nil)) |
| 660 | 662 | ||
| 663 | ;;;###autoload | ||
| 664 | (define-derived-mode lisp-data-mode prog-mode "Lisp-Data" | ||
| 665 | "Major mode for buffers holding data written in Lisp syntax." | ||
| 666 | :group 'lisp | ||
| 667 | (lisp-mode-variables t t nil) | ||
| 668 | (setq-local electric-quote-string t) | ||
| 669 | (setq imenu-case-fold-search nil)) | ||
| 670 | |||
| 661 | (defun lisp-outline-level () | 671 | (defun lisp-outline-level () |
| 662 | "Lisp mode `outline-level' function." | 672 | "Lisp mode `outline-level' function." |
| 663 | (let ((len (- (match-end 0) (match-beginning 0)))) | 673 | (let ((len (- (match-end 0) (match-beginning 0)))) |
| @@ -737,7 +747,7 @@ font-lock keywords will not be case sensitive." | |||
| 737 | "Keymap for ordinary Lisp mode. | 747 | "Keymap for ordinary Lisp mode. |
| 738 | All commands in `lisp-mode-shared-map' are inherited by this map.") | 748 | All commands in `lisp-mode-shared-map' are inherited by this map.") |
| 739 | 749 | ||
| 740 | (define-derived-mode lisp-mode prog-mode "Lisp" | 750 | (define-derived-mode lisp-mode lisp-data-mode "Lisp" |
| 741 | "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp. | 751 | "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp. |
| 742 | Commands: | 752 | Commands: |
| 743 | Delete converts tabs to spaces as it moves back. | 753 | Delete converts tabs to spaces as it moves back. |
| @@ -746,7 +756,6 @@ Blank lines separate paragraphs. Semicolons start comments. | |||
| 746 | \\{lisp-mode-map} | 756 | \\{lisp-mode-map} |
| 747 | Note that `run-lisp' may be used either to start an inferior Lisp job | 757 | Note that `run-lisp' may be used either to start an inferior Lisp job |
| 748 | or to switch back to an existing one." | 758 | or to switch back to an existing one." |
| 749 | (lisp-mode-variables nil t) | ||
| 750 | (setq-local lisp-indent-function 'common-lisp-indent-function) | 759 | (setq-local lisp-indent-function 'common-lisp-indent-function) |
| 751 | (setq-local find-tag-default-function 'lisp-find-tag-default) | 760 | (setq-local find-tag-default-function 'lisp-find-tag-default) |
| 752 | (setq-local comment-start-skip | 761 | (setq-local comment-start-skip |
diff --git a/lisp/files.el b/lisp/files.el index fa72e51c497..56d4679ad7d 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -2657,6 +2657,13 @@ since only a single case-insensitive search through the alist is made." | |||
| 2657 | ("\\.ltx\\'" . latex-mode) | 2657 | ("\\.ltx\\'" . latex-mode) |
| 2658 | ("\\.dtx\\'" . doctex-mode) | 2658 | ("\\.dtx\\'" . doctex-mode) |
| 2659 | ("\\.org\\'" . org-mode) | 2659 | ("\\.org\\'" . org-mode) |
| 2660 | ;; .dir-locals.el is not really elisp. Could use the | ||
| 2661 | ;; `dir-locals-file' constant if it weren't defined below. | ||
| 2662 | ("\\.dir-locals\\(-2\\)?\\.el\\'" . lisp-data-mode) | ||
| 2663 | ("eww-bookmarks\\'" . lisp-data-mode) | ||
| 2664 | ("tramp\\'" . lisp-data-mode) | ||
| 2665 | ("places\\'" . lisp-data-mode) | ||
| 2666 | ("\\.emacs-places\\'" . lisp-data-mode) | ||
| 2660 | ("\\.el\\'" . emacs-lisp-mode) | 2667 | ("\\.el\\'" . emacs-lisp-mode) |
| 2661 | ("Project\\.ede\\'" . emacs-lisp-mode) | 2668 | ("Project\\.ede\\'" . emacs-lisp-mode) |
| 2662 | ("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode) | 2669 | ("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode) |
diff --git a/lisp/net/eww.el b/lisp/net/eww.el index c83884fd259..a4544023f61 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el | |||
| @@ -1733,7 +1733,7 @@ If CHARSET is nil then use UTF-8." | |||
| 1733 | 1733 | ||
| 1734 | (defun eww-write-bookmarks () | 1734 | (defun eww-write-bookmarks () |
| 1735 | (with-temp-file (expand-file-name "eww-bookmarks" eww-bookmarks-directory) | 1735 | (with-temp-file (expand-file-name "eww-bookmarks" eww-bookmarks-directory) |
| 1736 | (insert ";; Auto-generated file; don't edit\n") | 1736 | (insert ";; Auto-generated file; don't edit -*- mode: lisp-data -*-\n") |
| 1737 | (pp eww-bookmarks (current-buffer)))) | 1737 | (pp eww-bookmarks (current-buffer)))) |
| 1738 | 1738 | ||
| 1739 | (defun eww-read-bookmarks () | 1739 | (defun eww-read-bookmarks () |
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 2d36c5e2571..cc22427e6d1 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el | |||
| @@ -964,6 +964,7 @@ protocol." | |||
| 964 | 964 | ||
| 965 | (defun nsm-write-settings () | 965 | (defun nsm-write-settings () |
| 966 | (with-temp-file nsm-settings-file | 966 | (with-temp-file nsm-settings-file |
| 967 | (insert ";;;; -*- mode: lisp-data -*-\n") | ||
| 967 | (insert "(\n") | 968 | (insert "(\n") |
| 968 | (dolist (setting nsm-permanent-host-settings) | 969 | (dolist (setting nsm-permanent-host-settings) |
| 969 | (insert " ") | 970 | (insert " ") |
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 09e30f000f4..6d87ce297bc 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el | |||
| @@ -472,7 +472,7 @@ used to cache connection properties of the local machine." | |||
| 472 | ;; Dump it. | 472 | ;; Dump it. |
| 473 | (with-temp-file tramp-persistency-file-name | 473 | (with-temp-file tramp-persistency-file-name |
| 474 | (insert | 474 | (insert |
| 475 | ";; -*- emacs-lisp -*-" | 475 | ";; -*- lisp-data -*-" |
| 476 | ;; `time-stamp-string' might not exist in all Emacs flavors. | 476 | ;; `time-stamp-string' might not exist in all Emacs flavors. |
| 477 | (condition-case nil | 477 | (condition-case nil |
| 478 | (progn | 478 | (progn |
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index f85fd771ca8..b737134f90c 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el | |||
| @@ -250,7 +250,7 @@ Comments in the form will be lost." | |||
| 250 | map)) | 250 | map)) |
| 251 | 251 | ||
| 252 | ;;;###autoload | 252 | ;;;###autoload |
| 253 | (define-derived-mode emacs-lisp-mode prog-mode | 253 | (define-derived-mode emacs-lisp-mode lisp-data-mode |
| 254 | `("ELisp" | 254 | `("ELisp" |
| 255 | (lexical-binding (:propertize "/l" | 255 | (lexical-binding (:propertize "/l" |
| 256 | help-echo "Using lexical-binding mode") | 256 | help-echo "Using lexical-binding mode") |
| @@ -268,35 +268,26 @@ Blank lines separate paragraphs. Semicolons start comments. | |||
| 268 | \\{emacs-lisp-mode-map}" | 268 | \\{emacs-lisp-mode-map}" |
| 269 | :group 'lisp | 269 | :group 'lisp |
| 270 | (defvar project-vc-external-roots-function) | 270 | (defvar project-vc-external-roots-function) |
| 271 | (lisp-mode-variables nil nil 'elisp) | 271 | (setcar font-lock-defaults |
| 272 | '(lisp-el-font-lock-keywords | ||
| 273 | lisp-el-font-lock-keywords-1 | ||
| 274 | lisp-el-font-lock-keywords-2)) | ||
| 275 | (setf (nth 2 font-lock-defaults) nil) | ||
| 272 | (add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers) | 276 | (add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers) |
| 273 | (if (boundp 'electric-pair-text-pairs) | 277 | (if (boundp 'electric-pair-text-pairs) |
| 274 | (setq-local electric-pair-text-pairs | 278 | (setq-local electric-pair-text-pairs |
| 275 | (append '((?\` . ?\') (?\‘ . ?\’)) | 279 | (append '((?\` . ?\') (?\‘ . ?\’)) |
| 276 | electric-pair-text-pairs)) | 280 | electric-pair-text-pairs)) |
| 277 | (add-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-text-pairs)) | 281 | (add-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-text-pairs)) |
| 278 | (setq-local electric-quote-string t) | ||
| 279 | (setq imenu-case-fold-search nil) | ||
| 280 | (add-hook 'eldoc-documentation-functions | 282 | (add-hook 'eldoc-documentation-functions |
| 281 | #'elisp-eldoc-documentation-function nil t) | 283 | #'elisp-eldoc-documentation-function nil t) |
| 282 | (add-hook 'xref-backend-functions #'elisp--xref-backend nil t) | 284 | (add-hook 'xref-backend-functions #'elisp--xref-backend nil t) |
| 283 | (setq-local project-vc-external-roots-function #'elisp-load-path-roots) | 285 | (setq-local project-vc-external-roots-function #'elisp-load-path-roots) |
| 284 | (add-hook 'completion-at-point-functions | 286 | (add-hook 'completion-at-point-functions |
| 285 | #'elisp-completion-at-point nil 'local) | 287 | #'elisp-completion-at-point nil 'local) |
| 286 | ;; .dir-locals.el and lock files will cause the byte-compiler and | 288 | (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t) |
| 287 | ;; checkdoc emit spurious warnings, because they don't follow the | 289 | (add-hook 'flymake-diagnostic-functions |
| 288 | ;; conventions of Emacs Lisp sources. Until we have a better fix, | 290 | #'elisp-flymake-byte-compile nil t)) |
| 289 | ;; like teaching elisp-mode about files that only hold data | ||
| 290 | ;; structures, we disable the ELisp Flymake backend for these files. | ||
| 291 | (unless | ||
| 292 | (let* ((bfname (buffer-file-name)) | ||
| 293 | (fname (and (stringp bfname) (file-name-nondirectory bfname)))) | ||
| 294 | (and (stringp fname) | ||
| 295 | (or (string-match "\\`\\.#" fname) | ||
| 296 | (string-equal dir-locals-file fname)))) | ||
| 297 | (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t) | ||
| 298 | (add-hook 'flymake-diagnostic-functions | ||
| 299 | #'elisp-flymake-byte-compile nil t))) | ||
| 300 | 291 | ||
| 301 | ;; Font-locking support. | 292 | ;; Font-locking support. |
| 302 | 293 | ||
diff --git a/lisp/saveplace.el b/lisp/saveplace.el index fa0e181bb10..f78639db246 100644 --- a/lisp/saveplace.el +++ b/lisp/saveplace.el | |||
| @@ -248,7 +248,7 @@ may have changed) back to `save-place-alist'." | |||
| 248 | (delete-region (point-min) (point-max)) | 248 | (delete-region (point-min) (point-max)) |
| 249 | (when save-place-forget-unreadable-files | 249 | (when save-place-forget-unreadable-files |
| 250 | (save-place-forget-unreadable-files)) | 250 | (save-place-forget-unreadable-files)) |
| 251 | (insert (format ";;; -*- coding: %s -*-\n" | 251 | (insert (format ";;; -*- coding: %s mode: lisp-data -*-\n" |
| 252 | (symbol-name coding-system-for-write))) | 252 | (symbol-name coding-system-for-write))) |
| 253 | (let ((print-length nil) | 253 | (let ((print-length nil) |
| 254 | (print-level nil)) | 254 | (print-level nil)) |