Merge from origin/emacs-26

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

# Conflicts:
#	lisp/files.el
#	lisp/textmodes/sgml-mode.el
This commit is contained in:
Glenn Morris 2019-05-14 17:18:18 -07:00
commit 5fe9375a51
12 changed files with 223 additions and 67 deletions

View file

@ -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
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
@code{unibyte} in your @file{.dir-locals.el}, and they have the same
meanings as they would have in file local variables. @code{coding}

View file

@ -2485,10 +2485,13 @@ automatically back to binary.
into hex. This is useful if you visit a file normally and then discover
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.
There are special commands for insertion. Here is a list of the
commands of Hexl mode:
Ordinary text characters insert themselves (i.e., overwrite with
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.
@table @kbd
@ -2501,6 +2504,12 @@ Insert a byte with a code typed in octal.
@item C-M-x
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 [
Move to the beginning of a 1k-byte page.

View file

@ -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
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}
converts the tab into spaces so that it can move precisely to column
@var{column}. Other multicolumn characters can cause anomalies despite
@var{force}, since there is no way to split them.
either converts the tab into spaces (when @code{indent-tabs-mode} is
@code{nil}), or inserts enough spaces before it (otherwise), so that
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
enough to reach column @var{column}; if it is @code{t}, that means to

View file

@ -4110,6 +4110,52 @@ This function returns either:
(declare-function map-merge-with "map" (type function &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)
"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
@ -4147,6 +4193,7 @@ Return the new class name, which is a symbol named DIR."
variables
newvars))))))
(setq success latest))
(setq variables (dir-locals--sort-variables variables))
(dir-locals-set-class-variables class-name variables)
(dir-locals-set-directory-class dir class-name success)
class-name))

View file

@ -101,9 +101,9 @@ don't define this value."
(defcustom smtpmail-stream-type nil
"Type of SMTP connections to use.
This may be either nil (possibly upgraded to STARTTLS if possible),
or `starttls' (refuse to send if STARTTLS isn't available), or `plain'
\(never use STARTTLS), or `ssl' (to use TLS/SSL)."
This may be either nil (upgrade with STARTTLS if possible),
`starttls' (refuse to send if STARTTLS isn't available),
`plain' (never use STARTTLS), or `ssl' (to use TLS/SSL)."
:version "24.1"
:group 'smtpmail
:type '(choice (const :tag "Possibly upgrade to STARTTLS" nil)

View file

@ -2379,7 +2379,9 @@ With a prefix argument, inserts the character directly."
(put 'nxml-char-ref 'evaporate t)
(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)
(get-char-code-property n 'old-name)))
(glyph-string (and nxml-char-ref-display-glyph-flag

View file

@ -35,35 +35,25 @@
;;
;; Our strategy is to keep track of just the problematic things.
;; Specifically, we keep track of all comments, CDATA sections and
;; processing instructions in the instance. We do this by marking all
;; except the first character of these with a non-nil nxml-inside text
;; property. The value of the nxml-inside property is comment,
;; 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.
;; processing instructions in the instance. We do this by marking
;; the first character of these with the generic string syntax by setting
;; a 'syntax-table' text property in `sgml-syntax-propertize'.
;;
;; 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
;; <. Then we check whether the < has an nxml-inside property. If it
;; does we go backwards to first character that does not have an
;; nxml-inside property (this character must be a <). Then we start
;; parsing forward from the < we have found.
;; have scanned up to that point. Then we search backwards for a <.
;; Then we check whether the < has the generic string syntax. If it
;; does we go backwards to first character of the generic string (this
;; character must be a <). Then we start parsing forward from the <
;; we have found.
;;
;; 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
;; every change to the prolog. This won't work well if people try to
;; edit huge internal subsets. Hopefully that will be rare.
;;
;; We keep track of the changes by adding to the buffer's
;; after-change-functions hook. Scanning is also done as a
;; prerequisite to fontification by adding to fontification-functions
;; (in the same way as jit-lock). This means that scanning for these
;; We rely on the `syntax-propertize-function' machinery to keep track
;; of the changes in the buffer. Fontification also relies on correct
;; `syntax-table' properties. This means that scanning for these
;; constructs had better be quick. Fortunately it is. Firstly, the
;; typical proportion of comments, CDATA sections and processing
;; instructions is small relative to other things. Secondly, to scan
@ -79,7 +69,15 @@
"Integer giving position following end of the prolog.")
(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)
"Return the end of the inside region containing POS.

View file

@ -1650,7 +1650,14 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)."
(frame-terminal))))
'nomini 'visible (selected-window))))
(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
;; a minibuffer/dedicated-window (if there's no other).
(error (pop-to-buffer next-buffer)))))))

View file

@ -96,24 +96,20 @@ a DOCTYPE or an XML declaration."
`text-mode-hook' is run first."
:type 'hook)
;; As long as Emacs's syntax can't be complemented with predicates to context
;; sensitively confirm the syntax of characters, we have to live with this
;; kludgy kind of tradeoff.
(defvar sgml-specials '(?\")
;; The official handling of "--" is complicated in SGML, and
;; historically not well supported by browser HTML parsers.
;; Recommendations for writing HTML comments is to use <!--...-->
;; (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.
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.
?\\=' Makes \\=' in text start a string.
?- Makes -- in text start a comment.
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.")
Including ?- makes double dashes into comment delimiters, but
they are really only supposed to delimit comments within DTD
definitions. So we normally turn it off.")
(defvar sgml-quick-keys nil
"Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil.
@ -343,21 +339,12 @@ Any terminating `>' or `/' is not matched.")
("--[ \t\n]*\\(>\\)" (1 "> b"))
("\\(<\\)[?!]" (1 (prog1 "|>"
(sgml-syntax-propertize-inside end))))
;; Double quotes outside of tags should not introduce strings which end up
;; hiding tags. We used to test every double quote and mark it as "."
;; if it's outside of tags, but there are too many double quotes and
;; the resulting number of calls to syntax-ppss made it too slow
;; (bug#33887), so we're now careful to leave alone any pair
;; of quotes that doesn't hold a < or > char, which is the vast majority.
("\\(\"\\)[^\"<>]*[<>\"]"
(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 ".")))))
)))
;; 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'."

View file

@ -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.
Optional second argument FORCE non-nil means if COLUMN is in the
middle of a tab character, change it to spaces.
In addition, if FORCE is t, and the line is too short to reach
COLUMN, add spaces/tabs to get there.
middle of a tab character, either change it to spaces (when
`indent-tabs-mode' is nil), or insert enough spaces before it to reach
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. */)
(Lisp_Object column, Lisp_Object force)

View file

@ -0,0 +1,82 @@
;;; 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

View file

@ -125,7 +125,6 @@ The point is set to the beginning of the buffer."
(should (string= content (buffer-string))))))
(ert-deftest sgml-delete-tag-bug-8203-should-not-delete-apostrophe ()
:expected-result :failed
(sgml-with-content
"<title>Winter is comin'</title>"
(sgml-delete-tag 1)