diff options
| author | Alan Mackenzie | 2017-02-12 10:59:03 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2017-02-12 10:59:03 +0000 |
| commit | f4d5b687150810129b7a1d5b006e31ccf82b691b (patch) | |
| tree | 4229b13800349032697daae3904dc3773e6b7a80 /lisp/textmodes | |
| parent | d5514332d4a6092673ce1f78fadcae0c57f7be64 (diff) | |
| parent | 148100d98319499f0ac6f57b8be08cbd14884a5c (diff) | |
| download | emacs-comment-cache.tar.gz emacs-comment-cache.zip | |
Merge branch 'master' into comment-cachecomment-cache
Diffstat (limited to 'lisp/textmodes')
| -rw-r--r-- | lisp/textmodes/css-mode.el | 156 | ||||
| -rw-r--r-- | lisp/textmodes/reftex-vars.el | 2 |
2 files changed, 155 insertions, 3 deletions
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index c81c3f62e16..0c7d76f7924 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el | |||
| @@ -32,9 +32,11 @@ | |||
| 32 | 32 | ||
| 33 | ;;; Code: | 33 | ;;; Code: |
| 34 | 34 | ||
| 35 | (require 'eww) | ||
| 35 | (require 'seq) | 36 | (require 'seq) |
| 36 | (require 'sgml-mode) | 37 | (require 'sgml-mode) |
| 37 | (require 'smie) | 38 | (require 'smie) |
| 39 | (require 'subr-x) | ||
| 38 | 40 | ||
| 39 | (defgroup css nil | 41 | (defgroup css nil |
| 40 | "Cascading Style Sheets (CSS) editing mode." | 42 | "Cascading Style Sheets (CSS) editing mode." |
| @@ -621,6 +623,12 @@ cannot be completed sensibly: `custom-ident', | |||
| 621 | (modify-syntax-entry ?- "_" st) | 623 | (modify-syntax-entry ?- "_" st) |
| 622 | st)) | 624 | st)) |
| 623 | 625 | ||
| 626 | (defvar css-mode-map | ||
| 627 | (let ((map (make-sparse-keymap))) | ||
| 628 | (define-key map [remap info-lookup-symbol] 'css-lookup-symbol) | ||
| 629 | map) | ||
| 630 | "Keymap used in `css-mode'.") | ||
| 631 | |||
| 624 | (eval-and-compile | 632 | (eval-and-compile |
| 625 | (defconst css--uri-re | 633 | (defconst css--uri-re |
| 626 | (concat | 634 | (concat |
| @@ -734,7 +742,30 @@ cannot be completed sensibly: `custom-ident', | |||
| 734 | 742 | ||
| 735 | (defconst css-smie-grammar | 743 | (defconst css-smie-grammar |
| 736 | (smie-prec2->grammar | 744 | (smie-prec2->grammar |
| 737 | (smie-precs->prec2 '((assoc ";") (assoc ",") (left ":"))))) | 745 | (smie-precs->prec2 |
| 746 | '((assoc ";") | ||
| 747 | ;; Colons that belong to a CSS property. These get a higher | ||
| 748 | ;; precedence than other colons, such as colons in selectors, | ||
| 749 | ;; which are represented by a plain ":" token. | ||
| 750 | (left ":-property") | ||
| 751 | (assoc ",") | ||
| 752 | (assoc ":"))))) | ||
| 753 | |||
| 754 | (defun css--colon-inside-selector-p () | ||
| 755 | "Return t if point looks to be inside a CSS selector. | ||
| 756 | This function is intended to be good enough to help SMIE during | ||
| 757 | tokenization, but should not be regarded as a reliable function | ||
| 758 | for determining whether point is within a selector." | ||
| 759 | (save-excursion | ||
| 760 | (re-search-forward "[{};)]" nil t) | ||
| 761 | (eq (char-before) ?\{))) | ||
| 762 | |||
| 763 | (defun css--colon-inside-funcall () | ||
| 764 | "Return t if point is inside a function call." | ||
| 765 | (when-let (opening-paren-pos (nth 1 (syntax-ppss))) | ||
| 766 | (save-excursion | ||
| 767 | (goto-char opening-paren-pos) | ||
| 768 | (eq (char-after) ?\()))) | ||
| 738 | 769 | ||
| 739 | (defun css-smie--forward-token () | 770 | (defun css-smie--forward-token () |
| 740 | (cond | 771 | (cond |
| @@ -748,7 +779,13 @@ cannot be completed sensibly: `custom-ident', | |||
| 748 | ";") | 779 | ";") |
| 749 | ((progn (forward-comment (point-max)) | 780 | ((progn (forward-comment (point-max)) |
| 750 | (looking-at "[;,:]")) | 781 | (looking-at "[;,:]")) |
| 751 | (forward-char 1) (match-string 0)) | 782 | (forward-char 1) |
| 783 | (if (equal (match-string 0) ":") | ||
| 784 | (if (or (css--colon-inside-selector-p) | ||
| 785 | (css--colon-inside-funcall)) | ||
| 786 | ":" | ||
| 787 | ":-property") | ||
| 788 | (match-string 0))) | ||
| 752 | (t (smie-default-forward-token)))) | 789 | (t (smie-default-forward-token)))) |
| 753 | 790 | ||
| 754 | (defun css-smie--backward-token () | 791 | (defun css-smie--backward-token () |
| @@ -759,7 +796,13 @@ cannot be completed sensibly: `custom-ident', | |||
| 759 | ((and (eq (char-before) ?\}) (scss-smie--not-interpolation-p) | 796 | ((and (eq (char-before) ?\}) (scss-smie--not-interpolation-p) |
| 760 | (> pos (point))) ";") | 797 | (> pos (point))) ";") |
| 761 | ((memq (char-before) '(?\; ?\, ?\:)) | 798 | ((memq (char-before) '(?\; ?\, ?\:)) |
| 762 | (forward-char -1) (string (char-after))) | 799 | (forward-char -1) |
| 800 | (if (eq (char-after) ?\:) | ||
| 801 | (if (or (css--colon-inside-selector-p) | ||
| 802 | (css--colon-inside-funcall)) | ||
| 803 | ":" | ||
| 804 | ":-property") | ||
| 805 | (string (char-after)))) | ||
| 763 | (t (smie-default-backward-token))))) | 806 | (t (smie-default-backward-token))))) |
| 764 | 807 | ||
| 765 | (defun css-smie-rules (kind token) | 808 | (defun css-smie-rules (kind token) |
| @@ -1087,5 +1130,112 @@ pseudo-elements, pseudo-classes, at-rules, and bang-rules." | |||
| 1087 | (setq-local font-lock-defaults | 1130 | (setq-local font-lock-defaults |
| 1088 | (list (scss-font-lock-keywords) nil t))) | 1131 | (list (scss-font-lock-keywords) nil t))) |
| 1089 | 1132 | ||
| 1133 | |||
| 1134 | |||
| 1135 | (defvar css--mdn-lookup-history nil) | ||
| 1136 | |||
| 1137 | (defcustom css-lookup-url-format | ||
| 1138 | "https://developer.mozilla.org/en-US/docs/Web/CSS/%s?raw¯os" | ||
| 1139 | "Format for a URL where CSS documentation can be found. | ||
| 1140 | The format should include a single \"%s\" substitution. | ||
| 1141 | The name of the CSS property, @-id, pseudo-class, or pseudo-element | ||
| 1142 | to look up will be substituted there." | ||
| 1143 | :version "26.1" | ||
| 1144 | :type 'string | ||
| 1145 | :group 'css) | ||
| 1146 | |||
| 1147 | (defun css--mdn-after-render () | ||
| 1148 | (setf header-line-format nil) | ||
| 1149 | (goto-char (point-min)) | ||
| 1150 | (let ((window (get-buffer-window (current-buffer) 'visible))) | ||
| 1151 | (when window | ||
| 1152 | (when (re-search-forward "^Summary" nil 'move) | ||
| 1153 | (beginning-of-line) | ||
| 1154 | (set-window-start window (point)))))) | ||
| 1155 | |||
| 1156 | (defconst css--mdn-symbol-regexp | ||
| 1157 | (concat "\\(" | ||
| 1158 | ;; @-ids. | ||
| 1159 | "\\(@" (regexp-opt css-at-ids) "\\)" | ||
| 1160 | "\\|" | ||
| 1161 | ;; ;; Known properties. | ||
| 1162 | (regexp-opt css-property-ids t) | ||
| 1163 | "\\|" | ||
| 1164 | ;; Pseudo-classes. | ||
| 1165 | "\\(:" (regexp-opt css-pseudo-class-ids) "\\)" | ||
| 1166 | "\\|" | ||
| 1167 | ;; Pseudo-elements with either one or two ":"s. | ||
| 1168 | "\\(::?" (regexp-opt css-pseudo-element-ids) "\\)" | ||
| 1169 | "\\)") | ||
| 1170 | "Regular expression to match the CSS symbol at point.") | ||
| 1171 | |||
| 1172 | (defconst css--mdn-property-regexp | ||
| 1173 | (concat "\\_<" (regexp-opt css-property-ids t) "\\s-*\\(?:\\=\\|:\\)") | ||
| 1174 | "Regular expression to match a CSS property.") | ||
| 1175 | |||
| 1176 | (defconst css--mdn-completion-list | ||
| 1177 | (nconc | ||
| 1178 | ;; @-ids. | ||
| 1179 | (mapcar (lambda (atrule) (concat "@" atrule)) css-at-ids) | ||
| 1180 | ;; Pseudo-classes. | ||
| 1181 | (mapcar (lambda (class) (concat ":" class)) css-pseudo-class-ids) | ||
| 1182 | ;; Pseudo-elements with either one or two ":"s. | ||
| 1183 | (mapcar (lambda (elt) (concat ":" elt)) css-pseudo-element-ids) | ||
| 1184 | (mapcar (lambda (elt) (concat "::" elt)) css-pseudo-element-ids) | ||
| 1185 | ;; Properties. | ||
| 1186 | css-property-ids) | ||
| 1187 | "List of all symbols available for lookup via MDN.") | ||
| 1188 | |||
| 1189 | (defun css--mdn-find-symbol () | ||
| 1190 | "A helper for `css-lookup-symbol' that finds the symbol at point. | ||
| 1191 | Returns the symbol, a string, or nil if none found." | ||
| 1192 | (save-excursion | ||
| 1193 | ;; Skip backward over a word first. | ||
| 1194 | (skip-chars-backward "-[:alnum:] \t") | ||
| 1195 | ;; Now skip ":" or "@" to see if it's a pseudo-element or at-id. | ||
| 1196 | (skip-chars-backward "@:") | ||
| 1197 | (if (looking-at css--mdn-symbol-regexp) | ||
| 1198 | (match-string-no-properties 0) | ||
| 1199 | (let ((bound (save-excursion | ||
| 1200 | (beginning-of-line) | ||
| 1201 | (point)))) | ||
| 1202 | (when (re-search-backward css--mdn-property-regexp bound t) | ||
| 1203 | (match-string-no-properties 1)))))) | ||
| 1204 | |||
| 1205 | ;;;###autoload | ||
| 1206 | (defun css-lookup-symbol (symbol) | ||
| 1207 | "Display the CSS documentation for SYMBOL, as found on MDN. | ||
| 1208 | When this command is used interactively, it picks a default | ||
| 1209 | symbol based on the CSS text before point -- either an @-keyword, | ||
| 1210 | a property name, a pseudo-class, or a pseudo-element, depending | ||
| 1211 | on what is seen near point." | ||
| 1212 | (interactive | ||
| 1213 | (list | ||
| 1214 | (let* ((sym (css--mdn-find-symbol)) | ||
| 1215 | (enable-recursive-minibuffers t) | ||
| 1216 | (value (completing-read | ||
| 1217 | (if sym | ||
| 1218 | (format "Describe CSS symbol (default %s): " sym) | ||
| 1219 | "Describe CSS symbol: ") | ||
| 1220 | css--mdn-completion-list nil nil nil | ||
| 1221 | 'css--mdn-lookup-history sym))) | ||
| 1222 | (if (equal value "") sym value)))) | ||
| 1223 | (when symbol | ||
| 1224 | ;; If we see a single-colon pseudo-element like ":after", turn it | ||
| 1225 | ;; into "::after". | ||
| 1226 | (when (and (eq (aref symbol 0) ?:) | ||
| 1227 | (member (substring symbol 1) css-pseudo-element-ids)) | ||
| 1228 | (setq symbol (concat ":" symbol))) | ||
| 1229 | (let ((url (format css-lookup-url-format symbol)) | ||
| 1230 | (buffer (get-buffer-create "*MDN CSS*"))) | ||
| 1231 | (save-selected-window | ||
| 1232 | ;; Make sure to display the buffer before calling `eww', as | ||
| 1233 | ;; that calls `pop-to-buffer-same-window'. | ||
| 1234 | (switch-to-buffer-other-window buffer) | ||
| 1235 | (with-current-buffer buffer | ||
| 1236 | (eww-mode) | ||
| 1237 | (add-hook 'eww-after-render-hook #'css--mdn-after-render nil t) | ||
| 1238 | (eww url)))))) | ||
| 1239 | |||
| 1090 | (provide 'css-mode) | 1240 | (provide 'css-mode) |
| 1091 | ;;; css-mode.el ends here | 1241 | ;;; css-mode.el ends here |
diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index 63abd048e9d..03da584e96f 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el | |||
| @@ -164,6 +164,8 @@ distribution. Mixed-case symbols are convenience aliases.") | |||
| 164 | (?U . "\\autocite*[][]{%l}") | 164 | (?U . "\\autocite*[][]{%l}") |
| 165 | (?a . "\\citeauthor{%l}") | 165 | (?a . "\\citeauthor{%l}") |
| 166 | (?A . "\\citeauthor*{%l}") | 166 | (?A . "\\citeauthor*{%l}") |
| 167 | (?i . "\\citetitle{%l}") | ||
| 168 | (?I . "\\citetitle*{%l}") | ||
| 167 | (?y . "\\citeyear{%l}") | 169 | (?y . "\\citeyear{%l}") |
| 168 | (?Y . "\\citeyear*{%l}") | 170 | (?Y . "\\citeyear*{%l}") |
| 169 | (?n . "\\nocite{%l}"))) | 171 | (?n . "\\nocite{%l}"))) |