diff options
| author | Stefan Monnier | 2016-01-16 14:03:29 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2016-01-16 14:03:29 -0500 |
| commit | d7896a6f773dc4ae4e1b56c34b6708fe2bc5610a (patch) | |
| tree | e79a7eb44c198c5d4b79c08c552512144dc581c3 | |
| parent | d10982a91ac2b93bf9a375e00d676a25f90b885a (diff) | |
| download | emacs-d7896a6f773dc4ae4e1b56c34b6708fe2bc5610a.tar.gz emacs-d7896a6f773dc4ae4e1b56c34b6708fe2bc5610a.zip | |
* lisp/nxml: Use standard completion; it also works for company-mode
* lisp/nxml/nxml-mode.el (nxml-complete): Obsolete.
(nxml-completion-at-point-function): Remove.
(nxml-mode): Don't set completion-at-point-functions.
* lisp/nxml/rng-nxml.el (rng-nxml-mode-init): Set it here instead.
(rng-completion-at-point): Rename from rng-complete and mark it
non-interactive. It is now to be used as completion-at-point-function.
(rng-complete-tag, rng-complete-end-tag, rng-complete-attribute-name)
(rng-complete-attribute-value): Don't perform completion, but return
completion data instead.
(rng-complete-qname-function, rng-generate-qname-list): Add a few
arguments, previously passed via dynamic coping.
(rng-strings-to-completion-table): Rename from
rng-strings-to-completion-alist. Don't return an alist. Don't both
sorting and uniquifying.
* lisp/nxml/rng-util.el (rng-complete-before-point): Delete function.
(rng-completion-exact-p, rng-quote-string): Delete functions.
* lisp/nxml/rng-valid.el (rng-recover-start-tag-open)
(rng-missing-attributes-message, rng-missing-element-message)
(rng-mark-missing-end-tags): Use explicit ".." in formats rather than
calling rng-quote-string everywhere.
| -rw-r--r-- | lisp/nxml/nxml-mode.el | 28 | ||||
| -rw-r--r-- | lisp/nxml/rng-nxml.el | 223 | ||||
| -rw-r--r-- | lisp/nxml/rng-util.el | 63 | ||||
| -rw-r--r-- | lisp/nxml/rng-valid.el | 35 |
4 files changed, 115 insertions, 234 deletions
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el index b7a4e2e2469..c6600b185e6 100644 --- a/lisp/nxml/nxml-mode.el +++ b/lisp/nxml/nxml-mode.el | |||
| @@ -535,8 +535,6 @@ Many aspects this mode can be customized using | |||
| 535 | (nxml-clear-inside (point-min) (point-max)) | 535 | (nxml-clear-inside (point-min) (point-max)) |
| 536 | (nxml-with-invisible-motion | 536 | (nxml-with-invisible-motion |
| 537 | (nxml-scan-prolog))))) | 537 | (nxml-scan-prolog))))) |
| 538 | (add-hook 'completion-at-point-functions | ||
| 539 | #'nxml-completion-at-point-function nil t) | ||
| 540 | (setq-local syntax-propertize-function #'nxml-after-change) | 538 | (setq-local syntax-propertize-function #'nxml-after-change) |
| 541 | (add-hook 'change-major-mode-hook #'nxml-cleanup nil t) | 539 | (add-hook 'change-major-mode-hook #'nxml-cleanup nil t) |
| 542 | 540 | ||
| @@ -557,7 +555,6 @@ Many aspects this mode can be customized using | |||
| 557 | t ; keywords-only; we highlight comments and strings here | 555 | t ; keywords-only; we highlight comments and strings here |
| 558 | nil ; font-lock-keywords-case-fold-search. XML is case sensitive | 556 | nil ; font-lock-keywords-case-fold-search. XML is case sensitive |
| 559 | nil ; no special syntax table | 557 | nil ; no special syntax table |
| 560 | nil ; no automatic syntactic fontification | ||
| 561 | (font-lock-extend-region-functions . (nxml-extend-region)) | 558 | (font-lock-extend-region-functions . (nxml-extend-region)) |
| 562 | (jit-lock-contextually . t) | 559 | (jit-lock-contextually . t) |
| 563 | (font-lock-unfontify-region-function . nxml-unfontify-region))) | 560 | (font-lock-unfontify-region-function . nxml-unfontify-region))) |
| @@ -1577,30 +1574,7 @@ of the line. This expects the xmltok-* variables to be set up as by | |||
| 1577 | (t (back-to-indentation))) | 1574 | (t (back-to-indentation))) |
| 1578 | (current-column)) | 1575 | (current-column)) |
| 1579 | 1576 | ||
| 1580 | ;;; Completion | 1577 | (define-obsolete-function-alias 'nxml-complete #'completion-at-point "26.1") |
| 1581 | |||
| 1582 | (defun nxml-complete () | ||
| 1583 | "Perform completion on the symbol preceding point. | ||
| 1584 | |||
| 1585 | Inserts as many characters as can be completed. However, if not even | ||
| 1586 | one character can be completed, then a buffer with the possibilities | ||
| 1587 | is popped up and the symbol is read from the minibuffer with | ||
| 1588 | completion. If the symbol is complete, then any characters that must | ||
| 1589 | follow the symbol are also inserted. | ||
| 1590 | |||
| 1591 | The name space used for completion and what is treated as a symbol | ||
| 1592 | depends on the context. The contexts in which completion is performed | ||
| 1593 | depend on `nxml-completion-hook'." | ||
| 1594 | (interactive) | ||
| 1595 | (unless (run-hook-with-args-until-success 'nxml-completion-hook) | ||
| 1596 | ;; Eventually we will complete on entity names here. | ||
| 1597 | (ding) | ||
| 1598 | (message "Cannot complete in this context"))) | ||
| 1599 | |||
| 1600 | (defun nxml-completion-at-point-function () | ||
| 1601 | "Call `nxml-complete' to perform completion at point." | ||
| 1602 | (when nxml-bind-meta-tab-to-complete-flag | ||
| 1603 | #'nxml-complete)) | ||
| 1604 | 1578 | ||
| 1605 | ;;; Movement | 1579 | ;;; Movement |
| 1606 | 1580 | ||
diff --git a/lisp/nxml/rng-nxml.el b/lisp/nxml/rng-nxml.el index 467f7af0bb7..954a1eb9599 100644 --- a/lisp/nxml/rng-nxml.el +++ b/lisp/nxml/rng-nxml.el | |||
| @@ -111,25 +111,15 @@ Validation will be enabled if `rng-nxml-auto-validate-flag' is non-nil." | |||
| 111 | 'append) | 111 | 'append) |
| 112 | (cond (rng-nxml-auto-validate-flag | 112 | (cond (rng-nxml-auto-validate-flag |
| 113 | (rng-validate-mode 1) | 113 | (rng-validate-mode 1) |
| 114 | (add-hook 'nxml-completion-hook #'rng-complete nil t) | 114 | (add-hook 'completion-at-point-functions #'rng-completion-at-point nil t) |
| 115 | (add-hook 'nxml-in-mixed-content-hook #'rng-in-mixed-content-p nil t)) | 115 | (add-hook 'nxml-in-mixed-content-hook #'rng-in-mixed-content-p nil t)) |
| 116 | (t | 116 | (t |
| 117 | (rng-validate-mode 0) | 117 | (rng-validate-mode 0) |
| 118 | (remove-hook 'nxml-completion-hook #'rng-complete t) | 118 | (remove-hook 'completion-at-point-functions #'rng-completion-at-point t) |
| 119 | (remove-hook 'nxml-in-mixed-content-hook #'rng-in-mixed-content-p t)))) | 119 | (remove-hook 'nxml-in-mixed-content-hook #'rng-in-mixed-content-p t)))) |
| 120 | 120 | ||
| 121 | (defvar rng-tag-history nil) | 121 | (defun rng-completion-at-point () |
| 122 | (defvar rng-attribute-name-history nil) | 122 | "Return completion data for the string before point using the current schema." |
| 123 | (defvar rng-attribute-value-history nil) | ||
| 124 | |||
| 125 | (defvar rng-complete-target-names nil) | ||
| 126 | (defvar rng-complete-name-attribute-flag nil) | ||
| 127 | (defvar rng-complete-extra-strings nil) | ||
| 128 | |||
| 129 | (defun rng-complete () | ||
| 130 | "Complete the string before point using the current schema. | ||
| 131 | Return non-nil if in a context it understands." | ||
| 132 | (interactive) | ||
| 133 | (and rng-validate-mode | 123 | (and rng-validate-mode |
| 134 | (let ((lt-pos (save-excursion (search-backward "<" nil t))) | 124 | (let ((lt-pos (save-excursion (search-backward "<" nil t))) |
| 135 | xmltok-dtd) | 125 | xmltok-dtd) |
| @@ -149,53 +139,48 @@ Return non-nil if in a context it understands." | |||
| 149 | t)) | 139 | t)) |
| 150 | 140 | ||
| 151 | (defun rng-complete-tag (lt-pos) | 141 | (defun rng-complete-tag (lt-pos) |
| 152 | (let (rng-complete-extra-strings) | 142 | (let ((extra-strings |
| 153 | (when (and (= lt-pos (1- (point))) | 143 | (when (and (= lt-pos (1- (point))) |
| 154 | rng-complete-end-tags-after-< | 144 | rng-complete-end-tags-after-< |
| 155 | rng-open-elements | 145 | rng-open-elements |
| 156 | (not (eq (car rng-open-elements) t)) | 146 | (not (eq (car rng-open-elements) t)) |
| 157 | (or rng-collecting-text | 147 | (or rng-collecting-text |
| 158 | (rng-match-save | 148 | (rng-match-save |
| 159 | (rng-match-end-tag)))) | 149 | (rng-match-end-tag)))) |
| 160 | (setq rng-complete-extra-strings | 150 | (list (concat "/" |
| 161 | (cons (concat "/" | 151 | (if (caar rng-open-elements) |
| 162 | (if (caar rng-open-elements) | 152 | (concat (caar rng-open-elements) |
| 163 | (concat (caar rng-open-elements) | 153 | ":" |
| 164 | ":" | 154 | (cdar rng-open-elements)) |
| 165 | (cdar rng-open-elements)) | 155 | (cdar rng-open-elements))))))) |
| 166 | (cdar rng-open-elements))) | ||
| 167 | rng-complete-extra-strings))) | ||
| 168 | (when (save-excursion | 156 | (when (save-excursion |
| 169 | (re-search-backward rng-in-start-tag-name-regex | 157 | (re-search-backward rng-in-start-tag-name-regex |
| 170 | lt-pos | 158 | lt-pos |
| 171 | t)) | 159 | t)) |
| 172 | (and rng-collecting-text (rng-flush-text)) | 160 | (and rng-collecting-text (rng-flush-text)) |
| 173 | (let ((completion | 161 | (let ((target-names (rng-match-possible-start-tag-names))) |
| 174 | (let ((rng-complete-target-names | 162 | `(,(1+ lt-pos) |
| 175 | (rng-match-possible-start-tag-names)) | 163 | ,(save-excursion (skip-chars-forward "[[:alnum:]_.-:]") (point)) |
| 176 | (rng-complete-name-attribute-flag nil)) | 164 | ,(apply-partially #'rng-complete-qname-function |
| 177 | (rng-complete-before-point (1+ lt-pos) | 165 | target-names nil extra-strings) |
| 178 | 'rng-complete-qname-function | 166 | :exit-function |
| 179 | "Tag: " | 167 | ,(lambda (completion status) |
| 180 | nil | 168 | (cond |
| 181 | 'rng-tag-history))) | 169 | ((not (eq status 'finished)) nil) |
| 182 | name) | 170 | ((rng-qname-p completion) |
| 183 | (when completion | 171 | (let ((name (rng-expand-qname completion |
| 184 | (cond ((rng-qname-p completion) | 172 | t |
| 185 | (setq name (rng-expand-qname completion | 173 | #'rng-start-tag-expand-recover))) |
| 186 | t | 174 | (when (and name |
| 187 | 'rng-start-tag-expand-recover)) | 175 | (rng-match-start-tag-open name) |
| 188 | (when (and name | 176 | (or (not (rng-match-start-tag-close)) |
| 189 | (rng-match-start-tag-open name) | 177 | ;; need a namespace decl on the root element |
| 190 | (or (not (rng-match-start-tag-close)) | 178 | (and (car name) |
| 191 | ;; need a namespace decl on the root element | 179 | (not rng-open-elements)))) |
| 192 | (and (car name) | 180 | ;; attributes are required |
| 193 | (not rng-open-elements)))) | 181 | (insert " ")))) |
| 194 | ;; attributes are required | 182 | ((member completion extra-strings) |
| 195 | (insert " "))) | 183 | (insert ">"))))))))) |
| 196 | ((member completion rng-complete-extra-strings) | ||
| 197 | (insert ">"))))) | ||
| 198 | t))) | ||
| 199 | 184 | ||
| 200 | (defconst rng-in-end-tag-name-regex | 185 | (defconst rng-in-end-tag-name-regex |
| 201 | (replace-regexp-in-string | 186 | (replace-regexp-in-string |
| @@ -220,29 +205,18 @@ Return non-nil if in a context it understands." | |||
| 220 | (concat (caar rng-open-elements) | 205 | (concat (caar rng-open-elements) |
| 221 | ":" | 206 | ":" |
| 222 | (cdar rng-open-elements)) | 207 | (cdar rng-open-elements)) |
| 223 | (cdar rng-open-elements))) | 208 | (cdar rng-open-elements)))) |
| 224 | (end-tag-name | 209 | `(,(+ (match-beginning 0) 2) |
| 225 | (buffer-substring-no-properties (+ (match-beginning 0) 2) | 210 | ,(save-excursion (skip-chars-forward "[[:alnum:]_.-:]") (point)) |
| 226 | (point)))) | 211 | ,(list start-tag-name) ;Sole completion candidate. |
| 227 | (cond ((or (> (length end-tag-name) | 212 | :exit-function |
| 228 | (length start-tag-name)) | 213 | ,(lambda (_completion status) |
| 229 | (not (string= (substring start-tag-name | 214 | (when (eq status 'finished) |
| 230 | 0 | 215 | (unless (eq (char-after) ?>) (insert ">")) |
| 231 | (length end-tag-name)) | 216 | (when (not (or rng-collecting-text |
| 232 | end-tag-name))) | 217 | (rng-match-end-tag))) |
| 233 | (message "Expected end-tag %s" | 218 | (message "Element \"%s\" is incomplete" |
| 234 | (rng-quote-string | 219 | start-tag-name)))))))))) |
| 235 | (concat "</" start-tag-name ">"))) | ||
| 236 | (ding)) | ||
| 237 | (t | ||
| 238 | (delete-region (- (point) (length end-tag-name)) | ||
| 239 | (point)) | ||
| 240 | (insert start-tag-name ">") | ||
| 241 | (when (not (or rng-collecting-text | ||
| 242 | (rng-match-end-tag))) | ||
| 243 | (message "Element %s is incomplete" | ||
| 244 | (rng-quote-string start-tag-name)))))))) | ||
| 245 | t)) | ||
| 246 | 220 | ||
| 247 | (defconst rng-in-attribute-regex | 221 | (defconst rng-in-attribute-regex |
| 248 | (replace-regexp-in-string | 222 | (replace-regexp-in-string |
| @@ -264,22 +238,24 @@ Return non-nil if in a context it understands." | |||
| 264 | rng-undeclared-prefixes) | 238 | rng-undeclared-prefixes) |
| 265 | (and (rng-adjust-state-for-attribute lt-pos | 239 | (and (rng-adjust-state-for-attribute lt-pos |
| 266 | attribute-start) | 240 | attribute-start) |
| 267 | (let ((rng-complete-target-names | 241 | (let ((target-names |
| 268 | (rng-match-possible-attribute-names)) | 242 | (rng-match-possible-attribute-names)) |
| 269 | (rng-complete-extra-strings | 243 | (extra-strings |
| 270 | (mapcar (lambda (prefix) | 244 | (mapcar (lambda (prefix) |
| 271 | (if prefix | 245 | (if prefix |
| 272 | (concat "xmlns:" prefix) | 246 | (concat "xmlns:" prefix) |
| 273 | "xmlns")) | 247 | "xmlns")) |
| 274 | rng-undeclared-prefixes)) | 248 | rng-undeclared-prefixes))) |
| 275 | (rng-complete-name-attribute-flag t)) | 249 | `(,attribute-start |
| 276 | (rng-complete-before-point attribute-start | 250 | ,(save-excursion (skip-chars-forward "[[:alnum:]_.-:]") (point)) |
| 277 | 'rng-complete-qname-function | 251 | ,(apply-partially #'rng-complete-qname-function |
| 278 | "Attribute: " | 252 | target-names t extra-strings) |
| 279 | nil | 253 | :exit-function |
| 280 | 'rng-attribute-name-history)) | 254 | ,(lambda (_completion status) |
| 281 | (insert "=\""))) | 255 | (when (and (eq status 'finished) |
| 282 | t)) | 256 | (not (looking-at "="))) |
| 257 | (insert "=\"\"") | ||
| 258 | (forward-char -1))))))))) | ||
| 283 | 259 | ||
| 284 | (defconst rng-in-attribute-value-regex | 260 | (defconst rng-in-attribute-value-regex |
| 285 | (replace-regexp-in-string | 261 | (replace-regexp-in-string |
| @@ -296,36 +272,33 @@ Return non-nil if in a context it understands." | |||
| 296 | (defun rng-complete-attribute-value (lt-pos) | 272 | (defun rng-complete-attribute-value (lt-pos) |
| 297 | (when (save-excursion | 273 | (when (save-excursion |
| 298 | (re-search-backward rng-in-attribute-value-regex lt-pos t)) | 274 | (re-search-backward rng-in-attribute-value-regex lt-pos t)) |
| 299 | (let ((name-start (match-beginning 1)) | 275 | (let* ((name-start (match-beginning 1)) |
| 300 | (name-end (match-end 1)) | 276 | (name-end (match-end 1)) |
| 301 | (colon (match-beginning 2)) | 277 | (colon (match-beginning 2)) |
| 302 | (value-start (1+ (match-beginning 3)))) | 278 | (value-start (1+ (match-beginning 3))) |
| 279 | (exit-function | ||
| 280 | (lambda (_completion status) | ||
| 281 | (when (eq status 'finished) | ||
| 282 | (let ((delim (char-before value-start))) | ||
| 283 | (unless (eq (char-after) delim) (insert delim))))))) | ||
| 303 | (and (rng-adjust-state-for-attribute lt-pos | 284 | (and (rng-adjust-state-for-attribute lt-pos |
| 304 | name-start) | 285 | name-start) |
| 305 | (if (string= (buffer-substring-no-properties name-start | 286 | (if (string= (buffer-substring-no-properties name-start |
| 306 | (or colon name-end)) | 287 | (or colon name-end)) |
| 307 | "xmlns") | 288 | "xmlns") |
| 308 | (rng-complete-before-point | 289 | `(,value-start ,(point) |
| 309 | value-start | 290 | ,(rng-strings-to-completion-table |
| 310 | (rng-strings-to-completion-alist | 291 | (rng-possible-namespace-uris |
| 311 | (rng-possible-namespace-uris | 292 | (and colon |
| 312 | (and colon | 293 | (buffer-substring-no-properties (1+ colon) name-end)))) |
| 313 | (buffer-substring-no-properties (1+ colon) name-end)))) | 294 | :exit-function ,exit-function) |
| 314 | "Namespace URI: " | ||
| 315 | nil | ||
| 316 | 'rng-namespace-uri-history) | ||
| 317 | (rng-adjust-state-for-attribute-value name-start | 295 | (rng-adjust-state-for-attribute-value name-start |
| 318 | colon | 296 | colon |
| 319 | name-end) | 297 | name-end) |
| 320 | (rng-complete-before-point | 298 | `(,value-start ,(point) |
| 321 | value-start | 299 | ,(rng-strings-to-completion-table |
| 322 | (rng-strings-to-completion-alist | 300 | (rng-match-possible-value-strings)) |
| 323 | (rng-match-possible-value-strings)) | 301 | :exit-function ,exit-function)))))) |
| 324 | "Value: " | ||
| 325 | nil | ||
| 326 | 'rng-attribute-value-history)) | ||
| 327 | (insert (char-before value-start)))) | ||
| 328 | t)) | ||
| 329 | 302 | ||
| 330 | (defun rng-possible-namespace-uris (prefix) | 303 | (defun rng-possible-namespace-uris (prefix) |
| 331 | (let ((ns (if prefix (nxml-ns-get-prefix prefix) | 304 | (let ((ns (if prefix (nxml-ns-get-prefix prefix) |
| @@ -505,17 +478,21 @@ set `xmltok-dtd'. Returns the position of the end of the token." | |||
| 505 | (and (or (not prefix) ns) | 478 | (and (or (not prefix) ns) |
| 506 | (rng-match-attribute-name (cons ns local-name))))) | 479 | (rng-match-attribute-name (cons ns local-name))))) |
| 507 | 480 | ||
| 508 | (defun rng-complete-qname-function (string predicate flag) | 481 | (defun rng-complete-qname-function (candidates attributes-flag extra-strings |
| 509 | (complete-with-action flag (rng-generate-qname-list string) string predicate)) | 482 | string predicate flag) |
| 483 | (complete-with-action flag | ||
| 484 | (rng-generate-qname-list | ||
| 485 | string candidates attributes-flag extra-strings) | ||
| 486 | string predicate)) | ||
| 510 | 487 | ||
| 511 | (defun rng-generate-qname-list (&optional string) | 488 | (defun rng-generate-qname-list (&optional string candidates attribute-flag extra-strings) |
| 512 | (let ((forced-prefix (and string | 489 | (let ((forced-prefix (and string |
| 513 | (string-match ":" string) | 490 | (string-match ":" string) |
| 514 | (> (match-beginning 0) 0) | 491 | (> (match-beginning 0) 0) |
| 515 | (substring string | 492 | (substring string |
| 516 | 0 | 493 | 0 |
| 517 | (match-beginning 0)))) | 494 | (match-beginning 0)))) |
| 518 | (namespaces (mapcar 'car rng-complete-target-names)) | 495 | (namespaces (mapcar #'car candidates)) |
| 519 | ns-prefixes-alist ns-prefixes iter ns prefer) | 496 | ns-prefixes-alist ns-prefixes iter ns prefer) |
| 520 | (while namespaces | 497 | (while namespaces |
| 521 | (setq ns (car namespaces)) | 498 | (setq ns (car namespaces)) |
| @@ -523,7 +500,7 @@ set `xmltok-dtd'. Returns the position of the end of the token." | |||
| 523 | (setq ns-prefixes-alist | 500 | (setq ns-prefixes-alist |
| 524 | (cons (cons ns (nxml-ns-prefixes-for | 501 | (cons (cons ns (nxml-ns-prefixes-for |
| 525 | ns | 502 | ns |
| 526 | rng-complete-name-attribute-flag)) | 503 | attribute-flag)) |
| 527 | ns-prefixes-alist))) | 504 | ns-prefixes-alist))) |
| 528 | (setq namespaces (delq ns (cdr namespaces)))) | 505 | (setq namespaces (delq ns (cdr namespaces)))) |
| 529 | (setq iter ns-prefixes-alist) | 506 | (setq iter ns-prefixes-alist) |
| @@ -543,12 +520,12 @@ set `xmltok-dtd'. Returns the position of the end of the token." | |||
| 543 | (setcdr ns-prefixes (list prefer))) | 520 | (setcdr ns-prefixes (list prefer))) |
| 544 | ;; Unless it's an attribute with a non-nil namespace, | 521 | ;; Unless it's an attribute with a non-nil namespace, |
| 545 | ;; allow no prefix for this namespace. | 522 | ;; allow no prefix for this namespace. |
| 546 | (unless rng-complete-name-attribute-flag | 523 | (unless attribute-flag |
| 547 | (setcdr ns-prefixes (cons nil (cdr ns-prefixes)))))) | 524 | (setcdr ns-prefixes (cons nil (cdr ns-prefixes)))))) |
| 548 | (setq iter (cdr iter))) | 525 | (setq iter (cdr iter))) |
| 549 | (rng-uniquify-equal | 526 | (rng-uniquify-equal |
| 550 | (sort (apply #'append | 527 | (sort (apply #'append |
| 551 | (cons rng-complete-extra-strings | 528 | (cons extra-strings |
| 552 | (mapcar (lambda (name) | 529 | (mapcar (lambda (name) |
| 553 | (if (car name) | 530 | (if (car name) |
| 554 | (mapcar (lambda (prefix) | 531 | (mapcar (lambda (prefix) |
| @@ -560,7 +537,7 @@ set `xmltok-dtd'. Returns the position of the end of the token." | |||
| 560 | (cdr (assoc (car name) | 537 | (cdr (assoc (car name) |
| 561 | ns-prefixes-alist))) | 538 | ns-prefixes-alist))) |
| 562 | (list (cdr name)))) | 539 | (list (cdr name)))) |
| 563 | rng-complete-target-names))) | 540 | candidates))) |
| 564 | 'string<)))) | 541 | 'string<)))) |
| 565 | 542 | ||
| 566 | (defun rng-get-preferred-unused-prefix (ns) | 543 | (defun rng-get-preferred-unused-prefix (ns) |
| @@ -579,10 +556,8 @@ set `xmltok-dtd'. Returns the position of the end of the token." | |||
| 579 | nil)))) | 556 | nil)))) |
| 580 | prefix)) | 557 | prefix)) |
| 581 | 558 | ||
| 582 | (defun rng-strings-to-completion-alist (strings) | 559 | (defun rng-strings-to-completion-table (strings) |
| 583 | (mapcar (lambda (s) (cons s s)) | 560 | (mapcar #'rng-escape-string strings)) |
| 584 | (rng-uniquify-equal (sort (mapcar #'rng-escape-string strings) | ||
| 585 | 'string<)))) | ||
| 586 | 561 | ||
| 587 | (provide 'rng-nxml) | 562 | (provide 'rng-nxml) |
| 588 | 563 | ||
diff --git a/lisp/nxml/rng-util.el b/lisp/nxml/rng-util.el index 4c14e2b6597..c5d4b6567ed 100644 --- a/lisp/nxml/rng-util.el +++ b/lisp/nxml/rng-util.el | |||
| @@ -82,69 +82,6 @@ LIST is not modified." | |||
| 82 | (cons item nil)))))))) | 82 | (cons item nil)))))))) |
| 83 | list))) | 83 | list))) |
| 84 | 84 | ||
| 85 | (defun rng-complete-before-point (start table prompt &optional predicate hist) | ||
| 86 | "Complete text between START and point. | ||
| 87 | Replaces the text between START and point with a string chosen using a | ||
| 88 | completion table and, when needed, input read from the user with the | ||
| 89 | minibuffer. | ||
| 90 | Returns the new string if either a complete and unique completion was | ||
| 91 | determined automatically or input was read from the user. Otherwise, | ||
| 92 | returns nil. | ||
| 93 | TABLE is an alist, a symbol bound to a function or an obarray as with | ||
| 94 | the function `completing-read'. | ||
| 95 | PROMPT is the string to prompt with if user input is needed. | ||
| 96 | PREDICATE is nil or a function as with `completing-read'. | ||
| 97 | HIST, if non-nil, specifies a history list as with `completing-read'." | ||
| 98 | (let* ((orig (buffer-substring-no-properties start (point))) | ||
| 99 | (completion (try-completion orig table predicate))) | ||
| 100 | (cond ((not completion) | ||
| 101 | (if (string= orig "") | ||
| 102 | (message "No completions available") | ||
| 103 | (message "No completion for %s" (rng-quote-string orig))) | ||
| 104 | (ding) | ||
| 105 | nil) | ||
| 106 | ((eq completion t) orig) | ||
| 107 | ((not (string= completion orig)) | ||
| 108 | (delete-region start (point)) | ||
| 109 | (insert completion) | ||
| 110 | (cond ((not (rng-completion-exact-p completion table predicate)) | ||
| 111 | (message "Incomplete") | ||
| 112 | nil) | ||
| 113 | ((eq (try-completion completion table predicate) t) | ||
| 114 | completion) | ||
| 115 | (t | ||
| 116 | (message "Complete but not unique") | ||
| 117 | nil))) | ||
| 118 | (t | ||
| 119 | (setq completion | ||
| 120 | (let ((saved-minibuffer-setup-hook | ||
| 121 | (default-value 'minibuffer-setup-hook))) | ||
| 122 | (add-hook 'minibuffer-setup-hook | ||
| 123 | 'minibuffer-completion-help | ||
| 124 | t) | ||
| 125 | (unwind-protect | ||
| 126 | (completing-read prompt | ||
| 127 | table | ||
| 128 | predicate | ||
| 129 | nil | ||
| 130 | orig | ||
| 131 | hist) | ||
| 132 | (setq-default minibuffer-setup-hook | ||
| 133 | saved-minibuffer-setup-hook)))) | ||
| 134 | (delete-region start (point)) | ||
| 135 | (insert completion) | ||
| 136 | completion)))) | ||
| 137 | |||
| 138 | (defun rng-completion-exact-p (string table predicate) | ||
| 139 | (cond ((symbolp table) | ||
| 140 | (funcall table string predicate 'lambda)) | ||
| 141 | ((vectorp table) | ||
| 142 | (intern-soft string table)) | ||
| 143 | (t (assoc string table)))) | ||
| 144 | |||
| 145 | (defun rng-quote-string (s) | ||
| 146 | (concat "\"" s "\"")) | ||
| 147 | |||
| 148 | (defun rng-escape-string (s) | 85 | (defun rng-escape-string (s) |
| 149 | (replace-regexp-in-string "[&\"<>]" | 86 | (replace-regexp-in-string "[&\"<>]" |
| 150 | (lambda (match) | 87 | (lambda (match) |
diff --git a/lisp/nxml/rng-valid.el b/lisp/nxml/rng-valid.el index 9b0b4df67f8..946bf791ff8 100644 --- a/lisp/nxml/rng-valid.el +++ b/lisp/nxml/rng-valid.el | |||
| @@ -1138,9 +1138,8 @@ as empty-element." | |||
| 1138 | (rng-match-start-tag-open required) | 1138 | (rng-match-start-tag-open required) |
| 1139 | (rng-match-after) | 1139 | (rng-match-after) |
| 1140 | (rng-match-start-tag-open name)) | 1140 | (rng-match-start-tag-open name)) |
| 1141 | (rng-mark-invalid (concat "Missing element " | 1141 | (rng-mark-invalid (format "Missing element \"%s\"" |
| 1142 | (rng-quote-string | 1142 | (rng-name-to-string required)) |
| 1143 | (rng-name-to-string required))) | ||
| 1144 | xmltok-start | 1143 | xmltok-start |
| 1145 | (1+ xmltok-start))) | 1144 | (1+ xmltok-start))) |
| 1146 | ((and (rng-match-optionalize-elements) | 1145 | ((and (rng-match-optionalize-elements) |
| @@ -1177,16 +1176,14 @@ as empty-element." | |||
| 1177 | (cond ((not required-attributes) | 1176 | (cond ((not required-attributes) |
| 1178 | "Required attributes missing") | 1177 | "Required attributes missing") |
| 1179 | ((not (cdr required-attributes)) | 1178 | ((not (cdr required-attributes)) |
| 1180 | (concat "Missing attribute " | 1179 | (format "Missing attribute \"%s\"" |
| 1181 | (rng-quote-string | 1180 | (rng-name-to-string (car required-attributes) t))) |
| 1182 | (rng-name-to-string (car required-attributes) t)))) | ||
| 1183 | (t | 1181 | (t |
| 1184 | (concat "Missing attributes " | 1182 | (format "Missing attributes \"%s\"" |
| 1185 | (mapconcat (lambda (nm) | 1183 | (mapconcat (lambda (nm) |
| 1186 | (rng-quote-string | 1184 | (rng-name-to-string nm t)) |
| 1187 | (rng-name-to-string nm t))) | ||
| 1188 | required-attributes | 1185 | required-attributes |
| 1189 | ", ")))))) | 1186 | "\", \"")))))) |
| 1190 | 1187 | ||
| 1191 | (defun rng-process-end-tag (&optional partial) | 1188 | (defun rng-process-end-tag (&optional partial) |
| 1192 | (cond ((not rng-open-elements) | 1189 | (cond ((not rng-open-elements) |
| @@ -1229,8 +1226,7 @@ as empty-element." | |||
| 1229 | (defun rng-missing-element-message () | 1226 | (defun rng-missing-element-message () |
| 1230 | (let ((element (rng-match-required-element-name))) | 1227 | (let ((element (rng-match-required-element-name))) |
| 1231 | (if element | 1228 | (if element |
| 1232 | (concat "Missing element " | 1229 | (format "Missing element \"%s\"" (rng-name-to-string element)) |
| 1233 | (rng-quote-string (rng-name-to-string element))) | ||
| 1234 | "Required child elements missing"))) | 1230 | "Required child elements missing"))) |
| 1235 | 1231 | ||
| 1236 | (defun rng-recover-mismatched-end-tag () | 1232 | (defun rng-recover-mismatched-end-tag () |
| @@ -1258,17 +1254,16 @@ as empty-element." | |||
| 1258 | 1254 | ||
| 1259 | (defun rng-mark-missing-end-tags (missing) | 1255 | (defun rng-mark-missing-end-tags (missing) |
| 1260 | (rng-mark-not-well-formed | 1256 | (rng-mark-not-well-formed |
| 1261 | (format "Missing end-tag%s %s" | 1257 | (format "Missing end-tag%s \"%s\"" |
| 1262 | (if (null (cdr missing)) "" "s") | 1258 | (if (null (cdr missing)) "" "s") |
| 1263 | (mapconcat (lambda (name) | 1259 | (mapconcat (lambda (name) |
| 1264 | (rng-quote-string | 1260 | (if (car name) |
| 1265 | (if (car name) | 1261 | (concat (car name) |
| 1266 | (concat (car name) | 1262 | ":" |
| 1267 | ":" | 1263 | (cdr name)) |
| 1268 | (cdr name)) | 1264 | (cdr name))) |
| 1269 | (cdr name)))) | ||
| 1270 | missing | 1265 | missing |
| 1271 | ", ")) | 1266 | "\", \"")) |
| 1272 | xmltok-start | 1267 | xmltok-start |
| 1273 | (+ xmltok-start 2))) | 1268 | (+ xmltok-start 2))) |
| 1274 | 1269 | ||