Compare commits

...

5 commits

Author SHA1 Message Date
João Távora
bf3276240e Improve Python triple-quote pairing tests for electric-pair-mode
These tests were once passing incorrectly, i.e. the auto-pairing
functionality they purport to guard wasn't really working.  Added a
new test in hopes that regressions can be spotted in the future for
the now-working functionality of Python triple-quote auto-pairing via
electric-pair-mode.

bug#49518

* test/lisp/progmodes/python-tests.el
(python-triple-double-quote-pairing): Rename from
python-triple-quote-pairing.
(python-triple-single-quote-pairing): New test.
2021-09-20 11:57:07 +01:00
João Távora
b0c34e3c20 Test electric-pair-mode more closely in python-mode, too (bug#49518)
* test/lisp/electric-tests.el (define-electric-pair-test): Also run
main tests for python-mode.  (pair-some-quotes-skip-others): Test
another slightly different pairing.
2021-09-19 17:20:43 +01:00
João Távora
44870df239 Make syntax-ppss more accurate for Python triple quotes (bug#49518)
By putting delimiter syntax on the "inside" of Python triple-quoted
strings, this makes syntax-ppss be more accurate and thus helps things
like electric-pair-mode.  Also, the test
python-syntax-after-python-backspace now passes, again.

* lisp/progmodes/python.el (python-syntax-stringify): Put
delimiter syntax in "inner" of the surrouding triple quotes.

* test/lisp/progmodes/python-tests.el
(python-syntax-after-python-backspace): Passes again.
2021-09-19 17:18:17 +01:00
João Távora
989c921fcb Add docstring for 'electric-pair-p-s-i-f' and minor refactor
Extract the "open newline between pairs behaviour" into its own
function, electric-pair-open-newline-between-pairs-psif.

* lisp/elec-pair.el (electric-pair-post-self-insert-function): Add
docstring.
(electric-pair-open-newline-between-pairs-psif): New function.
(electric-pair-mode): Add/remove electric-pair-open-newline-between-pairs-psif
2021-09-19 16:49:26 +01:00
João Távora
4c3da467d0 Speed up test/lisp/electric-tests.el when run interactively
'blink-paren-function' and its timers could sometimes interfere with
the tests and slow them down significantly.

* test/lisp/electric-tests.el (call-with-saved-electric-modes):
Bind blink-paren-function to nil.
2021-09-19 10:25:36 +01:00
4 changed files with 79 additions and 21 deletions

View file

@ -485,6 +485,27 @@ happened."
(electric-pair-conservative-inhibit char)))
(defun electric-pair-post-self-insert-function ()
"Member of `post-self-insert-hook'. Do main work for `electric-pair-mode'.
If the newly inserted character C has delimiter syntax, this
function may decide to insert additional paired delimiters, or
skip the insertion of the new character altogether by jumping
over an existing identical character, or do nothing.
The decision is taken by order of preference:
* According to `use-region-p'. If this returns non-nil this
function will unconditionally \"wrap\" the region in the
corresponding delimiter for C;
* According to C alone, by looking C up in the tables
`electric-pair-paris' or `electric-pair-text-pairs' (which
see);
* According to C's syntax and the syntactic state of the buffer
(both as defined by the major mode's syntax table). This is
done by looking up up the variables
`electric-pair-inhibit-predicate', `electric-pair-skip-self'
and `electric-pair-skip-whitespace' (which see)."
(let* ((pos (and electric-pair-mode (electric--after-char-pos)))
(skip-whitespace-info))
(pcase (electric-pair-syntax-info last-command-event)
@ -551,18 +572,21 @@ happened."
(goto-char pos)
(funcall electric-pair-inhibit-predicate
last-command-event)))))
(save-excursion (electric-pair--insert pair)))))
(_
(when (and (if (functionp electric-pair-open-newline-between-pairs)
(funcall electric-pair-open-newline-between-pairs)
electric-pair-open-newline-between-pairs)
(eq last-command-event ?\n)
(< (1+ (point-min)) (point) (point-max))
(eq (save-excursion
(skip-chars-backward "\t\s")
(char-before (1- (point))))
(matching-paren (char-after))))
(save-excursion (newline 1 t)))))))
(save-excursion (electric-pair--insert pair))))))))
(defun electric-pair-open-newline-between-pairs-psif ()
"Honour `electric-pair-open-newline-between-pairs'.
Member of `post-self-insert-hook' if `electric-pair-mode' is on."
(when (and (if (functionp electric-pair-open-newline-between-pairs)
(funcall electric-pair-open-newline-between-pairs)
electric-pair-open-newline-between-pairs)
(eq last-command-event ?\n)
(< (1+ (point-min)) (point) (point-max))
(eq (save-excursion
(skip-chars-backward "\t\s")
(char-before (1- (point))))
(matching-paren (char-after))))
(save-excursion (newline 1 t))))
(defun electric-pair-will-use-region ()
(and (use-region-p)
@ -623,10 +647,15 @@ To toggle the mode in a single buffer, use `electric-pair-local-mode'."
;; `electric-indent-mode' are used together.
;; Use `vc-region-history' on these lines for more info.
50)
(add-hook 'post-self-insert-hook
#'electric-pair-open-newline-between-pairs-psif
50)
(add-hook 'self-insert-uses-region-functions
#'electric-pair-will-use-region))
(remove-hook 'post-self-insert-hook
#'electric-pair-post-self-insert-function)
(remove-hook 'post-self-insert-hook
#'electric-pair-open-newline-between-pairs-psif)
(remove-hook 'self-insert-uses-region-functions
#'electric-pair-will-use-region)))

View file

@ -775,12 +775,14 @@ is used to limit the scan."
;; The first quote is escaped, so it's not part of a triple quote!
(goto-char (1+ quote-starting-pos)))
((null string-start)
;; This set of quotes delimit the start of a string.
(put-text-property quote-starting-pos (1+ quote-starting-pos)
;; This set of quotes delimit the start of a string. Put
;; the delimiter syntax in the last of the three quotes.
(put-text-property (1- quote-ending-pos) quote-ending-pos
'syntax-table (string-to-syntax "|")))
(t
;; This set of quotes delimit the end of a string.
(put-text-property (1- quote-ending-pos) quote-ending-pos
;; This set of quotes delimit the end of a string. Put the
;; delimiter syntax in the first of the three quotess.
(put-text-property quote-starting-pos (1+ quote-starting-pos)
'syntax-table (string-to-syntax "|"))))))
(defvar python-mode-syntax-table

View file

@ -35,7 +35,8 @@
(defun call-with-saved-electric-modes (fn)
(let ((saved-electric (if electric-pair-mode 1 -1))
(saved-layout (if electric-layout-mode 1 -1))
(saved-indent (if electric-indent-mode 1 -1)))
(saved-indent (if electric-indent-mode 1 -1))
(blink-paren-function nil))
(electric-pair-mode -1)
(electric-layout-mode -1)
(electric-indent-mode -1)
@ -173,7 +174,7 @@ The buffer's contents should %s:
expected-string
expected-point
bindings
(modes '(quote (ruby-mode js-mode)))
(modes '(quote (ruby-mode js-mode python-mode)))
(test-in-comments t)
(test-in-strings t)
(test-in-code t)
@ -296,7 +297,7 @@ The buffer's contents should %s:
;;; Quotes
;;;
(define-electric-pair-test pair-some-quotes-skip-others
" \"\" " "-\"\"-----" :skip-pair-string "-ps------"
" \"\" " "-\"\"\"\"---" :skip-pair-string "-ps-p----"
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))

View file

@ -193,7 +193,6 @@ aliqua."
(ert-deftest python-syntax-after-python-backspace ()
;; `python-indent-dedent-line-backspace' garbles syntax
:expected-result :failed
(python-tests-with-temp-buffer
"\"\"\""
(goto-char (point-max))
@ -5283,7 +5282,7 @@ urlpatterns = patterns('',
(should (= (current-indentation) 23))))
(or eim (electric-indent-mode -1)))))
(ert-deftest python-triple-quote-pairing ()
(ert-deftest python-triple-double-quote-pairing ()
(let ((epm electric-pair-mode))
(unwind-protect
(progn
@ -5310,6 +5309,33 @@ urlpatterns = patterns('',
"\"\n\"\"\"\n"))))
(or epm (electric-pair-mode -1)))))
(ert-deftest python-triple-single-quote-pairing ()
(let ((epm electric-pair-mode))
(unwind-protect
(progn
(python-tests-with-temp-buffer
"''\n"
(or epm (electric-pair-mode 1))
(goto-char (1- (point-max)))
(python-tests-self-insert ?')
(should (string= (buffer-string)
"''''''\n"))
(should (= (point) 4)))
(python-tests-with-temp-buffer
"\n"
(python-tests-self-insert (list ?' ?' ?'))
(should (string= (buffer-string)
"''''''\n"))
(should (= (point) 4)))
(python-tests-with-temp-buffer
"'\n''\n"
(goto-char (1- (point-max)))
(python-tests-self-insert ?')
(should (= (point) (1- (point-max))))
(should (string= (buffer-string)
"'\n'''\n"))))
(or epm (electric-pair-mode -1)))))
;;; Hideshow support