commit 7a21bdce197915d362750e9a73cc27e4968cf109 (HEAD, refs/remotes/origin/master) Author: Ken Raeburn Date: Wed Apr 5 23:16:10 2017 -0400 In CANNOT_DUMP builds, allow editing of files named "dump". * lisp/loadup.el: Perform the "dump" or "bootstrap" actions like calling dump-emacs only if dump-emacs is defined; otherwise, don't treat those command-line argument specially. diff --git a/lisp/loadup.el b/lisp/loadup.el index a3234e1d26..112282740a 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -85,8 +85,9 @@ (message "Using load-path %s" load-path) ;; This is a poor man's `last', since we haven't loaded subr.el yet. -(if (or (equal (member "bootstrap" command-line-args) '("bootstrap")) - (equal (member "dump" command-line-args) '("dump"))) +(if (and (fboundp 'dump-emacs) + (or (equal (member "bootstrap" command-line-args) '("bootstrap")) + (equal (member "dump" command-line-args) '("dump")))) (progn ;; To reduce the size of dumped Emacs, we avoid making huge char-tables. (setq inhibit-load-charset-map t) @@ -345,12 +346,14 @@ lost after dumping"))) ;; in non-ASCII directories is to manipulate unibyte strings in the ;; current locale's encoding. (if (and (member (car (last command-line-args)) '("dump" "bootstrap")) + (fboundp 'dump-emacs) (multibyte-string-p default-directory)) (error "default-directory must be unibyte when dumping Emacs!")) ;; Determine which build number to use ;; based on the executables that now exist. (if (and (equal (last command-line-args) '("dump")) + (fboundp 'dump-emacs) (not (eq system-type 'ms-dos))) (let* ((base (concat "emacs-" emacs-version ".")) (exelen (if (eq system-type 'windows-nt) -4)) @@ -368,7 +371,8 @@ lost after dumping"))) (message "Finding pointers to doc strings...") -(if (equal (last command-line-args) '("dump")) +(if (and (fboundp 'dump-emacs) + (equal (last command-line-args) '("dump"))) (Snarf-documentation "DOC") (condition-case nil (Snarf-documentation "DOC") @@ -437,7 +441,8 @@ lost after dumping"))) ;; Make sure we will attempt bidi reordering henceforth. (setq redisplay--inhibit-bidi nil) -(if (member (car (last command-line-args)) '("dump" "bootstrap")) +(if (and (fboundp 'dump-emacs) + (member (car (last command-line-args)) '("dump" "bootstrap"))) (progn ;; Prevent build-time PATH getting stored in the binary. ;; Mainly cosmetic, but helpful for Guix. (Bug#20330) commit 8ca2bd1ce7eebaf3b995786d9f9f61907ebbb060 Author: Ken Raeburn Date: Wed Apr 5 02:48:49 2017 -0400 In CANNOT_DUMP builds, don't prepare for unexec. Having a command-line argument of "dump" or "bootstrap" would trigger behavior like not installing signal handlers. In CANNOT_DUMP modes, we should get signal handlers installed regardless of whatever funny file names we decide to edit. src/emacs.c (main) [CANNOT_DUMP]: Don't enable the "dumping" alterations to initialization that prepares the process for unexec. diff --git a/src/emacs.c b/src/emacs.c index 2b01a37f5a..9339d60866 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -683,8 +683,12 @@ main (int argc, char **argv) /* Record (approximately) where the stack begins. */ stack_bottom = &stack_bottom_variable; +#ifndef CANNOT_DUMP dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0 || strcmp (argv[argc - 1], "bootstrap") == 0); +#else + dumping = false; +#endif /* True if address randomization interferes with memory allocation. */ # ifdef __PPC64__ commit dd09e72ed6b1c6ba5c584e7aa32d98437d96326a Author: Ken Raeburn Date: Thu Mar 9 01:15:53 2017 -0500 Allow a CANNOT_DUMP build to use exec-path during bootstrap. During a bootstrap, loading rmail.el invokes movemail to determine its flavor, but call-process doesn't work if exec-path is nil. * lisp/loadup.el: Only clear exec-path if dumping. diff --git a/lisp/loadup.el b/lisp/loadup.el index 3d21be3611..a3234e1d26 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -427,12 +427,6 @@ lost after dumping"))) (message "Pure-hashed: %d strings, %d vectors, %d conses, %d bytecodes, %d others" strings vectors conses bytecodes others))) -;; Prevent build-time PATH getting stored in the binary. -;; Mainly cosmetic, but helpful for Guix. (Bug#20330) -;; Do this here, rather than earlier, so that the above code -;; can invoke Git commands and the like. -(setq exec-path nil) - ;; Avoid error if user loads some more libraries now and make sure the ;; hash-consing hash table is GC'd. (setq purify-flag nil) @@ -445,6 +439,11 @@ lost after dumping"))) (if (member (car (last command-line-args)) '("dump" "bootstrap")) (progn + ;; Prevent build-time PATH getting stored in the binary. + ;; Mainly cosmetic, but helpful for Guix. (Bug#20330) + ;; Do this here, rather than earlier, so that the above code + ;; can invoke Git commands and the like. + (setq exec-path nil) (message "Dumping under the name emacs") (condition-case () (delete-file "emacs") commit d15719d36e8fab262e7803d9409326321b890941 Author: Ken Raeburn Date: Wed Mar 8 06:28:45 2017 -0500 Fix CANNOT_DUMP build on Darwin/macOS. * src/conf_post.h (malloc, realloc, free) [DARWIN_OS && emacs && CANNOT_DUMP]: Don't define as unexec_malloc, etc. * src/emacs.c (main): Don't call unexec_init_emacs_zone. diff --git a/src/conf_post.h b/src/conf_post.h index e146b9bbe8..30c948e39a 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -94,7 +94,7 @@ typedef bool bool_bf; #endif #ifdef DARWIN_OS -#ifdef emacs +#if defined emacs && !defined CANNOT_DUMP #define malloc unexec_malloc #define realloc unexec_realloc #define free unexec_free diff --git a/src/emacs.c b/src/emacs.c index 1868961090..2b01a37f5a 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -137,7 +137,7 @@ static bool might_dump; #endif -#ifdef DARWIN_OS +#if defined DARWIN_OS && !defined CANNOT_DUMP extern void unexec_init_emacs_zone (void); #endif @@ -742,7 +742,7 @@ main (int argc, char **argv) #endif /* If using unexmacosx.c (set by s/darwin.h), we must do this. */ -#ifdef DARWIN_OS +#if defined DARWIN_OS && !defined CANNOT_DUMP if (!initialized) unexec_init_emacs_zone (); #endif commit 04a5ce0b65fcc8f49c26b74b30b37322b559a0d5 Author: Tom Tromey Date: Wed Apr 5 15:55:22 2017 -0600 add two more mhtml tests * test/manual/indent/html-multi-2.html: New file. * test/manual/indent/html-multi-3.html: New file. diff --git a/test/manual/indent/html-multi-2.html b/test/manual/indent/html-multi-2.html new file mode 100644 index 0000000000..fac5eb1401 --- /dev/null +++ b/test/manual/indent/html-multi-2.html @@ -0,0 +1,35 @@ + + + + test + + + + + + + + + diff --git a/test/manual/indent/html-multi-3.html b/test/manual/indent/html-multi-3.html new file mode 100644 index 0000000000..62daf1d715 --- /dev/null +++ b/test/manual/indent/html-multi-3.html @@ -0,0 +1,35 @@ + + + + test + + + + + + + + + commit 59409f409d4e20b6657e8c278dba9bf403c5ebd9 Author: Tom Tromey Date: Thu Mar 23 11:34:27 2017 -0600 enable mhtml-mode by default * lisp/files.el (auto-mode-alist): Reference mhtml-mode, not html-mode. (magic-fallback-mode-alist): Likewise. * lisp/net/eww.el (eww-view-source): Use mthml-mode. diff --git a/lisp/files.el b/lisp/files.el index 204c26416a..6848818cad 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2429,7 +2429,7 @@ since only a single case-insensitive search through the alist is made." (lambda (elt) (cons (purecopy (car elt)) (cdr elt))) `(;; do this first, so that .html.pl is Polish html, not Perl - ("\\.[sx]?html?\\(\\.[a-zA-Z_]+\\)?\\'" . html-mode) + ("\\.[sx]?html?\\(\\.[a-zA-Z_]+\\)?\\'" . mhtml-mode) ("\\.svgz?\\'" . image-mode) ("\\.svgz?\\'" . xml-mode) ("\\.x[bp]m\\'" . image-mode) @@ -2791,8 +2791,8 @@ If FUNCTION is nil, then it is not called. (That is a way of saying comment-re "*" "\\(?:!DOCTYPE[ \t\r\n]+[^>]*>[ \t\r\n]*<[ \t\r\n]*" comment-re "*\\)?" "[Hh][Tt][Mm][Ll]")) - . html-mode) - (" Date: Thu Mar 23 11:34:18 2017 -0600 add mhtml-mode.el * etc/NEWS: Update. * lisp/textmodes/mhtml-mode.el: New file. * test/manual/indent/html-multi.html: New file. * test/lisp/textmodes/mhtml-mode-tests.el: New file. * doc/emacs/text.texi (HTML Mode): Mention mhtml-mode. diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index 5f02d0b692..d1e451175e 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -1899,8 +1899,14 @@ between Latin-1 encoded files and @TeX{}-encoded equivalents. @findex html-mode The major modes for SGML and HTML provide indentation support and -commands for operating on tags. HTML mode is a slightly customized -variant of SGML mode. +commands for operating on tags. + + HTML consists of two modes---one, a basic mode called +@code{html-mode} is a slightly customized variant of SGML mode. The +other, which is used by default for HTML files, is called +@code{mhtml-mode}, and attempts to properly handle Javascript enclosed +in a @code{ + +When nil, indentation of the script body starts just below the +tag, like: + + + +When `ignore', the script body starts in the first column, like: + + " + :group 'sgml + :type '(choice (const nil) (const t) (const ignore)) + :safe 'symbolp + :version "26.1") + +(cl-defstruct mhtml--submode + ;; Name of this submode. + name + ;; HTML end tag. + end-tag + ;; Syntax table. + syntax-table + ;; Propertize function. + propertize + ;; Keymap. + keymap + ;; Captured locals that are set when entering a region. + crucial-captured-locals + ;; Other captured local variables; these are not set when entering a + ;; region but let-bound during certain operations, e.g., + ;; indentation. + captured-locals) + +(defconst mhtml--crucial-variable-prefix + (regexp-opt '("comment-" "uncomment-" "electric-indent-" + "smie-" "forward-sexp-function")) + "Regexp matching the prefix of \"crucial\" buffer-locals we want to capture.") + +(defconst mhtml--variable-prefix + (regexp-opt '("font-lock-" "indent-line-function" "major-mode")) + "Regexp matching the prefix of buffer-locals we want to capture.") + +(defun mhtml--construct-submode (mode &rest args) + "A wrapper for make-mhtml--submode that computes the buffer-local variables." + (let ((captured-locals nil) + (crucial-captured-locals nil) + (submode (apply #'make-mhtml--submode args))) + (with-temp-buffer + (funcall mode) + ;; Make sure font lock is all set up. + (font-lock-set-defaults) + ;; This has to be set to a value other than the mthml-mode + ;; value, to avoid recursion. + (unless (variable-binding-locus 'font-lock-fontify-region-function) + (setq-local font-lock-fontify-region-function + #'font-lock-default-fontify-region)) + (dolist (iter (buffer-local-variables)) + (when (string-match mhtml--crucial-variable-prefix + (symbol-name (car iter))) + (push iter crucial-captured-locals)) + (when (string-match mhtml--variable-prefix (symbol-name (car iter))) + (push iter captured-locals))) + (setf (mhtml--submode-crucial-captured-locals submode) + crucial-captured-locals) + (setf (mhtml--submode-captured-locals submode) captured-locals)) + submode)) + +(defun mhtml--mark-buffer-locals (submode) + (dolist (iter (mhtml--submode-captured-locals submode)) + (make-local-variable (car iter)))) + +(defvar-local mhtml--crucial-variables nil + "List of all crucial variable symbols.") + +(defun mhtml--mark-crucial-buffer-locals (submode) + (dolist (iter (mhtml--submode-crucial-captured-locals submode)) + (make-local-variable (car iter)) + (push (car iter) mhtml--crucial-variables))) + +(defconst mhtml--css-submode + (mhtml--construct-submode 'css-mode + :name "CSS" + :end-tag "" + :syntax-table css-mode-syntax-table + :propertize css-syntax-propertize-function + :keymap css-mode-map)) + +(defconst mhtml--js-submode + (mhtml--construct-submode 'js-mode + :name "JS" + :end-tag "" + :syntax-table js-mode-syntax-table + :propertize #'js-syntax-propertize + :keymap js-mode-map)) + +(defmacro mhtml--with-locals (submode &rest body) + (declare (indent 1)) + `(cl-progv + (when ,submode (mapcar #'car (mhtml--submode-captured-locals ,submode))) + (when ,submode (mapcar #'cdr (mhtml--submode-captured-locals ,submode))) + (cl-progv + (when ,submode (mapcar #'car (mhtml--submode-crucial-captured-locals + ,submode))) + (when ,submode (mapcar #'cdr (mhtml--submode-crucial-captured-locals + ,submode))) + ,@body))) + +(defun mhtml--submode-lighter () + "Mode-line lighter indicating the current submode." + (let ((submode (get-text-property (point) 'mhtml-submode))) + (if submode + (mhtml--submode-name submode) + ""))) + +(defvar font-lock-beg) +(defvar font-lock-end) + +(defun mhtml--extend-font-lock-region () + "Extend the font lock region according to HTML sub-mode needs. + +This is used via `font-lock-extend-region-functions'. It ensures +that the font-lock region is extended to cover either whole +lines, or to the spot where the submode changes, whichever is +smallest." + (let ((orig-beg font-lock-beg) + (orig-end font-lock-end)) + ;; The logic here may look odd but it is needed to ensure that we + ;; do the right thing when trying to limit the search. + (save-excursion + (goto-char font-lock-beg) + ;; previous-single-property-change starts by looking at the + ;; previous character, but we're trying to extend a region to + ;; include just characters with the same submode as this + ;; character. + (unless (eobp) + (forward-char)) + (setq font-lock-beg (previous-single-property-change + (point) 'mhtml-submode nil + (line-beginning-position))) + (unless (eq (get-text-property font-lock-beg 'mhtml-submode) + (get-text-property orig-beg 'mhtml-submode)) + (cl-incf font-lock-beg)) + + (goto-char font-lock-end) + (unless (bobp) + (backward-char)) + (setq font-lock-end (next-single-property-change + (point) 'mhtml-submode nil + (line-beginning-position 2))) + (unless (eq (get-text-property font-lock-end 'mhtml-submode) + (get-text-property orig-end 'mhtml-submode)) + (cl-decf font-lock-end))) + + (or (/= font-lock-beg orig-beg) + (/= font-lock-end orig-end)))) + +(defun mhtml--submode-fontify-one-region (submode beg end &optional loudly) + (if submode + (mhtml--with-locals submode + (save-restriction + (font-lock-fontify-region beg end loudly))) + (font-lock-set-defaults) + (font-lock-default-fontify-region beg end loudly))) + +(defun mhtml--submode-fontify-region (beg end loudly) + (syntax-propertize end) + (let ((orig-beg beg) + (orig-end end) + (new-beg beg) + (new-end end)) + (while (< beg end) + (let ((submode (get-text-property beg 'mhtml-submode)) + (this-end (next-single-property-change beg 'mhtml-submode + nil end))) + (let ((extended (mhtml--submode-fontify-one-region submode beg + this-end loudly))) + ;; If the call extended the region, take note. We track the + ;; bounds we were passed and take the union of any extended + ;; bounds. + (when (and (consp extended) + (eq (car extended) 'jit-lock-bounds)) + (setq new-beg (min new-beg (cadr extended))) + ;; Make sure that the next region starts where the + ;; extension of this region ends. + (setq this-end (cddr extended)) + (setq new-end (max new-end this-end)))) + (setq beg this-end))) + (when (or (/= orig-beg new-beg) + (/= orig-end new-end)) + (cons 'jit-lock-bounds (cons new-beg new-end))))) + +(defvar-local mhtml--last-submode nil + "Record the last visited submode, so the cursor-sensor function +can function properly.") + +(defvar-local mhtml--stashed-crucial-variables nil + "Alist of stashed values of the crucial variables.") + +(defun mhtml--stash-crucial-variables () + (setq mhtml--stashed-crucial-variables + (mapcar (lambda (sym) + (cons sym (buffer-local-value sym (current-buffer)))) + mhtml--crucial-variables))) + +(defun mhtml--map-in-crucial-variables (alist) + (dolist (item alist) + (set (car item) (cdr item)))) + +(defun mhtml--pre-command () + (let ((submode (get-text-property (point) 'mhtml-submode))) + (unless (eq submode mhtml--last-submode) + ;; If we're entering a submode, and the previous submode was + ;; nil, then stash the current values first. This lets the user + ;; at least modify some values directly. FIXME maybe always + ;; stash into the current mode? + (when (and submode (not mhtml--last-submode)) + (mhtml--stash-crucial-variables)) + (mhtml--map-in-crucial-variables + (if submode + (mhtml--submode-crucial-captured-locals submode) + mhtml--stashed-crucial-variables)) + (setq mhtml--last-submode submode)))) + +(defun mhtml--syntax-propertize-submode (submode end) + (save-excursion + (when (search-forward (mhtml--submode-end-tag submode) end t) + (setq end (match-beginning 0)))) + (set-text-properties (point) end + (list 'mhtml-submode submode + 'syntax-table (mhtml--submode-syntax-table submode) + ;; We want local-map here so that we act + ;; more like the sub-mode and don't + ;; override minor mode maps. + 'local-map (mhtml--submode-keymap submode))) + (funcall (mhtml--submode-propertize submode) (point) end) + (goto-char end)) + +(defun mhtml-syntax-propertize (start end) + ;; First remove our special settings from the affected text. They + ;; will be re-applied as needed. + (remove-list-of-text-properties start end + '(syntax-table local-map mhtml-submode)) + (goto-char start) + (when (and + ;; Don't search in a comment or string + (not (syntax-ppss-context (syntax-ppss))) + ;; Be sure to look back one character, because START won't + ;; yet have been propertized. + (not (bobp))) + (when-let ((submode (get-text-property (1- (point)) 'mhtml-submode))) + (mhtml--syntax-propertize-submode submode end))) + (funcall + (syntax-propertize-rules + ("" + (0 (ignore + (goto-char (match-end 0)) + ;; Don't apply in a comment. + (unless (syntax-ppss-context (syntax-ppss)) + (mhtml--syntax-propertize-submode mhtml--css-submode end))))) + ("" + (0 (ignore + (goto-char (match-end 0)) + ;; Don't apply in a comment. + (unless (syntax-ppss-context (syntax-ppss)) + (mhtml--syntax-propertize-submode mhtml--js-submode end))))) + sgml-syntax-propertize-rules) + ;; Make sure to handle the situation where + ;; mhtml--syntax-propertize-submode moved point. + (point) end)) + +(defun mhtml-indent-line () + "Indent the current line as HTML, JS, or CSS, according to its context." + (interactive) + (let ((submode (save-excursion + (back-to-indentation) + (get-text-property (point) 'mhtml-submode)))) + (if submode + (save-restriction + (let* ((region-start + (or (previous-single-property-change (point) 'mhtml-submode) + (point))) + (base-indent (save-excursion + (goto-char region-start) + (sgml-calculate-indent)))) + (cond + ((eq mhtml-tag-relative-indent nil) + (setq base-indent (- base-indent sgml-basic-offset))) + ((eq mhtml-tag-relative-indent 'ignore) + (setq base-indent 0))) + (narrow-to-region region-start (point-max)) + (let ((prog-indentation-context (list base-indent + (cons (point-min) nil) + nil))) + (mhtml--with-locals submode + ;; indent-line-function was rebound by + ;; mhtml--with-locals. + (funcall indent-line-function))))) + ;; HTML. + (sgml-indent-line)))) + +(defun mhtml--flyspell-check-word () + (let ((submode (get-text-property (point) 'mhtml-submode))) + (if submode + (flyspell-generic-progmode-verify) + t))) + +;;;###autoload +(define-derived-mode mhtml-mode html-mode + '((sgml-xml-mode "XHTML+" "HTML+") (:eval (mhtml--submode-lighter))) + "Major mode based on `html-mode', but works with embedded JS and CSS. + +Code inside a + + + + commit d392b6e82460d94b11627998da87e33880664060 Author: Tom Tromey Date: Thu Mar 23 11:33:47 2017 -0600 change sgml-mode to help multi-html mode * lisp/textmodes/sgml-mode.el (sgml-syntax-propertize-rules): New defconst. (sgml-syntax-propertize): Use it. (sgml--find-<>-backward): New function. (sgml-parse-tag-backward): Use it. diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 97a1144398..a6965fa32d 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -341,26 +341,30 @@ Any terminating `>' or `/' is not matched.") (defvar sgml-font-lock-keywords sgml-font-lock-keywords-1 "Rules for highlighting SGML code. See also `sgml-tag-face-alist'.") +(eval-and-compile + (defconst sgml-syntax-propertize-rules + (syntax-propertize-precompile-rules + ;; Use the `b' style of comments to avoid interference with the -- ... -- + ;; comments recognized when `sgml-specials' includes ?-. + ;; FIXME: beware of blabla !! + ("\\(<\\)!--" (1 "< b")) + ("--[ \t\n]*\\(>\\)" (1 "> b")) + ("\\(<\\)[?!]" (1 (prog1 "|>" + (sgml-syntax-propertize-inside end)))) + ;; Double quotes outside of tags should not introduce strings. + ;; Be careful to call `syntax-ppss' on a position before the one we're + ;; going to change, so as not to need to flush the data we just computed. + ("\"" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) + (goto-char (match-end 0))) + (string-to-syntax "."))))))) + (defun sgml-syntax-propertize (start end) "Syntactic keywords for `sgml-mode'." (goto-char start) (sgml-syntax-propertize-inside end) (funcall - (syntax-propertize-rules - ;; Use the `b' style of comments to avoid interference with the -- ... -- - ;; comments recognized when `sgml-specials' includes ?-. - ;; FIXME: beware of blabla !! - ("\\(<\\)!--" (1 "< b")) - ("--[ \t\n]*\\(>\\)" (1 "> b")) - ("\\(<\\)[?!]" (1 (prog1 "|>" - (sgml-syntax-propertize-inside end)))) - ;; Double quotes outside of tags should not introduce strings. - ;; Be careful to call `syntax-ppss' on a position before the one we're - ;; going to change, so as not to need to flush the data we just computed. - ("\"" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) - (goto-char (match-end 0))) - (string-to-syntax "."))))) - start end)) + (syntax-propertize-rules sgml-syntax-propertize-rules) + start end)) (defun sgml-syntax-propertize-inside (end) (let ((ppss (syntax-ppss))) @@ -1304,13 +1308,24 @@ really isn't a tag after all." (let ((pps (parse-partial-sexp start end 2))) (and (= (nth 0 pps) 0)))))) +(defun sgml--find-<>-backward (limit) + "Search backward for a '<' or '>' character. +The character must have open or close syntax. +Returns t if found, nil otherwise." + (catch 'found + (while (re-search-backward "[<>]" limit 'move) + ;; If this character has "open" or "close" syntax, then we've + ;; found the one we want. + (when (memq (syntax-class (syntax-after (point))) '(4 5)) + (throw 'found t))))) + (defun sgml-parse-tag-backward (&optional limit) "Parse an SGML tag backward, and return information about the tag. Assume that parsing starts from within a textual context. Leave point at the beginning of the tag." (catch 'found (let (tag-type tag-start tag-end name) - (or (re-search-backward "[<>]" limit 'move) + (or (sgml--find-<>-backward limit) (error "No tag found")) (when (eq (char-after) ?<) ;; Oops!! Looks like we were not in a textual context after all!. commit 5331ef8a1861c95fd634bf90c8c3ea624286820d Author: Tom Tromey Date: Thu Mar 23 11:33:22 2017 -0600 make js.el respect prog-first-column * lisp/progmodes/js.el (js--proper-indentation): Call prog-first-column. diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 3c720c0561..c220353e9b 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -53,6 +53,7 @@ (require 'moz nil t) (require 'json nil t) (require 'sgml-mode) +(require 'prog-mode) (eval-when-compile (require 'cl-lib) @@ -2125,7 +2126,7 @@ indentation is aligned to that column." ((js--continued-expression-p) (+ js-indent-level js-expr-indent-offset)) - (t 0)))) + (t (prog-first-column))))) ;;; JSX Indentation commit 473a42010c5b37e30d9bfb81cae77de6a95073eb Author: Tom Tromey Date: Thu Mar 23 11:32:59 2017 -0600 make smie.el respect prog-first-column * lisp/emacs-lisp/smie.el (smie-indent-bob): Call prog-first-column. diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index 4d02b751af..7baccbc752 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -123,6 +123,8 @@ (eval-when-compile (require 'cl-lib)) +(require 'prog-mode) + (defgroup smie nil "Simple Minded Indentation Engine." :group 'languages) @@ -1455,7 +1457,7 @@ in order to figure out the indentation of some other (further down) point." ;; Start the file at column 0. (save-excursion (forward-comment (- (point))) - (if (bobp) 0))) + (if (bobp) (prog-first-column)))) (defun smie-indent-close () ;; Align close paren with opening paren. commit 14659f69b0330187c7390418a0c7366083de9fd7 Author: Tom Tromey Date: Sun Mar 19 10:52:28 2017 -0600 change viper to use derived-mode-p * lisp/subr.el (provided-mode-derived-p): New function. (derived-mode-p): Use it. * lisp/emulation/viper.el (viper-mode): Use derived-mode-p. (this-major-mode-requires-vi-state): Use provided-mode-derived-p. (set-viper-state-in-major-mode): Use derived-mode-p. diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index b03af9b083..81acedbc16 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el @@ -592,8 +592,10 @@ This startup message appears whenever you load Viper, unless you type `y' now." )) (viper-set-expert-level 'dont-change-unless))) - (or (memq major-mode viper-emacs-state-mode-list) ; don't switch to Vi - (memq major-mode viper-insert-state-mode-list) ; don't switch + (or (cl-member-if #'derived-mode-p + viper-emacs-state-mode-list) ; don't switch to Vi + (cl-member-if #'derived-mode-p + viper-insert-state-mode-list) ; don't switch (viper-change-state-to-vi)) )) @@ -605,11 +607,15 @@ This startup message appears whenever you load Viper, unless you type `y' now." ;; Apply a little heuristic to invoke vi state on major-modes ;; that are not listed in viper-vi-state-mode-list (defun this-major-mode-requires-vi-state (mode) - (cond ((memq mode viper-vi-state-mode-list) t) - ((memq mode viper-emacs-state-mode-list) nil) - ((memq mode viper-insert-state-mode-list) nil) - (t (and (eq (key-binding "a") 'self-insert-command) - (eq (key-binding " ") 'self-insert-command))))) + (let ((check (lambda (one-mode) + (provided-mode-derived-p mode one-mode)))) + (cond ((cl-member-if check viper-vi-state-mode-list) t) + ((cl-member-if check viper-emacs-state-mode-list) + nil) + ((cl-member-if check viper-insert-state-mode-list) + nil) + (t (and (eq (key-binding "a") 'self-insert-command) + (eq (key-binding " ") 'self-insert-command)))))) ;; This hook designed to enable Vi-style editing in comint-based modes." @@ -802,13 +808,14 @@ It also can't undo some Viper settings." (cond ((and (this-major-mode-requires-vi-state major-mode) (eq viper-current-state 'emacs-state)) (viper-mode)) - ((memq major-mode viper-emacs-state-mode-list) + ((cl-member-if #'derived-mode-p viper-emacs-state-mode-list) ;; not checking (eq viper-current-state 'emacs-state) ;; because viper-current-state could have gotten it by ;; default. We need viper-change-state-to-emacs here to have ;; the keymaps take effect. (viper-change-state-to-emacs)) - ((and (memq major-mode viper-insert-state-mode-list) + ((and (cl-member-if #'derived-mode-p + viper-insert-state-mode-list) (not (eq viper-current-state 'insert-state))) (viper-change-state-to-insert)) )) ; with-current-buffer diff --git a/lisp/subr.el b/lisp/subr.el index 6b0403890c..13567d8753 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1872,13 +1872,18 @@ Only affects hooks run in the current buffer." ;; PUBLIC: find if the current mode derives from another. +(defun provided-mode-derived-p (mode &rest modes) + "Non-nil if MODE is derived from one of MODES. +Uses the `derived-mode-parent' property of the symbol to trace backwards. +If you just want to check `major-mode', use `derived-mode-p'." + (while (and (not (memq mode modes)) + (setq mode (get mode 'derived-mode-parent)))) + mode) + (defun derived-mode-p (&rest modes) "Non-nil if the current major mode is derived from one of MODES. Uses the `derived-mode-parent' property of the symbol to trace backwards." - (let ((parent major-mode)) - (while (and (not (memq parent modes)) - (setq parent (get parent 'derived-mode-parent)))) - parent)) + (apply #'provided-mode-derived-p major-mode modes)) ;;;; Minor modes. commit 95aba610f1c1a40b0218b64b4d20ade7a6299208 Author: Tom Tromey Date: Sat Mar 18 23:06:05 2017 +0100 change align to use derived-mode-p * lisp/align.el (align-region): Use derived-mode-p. diff --git a/lisp/align.el b/lisp/align.el index b6a855b495..000b63ed78 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -1322,7 +1322,7 @@ aligner would have dealt with are." (modes (assq 'modes rule))) ;; unless the `run-if' form tells us not to, look for the ;; rule.. - (unless (or (and modes (not (memq major-mode + (unless (or (and modes (not (cl-member-if #'derived-mode-p (eval (cdr modes))))) (and run-if (not (funcall (cdr run-if))))) (let* ((case-fold-search case-fold-search) commit c92bae9a08cc7c2eb61bad32d9a9d6553b6d2c19 Author: Tom Tromey Date: Sat Mar 18 23:03:15 2017 +0100 change org to use derived-mode-p * lisp/org/org-list.el (org-list-insert-radio-list): Use derived-mode-p. * lisp/org/org-table.el (orgtbl-setup, orgtbl-toggle-comment): Use derived-mode-p. diff --git a/lisp/org/org-list.el b/lisp/org/org-list.el index 4a45fd9817..a24c496d72 100644 --- a/lisp/org/org-list.el +++ b/lisp/org/org-list.el @@ -3035,7 +3035,7 @@ Point is left at list end." (defun org-list-insert-radio-list () "Insert a radio list template appropriate for this major mode." (interactive) - (let* ((e (assq major-mode org-list-radio-list-templates)) + (let* ((e (cl-assoc-if #'derived-mode-p org-list-radio-list-templates)) (txt (nth 1 e)) name pos) (unless e (error "No radio list setup defined for %s" major-mode)) diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 08bbf3277b..0c813d03a1 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -4269,7 +4269,7 @@ to execute outside of tables." "--" ("Radio tables" ["Insert table template" orgtbl-insert-radio-table - (assq major-mode orgtbl-radio-table-templates)] + (cl-assoc-if #'derived-mode-p orgtbl-radio-table-templates)] ["Comment/uncomment table" orgtbl-toggle-comment t]) "--" ["Set Column Formula" org-table-eval-formula :active (org-at-table-p) :keys "C-c ="] @@ -4549,7 +4549,7 @@ First element has index 0, or I0 if given." (defun orgtbl-insert-radio-table () "Insert a radio table template appropriate for this major mode." (interactive) - (let* ((e (assq major-mode orgtbl-radio-table-templates)) + (let* ((e (cl-assoc-if #'derived-mode-p orgtbl-radio-table-templates)) (txt (nth 1 e)) name pos) (unless e (user-error "No radio table setup defined for %s" major-mode)) commit d056b1faea69ccd61be4c00259e34de741b9a39e Author: Tom Tromey Date: Sat Mar 18 23:01:16 2017 +0100 change semantic to use derived-mode-p * lisp/cedet/semantic.el (semantic-new-buffer-fcn): Use derived-mode-p. diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el index bf5bfa89ca..a3c03dc460 100644 --- a/lisp/cedet/semantic.el +++ b/lisp/cedet/semantic.el @@ -329,7 +329,7 @@ If the major mode is ready for Semantic, and no to use Semantic, and `semantic-init-hook' is run." ;; In upstream Semantic, the parser setup functions are called from ;; mode hooks. In the version bundled with Emacs, we do it here. - (let ((entry (assq major-mode semantic-new-buffer-setup-functions))) + (let ((entry (cl-assoc-if #'derived-mode-p semantic-new-buffer-setup-functions))) (when entry (funcall (cdr entry)))) ;; Do stuff if semantic was activated by a mode hook in this buffer, commit 089b159287e6615246500bcb63fb33a97526bcf3 Author: Tom Tromey Date: Sat Mar 18 23:00:13 2017 +0100 change calc to use derived-mode-p * lisp/calc/calc-embed.el (calc-embedded-find-modes) (calc-embedded-make-info): Use derived-mode-p. diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el index bb37d7f9c9..bd5601b729 100644 --- a/lisp/calc/calc-embed.el +++ b/lisp/calc/calc-embed.el @@ -804,7 +804,7 @@ The command \\[yank] can retrieve it from there." (backward-char 6)) (goto-char save-pt) (unless (assq 'the-language modes) - (let ((lang (assoc major-mode calc-language-alist))) + (let ((lang (cl-assoc-if #'derived-mode-p calc-language-alist))) (if lang (setq modes (cons (cons 'the-language (cdr lang)) modes))))) @@ -829,13 +829,19 @@ The command \\[yank] can retrieve it from there." (setq found (list (current-buffer)) calc-embedded-active (cons found calc-embedded-active) calc-embedded-firsttime-buf t) - (let ((newann (assoc major-mode calc-embedded-announce-formula-alist)) - (newform (assoc major-mode calc-embedded-open-close-formula-alist)) - (newword (assoc major-mode calc-embedded-word-regexp-alist)) - (newplain (assoc major-mode calc-embedded-open-close-plain-alist)) + (let ((newann (cl-assoc-if #'derived-mode-p + calc-embedded-announce-formula-alist)) + (newform (cl-assoc-if #'derived-mode-p + calc-embedded-open-close-formula-alist)) + (newword (cl-assoc-if #'derived-mode-p + calc-embedded-word-regexp-alist)) + (newplain (cl-assoc-if #'derived-mode-p + calc-embedded-open-close-plain-alist)) (newnewform - (assoc major-mode calc-embedded-open-close-new-formula-alist)) - (newmode (assoc major-mode calc-embedded-open-close-mode-alist))) + (cl-assoc-if #'derived-mode-p + calc-embedded-open-close-new-formula-alist)) + (newmode (cl-assoc-if #'derived-mode-p + calc-embedded-open-close-mode-alist))) (when newann (make-local-variable 'calc-embedded-announce-formula) (setq calc-embedded-announce-formula (cdr newann))) commit a2a38790ee2db283a8b9d0b3f3ccc3b7860428a1 Author: Tom Tromey Date: Sat Mar 18 22:53:56 2017 +0100 change auto-insert to use derived-mode-p * lisp/autoinsert.el (auto-insert): Use derived-mode-p. diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el index 2ca557c52b..fef42161bf 100644 --- a/lisp/autoinsert.el +++ b/lisp/autoinsert.el @@ -348,7 +348,7 @@ Matches the visited file name against the elements of `auto-insert-alist'." (setq desc (cdr cond) cond (car cond))) (if (if (symbolp cond) - (eq cond major-mode) + (derived-mode-p cond) (and buffer-file-name (string-match cond buffer-file-name))) (setq action (cdr (car alist)) commit 0074ed536b560e60f63aead2ac73ec004d0bcfa2 Author: Paul Eggert Date: Wed Apr 5 09:43:14 2017 -0700 * lisp/info.el (Info-search): Fix typo in April 1 change. diff --git a/lisp/info.el b/lisp/info.el index 81e5d29f82..92e7c24ab1 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -2008,7 +2008,7 @@ If DIRECTION is `backward', search in the reverse direction." (unless (if backward (re-search-backward regexp nil t) (re-search-forward regexp nil t)) - (signal 'user-seach-failed (list regexp)))))) + (signal 'user-search-failed (list regexp)))))) (if (and bound (not found)) (signal 'user-search-failed (list regexp)))