diff options
| author | Dmitry Gutov | 2012-08-14 08:28:12 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-08-14 08:28:12 -0400 |
| commit | e636fafe20f0238d0aaabc4b822642efe68cad9b (patch) | |
| tree | e55e068aa5714d96fd180c4118156ffe8e83e98b /lisp | |
| parent | 8e99d072be7ce8aff322d65dc87527c4118722f2 (diff) | |
| download | emacs-e636fafe20f0238d0aaabc4b822642efe68cad9b.tar.gz emacs-e636fafe20f0238d0aaabc4b822642efe68cad9b.zip | |
* lisp/progmodes/ruby-mode.el: Improve percent literals.
(ruby-percent-literal-beg-re): New constant.
(ruby-syntax-general-delimiters-goto-beg): Rename to
`ruby-syntax-enclosing-percent-literal', improve literal type check.
(ruby-syntax-propertize-general-delimiters): Rename to
`ruby-syntax-propertize-percent-literal', it's a shorter and more
popular term. Adjust comments everywhere.
(ruby-syntax-propertize-percent-literal): Only propertize when not
inside a simple string or comment. When the literal is unclosed,
leave the text after it unpropertized.
Fixes: debbugs:6286
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 17 | ||||
| -rw-r--r-- | lisp/progmodes/ruby-mode.el | 85 |
2 files changed, 63 insertions, 39 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7232fa9f62b..db4cc8e7fab 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2012-08-14 Dmitry Gutov <dgutov@yandex.ru> | ||
| 2 | |||
| 3 | * progmodes/ruby-mode.el: Improve percent literals (bug#6286). | ||
| 4 | (ruby-percent-literal-beg-re): New constant. | ||
| 5 | (ruby-syntax-general-delimiters-goto-beg): Rename to | ||
| 6 | `ruby-syntax-enclosing-percent-literal', improve literal type check. | ||
| 7 | (ruby-syntax-propertize-general-delimiters): Rename to | ||
| 8 | `ruby-syntax-propertize-percent-literal', it's a shorter and more | ||
| 9 | popular term. Adjust comments everywhere. | ||
| 10 | (ruby-syntax-propertize-percent-literal): Only propertize when not | ||
| 11 | inside a simple string or comment. When the literal is unclosed, | ||
| 12 | leave the text after it unpropertized. | ||
| 13 | |||
| 1 | 2012-08-14 Andreas Schwab <schwab@linux-m68k.org> | 14 | 2012-08-14 Andreas Schwab <schwab@linux-m68k.org> |
| 2 | 15 | ||
| 3 | * emacs-lisp/bytecomp.el (byte-recompile-file): When LOAD is | 16 | * emacs-lisp/bytecomp.el (byte-recompile-file): When LOAD is |
| @@ -22,8 +35,8 @@ | |||
| 22 | Use `completion-table-dynamic' for completion functions. | 35 | Use `completion-table-dynamic' for completion functions. |
| 23 | * progmodes/python.el | 36 | * progmodes/python.el |
| 24 | (python-shell-completion--do-completion-at-point) | 37 | (python-shell-completion--do-completion-at-point) |
| 25 | (python-shell-completion--get-completions): Remove | 38 | (python-shell-completion--get-completions): |
| 26 | functions. | 39 | Remove functions. |
| 27 | (python-shell-completion-complete-at-point): New function. | 40 | (python-shell-completion-complete-at-point): New function. |
| 28 | (python-completion-complete-at-point): Use it. | 41 | (python-completion-complete-at-point): Use it. |
| 29 | 42 | ||
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 744dd430658..42e1ac72b33 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el | |||
| @@ -800,7 +800,7 @@ and `\\' when preceded by `?'." | |||
| 800 | ;; (not (or (eolp) (looking-at "#") | 800 | ;; (not (or (eolp) (looking-at "#") |
| 801 | ;; (and (eq (car (nth 1 state)) ?{) | 801 | ;; (and (eq (car (nth 1 state)) ?{) |
| 802 | ;; (looking-at "|")))))) | 802 | ;; (looking-at "|")))))) |
| 803 | ;; Not a regexp or general delimited literal. | 803 | ;; Not a regexp or percent literal. |
| 804 | (null (nth 0 (ruby-parse-region (or begin parse-start) | 804 | (null (nth 0 (ruby-parse-region (or begin parse-start) |
| 805 | (point)))) | 805 | (point)))) |
| 806 | (or (not (eq ?| (char-after (point)))) | 806 | (or (not (eq ?| (char-after (point)))) |
| @@ -1169,17 +1169,22 @@ See `add-log-current-defun-function'." | |||
| 1169 | (ruby-do-end-to-brace))) | 1169 | (ruby-do-end-to-brace))) |
| 1170 | 1170 | ||
| 1171 | (declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit)) | 1171 | (declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit)) |
| 1172 | (declare-function ruby-syntax-general-delimiters-goto-beg "ruby-mode" ()) | 1172 | (declare-function ruby-syntax-enclosing-percent-literal "ruby-mode" (limit)) |
| 1173 | (declare-function ruby-syntax-propertize-general-delimiters "ruby-mode" (limit)) | 1173 | (declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit)) |
| 1174 | 1174 | ||
| 1175 | (if (eval-when-compile (fboundp #'syntax-propertize-rules)) | 1175 | (if (eval-when-compile (fboundp #'syntax-propertize-rules)) |
| 1176 | ;; New code that works independently from font-lock. | 1176 | ;; New code that works independently from font-lock. |
| 1177 | (progn | 1177 | (progn |
| 1178 | (eval-and-compile | ||
| 1179 | (defconst ruby-percent-literal-beg-re | ||
| 1180 | "\\(%\\)[qQrswWx]?\\([[:punct:]]\\)" | ||
| 1181 | "Regexp to match the beginning of percent literal.")) | ||
| 1182 | |||
| 1178 | (defun ruby-syntax-propertize-function (start end) | 1183 | (defun ruby-syntax-propertize-function (start end) |
| 1179 | "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." | 1184 | "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." |
| 1180 | (goto-char start) | 1185 | (goto-char start) |
| 1181 | (ruby-syntax-propertize-heredoc end) | 1186 | (ruby-syntax-propertize-heredoc end) |
| 1182 | (ruby-syntax-general-delimiters-goto-beg) | 1187 | (ruby-syntax-enclosing-percent-literal end) |
| 1183 | (funcall | 1188 | (funcall |
| 1184 | (syntax-propertize-rules | 1189 | (syntax-propertize-rules |
| 1185 | ;; #{ }, #$hoge, #@foo are not comments. | 1190 | ;; #{ }, #$hoge, #@foo are not comments. |
| @@ -1222,8 +1227,8 @@ See `add-log-current-defun-function'." | |||
| 1222 | 'syntax-table (string-to-syntax "\"")) | 1227 | 'syntax-table (string-to-syntax "\"")) |
| 1223 | (ruby-syntax-propertize-heredoc end)))) | 1228 | (ruby-syntax-propertize-heredoc end)))) |
| 1224 | ;; Handle percent literals: %w(), %q{}, etc. | 1229 | ;; Handle percent literals: %w(), %q{}, etc. |
| 1225 | ("\\(?:^\\|[[ \t\n<+(,=]\\)\\(%\\)[qQrswWx]?\\([[:punct:]]\\)" | 1230 | ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re) |
| 1226 | (1 (prog1 "|" (ruby-syntax-propertize-general-delimiters end))))) | 1231 | (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) |
| 1227 | (point) end)) | 1232 | (point) end)) |
| 1228 | 1233 | ||
| 1229 | (defun ruby-syntax-propertize-heredoc (limit) | 1234 | (defun ruby-syntax-propertize-heredoc (limit) |
| @@ -1251,40 +1256,46 @@ See `add-log-current-defun-function'." | |||
| 1251 | ;; inf-loop. | 1256 | ;; inf-loop. |
| 1252 | (if (< (point) start) (goto-char start)))))) | 1257 | (if (< (point) start) (goto-char start)))))) |
| 1253 | 1258 | ||
| 1254 | (defun ruby-syntax-general-delimiters-goto-beg () | 1259 | (defun ruby-syntax-enclosing-percent-literal (limit) |
| 1255 | (let ((state (syntax-ppss))) | 1260 | (let ((state (syntax-ppss)) |
| 1256 | ;; Move to the start of the literal, in case it's multiline. | 1261 | (start (point))) |
| 1257 | ;; TODO: determine the literal type more reliably here? | 1262 | ;; When already inside percent literal, re-propertize it. |
| 1258 | (when (eq t (nth 3 state)) | 1263 | (when (eq t (nth 3 state)) |
| 1259 | (goto-char (nth 8 state)) | 1264 | (goto-char (nth 8 state)) |
| 1260 | (beginning-of-line)))) | 1265 | (when (looking-at ruby-percent-literal-beg-re) |
| 1266 | (ruby-syntax-propertize-percent-literal limit)) | ||
| 1267 | (when (< (point) start) (goto-char start))))) | ||
| 1261 | 1268 | ||
| 1262 | (defun ruby-syntax-propertize-general-delimiters (limit) | 1269 | (defun ruby-syntax-propertize-percent-literal (limit) |
| 1263 | (goto-char (match-beginning 2)) | 1270 | (goto-char (match-beginning 2)) |
| 1264 | (let* ((op (char-after)) | 1271 | ;; Not inside a simple string or comment. |
| 1265 | (ops (char-to-string op)) | 1272 | (when (eq t (nth 3 (syntax-ppss))) |
| 1266 | (cl (or (cdr (aref (syntax-table) op)) | 1273 | (let* ((op (char-after)) |
| 1267 | (cdr (assoc op '((?< . ?>)))))) | 1274 | (ops (char-to-string op)) |
| 1268 | parse-sexp-lookup-properties) | 1275 | (cl (or (cdr (aref (syntax-table) op)) |
| 1269 | (ignore-errors | 1276 | (cdr (assoc op '((?< . ?>)))))) |
| 1270 | (if cl | 1277 | parse-sexp-lookup-properties) |
| 1271 | (progn ; Paired delimiters. | 1278 | (condition-case nil |
| 1272 | ;; Delimiter pairs of the same kind can be nested | 1279 | (progn |
| 1273 | ;; inside the literal, as long as they are balanced. | 1280 | (if cl ; Paired delimiters. |
| 1274 | ;; Create syntax table that ignores other characters. | 1281 | ;; Delimiter pairs of the same kind can be nested |
| 1275 | (with-syntax-table (make-char-table 'syntax-table nil) | 1282 | ;; inside the literal, as long as they are balanced. |
| 1276 | (modify-syntax-entry op (concat "(" (char-to-string cl))) | 1283 | ;; Create syntax table that ignores other characters. |
| 1277 | (modify-syntax-entry cl (concat ")" ops)) | 1284 | (with-syntax-table (make-char-table 'syntax-table nil) |
| 1278 | (modify-syntax-entry ?\\ "\\") | 1285 | (modify-syntax-entry op (concat "(" (char-to-string cl))) |
| 1279 | (save-restriction | 1286 | (modify-syntax-entry cl (concat ")" ops)) |
| 1280 | (narrow-to-region (point) limit) | 1287 | (modify-syntax-entry ?\\ "\\") |
| 1281 | (forward-list)))) ; skip to the paired character | 1288 | (save-restriction |
| 1282 | ;; Single character delimiter. | 1289 | (narrow-to-region (point) limit) |
| 1283 | (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*" | 1290 | (forward-list))) ; skip to the paired character |
| 1284 | (regexp-quote ops)) limit nil)) | 1291 | ;; Single character delimiter. |
| 1285 | ;; If we reached here, the closing delimiter was found. | 1292 | (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*" |
| 1286 | (put-text-property (1- (point)) (point) | 1293 | (regexp-quote ops)) limit nil)) |
| 1287 | 'syntax-table (string-to-syntax "|"))))) | 1294 | ;; Found the closing delimiter. |
| 1295 | (put-text-property (1- (point)) (point) 'syntax-table | ||
| 1296 | (string-to-syntax "|"))) | ||
| 1297 | ;; Unclosed literal, leave the following text unpropertized. | ||
| 1298 | ((scan-error search-failed) (goto-char limit)))))) | ||
| 1288 | ) | 1299 | ) |
| 1289 | 1300 | ||
| 1290 | ;; For Emacsen where syntax-propertize-rules is not (yet) available, | 1301 | ;; For Emacsen where syntax-propertize-rules is not (yet) available, |
| @@ -1329,7 +1340,7 @@ This should only be called after matching against `ruby-here-doc-end-re'." | |||
| 1329 | (4 (7 . ?/)) | 1340 | (4 (7 . ?/)) |
| 1330 | (6 (7 . ?/))) | 1341 | (6 (7 . ?/))) |
| 1331 | ("^=en\\(d\\)\\_>" 1 "!") | 1342 | ("^=en\\(d\\)\\_>" 1 "!") |
| 1332 | ;; General delimited string. | 1343 | ;; Percent literal. |
| 1333 | ("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)" | 1344 | ("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)" |
| 1334 | (3 "\"") | 1345 | (3 "\"") |
| 1335 | (5 "\"")) | 1346 | (5 "\"")) |