Commit 5fe9375a authored by Glenn Morris's avatar Glenn Morris

Merge from origin/emacs-26

02bee786 Let dir locals for more specific modes override those from less
b1235f9a Improve documentation of Hexl mode
32d18132 Fix description of (move-to-column <n> t) when column <n> is ...
0397b7c7 ; Fix smtpmail-stream-type docstring
7dab3ee7 Recognize single quote attribute values in nxml and sgml (Bug...
e4cde426 Disable extra display of &#10; in nxml-mode (Bug#32897)
ca14dd1d Fix nxml-get-inside (Bug#32003)
e7ab351c Fix positioning client buffer as instructed by emacsclient

# Conflicts:
#	lisp/files.el
#	lisp/textmodes/sgml-mode.el
parents 0f63e176 02bee786
...@@ -1377,6 +1377,28 @@ be applied in the current directory, not in any subdirectories. ...@@ -1377,6 +1377,28 @@ be applied in the current directory, not in any subdirectories.
Finally, it specifies a different @file{ChangeLog} file name for any Finally, it specifies a different @file{ChangeLog} file name for any
file in the @file{src/imported} subdirectory. file in the @file{src/imported} subdirectory.
If the @file{.dir-locals.el} file contains multiple different values
for a variable using different mode names or directories, the values
will be applied in an order such that the values for more specific
modes take priority over more generic modes. Values specified under a
directory have even more priority. For example:
@example
((nil . ((fill-column . 40)))
(c-mode . ((fill-column . 50)))
(prog-mode . ((fill-column . 60)))
("narrow-files" . ((nil . ((fill-column . 20))))))
@end example
Files that use @code{c-mode} also match @code{prog-mode} because the
former inherits from the latter. The value used for
@code{fill-column} in C files will however be @code{50} because the
mode name is more specific than @code{prog-mode}. Files using other
modes inheriting from @code{prog-mode} will use @code{60}. Any file
under the directory @file{narrow-files} will use the value @code{20}
even if they use @code{c-mode} because directory entries have priority
over mode entries.
You can specify the variables @code{mode}, @code{eval}, and You can specify the variables @code{mode}, @code{eval}, and
@code{unibyte} in your @file{.dir-locals.el}, and they have the same @code{unibyte} in your @file{.dir-locals.el}, and they have the same
meanings as they would have in file local variables. @code{coding} meanings as they would have in file local variables. @code{coding}
......
...@@ -2485,10 +2485,13 @@ automatically back to binary. ...@@ -2485,10 +2485,13 @@ automatically back to binary.
into hex. This is useful if you visit a file normally and then discover into hex. This is useful if you visit a file normally and then discover
it is a binary file. it is a binary file.
Ordinary text characters overwrite in Hexl mode. This is to reduce Inserting text always overwrites in Hexl mode. This is to reduce
the risk of accidentally spoiling the alignment of data in the file. the risk of accidentally spoiling the alignment of data in the file.
There are special commands for insertion. Here is a list of the Ordinary text characters insert themselves (i.e., overwrite with
commands of Hexl mode: themselves). There are commands for insertion of special characters
by their code. Most cursor motion keys, as well as @kbd{C-x C-s}, are
bound in Hexl mode to commands that produce the same effect. Here is
a list of other important commands special to Hexl mode:
@c I don't think individual index entries for these commands are useful--RMS. @c I don't think individual index entries for these commands are useful--RMS.
@table @kbd @table @kbd
...@@ -2501,6 +2504,12 @@ Insert a byte with a code typed in octal. ...@@ -2501,6 +2504,12 @@ Insert a byte with a code typed in octal.
@item C-M-x @item C-M-x
Insert a byte with a code typed in hex. Insert a byte with a code typed in hex.
@item C-M-a
Move to the beginning of a 512-byte page.
@item C-M-e
Move to the end of a 512-byte page.
@item C-x [ @item C-x [
Move to the beginning of a 1k-byte page. Move to the beginning of a 1k-byte page.
......
...@@ -2252,9 +2252,11 @@ If it is impossible to move to column @var{column} because that is in ...@@ -2252,9 +2252,11 @@ If it is impossible to move to column @var{column} because that is in
the middle of a multicolumn character such as a tab, point moves to the the middle of a multicolumn character such as a tab, point moves to the
end of that character. However, if @var{force} is non-@code{nil}, and end of that character. However, if @var{force} is non-@code{nil}, and
@var{column} is in the middle of a tab, then @code{move-to-column} @var{column} is in the middle of a tab, then @code{move-to-column}
converts the tab into spaces so that it can move precisely to column either converts the tab into spaces (when @code{indent-tabs-mode} is
@var{column}. Other multicolumn characters can cause anomalies despite @code{nil}), or inserts enough spaces before it (otherwise), so that
@var{force}, since there is no way to split them. point can move precisely to column @var{column}. Other multicolumn
characters can cause anomalies despite @var{force}, since there is no
way to split them.
The argument @var{force} also has an effect if the line isn't long The argument @var{force} also has an effect if the line isn't long
enough to reach column @var{column}; if it is @code{t}, that means to enough to reach column @var{column}; if it is @code{t}, that means to
......
...@@ -4110,6 +4110,52 @@ This function returns either: ...@@ -4110,6 +4110,52 @@ This function returns either:
(declare-function map-merge-with "map" (type function &rest maps)) (declare-function map-merge-with "map" (type function &rest maps))
(declare-function map-merge "map" (type &rest maps)) (declare-function map-merge "map" (type &rest maps))
(defun dir-locals--get-sort-score (node)
"Return a number used for sorting the definitions of dir locals.
NODE is assumed to be a cons cell where the car is either a
string or a symbol representing a mode name.
If it is a mode then the the depth of the mode (ie, how many
parents that mode has) will be returned.
If it is a string then the length of the string plus 1000 will be
returned.
Otherwise it returns -1.
That way the value can be used to sort the list such that deeper
modes will be after the other modes. This will be followed by
directory entries in order of length. If the entries are all
applied in order then that means the more specific modes will
override the values specified by the earlier modes and directory
variables will override modes."
(let ((key (car node)))
(cond ((null key) -1)
((symbolp key)
(let ((mode key)
(depth 0))
(while (setq mode (get mode 'derived-mode-parent))
(setq depth (1+ depth)))
depth))
((stringp key)
(+ 1000 (length key)))
(t -2))))
(defun dir-locals--sort-variables (variables)
"Sorts VARIABLES so that applying them in order has the right effect.
The variables are compared by dir-locals--get-sort-score.
Directory entries are then recursively sorted using the same
criteria."
(setq variables (sort variables
(lambda (a b)
(< (dir-locals--get-sort-score a)
(dir-locals--get-sort-score b)))))
(dolist (n variables)
(when (stringp (car n))
(setcdr n (dir-locals--sort-variables (cdr n)))))
variables)
(defun dir-locals-read-from-dir (dir) (defun dir-locals-read-from-dir (dir)
"Load all variables files in DIR and register a new class and instance. "Load all variables files in DIR and register a new class and instance.
DIR is the absolute name of a directory which must contain at DIR is the absolute name of a directory which must contain at
...@@ -4147,6 +4193,7 @@ Return the new class name, which is a symbol named DIR." ...@@ -4147,6 +4193,7 @@ Return the new class name, which is a symbol named DIR."
variables variables
newvars)))))) newvars))))))
(setq success latest)) (setq success latest))
(setq variables (dir-locals--sort-variables variables))
(dir-locals-set-class-variables class-name variables) (dir-locals-set-class-variables class-name variables)
(dir-locals-set-directory-class dir class-name success) (dir-locals-set-directory-class dir class-name success)
class-name)) class-name))
......
...@@ -101,9 +101,9 @@ don't define this value." ...@@ -101,9 +101,9 @@ don't define this value."
(defcustom smtpmail-stream-type nil (defcustom smtpmail-stream-type nil
"Type of SMTP connections to use. "Type of SMTP connections to use.
This may be either nil (possibly upgraded to STARTTLS if possible), This may be either nil (upgrade with STARTTLS if possible),
or `starttls' (refuse to send if STARTTLS isn't available), or `plain' `starttls' (refuse to send if STARTTLS isn't available),
\(never use STARTTLS), or `ssl' (to use TLS/SSL)." `plain' (never use STARTTLS), or `ssl' (to use TLS/SSL)."
:version "24.1" :version "24.1"
:group 'smtpmail :group 'smtpmail
:type '(choice (const :tag "Possibly upgrade to STARTTLS" nil) :type '(choice (const :tag "Possibly upgrade to STARTTLS" nil)
......
...@@ -2379,7 +2379,9 @@ With a prefix argument, inserts the character directly." ...@@ -2379,7 +2379,9 @@ With a prefix argument, inserts the character directly."
(put 'nxml-char-ref 'evaporate t) (put 'nxml-char-ref 'evaporate t)
(defun nxml-char-ref-display-extra (start end n) (defun nxml-char-ref-display-extra (start end n)
(when nxml-char-ref-extra-display (when (and ;; Displaying literal newline is unhelpful.
(not (eql n ?\n))
nxml-char-ref-extra-display)
(let ((name (or (get-char-code-property n 'name) (let ((name (or (get-char-code-property n 'name)
(get-char-code-property n 'old-name))) (get-char-code-property n 'old-name)))
(glyph-string (and nxml-char-ref-display-glyph-flag (glyph-string (and nxml-char-ref-display-glyph-flag
......
...@@ -35,35 +35,25 @@ ...@@ -35,35 +35,25 @@
;; ;;
;; Our strategy is to keep track of just the problematic things. ;; Our strategy is to keep track of just the problematic things.
;; Specifically, we keep track of all comments, CDATA sections and ;; Specifically, we keep track of all comments, CDATA sections and
;; processing instructions in the instance. We do this by marking all ;; processing instructions in the instance. We do this by marking
;; except the first character of these with a non-nil nxml-inside text ;; the first character of these with the generic string syntax by setting
;; property. The value of the nxml-inside property is comment, ;; a 'syntax-table' text property in `sgml-syntax-propertize'.
;; cdata-section or processing-instruction. The first character does
;; not have the nxml-inside property so we can find the beginning of
;; the construct by looking for a change in a text property value
;; (Emacs provides primitives for this). We use text properties
;; rather than overlays, since the implementation of overlays doesn't
;; look like it scales to large numbers of overlays in a buffer.
;;
;; We don't in fact track all these constructs, but only track them in
;; some initial part of the instance.
;; ;;
;; Thus to parse some random point in the file we first ensure that we ;; Thus to parse some random point in the file we first ensure that we
;; have scanned up to that point. Then we search backwards for a ;; have scanned up to that point. Then we search backwards for a <.
;; <. Then we check whether the < has an nxml-inside property. If it ;; Then we check whether the < has the generic string syntax. If it
;; does we go backwards to first character that does not have an ;; does we go backwards to first character of the generic string (this
;; nxml-inside property (this character must be a <). Then we start ;; character must be a <). Then we start parsing forward from the <
;; parsing forward from the < we have found. ;; we have found.
;; ;;
;; The prolog has to be parsed specially, so we also keep track of the ;; The prolog has to be parsed specially, so we also keep track of the
;; end of the prolog in `nxml-prolog-end'. The prolog is reparsed on ;; end of the prolog in `nxml-prolog-end'. The prolog is reparsed on
;; every change to the prolog. This won't work well if people try to ;; every change to the prolog. This won't work well if people try to
;; edit huge internal subsets. Hopefully that will be rare. ;; edit huge internal subsets. Hopefully that will be rare.
;; ;;
;; We keep track of the changes by adding to the buffer's ;; We rely on the `syntax-propertize-function' machinery to keep track
;; after-change-functions hook. Scanning is also done as a ;; of the changes in the buffer. Fontification also relies on correct
;; prerequisite to fontification by adding to fontification-functions ;; `syntax-table' properties. This means that scanning for these
;; (in the same way as jit-lock). This means that scanning for these
;; constructs had better be quick. Fortunately it is. Firstly, the ;; constructs had better be quick. Fortunately it is. Firstly, the
;; typical proportion of comments, CDATA sections and processing ;; typical proportion of comments, CDATA sections and processing
;; instructions is small relative to other things. Secondly, to scan ;; instructions is small relative to other things. Secondly, to scan
...@@ -79,7 +69,15 @@ ...@@ -79,7 +69,15 @@
"Integer giving position following end of the prolog.") "Integer giving position following end of the prolog.")
(defsubst nxml-get-inside (pos) (defsubst nxml-get-inside (pos)
(save-excursion (nth 8 (syntax-ppss pos)))) "Return non-nil if inside comment, CDATA, or PI."
(let ((ppss (save-excursion (syntax-ppss pos))))
(or
;; Inside comment.
(nth 4 ppss)
;; Inside "generic" string which is used for CDATA, and PI.
;; "Normal" double and single quoted strings are used for
;; attribute values.
(eq t (nth 3 ppss)))))
(defun nxml-inside-end (pos) (defun nxml-inside-end (pos)
"Return the end of the inside region containing POS. "Return the end of the inside region containing POS.
......
...@@ -1650,7 +1650,14 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)." ...@@ -1650,7 +1650,14 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)."
(frame-terminal)))) (frame-terminal))))
'nomini 'visible (selected-window)))) 'nomini 'visible (selected-window))))
(condition-case nil (condition-case nil
(switch-to-buffer next-buffer) ;; If the client specified a new buffer position,
;; treat that as an explicit point-move command, and
;; override switch-to-buffer-preserve-window-point.
(let ((switch-to-buffer-preserve-window-point
(if filepos
nil
switch-to-buffer-preserve-window-point)))
(switch-to-buffer next-buffer))
;; After all the above, we might still have ended up with ;; After all the above, we might still have ended up with
;; a minibuffer/dedicated-window (if there's no other). ;; a minibuffer/dedicated-window (if there's no other).
(error (pop-to-buffer next-buffer))))))) (error (pop-to-buffer next-buffer)))))))
......
...@@ -96,24 +96,20 @@ a DOCTYPE or an XML declaration." ...@@ -96,24 +96,20 @@ a DOCTYPE or an XML declaration."
`text-mode-hook' is run first." `text-mode-hook' is run first."
:type 'hook) :type 'hook)
;; As long as Emacs's syntax can't be complemented with predicates to context ;; The official handling of "--" is complicated in SGML, and
;; sensitively confirm the syntax of characters, we have to live with this ;; historically not well supported by browser HTML parsers.
;; kludgy kind of tradeoff. ;; Recommendations for writing HTML comments is to use <!--...-->
(defvar sgml-specials '(?\") ;; (where ... doesn't contain "--") to avoid the complications
;; altogether (XML goes even further by requiring this in the spec).
;; So there is probably no need to handle it "correctly".
(defvar sgml-specials '(?\" ?\')
"List of characters that have a special meaning for SGML mode. "List of characters that have a special meaning for SGML mode.
This list is used when first loading the `sgml-mode' library. This list is used when first loading the `sgml-mode' library.
The supported characters and potential disadvantages are: The supported characters are ?\\\", ?\\=', and ?-.
?\\\" Makes \" in text start a string. Including ?- makes double dashes into comment delimiters, but
?\\=' Makes \\=' in text start a string. they are really only supposed to delimit comments within DTD
?- Makes -- in text start a comment. definitions. So we normally turn it off.")
When only one of ?\\\" or ?\\=' are included, \"\\='\" or \\='\"\\=', as can be found in
DTDs, start a string. To partially avoid this problem this also makes these
self insert as named entities depending on `sgml-quick-keys'.
Including ?- has the problem of affecting dashes that have nothing to do
with comments, so we normally turn it off.")
(defvar sgml-quick-keys nil (defvar sgml-quick-keys nil
"Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil. "Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil.
...@@ -343,21 +339,12 @@ Any terminating `>' or `/' is not matched.") ...@@ -343,21 +339,12 @@ Any terminating `>' or `/' is not matched.")
("--[ \t\n]*\\(>\\)" (1 "> b")) ("--[ \t\n]*\\(>\\)" (1 "> b"))
("\\(<\\)[?!]" (1 (prog1 "|>" ("\\(<\\)[?!]" (1 (prog1 "|>"
(sgml-syntax-propertize-inside end)))) (sgml-syntax-propertize-inside end))))
;; Double quotes outside of tags should not introduce strings which end up ;; Quotes outside of tags should not introduce strings.
;; hiding tags. We used to test every double quote and mark it as "." ;; Be careful to call `syntax-ppss' on a position before the one we're
;; if it's outside of tags, but there are too many double quotes and ;; going to change, so as not to need to flush the data we just computed.
;; the resulting number of calls to syntax-ppss made it too slow ("[\"']" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0))))
;; (bug#33887), so we're now careful to leave alone any pair (goto-char (match-end 0)))
;; of quotes that doesn't hold a < or > char, which is the vast majority. (string-to-syntax ".")))))))
("\\(\"\\)[^\"<>]*[<>\"]"
(1 (unless (eq ?\" (char-before))
;; 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.
(if (prog1 (zerop (car (syntax-ppss (match-beginning 0))))
(goto-char (1- (match-end 0))))
(string-to-syntax ".")))))
)))
(defun sgml-syntax-propertize (start end) (defun sgml-syntax-propertize (start end)
"Syntactic keywords for `sgml-mode'." "Syntactic keywords for `sgml-mode'."
......
...@@ -983,9 +983,10 @@ If specified column is within a character, point goes after that character. ...@@ -983,9 +983,10 @@ If specified column is within a character, point goes after that character.
If it's past end of line, point goes to end of line. If it's past end of line, point goes to end of line.
Optional second argument FORCE non-nil means if COLUMN is in the Optional second argument FORCE non-nil means if COLUMN is in the
middle of a tab character, change it to spaces. middle of a tab character, either change it to spaces (when
In addition, if FORCE is t, and the line is too short to reach `indent-tabs-mode' is nil), or insert enough spaces before it to reach
COLUMN, add spaces/tabs to get there. COLUMN (otherwise). In addition, if FORCE is t, and the line is too short
to reach COLUMN, add spaces/tabs to get there.
The return value is the current column. */) The return value is the current column. */)
(Lisp_Object column, Lisp_Object force) (Lisp_Object column, Lisp_Object force)
......
;;; nxml-mode-tests.el --- Test NXML Mode -*- lexical-binding: t; -*-
;; Copyright (C) 2019 Free Software Foundation, Inc.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Code:
(require 'ert)
(require 'nxml-mode)
(defun nxml-mode-tests-correctly-indented-string (str)
(with-temp-buffer
(nxml-mode)
(insert str)
(indent-region (point-min) (point-max))
(equal (buffer-string) str)))
(ert-deftest nxml-indent-line-after-attribute ()
(should (nxml-mode-tests-correctly-indented-string "
<settings
xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd\">
<mirrors>
...
</mirrors>
</settings>
"))
(should (nxml-mode-tests-correctly-indented-string "\
<x>
<abc xx=\"x/x/x/x/x/x/x/
y/y/y/y/y/y/
\">
<zzz/>
</abc>
<nl>&#10;</nl>
</x>
")))
(ert-deftest nxml-balanced-close-start-tag-inline ()
(with-temp-buffer
(nxml-mode)
(insert "<a><b c=\"\"</a>")
(search-backward "</a>")
(nxml-balanced-close-start-tag-inline)
(should (equal (buffer-string) "<a><b c=\"\"></b></a>"))))
(ert-deftest nxml-mode-font-lock-quotes ()
(with-temp-buffer
(nxml-mode)
(insert "<x a=\"dquote attr\" b='squote attr'>\"dquote text\"'squote text'</x>")
(font-lock-ensure)
(let ((squote-txt-pos (search-backward "squote text"))
(dquote-txt-pos (search-backward "dquote text"))
(squote-att-pos (search-backward "squote attr"))
(dquote-att-pos (search-backward "dquote attr")))
;; Just make sure that each quote uses the same face for quoted
;; attribute values, and a different face for quoted text
;; outside tags. Don't test `font-lock-string-face' vs
;; `nxml-attribute-value' here.
(should (equal (get-text-property squote-att-pos 'face)
(get-text-property dquote-att-pos 'face)))
(should (equal (get-text-property squote-txt-pos 'face)
(get-text-property dquote-txt-pos 'face)))
(should-not (equal (get-text-property squote-txt-pos 'face)
(get-text-property dquote-att-pos 'face))))))
(provide 'nxml-mode-tests)
;;; nxml-mode-tests.el ends here
...@@ -125,7 +125,6 @@ The point is set to the beginning of the buffer." ...@@ -125,7 +125,6 @@ The point is set to the beginning of the buffer."
(should (string= content (buffer-string)))))) (should (string= content (buffer-string))))))
(ert-deftest sgml-delete-tag-bug-8203-should-not-delete-apostrophe () (ert-deftest sgml-delete-tag-bug-8203-should-not-delete-apostrophe ()
:expected-result :failed
(sgml-with-content (sgml-with-content
"<title>Winter is comin'</title>" "<title>Winter is comin'</title>"
(sgml-delete-tag 1) (sgml-delete-tag 1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment