diff options
| author | Felix S Klock II <pnkfelix@pnkfx.org> | 2015-06-10 17:41:08 +0200 |
|---|---|---|
| committer | Felix S Klock II <pnkfelix@pnkfx.org> | 2015-06-10 17:41:08 +0200 |
| commit | 5ed467549abe81415241b0ea45e2ae87584b588c (patch) | |
| tree | 9897c7a87d639c014f0b78024600933ac0a975b6 | |
| parent | 86db9bdb55e9812425f4c9ece47b1bc2b5dd836b (diff) | |
| parent | 9d773b42d7345d8402426eb89070e0f374031d44 (diff) | |
| download | rust-mode-5ed467549abe81415241b0ea45e2ae87584b588c.tar.gz | |
Merge pull request #73 from MicahChalmer/raw-string-multiline-edit-fix
Fix multi-line raw strings when editing
| -rw-r--r-- | rust-mode-tests.el | 18 | ||||
| -rw-r--r-- | rust-mode.el | 38 |
2 files changed, 56 insertions, 0 deletions
diff --git a/rust-mode-tests.el b/rust-mode-tests.el index bb40781..b40aed0 100644 --- a/rust-mode-tests.el +++ b/rust-mode-tests.el @@ -1067,6 +1067,24 @@ this_is_not_a_string();)" "r\" this is a comment\n" font-lock-comment-face "\"this is a string\"" font-lock-string-face))) +(ert-deftest font-lock-raw-string-constant () + ;; There was an issue in which a multi-line raw string would be fontified + ;; correctly if inserted, but then incorrectly if one of the lines was then + ;; edited. This test replicates how font-lock responds when text in the + ;; buffer is modified in order to reproduce it. + (with-temp-buffer + (rust-mode) + (font-lock-fontify-buffer) + (insert "const BOO:&str = r#\"\nBOO\"#;") + (beginning-of-buffer) + (insert " ") + (font-lock-after-change-function 1 2 0) + + (should (equal 'font-lock-string-face (get-text-property 19 'face))) ;; Opening "r" of raw string + (should (equal 'font-lock-string-face (get-text-property 27 'face))) ;; Closing "#" of raw string + (should (equal nil (get-text-property 28 'face))) ;; Semicolon--should not be part of the string + )) + (ert-deftest indent-method-chains-no-align () (let ((rust-indent-method-chain nil)) (test-indent " diff --git a/rust-mode.el b/rust-mode.el index 58df76d..c45d5c1 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -374,6 +374,43 @@ ("fn" . font-lock-function-name-face) ("static" . font-lock-constant-face))))) +(defun rust-extend-region-raw-string () + "Extend the region given by `font-lock-beg' and `font-lock-end' + to include the beginning of a string if it includes part of it. + Adjusts to include the r[#] of a raw string as well." + + (let* ((orig-beg font-lock-beg) + (orig-end font-lock-end) + (beg-ppss (syntax-ppss font-lock-beg)) + (beg-in-str (nth 3 beg-ppss)) + (end-ppss (syntax-ppss font-lock-end)) + (end-in-str (nth 3 end-ppss))) + + (when (and beg-in-str (> font-lock-beg (nth 8 beg-ppss))) + (setq font-lock-beg str-beg) + (while (equal ?# (char-before font-lock-beg)) + (setq font-lock-beg (1- font-lock-beg))) + (when (equal ?r (char-before font-lock-beg)) + (setq font-lock-beg (1- font-lock-beg)))) + + (when end-in-str + (save-excursion + (goto-char (nth 8 end-ppss)) + (ignore-errors (forward-sexp)) + (setq font-lock-end (max font-lock-end (point))))) + + ;; If we have the beginning of a raw string in the region, make sure we have the end of + ;; it. + (when (or beg-in-str end-in-str) + (save-excursion + (goto-char font-lock-beg) + (while (and (< (point) font-lock-end) (ignore-errors (rust-look-for-raw-string (buffer-end 1))))) + (setq font-lock-end (max font-lock-end (point))))) + + (or (/= font-lock-beg orig-beg) + (/= font-lock-end orig-end)) + )) + (defun rust-look-for-raw-string (bound) ;; Find a raw string, but only if it's not in the middle of another string or ;; a comment @@ -702,6 +739,7 @@ This is written mainly to be used as `end-of-defun-function' for Rust." (setq-local indent-line-function 'rust-mode-indent-line) ;; Fonts + (add-to-list 'font-lock-extend-region-functions 'rust-extend-region-raw-string) (setq-local font-lock-defaults '(rust-mode-font-lock-keywords nil nil nil nil (font-lock-syntactic-keywords . rust-mode-font-lock-syntactic-keywords))) ;; Misc |
