From 59adcfda3d9f7948b25e81684cf5b5be2ab34506 Mon Sep 17 00:00:00 2001 From: Matus Goljer Date: Tue, 14 Jun 2016 21:46:22 +0200 Subject: [PATCH] [Fix #365] Check string fence syntax on backward search --- smartparens.el | 24 +++++++++++++++---- ...tparens-get-paired-expression-ruby-test.el | 5 +++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/smartparens.el b/smartparens.el index eef899d1..c29a5e80 100644 --- a/smartparens.el +++ b/smartparens.el @@ -3804,6 +3804,16 @@ The expressions considered are those delimited by pairs on ;; in C-like language. In this case, we want to report the ;; context as comment. + ;; In some languages, special paren syntax with a prefix + ;; serves to mark strings. This means that regular + ;; delimiters, like () are used to delimit strings. For + ;; example, in ruby the sequence %w(...) signifies a + ;; string. If the point is after such a sequence and we + ;; are searching back, we must use the string context, + ;; because the paren is now a string delimiter. This is + ;; usually implemented with "string fence" syntax, so we + ;; will simply check for that. + ;; Thanks for being consistent at handling syntax bounds Emacs! (in-string-or-comment (if back (let ((in-comment (sp-point-in-comment)) @@ -3812,11 +3822,15 @@ The expressions considered are those delimited by pairs on (unless (= (point) (point-min)) (backward-char) (cond - (in-comment (and in-comment (sp-point-in-comment))) - ((and (not in-comment) (sp-point-in-comment)) t) - ((or in-comment in-string)))))) - (sp-point-in-string-or-comment))) - (string-bounds (and in-string-or-comment (sp--get-string-or-comment-bounds))) + ((eq (car (syntax-after (point))) 15) (point)) + (in-comment (when (sp-point-in-comment) (1+ (point)))) + ((and (not in-comment) (sp-point-in-comment)) (1+ (point))) + ((or in-comment in-string) (1+ (point))))))) + (when (sp-point-in-string-or-comment) (point)))) + (string-bounds (and in-string-or-comment + (progn + (goto-char in-string-or-comment) + (sp--get-string-or-comment-bounds)))) (fw-bound (if in-string-or-comment (cdr string-bounds) (point-max))) (bw-bound (if in-string-or-comment (car string-bounds) (point-min))) s e active-pair forward mb me ms r done diff --git a/test/smartparens-get-paired-expression-ruby-test.el b/test/smartparens-get-paired-expression-ruby-test.el index d945c28c..698c8671 100644 --- a/test/smartparens-get-paired-expression-ruby-test.el +++ b/test/smartparens-get-paired-expression-ruby-test.el @@ -2,7 +2,8 @@ (let ((sp-pairs '((t . ((:open "def" :close "end" :actions (insert wrap autoskip navigate)) (:open "if" :close "end" :actions (insert wrap autoskip navigate)) (:open "do" :close "end" :actions (insert wrap autoskip navigate)) - (:open "begin" :close "end" :actions (insert wrap autoskip navigate))))))) + (:open "begin" :close "end" :actions (insert wrap autoskip navigate)) + (:open "(" :close ")" :actions (insert wrap autoskip navigate))))))) (sp-test-with-temp-buffer initial (ruby-mode) (should (equal (sp-get-paired-expression back) result))))) @@ -19,6 +20,8 @@ (sp-test--paired-expression-parse-in-ruby "begin| end" '(:beg 1 :end 10 :op "begin" :cl "end" :prefix "" :suffix "") t) (sp-test--paired-expression-parse-in-ruby "def foo bar if blaz end end|" '(:beg 1 :end 28 :op "def" :cl "end" :prefix "" :suffix "") t) (sp-test--paired-expression-parse-in-ruby "def foo end;|" '(:beg 1 :end 12 :op "def" :cl "end" :prefix "" :suffix "") t) + (sp-test--paired-expression-parse-in-ruby "asd (asd)|#asdas" '(:beg 5 :end 10 :op "(" :cl ")" :prefix "" :suffix "") t) + (sp-test--paired-expression-parse-in-ruby "C = %w(asd)|#asdas" '(:beg 7 :end 12 :op "(" :cl ")" :prefix "" :suffix "") t) ) (ert-deftest sp-test-get-paired-expression-ruby-fail ()