]> git.eshelyaron.com Git - emacs.git/commitdiff
Add lisp-data-mode for editing non-code Lisp data
authorJoão Távora <joaotavora@gmail.com>
Sat, 18 Apr 2020 01:46:04 +0000 (02:46 +0100)
committerJoão Távora <joaotavora@gmail.com>
Fri, 1 May 2020 11:11:10 +0000 (12:11 +0100)
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.

doc/lispref/modes.texi
etc/NEWS
lisp/bookmark.el
lisp/emacs-lisp/lisp-mode.el
lisp/files.el
lisp/net/eww.el
lisp/net/nsm.el
lisp/net/tramp-cache.el
lisp/progmodes/elisp-mode.el
lisp/saveplace.el

index fc68ee1b3227585d1d86dc492ec4c70ade89e2cf..eaee56f0a32c7646a6ee71ce542d153b5e5c7e21 100644 (file)
@@ -1352,19 +1352,11 @@ illustrate how these modes are written.
 @end smallexample
 
   The three modes for Lisp share much of their code.  For instance,
-each calls the following function to set various variables:
-
-@smallexample
-@group
-(defun lisp-mode-variables (&optional syntax keywords-case-insensitive elisp)
-  (when syntax
-    (set-syntax-table lisp-mode-syntax-table))
-  @dots{}
-@end group
-@end smallexample
+Lisp mode and Emacs Lisp mode inherit from Lisp Data mode and Lisp
+Interaction Mode inherits from Emacs Lisp mode.
 
 @noindent
-Amongst other things, this function sets up the @code{comment-start}
+Amongst other things, Lisp Data mode sets up the @code{comment-start}
 variable to handle Lisp comments:
 
 @smallexample
@@ -1414,7 +1406,7 @@ Finally, here is the major mode command for Lisp mode:
 
 @smallexample
 @group
-(define-derived-mode lisp-mode prog-mode "Lisp"
+(define-derived-mode lisp-mode lisp-data-mode "Lisp"
   "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
 Commands:
 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
 or to switch back to an existing one."
 @end group
 @group
-  (lisp-mode-variables nil t)
   (setq-local find-tag-default-function 'lisp-find-tag-default)
   (setq-local comment-start-skip
               "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *")
index c4911726a85d5a4cd0dcbdc6bfa1f4cc09936d9d..8fc2311159028071696aa9b729b9b6c3348d029a 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -291,6 +291,12 @@ These new navigation commands are bound to 'n' and 'p' in
 \f
 * New Modes and Packages in Emacs 28.1
 
+*** Lisp Data mode
+The new command 'lisp-data-mode' enables a major mode for buffers
+composed of Lisp symbolic expressions that do not form a computer
+program.  The '.dir-locals.el' file is automatically set to use this
+mode, as are other data files produced by Emacs.
+
 \f
 * Incompatible Editing Changes in Emacs 28.1
 
index 720ad18c16f91d87e2852b65e2c8a288cb9ac856..f2384973e9ce5026d8592a5991bc41dda5b4422f 100644 (file)
@@ -734,8 +734,10 @@ CODING is the symbol of the coding-system in which the file is encoded."
   (if (memq (coding-system-base coding) '(undecided prefer-utf-8))
       (setq coding 'utf-8-emacs))
   (insert
-   (format ";;;; Emacs Bookmark Format Version %d ;;;; -*- coding: %S -*-\n"
-           bookmark-file-format-version (coding-system-base coding)))
+   (format
+    ";;;; Emacs Bookmark Format Version %d\
+;;;; -*- coding: %S mode: lisp-data -*-\n"
+    bookmark-file-format-version (coding-system-base coding)))
   (insert ";;; This format is meant to be slightly human-readable;\n"
           ";;; nevertheless, you probably don't want to edit it.\n"
           ";;; "
index 98c44161ad049eb3c4032570bd55c0c5eb3130e4..7098a41f274052c6648d55324f227cbf55ffd924 100644 (file)
@@ -611,6 +611,8 @@ Value for `adaptive-fill-function'."
   ;; a single docstring.  Let's fix it here.
   (if (looking-at "\\s-+\"[^\n\"]+\"\\s-*$") ""))
 
+;; Maybe this should be discouraged/obsoleted and users should be
+;; encouraged to use `lisp-data-mode` instead.
 (defun lisp-mode-variables (&optional lisp-syntax keywords-case-insensitive
                                       elisp)
   "Common initialization routine for lisp modes.
@@ -658,6 +660,14 @@ font-lock keywords will not be case sensitive."
   (setq-local electric-pair-skip-whitespace 'chomp)
   (setq-local electric-pair-open-newline-between-pairs nil))
 
+;;;###autoload
+(define-derived-mode lisp-data-mode prog-mode "Lisp-Data"
+  "Major mode for buffers holding data written in Lisp syntax."
+  :group 'lisp
+  (lisp-mode-variables t t nil)
+  (setq-local electric-quote-string t)
+  (setq imenu-case-fold-search nil))
+
 (defun lisp-outline-level ()
   "Lisp mode `outline-level' function."
   (let ((len (- (match-end 0) (match-beginning 0))))
@@ -737,7 +747,7 @@ font-lock keywords will not be case sensitive."
   "Keymap for ordinary Lisp mode.
 All commands in `lisp-mode-shared-map' are inherited by this map.")
 
-(define-derived-mode lisp-mode prog-mode "Lisp"
+(define-derived-mode lisp-mode lisp-data-mode "Lisp"
   "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
 Commands:
 Delete converts tabs to spaces as it moves back.
@@ -746,7 +756,6 @@ Blank lines separate paragraphs.  Semicolons start comments.
 \\{lisp-mode-map}
 Note that `run-lisp' may be used either to start an inferior Lisp job
 or to switch back to an existing one."
-  (lisp-mode-variables nil t)
   (setq-local lisp-indent-function 'common-lisp-indent-function)
   (setq-local find-tag-default-function 'lisp-find-tag-default)
   (setq-local comment-start-skip
index fa72e51c4977dc7b9b32274e0c42b3a3f5be9e6c..56d4679ad7dc7c41677ae594575ac4f95ca890db 100644 (file)
@@ -2657,6 +2657,13 @@ since only a single case-insensitive search through the alist is made."
      ("\\.ltx\\'" . latex-mode)
      ("\\.dtx\\'" . doctex-mode)
      ("\\.org\\'" . org-mode)
+     ;; .dir-locals.el is not really elisp.  Could use the
+     ;; `dir-locals-file' constant if it weren't defined below.
+     ("\\.dir-locals\\(-2\\)?\\.el\\'" . lisp-data-mode)
+     ("eww-bookmarks\\'" . lisp-data-mode)
+     ("tramp\\'" . lisp-data-mode)
+     ("places\\'" . lisp-data-mode)
+     ("\\.emacs-places\\'" . lisp-data-mode)
      ("\\.el\\'" . emacs-lisp-mode)
      ("Project\\.ede\\'" . emacs-lisp-mode)
      ("\\.\\(scm\\|stk\\|ss\\|sch\\)\\'" . scheme-mode)
index c83884fd2593f4369c491c9b60d2393a125f5fe7..a4544023f61e768736045df16674f0224df3dfe4 100644 (file)
@@ -1733,7 +1733,7 @@ If CHARSET is nil then use UTF-8."
 
 (defun eww-write-bookmarks ()
   (with-temp-file (expand-file-name "eww-bookmarks" eww-bookmarks-directory)
-    (insert ";; Auto-generated file; don't edit\n")
+    (insert ";; Auto-generated file; don't edit -*- mode: lisp-data -*-\n")
     (pp eww-bookmarks (current-buffer))))
 
 (defun eww-read-bookmarks ()
index 2d36c5e2571292a5362d05bdf4911694a5a1721c..cc22427e6d1ff55520c0564af2ba41ce65995a46 100644 (file)
@@ -964,6 +964,7 @@ protocol."
 
 (defun nsm-write-settings ()
   (with-temp-file nsm-settings-file
+    (insert ";;;; -*- mode: lisp-data -*-\n")
     (insert "(\n")
     (dolist (setting nsm-permanent-host-settings)
       (insert " ")
index 09e30f000f461336b51219510c96d4a67f81e609..6d87ce297bc4d0c14d2aef7f3efc5fa6f83bc530 100644 (file)
@@ -472,7 +472,7 @@ used to cache connection properties of the local machine."
        ;; Dump it.
        (with-temp-file tramp-persistency-file-name
          (insert
-          ";; -*- emacs-lisp -*-"
+          ";; -*- lisp-data -*-"
           ;; `time-stamp-string' might not exist in all Emacs flavors.
           (condition-case nil
               (progn
index f85fd771ca80f27453500aa3db133cbd680d5931..b737134f90c5451109e9f8c47718bdc81504b03c 100644 (file)
@@ -250,7 +250,7 @@ Comments in the form will be lost."
     map))
 
 ;;;###autoload
-(define-derived-mode emacs-lisp-mode prog-mode
+(define-derived-mode emacs-lisp-mode lisp-data-mode
   `("ELisp"
     (lexical-binding (:propertize "/l"
                       help-echo "Using lexical-binding mode")
@@ -268,35 +268,26 @@ Blank lines separate paragraphs.  Semicolons start comments.
 \\{emacs-lisp-mode-map}"
   :group 'lisp
   (defvar project-vc-external-roots-function)
-  (lisp-mode-variables nil nil 'elisp)
+  (setcar font-lock-defaults
+          '(lisp-el-font-lock-keywords
+            lisp-el-font-lock-keywords-1
+            lisp-el-font-lock-keywords-2))
+  (setf (nth 2 font-lock-defaults) nil)
   (add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers)
   (if (boundp 'electric-pair-text-pairs)
       (setq-local electric-pair-text-pairs
                   (append '((?\` . ?\') (?\‘ . ?\’))
                           electric-pair-text-pairs))
     (add-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-text-pairs))
-  (setq-local electric-quote-string t)
-  (setq imenu-case-fold-search nil)
   (add-hook 'eldoc-documentation-functions
             #'elisp-eldoc-documentation-function nil t)
   (add-hook 'xref-backend-functions #'elisp--xref-backend nil t)
   (setq-local project-vc-external-roots-function #'elisp-load-path-roots)
   (add-hook 'completion-at-point-functions
             #'elisp-completion-at-point nil 'local)
-  ;; .dir-locals.el and lock files will cause the byte-compiler and
-  ;; checkdoc emit spurious warnings, because they don't follow the
-  ;; conventions of Emacs Lisp sources.  Until we have a better fix,
-  ;; like teaching elisp-mode about files that only hold data
-  ;; structures, we disable the ELisp Flymake backend for these files.
-  (unless
-      (let* ((bfname (buffer-file-name))
-             (fname (and (stringp bfname) (file-name-nondirectory bfname))))
-        (and (stringp fname)
-             (or (string-match "\\`\\.#" fname)
-                 (string-equal dir-locals-file fname))))
-    (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
-    (add-hook 'flymake-diagnostic-functions
-              #'elisp-flymake-byte-compile nil t)))
+  (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
+  (add-hook 'flymake-diagnostic-functions
+              #'elisp-flymake-byte-compile nil t))
 
 ;; Font-locking support.
 
index fa0e181bb101750fc1dafa4ceda17775f93b595f..f78639db246d9e25bc022b21e2b2dfc9fd44b100 100644 (file)
@@ -248,7 +248,7 @@ may have changed) back to `save-place-alist'."
       (delete-region (point-min) (point-max))
       (when save-place-forget-unreadable-files
        (save-place-forget-unreadable-files))
-      (insert (format ";;; -*- coding: %s -*-\n"
+      (insert (format ";;; -*- coding: %s mode: lisp-data -*-\n"
                       (symbol-name coding-system-for-write)))
       (let ((print-length nil)
             (print-level nil))