4 (eval-when-compile (require 'cl))
6 (defconst company-nxml-token-regexp
7 "\\(?:[_[:alpha:]][-._[:alnum:]]*\\_>\\)")
9 (defvar company-nxml-in-attribute-value-regexp
10 (replace-regexp-in-string "w" company-nxml-token-regexp
12 \\(?:[ \t\r\n]+w\\(?::w\\)?[ \t\r\n]*=\
13 [ \t\r\n]*\\(?:\"[^\"]*\"\\|'[^']*'\\)\\)*\
14 [ \t\r\n]+\\(w\\(:w\\)?\\)[ \t\r\n]*=[ \t\r\n]*\
15 \\(\"\\([^\"]*\\>\\)\\|'\\([^']*\\>\\)\\)\\="
18 (defvar company-nxml-in-tag-name-regexp
19 (replace-regexp-in-string "w" company-nxml-token-regexp
20 "<\\(/?w\\(?::w?\\)?\\)?\\=" t t))
22 (defun company-nxml-all-completions (prefix alist)
23 (let ((candidates (mapcar 'cdr alist))
24 (case-fold-search nil)
26 (when (cdar rng-open-elements)
27 (push (concat "/" (cdar rng-open-elements)) candidates))
28 (setq candidates (sort (all-completions prefix candidates) 'string<))
30 (unless (equal (car candidates) (car filtered))
31 (push (car candidates) filtered))
35 (defmacro company-nxml-prepared (&rest body)
36 (declare (indent 0) (debug t))
37 `(let ((lt-pos (save-excursion (search-backward "<" nil t)))
39 (when (and lt-pos (= (rng-set-state-after lt-pos) lt-pos))
42 (defun company-nxml-tag (command &optional arg &rest ignored)
44 ('prefix (and (eq major-mode 'nxml-mode)
46 (company-grab company-nxml-in-tag-name-regexp 1)))
47 ('candidates (company-nxml-prepared
48 (company-nxml-all-completions arg
49 (rng-match-possible-start-tag-names))))
52 (defun company-nxml-attribute (command &optional arg &rest ignored)
54 ('prefix (and (eq major-mode 'nxml-mode)
56 (memq (char-after) '(?\ ?\t ?\n)) ;; outside word
57 (company-grab rng-in-attribute-regex 1)))
58 ('candidates (company-nxml-prepared
59 (and (rng-adjust-state-for-attribute
60 lt-pos (- (point) (length arg)))
61 (company-nxml-all-completions arg
62 (rng-match-possible-attribute-names)))))
65 (defun company-nxml-attribute-value (command &optional arg &rest ignored)
67 ('prefix (and (eq major-mode 'nxml-mode)
69 (and (memq (char-after) '(?' ?\" ?\ ?\t ?\n)) ;; outside word
70 (looking-back company-nxml-in-attribute-value-regexp)
71 (or (match-string-no-properties 4)
72 (match-string-no-properties 5)
74 ('candidates (company-nxml-prepared
75 (let (attr-start attr-end colon)
76 (and (looking-back rng-in-attribute-value-regex lt-pos)
77 (setq colon (match-beginning 2)
78 attr-start (match-beginning 1)
79 attr-end (match-end 1))
80 (rng-adjust-state-for-attribute lt-pos attr-start)
81 (rng-adjust-state-for-attribute-value
82 attr-start colon attr-end)
84 (rng-match-possible-value-strings))))))))
86 (defun company-nxml (command &optional arg &rest ignored)
88 ('prefix (or (company-nxml-tag 'prefix)
89 (company-nxml-attribute 'prefix)
90 (company-nxml-attribute-value 'prefix)))
92 ((company-nxml-tag 'prefix)
93 (company-nxml-tag 'candidates arg))
94 ((company-nxml-attribute 'prefix)
95 (company-nxml-attribute 'candidates arg))
96 ((company-nxml-attribute-value 'prefix)
97 (sort (company-nxml-attribute-value 'candidates arg)
101 (provide 'company-nxml)
102 ;;; company-nxml.el ends here