Skip to content

Commit

Permalink
[Fix #661] Fix parsing of strings nested in string fences
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuco1 committed Nov 5, 2016
1 parent cebc566 commit 1a8215a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
19 changes: 16 additions & 3 deletions smartparens.el
Original file line number Diff line number Diff line change
Expand Up @@ -4496,7 +4496,8 @@ on it when calling directly."
;; `sp-get-string'
(if (and delimiter
(= (length delimiter) 1)
(eq (char-syntax (string-to-char delimiter)) 34))
(eq (char-syntax (string-to-char delimiter)) 34)
(not (eq t (sp-point-in-string))))
(sp-get-string back)
(sp-get-stringlike-expression back))))

Expand Down Expand Up @@ -5238,7 +5239,9 @@ expressions are considered."
(sp-get-sexp t))
((and (eq (char-syntax (preceding-char)) 34)
(not (sp-char-is-escaped-p (1- (point)))))
(sp-get-string t))
(if (eq t (sp-point-in-string))
(sp-get-stringlike-expression t)
(sp-get-string t)))
((sp--valid-initial-delimiter-p (sp--looking-back (sp--get-stringlike-regexp) nil))
(sp-get-expression t))
;; We might be somewhere inside the prefix of the
Expand Down Expand Up @@ -5275,7 +5278,17 @@ expressions are considered."
(sp-get-sexp nil))
((and (eq (char-syntax (following-char)) 34)
(not (sp-char-is-escaped-p)))
(sp-get-string nil))
;; It might happen that the string delimiter we are
;; looking at is nested inside another string
;; delimited by string fences (for example nested "
;; and ' in python). In this case we can't use
;; `sp-get-string' parser because it would pick up the
;; outer string. So if we are inside a string and
;; `syntax-ppss' returns t as delimiter we need to use
;; `sp-get-stringlike-expression'
(if (eq t (sp-point-in-string))
(sp-get-stringlike-expression nil)
(sp-get-string nil)))
((sp--valid-initial-delimiter-p (sp--looking-at (sp--get-stringlike-regexp)))
(sp-get-expression nil))
;; it can still be that we are looking at a /prefix/ of a
Expand Down
12 changes: 12 additions & 0 deletions test/smartparens-commands-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,18 @@ be."
("(`|(depends-on ,pkg))" "|(`(depends-on ,pkg))")
("(,@|(depends-on ,pkg))" "|(,@(depends-on ,pkg))"))))

(sp-test-command sp-down-sexp
((((mode 'python))
("\"foo bar| 'baz qux' fux\"" "\"foo bar '|baz qux' fux\"")
("\"foo |bar 'baz qux' fux\"" "\"foo bar '|baz qux' fux\"")
("\"foo |bar [baz qux] fux\"" "\"foo bar [|baz qux] fux\""))))

(sp-test-command sp-backward-down-sexp
((((mode 'python))
("\"foo bar 'baz qux' |fux\"" "\"foo bar 'baz qux|' fux\"")
("\"foo bar 'baz qux' fux| bla\"" "\"foo bar 'baz qux|' fux bla\"")
("\"foo bar [baz qux] fux| bla\"" "\"foo bar [baz qux|] fux bla\""))))

(sp-test-command sp-end-of-sexp
((nil
;; #446
Expand Down
36 changes: 36 additions & 0 deletions test/smartparens-get-stringlike-expression-python-test.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(require 'smartparens-python)

(defmacro sp-test-with-temp-python-buffer (initial &rest forms)
(declare (indent 1)
(debug (form body)))
`(sp-test-with-temp-buffer ,initial
(shut-up (python-mode))
,@forms))

(ert-deftest sp-test--python-get-thing-which-is-string-inside-string ()
(sp-test-with-temp-python-buffer "\"foo bar | 'baz qux' fux\""
(should (equal (sp-get-thing) '(:beg 11 :end 20 :op "'" :cl "'" :prefix "" :suffix ""))))

(sp-test-with-temp-python-buffer "\"foo bar 'baz qux' | fux\""
(should (equal (sp-get-thing t) '(:beg 10 :end 19 :op "'" :cl "'" :prefix "" :suffix "")))))

(ert-deftest sp-test--python-get-expression-which-is-string-inside-string ()
(sp-test-with-temp-python-buffer "\"foo bar | 'baz qux' fux\""
(should (equal (sp-get-expression) '(:beg 11 :end 20 :op "'" :cl "'" :prefix "" :suffix ""))))

(sp-test-with-temp-python-buffer "\"foo bar 'baz qux' | fux\""
(should (equal (sp-get-expression t) '(:beg 10 :end 19 :op "'" :cl "'" :prefix "" :suffix "")))))

(ert-deftest sp-test--python-get-stringlike-expression-inside-string ()
(sp-test-with-temp-python-buffer "\"foo bar | 'baz qux' fux\""
(should (equal (sp-get-stringlike-expression) '(:beg 11 :end 20 :op "'" :cl "'" :prefix "" :suffix ""))))

(sp-test-with-temp-python-buffer "\"foo bar 'baz qux' | fux\""
(should (equal (sp-get-stringlike-expression t) '(:beg 10 :end 19 :op "'" :cl "'" :prefix "" :suffix "")))))

(ert-deftest sp-test--python-get-stringlike-or-textmode-expression-inside-string ()
(sp-test-with-temp-python-buffer "\"foo bar | 'baz qux' fux\""
(should (equal (sp-get-stringlike-or-textmode-expression) '(:beg 11 :end 20 :op "'" :cl "'" :prefix "" :suffix ""))))

(sp-test-with-temp-python-buffer "\"foo bar 'baz qux' | fux\""
(should (equal (sp-get-stringlike-or-textmode-expression t) '(:beg 10 :end 19 :op "'" :cl "'" :prefix "" :suffix "")))))

0 comments on commit 1a8215a

Please sign in to comment.