diff options
| author | Nathan Moreau <nathan.moreau@m4x.org> | 2019-11-18 11:15:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-18 11:15:09 +0100 |
| commit | 4fd637c06b27c74df2e8080e832b8bd80a55be81 (patch) | |
| tree | e7a187763b156e2a7392345702afb945be7196cf | |
| parent | 6a5725328a155e12fee567de03a4625e3eddac26 (diff) | |
| download | rust-mode-4fd637c06b27c74df2e8080e832b8bd80a55be81.tar.gz | |
rust-insert-dbg: handle the case of string literals. (#342)
| -rw-r--r-- | rust-mode-tests.el | 11 | ||||
| -rw-r--r-- | rust-mode.el | 66 |
2 files changed, 73 insertions, 4 deletions
diff --git a/rust-mode-tests.el b/rust-mode-tests.el index b234771..e2e1218 100644 --- a/rust-mode-tests.el +++ b/rust-mode-tests.el @@ -245,10 +245,6 @@ fn bar() { }" /// even more. fn bar() { }" 14 85)) -(defun test-dbg-wrap (initial expected position &optional end) - (with-temp-buffer - (insert initial))) - (defun test-auto-fill (initial position inserted expected) (rust-test-manip-code initial @@ -3186,6 +3182,13 @@ impl Two<'a> { (ert-deftest rust-test-dbg-uwnrap-on-dbg-start () (rust-test-dbg-unwrap 13)) +(ert-deftest rust-test-dbg-unwrap-inside-string-literal () + (rust-test-manip-code + "let x = \"foo, bar\"";" + 15 + #'rust-dbg-wrap-or-unwrap + "let x = dbg!(\"foo, bar\")")) + (when (executable-find rust-cargo-bin) (ert-deftest rust-test-project-located () (lexical-let* ((test-dir (expand-file-name "test-project/" default-directory)) diff --git a/rust-mode.el b/rust-mode.el index b839558..e98e488 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -1811,12 +1811,78 @@ visit the new file." (insert-parentheses) (goto-char old-point))) (t + (when (rust-in-str) + (rust--up-list -1 t t)) (insert "(") (forward-sexp) (insert ")") (backward-sexp))) (insert "dbg!")) +(defun rust--up-list (&optional arg escape-strings no-syntax-crossing) + "Compatibility for emacs 24." + (or arg (setq arg 1)) + (let ((inc (if (> arg 0) 1 -1)) + (pos nil)) + (while (/= arg 0) + (condition-case err + (save-restriction + ;; If we've been asked not to cross string boundaries + ;; and we're inside a string, narrow to that string so + ;; that scan-lists doesn't find a match in a different + ;; string. + (when no-syntax-crossing + (let* ((syntax (syntax-ppss)) + (string-comment-start (nth 8 syntax))) + (when string-comment-start + (save-excursion + (goto-char string-comment-start) + (narrow-to-region + (point) + (if (nth 3 syntax) ; in string + (condition-case nil + (progn (forward-sexp) (point)) + (scan-error (point-max))) + (forward-comment 1) + (point))))))) + (if (null forward-sexp-function) + (goto-char (or (scan-lists (point) inc 1) + (buffer-end arg))) + (condition-case err + (while (progn (setq pos (point)) + (forward-sexp inc) + (/= (point) pos))) + (scan-error (goto-char (nth (if (> arg 0) 3 2) err)))) + (if (= (point) pos) + (signal 'scan-error + (list "Unbalanced parentheses" (point) (point)))))) + (scan-error + (let ((syntax nil)) + (or + ;; If we bumped up against the end of a list, see whether + ;; we're inside a string: if so, just go to the beginning + ;; or end of that string. + (and escape-strings + (or syntax (setf syntax (syntax-ppss))) + (nth 3 syntax) + (goto-char (nth 8 syntax)) + (progn (when (> inc 0) + (forward-sexp)) + t)) + ;; If we narrowed to a comment above and failed to escape + ;; it, the error might be our fault, not an indication + ;; that we're out of syntax. Try again from beginning or + ;; end of the comment. + (and no-syntax-crossing + (or syntax (setf syntax (syntax-ppss))) + (nth 4 syntax) + (goto-char (nth 8 syntax)) + (or (< inc 0) + (forward-comment 1)) + (setf arg (+ arg inc))) + (signal (car err) (cdr err)))))) + (setq arg (- arg inc))))) + ;;;###autoload (defun rust-dbg-wrap-or-unwrap () "Either remove or add the dbg! macro." |
