1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-29 07:58:28 +00:00
emacs/test/lisp/electric-tests.el

992 lines
35 KiB
EmacsLisp
Raw Normal View History

;;; electric-tests.el --- tests for electric.el -*- lexical-binding: t; -*-
;; Copyright (C) 2013-2021 Free Software Foundation, Inc.
;; Author: João Távora <joaotavora@gmail.com>
;; Keywords:
2020-08-27 00:42:36 +00:00
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
2020-08-27 00:42:36 +00:00
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
2020-08-27 00:42:36 +00:00
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Tests for Electric Pair mode.
;; TODO: Add tests for other Electric-* functionality
;;; Code:
(require 'ert)
(require 'ert-x)
(require 'electric)
(require 'elec-pair)
(require 'cl-lib)
(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))
(blink-paren-function nil))
(electric-pair-mode -1)
(electric-layout-mode -1)
(electric-indent-mode -1)
(unwind-protect
(funcall fn)
(electric-pair-mode saved-electric)
(electric-indent-mode saved-indent)
(electric-layout-mode saved-layout))))
(defmacro save-electric-modes (&rest body)
(declare (indent defun) (debug t))
`(call-with-saved-electric-modes (lambda () ,@body)))
(defun electric-pair-test-for (fixture where char expected-string
expected-point mode bindings
fixture-fn &optional doc-string)
(with-temp-buffer
(dlet ((python-indent-guess-indent-offset-verbose nil))
(funcall mode)
(insert fixture)
(save-electric-modes
(let ((last-command-event char)
(transient-mark-mode 'lambda))
(goto-char where)
(funcall fixture-fn)
(cl-progv
(mapcar #'car bindings)
(mapcar #'cdr bindings)
(call-interactively (key-binding `[,last-command-event]))))))
(when
(and doc-string
(not
(and
(equal (buffer-substring-no-properties (point-min) (point-max))
expected-string)
(equal (point) expected-point))))
(message "\n%s\n" doc-string))
(should (equal (buffer-substring-no-properties (point-min) (point-max))
expected-string))
(should (equal (point)
expected-point))))
(eval-when-compile
(defun electric-pair-define-test-form (name fixture
char
pos
expected-string
expected-point
skip-pair-string
prefix
suffix
extra-desc
mode
bindings
fixture-fn)
(let* ((expected-string-and-point
(if skip-pair-string
(with-temp-buffer
(cl-progv
;; FIXME: avoid `eval'
(mapcar #'car (eval bindings t))
(mapcar #'cdr (eval bindings t))
(dlet ((python-indent-guess-indent-offset-verbose nil))
(funcall mode)
(insert fixture)
(goto-char (1+ pos))
(insert char)
(cond ((eq (aref skip-pair-string pos)
?p)
(insert (cadr (electric-pair-syntax-info char)))
(backward-char 1))
((eq (aref skip-pair-string pos)
?s)
(delete-char -1)
(forward-char 1)))
(list
(buffer-substring-no-properties (point-min) (point-max))
(point)))))
(list expected-string expected-point)))
(expected-string (car expected-string-and-point))
(expected-point (cadr expected-string-and-point))
(fixture (format "%s%s%s" prefix fixture suffix))
(expected-string (format "%s%s%s" prefix expected-string suffix))
(expected-point (+ (length prefix) expected-point))
(pos (+ (length prefix) pos))
(doc-string
(format "Electricity test in a `%s' buffer.\n
Start with point at %d in a %d-char-long buffer
like this one:
|%s| (buffer start and end are denoted by `|')
%s
%s
Now press the key for: %c
The buffer's contents should %s:
|%s|
, and point should be at %d."
mode
(1+ pos)
(length fixture)
fixture
(if fixture-fn (format "\nNow call this:\n\n%s"
(pp-to-string fixture-fn))
"")
(if bindings (format "\nEnsure the following bindings:\n\n%s"
(pp-to-string bindings))
"")
char
(if (string= fixture expected-string) "stay" "become")
Use string-replace instead of replace-regexp-in-string `string-replace` is easier to understand, less error-prone, much faster, and results in shorter Lisp and byte code. Use it where applicable and obviously safe (erring on the conservative side). * admin/authors.el (authors-scan-change-log): * lisp/autoinsert.el (auto-insert-alist): * lisp/calc/calc-prog.el (calc-edit-macro-combine-alg-ent) (calc-edit-macro-combine-ext-command) (calc-edit-macro-combine-var-name): * lisp/calc/calc-units.el (math-make-unit-string): * lisp/calendar/cal-html.el (cal-html-comment): * lisp/calendar/cal-tex.el (cal-tex-comment): * lisp/calendar/icalendar.el (icalendar--convert-string-for-export) (icalendar--convert-string-for-import): * lisp/calendar/iso8601.el (iso8601--concat-regexps) (iso8601--full-time-match, iso8601--combined-match): * lisp/calendar/time-date.el (format-seconds): * lisp/calendar/todo-mode.el (todo-filter-items-filename): * lisp/cedet/cedet-files.el (cedet-directory-name-to-file-name) (cedet-file-name-to-directory-name): * lisp/comint.el (comint-watch-for-password-prompt): * lisp/dired-aux.el (dired-do-chmod): * lisp/dired-x.el (dired-man): * lisp/dired.el (dired-insert-directory, dired-goto-file-1): * lisp/emacs-lisp/comp.el (comp-c-func-name): * lisp/emacs-lisp/re-builder.el (reb-copy): * lisp/erc/erc-dcc.el (erc-dcc-unquote-filename): * lisp/erc/erc.el (erc-quit-reason-zippy, erc-part-reason-zippy) (erc-update-mode-line-buffer, erc-message-english-PART): * lisp/files.el (make-backup-file-name-1, files--transform-file-name) (read-file-modes): * lisp/fringe.el (fringe-mode): * lisp/gnus/gnus-art.el (gnus-button-handle-info-url): * lisp/gnus/gnus-group.el (gnus-group-completing-read): * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-ical): * lisp/gnus/gnus-mlspl.el (gnus-group-split-fancy): * lisp/gnus/gnus-search.el (gnus-search-query-parse-date) (gnus-search-transform-expression, gnus-search-run-search): * lisp/gnus/gnus-start.el (gnus-dribble-enter): * lisp/gnus/gnus-sum.el (gnus-summary-refer-article): * lisp/gnus/gnus-util.el (gnus-mode-string-quote): * lisp/gnus/message.el (message-put-addresses-in-ecomplete) (message-parse-mailto-url, message-mailto-1): * lisp/gnus/mml-sec.el (mml-secure-epg-sign): * lisp/gnus/mml-smime.el (mml-smime-epg-verify): * lisp/gnus/mml2015.el (mml2015-epg-verify): * lisp/gnus/nnmaildir.el (nnmaildir--system-name) (nnmaildir-request-list, nnmaildir-retrieve-groups) (nnmaildir-request-group, nnmaildir-retrieve-headers): * lisp/gnus/nnrss.el (nnrss-node-text): * lisp/gnus/spam-report.el (spam-report-gmane-internal) (spam-report-user-mail-address): * lisp/ibuffer.el (name): * lisp/image-dired.el (image-dired-pngnq-thumb) (image-dired-pngcrush-thumb, image-dired-optipng-thumb) (image-dired-create-thumb-1): * lisp/info.el (Info-set-mode-line): * lisp/international/mule-cmds.el (describe-language-environment): * lisp/mail/rfc2231.el (rfc2231-parse-string): * lisp/mail/rfc2368.el (rfc2368-parse-mailto-url): * lisp/mail/rmail.el (rmail-insert-inbox-text) (rmail-simplified-subject-regexp): * lisp/mail/rmailout.el (rmail-output-body-to-file): * lisp/mail/undigest.el (rmail-digest-rfc1153): * lisp/man.el (Man-default-man-entry): * lisp/mouse.el (minor-mode-menu-from-indicator): * lisp/mpc.el (mpc--debug): * lisp/net/browse-url.el (browse-url-mail): * lisp/net/eww.el (eww-update-header-line-format): * lisp/net/newst-backend.el (newsticker-save-item): * lisp/net/rcirc.el (rcirc-sentinel): * lisp/net/soap-client.el (soap-decode-date-time): * lisp/nxml/rng-cmpct.el (rng-c-literal-2-re): * lisp/nxml/xmltok.el (let*): * lisp/obsolete/nnir.el (nnir-run-swish-e, nnir-run-hyrex) (nnir-run-find-grep): * lisp/play/dunnet.el (dun-doassign): * lisp/play/handwrite.el (handwrite): * lisp/proced.el (proced-format-args): * lisp/profiler.el (profiler-report-header-line-format): * lisp/progmodes/gdb-mi.el (gdb-mi-quote): * lisp/progmodes/make-mode.el (makefile-bsdmake-rule-action-regex) (makefile-make-font-lock-keywords): * lisp/progmodes/prolog.el (prolog-guess-fill-prefix): * lisp/progmodes/ruby-mode.el (ruby-toggle-string-quotes): * lisp/progmodes/sql.el (sql-remove-tabs-filter, sql-str-literal): * lisp/progmodes/which-func.el (which-func-current): * lisp/replace.el (query-replace-read-from) (occur-engine, replace-quote): * lisp/select.el (xselect--encode-string): * lisp/ses.el (ses-export-tab): * lisp/subr.el (shell-quote-argument): * lisp/term/pc-win.el (msdos-show-help): * lisp/term/w32-win.el (w32--set-selection): * lisp/term/xterm.el (gui-backend-set-selection): * lisp/textmodes/picture.el (picture-tab-search): * lisp/thumbs.el (thumbs-call-setroot-command): * lisp/tooltip.el (tooltip-show-help-non-mode): * lisp/transient.el (transient-format-key): * lisp/url/url-mailto.el (url-mailto): * lisp/vc/log-edit.el (log-edit-changelog-ours-p): * lisp/vc/vc-bzr.el (vc-bzr-status): * lisp/vc/vc-hg.el (vc-hg--glob-to-pcre): * lisp/vc/vc-svn.el (vc-svn-after-dir-status): * lisp/xdg.el (xdg-desktop-strings): * test/lisp/electric-tests.el (defun): * test/lisp/term-tests.el (term-simple-lines): * test/lisp/time-stamp-tests.el (formatz-mod-del-colons): * test/lisp/wdired-tests.el (wdired-test-bug32173-01) (wdired-test-unfinished-edit-01): * test/src/json-tests.el (json-parse-with-custom-null-and-false-objects): Use `string-replace` instead of `replace-regexp-in-string`.
2021-08-08 16:58:46 +00:00
(string-replace "\n" "\\n" expected-string)
expected-point)))
`(ert-deftest ,(intern (format "electric-pair-%s-at-point-%s-in-%s%s"
name
(1+ pos)
mode
extra-desc))
()
,doc-string
(electric-pair-test-for ,fixture
,(1+ pos)
,char
,expected-string
,expected-point
',mode
,bindings
,fixture-fn
,doc-string)))))
(cl-defmacro define-electric-pair-test
(name fixture
input
&key
skip-pair-string
expected-string
expected-point
bindings
(modes '(quote (ruby-mode js-mode python-mode c-mode)))
(test-in-comments t)
(test-in-strings t)
(test-in-code t)
;; The semantics of CL's defmacro "default values" is subtle:
;; contrary to the actual arguments, these are evaluated (and
;; are expected to return the "default form").
;; `fixture-fn' contains a form whose evaluation returns a function.
(fixture-fn '#'electric-pair-mode))
`(progn
,@(cl-loop
for mode in (eval modes t) ;FIXME: avoid `eval'
append
(cl-loop
for (prefix suffix extra-desc) in
(append (if test-in-comments
`((,(with-temp-buffer
(dlet ((python-indent-guess-indent-offset-verbose
nil))
(funcall mode)
(insert "z")
(comment-region (point-min) (point-max))
(buffer-substring-no-properties (point-min)
(1- (point-max)))))
""
"-in-comments")))
(if test-in-strings
Replace insignificant backquotes Replace most insignificant occurrences of '`' with a straight quote, sharp quote or nothing. This includes backquotes in 'pcase' patterns. * admin/admin.el: * lisp/apropos.el: * lisp/arc-mode.el: * lisp/auth-source.el: * lisp/avoid.el: * lisp/bindings.el: * lisp/bs.el: * lisp/calculator.el: * lisp/calendar/todo-mode.el: * lisp/cedet/semantic.el: * lisp/cedet/semantic/analyze/debug.el: * lisp/cedet/semantic/bovine.el: * lisp/cedet/semantic/dep.el: * lisp/cedet/semantic/grammar.el: * lisp/cedet/semantic/wisent/comp.el: * lisp/cedet/semantic/wisent/grammar.el: * lisp/cedet/srecode/mode.el: * lisp/cus-edit.el: * lisp/doc-view.el: * lisp/elec-pair.el: * lisp/electric.el: * lisp/emacs-lisp/autoload.el: * lisp/emacs-lisp/benchmark.el: * lisp/emacs-lisp/byte-opt.el: * lisp/emacs-lisp/bytecomp.el: * lisp/emacs-lisp/cconv.el: * lisp/emacs-lisp/cl-extra.el: * lisp/emacs-lisp/cl-generic.el: * lisp/emacs-lisp/cl-macs.el: * lisp/emacs-lisp/copyright.el: * lisp/emacs-lisp/debug.el: * lisp/emacs-lisp/eieio-compat.el: * lisp/emacs-lisp/ert.el: * lisp/emacs-lisp/generator.el: * lisp/emacs-lisp/inline.el: * lisp/emacs-lisp/macroexp.el: * lisp/emacs-lisp/map.el: * lisp/emacs-lisp/package-x.el: * lisp/emacs-lisp/package.el: * lisp/emacs-lisp/radix-tree.el: * lisp/emacs-lisp/smie.el: * lisp/epa.el: * lisp/erc/erc-dcc.el: * lisp/erc/erc-track.el: * lisp/erc/erc.el: * lisp/eshell/em-ls.el: * lisp/eshell/esh-cmd.el: * lisp/files.el: * lisp/filesets.el: * lisp/font-lock.el: * lisp/frameset.el: * lisp/gnus/gnus-agent.el: * lisp/gnus/gnus-art.el: * lisp/gnus/gnus-cite.el: * lisp/gnus/gnus-group.el: * lisp/gnus/gnus-msg.el: * lisp/gnus/gnus-salt.el: * lisp/gnus/gnus-srvr.el: * lisp/gnus/gnus-sum.el: * lisp/gnus/gnus-topic.el: * lisp/gnus/gnus-util.el: * lisp/gnus/gnus.el: * lisp/gnus/message.el: * lisp/gnus/mm-util.el: * lisp/gnus/mml.el: * lisp/gnus/nnheader.el: * lisp/gnus/nnimap.el: * lisp/gnus/nnmairix.el: * lisp/gnus/spam.el: * lisp/hexl.el: * lisp/hi-lock.el: * lisp/ibuf-ext.el: * lisp/ibuffer.el: * lisp/ido.el: * lisp/info.el: * lisp/international/mule-cmds.el: * lisp/international/mule-util.el: * lisp/json.el: * lisp/jsonrpc.el: * lisp/language/cyrillic.el: * lisp/language/european.el: * lisp/language/georgian.el: * lisp/language/tibetan.el: * lisp/language/utf-8-lang.el: * lisp/language/vietnamese.el: * lisp/ldefs-boot.el: * lisp/mail/mail-extr.el: * lisp/man.el: * lisp/menu-bar.el: * lisp/mh-e/mh-acros.el: * lisp/mh-e/mh-folder.el: * lisp/mh-e/mh-mime.el: * lisp/mh-e/mh-show.el: * lisp/mh-e/mh-speed.el: * lisp/minibuffer.el: * lisp/mpc.el: * lisp/net/ange-ftp.el: * lisp/net/hmac-def.el: * lisp/net/newst-backend.el: * lisp/net/quickurl.el: * lisp/net/tramp-archive.el: * lisp/net/tramp-compat.el: * lisp/notifications.el: * lisp/obsolete/pgg-parse.el: * lisp/obsolete/vc-arch.el: * lisp/obsolete/xesam.el: * lisp/org/ob-C.el: * lisp/org/ob-core.el: * lisp/org/ob-exp.el: * lisp/org/ob-groovy.el: * lisp/org/ob-haskell.el: * lisp/org/ob-io.el: * lisp/org/ob-lisp.el: * lisp/org/ob-lob.el: * lisp/org/ob-lua.el: * lisp/org/ob-octave.el: * lisp/org/ob-perl.el: * lisp/org/ob-python.el: * lisp/org/ob-ref.el: * lisp/org/ob-ruby.el: * lisp/org/ob-sql.el: * lisp/org/org-agenda.el: * lisp/org/org-capture.el: * lisp/org/org-clock.el: * lisp/org/org-colview.el: * lisp/org/org-duration.el: * lisp/org/org-element.el: * lisp/org/org-entities.el: * lisp/org/org-gnus.el: * lisp/org/org-indent.el: * lisp/org/org-info.el: * lisp/org/org-inlinetask.el: * lisp/org/org-lint.el: * lisp/org/org-list.el: * lisp/org/org-mouse.el: * lisp/org/org-plot.el: * lisp/org/org-src.el: * lisp/org/org-table.el: * lisp/org/org.el: * lisp/org/ox-ascii.el: * lisp/org/ox-html.el: * lisp/org/ox-latex.el: * lisp/org/ox-man.el: * lisp/org/ox-md.el: * lisp/org/ox-org.el: * lisp/org/ox-publish.el: * lisp/org/ox-texinfo.el: * lisp/org/ox.el: * lisp/play/bubbles.el: * lisp/play/gamegrid.el: * lisp/progmodes/autoconf.el: * lisp/progmodes/cc-defs.el: * lisp/progmodes/cc-engine.el: * lisp/progmodes/cc-fonts.el: * lisp/progmodes/cc-langs.el: * lisp/progmodes/cperl-mode.el: * lisp/progmodes/ebrowse.el: * lisp/progmodes/elisp-mode.el: * lisp/progmodes/flymake-cc.el: * lisp/progmodes/flymake.el: * lisp/progmodes/fortran.el: * lisp/progmodes/grep.el: * lisp/progmodes/gud.el: * lisp/progmodes/idlwave.el: * lisp/progmodes/js.el: * lisp/progmodes/m4-mode.el: * lisp/progmodes/make-mode.el: * lisp/progmodes/mixal-mode.el: * lisp/progmodes/modula2.el: * lisp/progmodes/octave.el: * lisp/progmodes/opascal.el: * lisp/progmodes/prolog.el: * lisp/progmodes/ps-mode.el: * lisp/progmodes/python.el: * lisp/progmodes/ruby-mode.el: * lisp/progmodes/sh-script.el: * lisp/progmodes/sql.el: * lisp/progmodes/verilog-mode.el: * lisp/ps-mule.el: * lisp/rtree.el: * lisp/ruler-mode.el: * lisp/ses.el: * lisp/simple.el: * lisp/startup.el: * lisp/subr.el: * lisp/term/ns-win.el: * lisp/textmodes/bibtex.el: * lisp/textmodes/conf-mode.el: * lisp/textmodes/css-mode.el: * lisp/textmodes/refill.el: * lisp/textmodes/sgml-mode.el: * lisp/textmodes/tex-mode.el: * lisp/tutorial.el: * lisp/url/url-dav.el: * lisp/url/url-gw.el: * lisp/url/url-http.el: * lisp/url/url-methods.el: * lisp/url/url-privacy.el: * lisp/vc/cvs-status.el: * lisp/vc/diff-mode.el: * lisp/vc/ediff-init.el: * lisp/vc/ediff-ptch.el: * lisp/vc/log-edit.el: * lisp/vc/log-view.el: * lisp/vc/pcvs-info.el: * lisp/vc/pcvs.el: * lisp/vc/smerge-mode.el: * lisp/vc/vc-git.el: * lisp/vc/vc-hg.el: * lisp/vc/vc-mtn.el: * lisp/vc/vc-rcs.el: * lisp/whitespace.el: * lisp/window.el: * test/lisp/electric-tests.el: * test/lisp/emacs-lisp/cl-lib-tests.el: * test/lisp/emacs-lisp/ert-tests.el: * test/lisp/epg-tests.el: * test/lisp/jsonrpc-tests.el: * test/src/data-tests.el: * test/src/json-tests.el: Replace most insignificant backquotes.
2018-11-05 00:22:15 +00:00
'(("\"" "\"" "-in-strings")))
(if test-in-code
Replace insignificant backquotes Replace most insignificant occurrences of '`' with a straight quote, sharp quote or nothing. This includes backquotes in 'pcase' patterns. * admin/admin.el: * lisp/apropos.el: * lisp/arc-mode.el: * lisp/auth-source.el: * lisp/avoid.el: * lisp/bindings.el: * lisp/bs.el: * lisp/calculator.el: * lisp/calendar/todo-mode.el: * lisp/cedet/semantic.el: * lisp/cedet/semantic/analyze/debug.el: * lisp/cedet/semantic/bovine.el: * lisp/cedet/semantic/dep.el: * lisp/cedet/semantic/grammar.el: * lisp/cedet/semantic/wisent/comp.el: * lisp/cedet/semantic/wisent/grammar.el: * lisp/cedet/srecode/mode.el: * lisp/cus-edit.el: * lisp/doc-view.el: * lisp/elec-pair.el: * lisp/electric.el: * lisp/emacs-lisp/autoload.el: * lisp/emacs-lisp/benchmark.el: * lisp/emacs-lisp/byte-opt.el: * lisp/emacs-lisp/bytecomp.el: * lisp/emacs-lisp/cconv.el: * lisp/emacs-lisp/cl-extra.el: * lisp/emacs-lisp/cl-generic.el: * lisp/emacs-lisp/cl-macs.el: * lisp/emacs-lisp/copyright.el: * lisp/emacs-lisp/debug.el: * lisp/emacs-lisp/eieio-compat.el: * lisp/emacs-lisp/ert.el: * lisp/emacs-lisp/generator.el: * lisp/emacs-lisp/inline.el: * lisp/emacs-lisp/macroexp.el: * lisp/emacs-lisp/map.el: * lisp/emacs-lisp/package-x.el: * lisp/emacs-lisp/package.el: * lisp/emacs-lisp/radix-tree.el: * lisp/emacs-lisp/smie.el: * lisp/epa.el: * lisp/erc/erc-dcc.el: * lisp/erc/erc-track.el: * lisp/erc/erc.el: * lisp/eshell/em-ls.el: * lisp/eshell/esh-cmd.el: * lisp/files.el: * lisp/filesets.el: * lisp/font-lock.el: * lisp/frameset.el: * lisp/gnus/gnus-agent.el: * lisp/gnus/gnus-art.el: * lisp/gnus/gnus-cite.el: * lisp/gnus/gnus-group.el: * lisp/gnus/gnus-msg.el: * lisp/gnus/gnus-salt.el: * lisp/gnus/gnus-srvr.el: * lisp/gnus/gnus-sum.el: * lisp/gnus/gnus-topic.el: * lisp/gnus/gnus-util.el: * lisp/gnus/gnus.el: * lisp/gnus/message.el: * lisp/gnus/mm-util.el: * lisp/gnus/mml.el: * lisp/gnus/nnheader.el: * lisp/gnus/nnimap.el: * lisp/gnus/nnmairix.el: * lisp/gnus/spam.el: * lisp/hexl.el: * lisp/hi-lock.el: * lisp/ibuf-ext.el: * lisp/ibuffer.el: * lisp/ido.el: * lisp/info.el: * lisp/international/mule-cmds.el: * lisp/international/mule-util.el: * lisp/json.el: * lisp/jsonrpc.el: * lisp/language/cyrillic.el: * lisp/language/european.el: * lisp/language/georgian.el: * lisp/language/tibetan.el: * lisp/language/utf-8-lang.el: * lisp/language/vietnamese.el: * lisp/ldefs-boot.el: * lisp/mail/mail-extr.el: * lisp/man.el: * lisp/menu-bar.el: * lisp/mh-e/mh-acros.el: * lisp/mh-e/mh-folder.el: * lisp/mh-e/mh-mime.el: * lisp/mh-e/mh-show.el: * lisp/mh-e/mh-speed.el: * lisp/minibuffer.el: * lisp/mpc.el: * lisp/net/ange-ftp.el: * lisp/net/hmac-def.el: * lisp/net/newst-backend.el: * lisp/net/quickurl.el: * lisp/net/tramp-archive.el: * lisp/net/tramp-compat.el: * lisp/notifications.el: * lisp/obsolete/pgg-parse.el: * lisp/obsolete/vc-arch.el: * lisp/obsolete/xesam.el: * lisp/org/ob-C.el: * lisp/org/ob-core.el: * lisp/org/ob-exp.el: * lisp/org/ob-groovy.el: * lisp/org/ob-haskell.el: * lisp/org/ob-io.el: * lisp/org/ob-lisp.el: * lisp/org/ob-lob.el: * lisp/org/ob-lua.el: * lisp/org/ob-octave.el: * lisp/org/ob-perl.el: * lisp/org/ob-python.el: * lisp/org/ob-ref.el: * lisp/org/ob-ruby.el: * lisp/org/ob-sql.el: * lisp/org/org-agenda.el: * lisp/org/org-capture.el: * lisp/org/org-clock.el: * lisp/org/org-colview.el: * lisp/org/org-duration.el: * lisp/org/org-element.el: * lisp/org/org-entities.el: * lisp/org/org-gnus.el: * lisp/org/org-indent.el: * lisp/org/org-info.el: * lisp/org/org-inlinetask.el: * lisp/org/org-lint.el: * lisp/org/org-list.el: * lisp/org/org-mouse.el: * lisp/org/org-plot.el: * lisp/org/org-src.el: * lisp/org/org-table.el: * lisp/org/org.el: * lisp/org/ox-ascii.el: * lisp/org/ox-html.el: * lisp/org/ox-latex.el: * lisp/org/ox-man.el: * lisp/org/ox-md.el: * lisp/org/ox-org.el: * lisp/org/ox-publish.el: * lisp/org/ox-texinfo.el: * lisp/org/ox.el: * lisp/play/bubbles.el: * lisp/play/gamegrid.el: * lisp/progmodes/autoconf.el: * lisp/progmodes/cc-defs.el: * lisp/progmodes/cc-engine.el: * lisp/progmodes/cc-fonts.el: * lisp/progmodes/cc-langs.el: * lisp/progmodes/cperl-mode.el: * lisp/progmodes/ebrowse.el: * lisp/progmodes/elisp-mode.el: * lisp/progmodes/flymake-cc.el: * lisp/progmodes/flymake.el: * lisp/progmodes/fortran.el: * lisp/progmodes/grep.el: * lisp/progmodes/gud.el: * lisp/progmodes/idlwave.el: * lisp/progmodes/js.el: * lisp/progmodes/m4-mode.el: * lisp/progmodes/make-mode.el: * lisp/progmodes/mixal-mode.el: * lisp/progmodes/modula2.el: * lisp/progmodes/octave.el: * lisp/progmodes/opascal.el: * lisp/progmodes/prolog.el: * lisp/progmodes/ps-mode.el: * lisp/progmodes/python.el: * lisp/progmodes/ruby-mode.el: * lisp/progmodes/sh-script.el: * lisp/progmodes/sql.el: * lisp/progmodes/verilog-mode.el: * lisp/ps-mule.el: * lisp/rtree.el: * lisp/ruler-mode.el: * lisp/ses.el: * lisp/simple.el: * lisp/startup.el: * lisp/subr.el: * lisp/term/ns-win.el: * lisp/textmodes/bibtex.el: * lisp/textmodes/conf-mode.el: * lisp/textmodes/css-mode.el: * lisp/textmodes/refill.el: * lisp/textmodes/sgml-mode.el: * lisp/textmodes/tex-mode.el: * lisp/tutorial.el: * lisp/url/url-dav.el: * lisp/url/url-gw.el: * lisp/url/url-http.el: * lisp/url/url-methods.el: * lisp/url/url-privacy.el: * lisp/vc/cvs-status.el: * lisp/vc/diff-mode.el: * lisp/vc/ediff-init.el: * lisp/vc/ediff-ptch.el: * lisp/vc/log-edit.el: * lisp/vc/log-view.el: * lisp/vc/pcvs-info.el: * lisp/vc/pcvs.el: * lisp/vc/smerge-mode.el: * lisp/vc/vc-git.el: * lisp/vc/vc-hg.el: * lisp/vc/vc-mtn.el: * lisp/vc/vc-rcs.el: * lisp/whitespace.el: * lisp/window.el: * test/lisp/electric-tests.el: * test/lisp/emacs-lisp/cl-lib-tests.el: * test/lisp/emacs-lisp/ert-tests.el: * test/lisp/epg-tests.el: * test/lisp/jsonrpc-tests.el: * test/src/data-tests.el: * test/src/json-tests.el: Replace most insignificant backquotes.
2018-11-05 00:22:15 +00:00
'(("" "" ""))))
append
(cl-loop
for char across input
for pos from 0
unless (eq char ?-)
collect (electric-pair-define-test-form
name
fixture
(aref input pos)
pos
expected-string
expected-point
skip-pair-string
prefix
suffix
extra-desc
mode
bindings
fixture-fn))))))
2013-12-28 06:37:35 +00:00
;;; Basic pairs and skips
;;;
(define-electric-pair-test balanced-situation
" (()) " "(((((((" :skip-pair-string "ppppppp"
:modes '(ruby-mode))
(define-electric-pair-test too-many-openings
" ((()) " "(((((((" :skip-pair-string "ppppppp")
(define-electric-pair-test too-many-closings
" (())) " "(((((((" :skip-pair-string "------p")
(define-electric-pair-test too-many-closings-2
"() ) " "---(---" :skip-pair-string "-------")
(define-electric-pair-test too-many-closings-3
")() " "(------" :skip-pair-string "-------")
(define-electric-pair-test balanced-autoskipping
" (()) " "---))--" :skip-pair-string "---ss--")
(define-electric-pair-test too-many-openings-autoskipping
" ((()) " "----))-" :skip-pair-string "-------")
(define-electric-pair-test too-many-closings-autoskipping
" (())) " "---)))-" :skip-pair-string "---sss-")
;;; Mixed parens
;;;
(define-electric-pair-test mixed-paren-1
" ()] " "-(-(---" :skip-pair-string "-p-p---")
(define-electric-pair-test mixed-paren-2
" [() " "-(-()--" :skip-pair-string "-p-ps--")
(define-electric-pair-test mixed-paren-3
" (]) " "-(-()--" :skip-pair-string "---ps--")
(define-electric-pair-test mixed-paren-4
" ()] " "---)]--" :skip-pair-string "---ss--")
(define-electric-pair-test mixed-paren-5
" [() " "----(--" :skip-pair-string "----p--")
(define-electric-pair-test find-matching-different-paren-type
" ()] " "-[-----" :skip-pair-string "-------")
(define-electric-pair-test find-matching-different-paren-type-inside-list
"( ()]) " "-[-----" :skip-pair-string "-------")
2013-12-28 06:37:35 +00:00
(define-electric-pair-test ignore-different-nonmatching-paren-type
"( ()]) " "-(-----" :skip-pair-string "-p-----")
(define-electric-pair-test autopair-keep-least-amount-of-mixed-unbalance
"( ()] " "-(-----" :skip-pair-string "-p-----")
(define-electric-pair-test dont-autopair-to-resolve-mixed-unbalance
"( ()] " "-[-----" :skip-pair-string "-------")
(define-electric-pair-test autopair-so-as-not-to-worsen-unbalance-situation
"( (]) " "-[-----" :skip-pair-string "-p-----")
(define-electric-pair-test skip-over-partially-balanced
" [([]) " "-----)---" :skip-pair-string "-----s---")
(define-electric-pair-test only-skip-over-at-least-partially-balanced-stuff
" [([()) " "-----))--" :skip-pair-string "-----s---")
;;; Quotes
;;;
(define-electric-pair-test pair-some-quotes-skip-others
" \"\" " "-\"\"-\"---" :skip-pair-string "-ps-p----"
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
(define-electric-pair-test skip-single-quotes-in-ruby-mode
" '' " "--'-" :skip-pair-string "--s-"
:modes '(ruby-mode)
:test-in-comments nil
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
(define-electric-pair-test leave-unbalanced-quotes-alone
" \"' " "-\"'-" :skip-pair-string "----"
:modes '(ruby-mode)
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
(define-electric-pair-test leave-unbalanced-quotes-alone-2
" \"\\\"' " "-\"--'-" :skip-pair-string "------"
:modes '(ruby-mode)
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
(define-electric-pair-test leave-unbalanced-quotes-alone-3
" foo\\''" "'------" :skip-pair-string "-------"
:modes '(ruby-mode)
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
(define-electric-pair-test inhibit-if-strings-mismatched
"\"foo\"\"bar" "\""
:expected-string "\"\"foo\"\"bar"
:expected-point 2
:test-in-strings nil
:bindings `((electric-pair-text-syntax-table
. ,prog-mode-syntax-table)))
(define-electric-pair-test inhibit-in-mismatched-string-inside-ruby-comments
"foo\"\"
#
# \"bar\"
# \" \"
# \"
#
baz\"\""
"\""
:modes '(ruby-mode)
:test-in-strings nil
:test-in-comments nil
:expected-point 19
:expected-string
"foo\"\"
#
# \"bar\"\"
# \" \"
# \"
#
baz\"\""
:fixture-fn (lambda () (goto-char (point-min)) (search-forward "bar")))
(define-electric-pair-test inhibit-in-mismatched-string-inside-c-comments
"foo\"\"/*
\"bar\"
\" \"
\"
*/baz\"\""
"\""
:modes '(c-mode)
:test-in-strings nil
:test-in-comments nil
:expected-point 18
:expected-string
"foo\"\"/*
\"bar\"\"
\" \"
\"
*/baz\"\""
:fixture-fn (lambda () (goto-char (point-min)) (search-forward "bar")))
;;; More quotes, but now don't bind `electric-pair-text-syntax-table'
;;; to `prog-mode-syntax-table'. Use the defaults for
;;; `electric-pair-pairs' and `electric-pair-text-pairs'.
;;;
(define-electric-pair-test pairing-skipping-quotes-in-code
" \"\" " "-\"\"-----" :skip-pair-string "-ps------"
:test-in-strings nil
:test-in-comments nil)
(define-electric-pair-test skipping-quotes-in-comments
" \"\" " "--\"-----" :skip-pair-string "--s------"
:test-in-strings nil)
;;; Skipping over whitespace
;;;
(define-electric-pair-test whitespace-jumping
" ( ) " "--))))---" :expected-string " ( ) " :expected-point 8
:bindings '((electric-pair-skip-whitespace . t)))
(define-electric-pair-test whitespace-chomping
" ( ) " "--)------" :expected-string " () " :expected-point 4
:bindings '((electric-pair-skip-whitespace . chomp)))
(define-electric-pair-test whitespace-chomping-2
" ( \n\t\t\n ) " "--)------" :expected-string " () " :expected-point 4
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-comments nil)
electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { <indented point> } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () <newline> { <newline> The e-p-m inserts the pair function () <newline> { <newline>} And then e-l-m kicks in for the pair again, yielding the desired result function () <newline> { <indented point> } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test.
2019-01-22 15:46:56 +00:00
(ert-deftest electric-pair-whitespace-chomping-2-at-point-4-in-c++-mode-in-strings nil
"Check if whitespace chomping works in `c++' unterminated strings."
(electric-pair-test-for
"\" ( \n \n ) \"" 4 41 "\" () \"" 5 'c++-mode
'((electric-pair-skip-whitespace . chomp))
(lambda () (electric-pair-mode 1))))
(define-electric-pair-test whitespace-chomping-dont-cross-comments
" ( \n\t\t\n ) " "--)------" :expected-string " () \n\t\t\n ) "
:expected-point 4
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-strings nil
:test-in-code nil
:test-in-comments t
:fixture-fn (lambda () (when (eq major-mode 'c-mode)
(c-toggle-comment-style -1))))
(define-electric-pair-test whitespace-skipping-for-quotes-not-outside
" \" \"" "\"-----" :expected-string "\"\" \" \""
:expected-point 2
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-strings nil
:test-in-code t
:test-in-comments nil)
(define-electric-pair-test whitespace-skipping-for-quotes-only-inside
" \" \"" "---\"--" :expected-string " \"\""
:expected-point 5
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-strings nil
:test-in-code t
:test-in-comments nil)
(define-electric-pair-test whitespace-skipping-quotes-not-without-proper-syntax
" \" \"" "---\"--" :expected-string " \"\"\" \""
:expected-point 5
:modes '(text-mode)
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-strings nil
:test-in-code t
:test-in-comments nil)
;;; Pairing arbitrary characters
;;;
(define-electric-pair-test angle-brackets-everywhere
"<>" "<>" :skip-pair-string "ps"
:bindings '((electric-pair-pairs . ((?\< . ?\>)))))
(define-electric-pair-test angle-brackets-everywhere-2
"(<>" "-<>" :skip-pair-string "-ps"
:bindings '((electric-pair-pairs . ((?\< . ?\>)))))
(defvar electric-pair-test-angle-brackets-table
(let ((table (make-syntax-table prog-mode-syntax-table)))
(modify-syntax-entry ?\< "(>" table)
(modify-syntax-entry ?\> ")<`" table)
table))
(define-electric-pair-test angle-brackets-pair
"<>" "<" :expected-string "<><>" :expected-point 2
:test-in-code nil
:bindings `((electric-pair-text-syntax-table
. ,electric-pair-test-angle-brackets-table)))
(define-electric-pair-test angle-brackets-skip
"<>" "->" :expected-string "<>" :expected-point 3
:test-in-code nil
:bindings `((electric-pair-text-syntax-table
. ,electric-pair-test-angle-brackets-table)))
(define-electric-pair-test pair-backtick-and-quote-in-comments
";; " "---`" :expected-string ";; `'" :expected-point 5
:test-in-comments nil
:test-in-strings nil
:modes '(emacs-lisp-mode)
:bindings '((electric-pair-text-pairs . ((?\` . ?\')))))
(define-electric-pair-test skip-backtick-and-quote-in-comments
";; `foo'" "-------'" :expected-string ";; `foo'" :expected-point 9
:test-in-comments nil
:test-in-strings nil
:modes '(emacs-lisp-mode)
:bindings '((electric-pair-text-pairs . ((?\` . ?\')))))
(define-electric-pair-test pair-backtick-and-quote-in-strings
"\"\"" "-`" :expected-string "\"`'\"" :expected-point 3
:test-in-comments nil
:test-in-strings nil
:modes '(emacs-lisp-mode)
:bindings '((electric-pair-text-pairs . ((?\` . ?\')))))
(define-electric-pair-test skip-backtick-and-quote-in-strings
"\"`'\"" "--'" :expected-string "\"`'\"" :expected-point 4
:test-in-comments nil
:test-in-strings nil
:modes '(emacs-lisp-mode)
:bindings '((electric-pair-text-pairs . ((?\` . ?\')))))
(define-electric-pair-test skip-backtick-and-quote-in-strings-2
" \"`'\"" "----'" :expected-string " \"`'\"" :expected-point 6
:test-in-comments nil
:test-in-strings nil
:modes '(emacs-lisp-mode)
:bindings '((electric-pair-text-pairs . ((?\` . ?\')))))
;;; `js-mode' has `electric-layout-rules' for '{ and '}
;;;
(define-electric-pair-test js-mode-braces
"" "{" :expected-string "{}" :expected-point 2
:modes '(js-mode)
:fixture-fn (lambda ()
(electric-pair-mode 1)))
electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { <indented point> } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () <newline> { <newline> The e-p-m inserts the pair function () <newline> { <newline>} And then e-l-m kicks in for the pair again, yielding the desired result function () <newline> { <indented point> } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test.
2019-01-22 15:46:56 +00:00
(define-electric-pair-test js-mode-braces-with-layout
"" "{" :expected-string "{\n\n}" :expected-point 3
:modes '(js-mode)
:test-in-comments nil
:test-in-strings nil
:fixture-fn (lambda ()
(electric-layout-mode 1)
(electric-pair-mode 1)))
(define-electric-pair-test js-mode-braces-with-layout-and-indent
"" "{" :expected-string "{\n \n}" :expected-point 7
:modes '(js-mode)
:test-in-comments nil
:test-in-strings nil
:fixture-fn (lambda ()
(electric-pair-mode 1)
(electric-indent-mode 1)
(electric-layout-mode 1)))
;;; Backspacing
;;; TODO: better tests
;;;
(ert-deftest electric-pair-backspace-1 ()
(save-electric-modes
(with-temp-buffer
(insert "()")
(goto-char 2)
(electric-pair-delete-pair 1)
(should (equal "" (buffer-string))))))
;;; Undoing
(ert-deftest electric-pair-undo-unrelated-state ()
"Make sure `electric-pair-mode' does not confuse `undo' (bug#39680)."
(with-temp-buffer
(buffer-enable-undo)
(electric-pair-local-mode)
(let ((last-command-event ?\())
(ert-simulate-command '(self-insert-command 1)))
(undo-boundary)
(let ((last-command-event ?a))
(ert-simulate-command '(self-insert-command 1)))
(undo-boundary)
(ert-simulate-command '(undo))
(let ((last-command-event ?\())
(ert-simulate-command '(self-insert-command 1)))
(should (string= (buffer-string) "(())"))))
;;; Electric newlines between pairs
;;; TODO: better tests
(ert-deftest electric-pair-open-extra-newline ()
(save-electric-modes
(with-temp-buffer
(c-mode)
(electric-pair-mode 1)
(electric-indent-mode 1)
(insert "int main {}")
(backward-char 1)
(let ((c-basic-offset 4))
(newline 1 t)
(should (equal "int main {\n \n}"
(buffer-string)))
(should (equal (point) (- (point-max) 2)))))))
;;; Autowrapping
;;;
(define-electric-pair-test autowrapping-1
"foo" "(" :expected-string "(foo)" :expected-point 2
:fixture-fn (lambda ()
(electric-pair-mode 1)
(mark-sexp 1)))
(define-electric-pair-test autowrapping-2
"foo" ")" :expected-string "(foo)" :expected-point 6
:fixture-fn (lambda ()
(electric-pair-mode 1)
(mark-sexp 1)))
(define-electric-pair-test autowrapping-3
"foo" ")" :expected-string "(foo)" :expected-point 6
:fixture-fn (lambda ()
(electric-pair-mode 1)
(goto-char (point-max))
(skip-chars-backward "\"")
(mark-sexp -1)))
(define-electric-pair-test autowrapping-4
"foo" "(" :expected-string "(foo)" :expected-point 2
:fixture-fn (lambda ()
(electric-pair-mode 1)
(goto-char (point-max))
(skip-chars-backward "\"")
(mark-sexp -1)))
(define-electric-pair-test autowrapping-5
"foo" "\"" :expected-string "\"foo\"" :expected-point 2
:fixture-fn (lambda ()
(electric-pair-mode 1)
(mark-sexp 1)))
(define-electric-pair-test autowrapping-6
"foo" "\"" :expected-string "\"foo\"" :expected-point 6
:fixture-fn (lambda ()
(electric-pair-mode 1)
(goto-char (point-max))
(skip-chars-backward "\"")
(mark-sexp -1)))
(define-electric-pair-test autowrapping-7
"foo" "\"" :expected-string "``foo''" :expected-point 8
:modes '(tex-mode)
:test-in-comments nil
:fixture-fn (lambda ()
(electric-pair-mode 1)
(goto-char (point-max))
(skip-chars-backward "\"")
(mark-sexp -1)))
;;; Electric quotes
(define-electric-pair-test electric-quote-string
"" "'" :expected-string "'" :expected-point 2
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-string . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-opening-single
"" "`" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-closing-single
"" "'" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-opening-double
"" "-`" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-closing-double
"" "-'" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-disabled
"" "\"" :expected-string "\"" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-backtick
"" "`" :expected-string "`" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-bob-single
"" "'" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-bob-double
"" "-'" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-bob
"" "\"" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-bol-single
"a\n" "--'" :expected-string "a\n" :expected-point 4
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-bol-double
"a\n" "---'" :expected-string "a\n" :expected-point 4
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-bol
"a\n" "--\"" :expected-string "a\n" :expected-point 4
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-after-space-single
" " "-'" :expected-string " " :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-after-space-double
" " "--'" :expected-string "" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-after-space
" " "-\"" :expected-string "" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-after-letter-single
"a" "-'" :expected-string "a" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-after-letter-double
"a" "--'" :expected-string "a”" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-after-letter
"a" "-\"" :expected-string "a”" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-after-paren-single
"(" "-'" :expected-string "(" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-context-sensitive-after-paren-double
"(" "--'" :expected-string "(“" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-after-paren
"(" "-\"" :expected-string "(“" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-no-context-single
" " "-'" :expected-string " " :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-replace-double-escaped-open
"foo \\" "-----\"" :expected-string "foo \\"
:expected-point 7 :modes '(emacs-lisp-mode c-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t)
(electric-quote-comment . t)
(electric-quote-string . t))
:test-in-comments t :test-in-strings t :test-in-code nil)
(define-electric-pair-test electric-quote-replace-double-escaped-close
"foo \\“foo\\" "----------\"" :expected-string "foo \\“foo\\"
:expected-point 12 :modes '(emacs-lisp-mode c-mode)
:fixture-fn #'electric-quote-local-mode
:bindings '((electric-quote-replace-double . t)
(electric-quote-comment . t)
(electric-quote-string . t))
:test-in-comments t :test-in-strings t :test-in-code nil)
;; Simulate markdown-mode: it sets both comment-start and
;; comment-use-syntax, but derives from text-mode.
(define-electric-pair-test electric-quote-markdown-in-text
"" "'" :expected-string "" :expected-point 2
:modes '(text-mode)
:fixture-fn (lambda ()
(electric-quote-local-mode)
(add-hook 'electric-quote-inhibit-functions
(lambda ()
(save-excursion (search-backward "`" nil t)))
nil :local))
:bindings '((comment-start . "<!--") (comment-use-syntax . t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-markdown-in-code
"`a`" "-'" :expected-string "`'a`" :expected-point 3
:modes '(text-mode)
:fixture-fn (lambda ()
(electric-quote-local-mode)
(add-hook 'electric-quote-inhibit-functions
(lambda ()
(save-excursion (search-backward "`" nil t)))
nil :local))
:bindings '((comment-start . "<!--") (comment-use-syntax . t))
:test-in-comments nil :test-in-strings nil)
;;; tests for `electric-layout-mode'
electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { <indented point> } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () <newline> { <newline> The e-p-m inserts the pair function () <newline> { <newline>} And then e-l-m kicks in for the pair again, yielding the desired result function () <newline> { <indented point> } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test.
2019-01-22 15:46:56 +00:00
(define-derived-mode plainer-c-mode c-mode "pC"
"A plainer/saner C-mode with no internal electric machinery."
(c-toggle-electric-state -1)
(setq-local electric-indent-local-mode-hook nil)
(setq-local electric-indent-mode-hook nil)
(electric-indent-local-mode 1)
(dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\]))
(local-set-key (vector key) 'self-insert-command)))
(defun electric-layout-for-c-style-du-jour (inserted)
"A function to use in `electric-layout-rules'."
(when (memq inserted '(?\{ ?\}))
electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { <indented point> } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () <newline> { <newline> The e-p-m inserts the pair function () <newline> { <newline>} And then e-l-m kicks in for the pair again, yielding the desired result function () <newline> { <indented point> } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test.
2019-01-22 15:46:56 +00:00
(save-excursion
(backward-char 2) (c-point-syntax) (forward-char) ; silly, but needed
(c-brace-newlines (c-point-syntax)))))
(ert-deftest electric-layout-plainer-c-mode-use-c-style ()
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
(electric-pair-local-mode 1)
(electric-indent-local-mode 1)
(setq-local electric-layout-rules
'(electric-layout-for-c-style-du-jour))
(insert "int main () ")
(let ((last-command-event ?\{))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main ()\n{\n \n}\n"))))
(ert-deftest electric-layout-int-main-kernel-style ()
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
(electric-pair-local-mode 1)
(electric-indent-local-mode 1)
(setq-local electric-layout-rules
electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { <indented point> } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () <newline> { <newline> The e-p-m inserts the pair function () <newline> { <newline>} And then e-l-m kicks in for the pair again, yielding the desired result function () <newline> { <indented point> } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test.
2019-01-22 15:46:56 +00:00
'((?\{ . (after))
(?\} . (before))))
(insert "int main () ")
(let ((last-command-event ?\{))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main () {\n \n}"))))
(ert-deftest electric-layout-control-reindentation ()
"Same as `emacs-lisp-int-main-kernel-style', but checking
Bug#35254."
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
(electric-pair-local-mode 1)
(electric-indent-local-mode 1)
(setq-local electric-layout-rules
'((?\{ . (after))
(?\} . (before))))
(insert "int main () ")
(let ((last-command-event ?\{))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main () {\n \n}"))
;; insert an additional newline and check indentation and
;; reindentation
(call-interactively 'newline)
(should (equal (buffer-string) "int main () {\n\n \n}"))))
(ert-deftest electric-modes-int-main-allman-style ()
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
(electric-pair-local-mode 1)
(electric-indent-local-mode 1)
(setq-local electric-layout-rules
electric-layout-mode kicks in before electric-pair-mode This aims to solve problems with indentation. Previously in, say, a js-mode buffer with electric-layout-rules set to (?\{ before after) (?\} before) would produce an intended: function () { <indented point> } The initial state function () { Would go immediately to the following by e-p-m function () {} Only then would e-l-m be applied to } first, and then again to {. This makes lines indent in the wrong order, which can be a problem in some modes. The way we fix this is by reversing the order of e-p-m and e-l-m in the post-self-insert-hook (and also fixing a number of details that this uncovered). In the end this changes the sequence from function () { By way of e-l-m becomes: function () <newline> { <newline> The e-p-m inserts the pair function () <newline> { <newline>} And then e-l-m kicks in for the pair again, yielding the desired result function () <newline> { <indented point> } * lisp/elec-pair.el (electric-pair--insert): Bind electric-layout-no-duplicate-newlines. (electric-pair-inhibit-if-helps-balance) (electric-pair-skip-if-helps-balance): Use insert-before-markers, playing nice with save-excurion. (electric-pair-post-self-insert-function): Go to correct position before checking electric-pair-inhibit-predicate and electric-pair-skip-self predicate. (electric-pair-post-self-insert-function): Increase priority to 50. * lisp/electric.el (electric-indent-post-self-insert-function): Delete trailing space in reindented line only if line was really reindented. Rewrite comment. (electric-layout-allow-duplicate-newlines): New variable. (electric-layout-post-self-insert-function-1): Rewrite comments. Honours electric-layout-allow-duplicate-newlines. Don't reindent previous line because racecar. * test/lisp/electric-tests.el: New test. (plainer-c-mode): Move up. (electric-modes-int-main-allman-style) (electric-layout-int-main-kernel-style): Simplify electric-layout-rules. (electric-layout-for-c-style-du-jour): New helper. (electric-layout-plainer-c-mode-use-c-style): New test.
2019-01-22 15:46:56 +00:00
'((?\{ . (before after))
(?\} . (before))))
(insert "int main () ")
(let ((last-command-event ?\{))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main ()\n{\n \n}"))))
(ert-deftest electric-pair-mode-newline-between-parens ()
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode -1) ;; ensure e-l-m mode is off
(electric-pair-local-mode 1)
(insert-before-markers "int main () {}")
(backward-char 1)
(let ((last-command-event ?\r))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main () {\n \n}"))))
(ert-deftest electric-layout-mode-newline-between-parens-without-e-p-m ()
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
(electric-pair-local-mode -1) ;; ensure e-p-m mode is off
(electric-indent-local-mode 1)
(setq-local electric-layout-rules
'((?\n
.
(lambda ()
(when (eq (save-excursion
(skip-chars-backward "\t\s")
(char-before (1- (point))))
(matching-paren (char-after)))
'(after-stay))))))
(insert "int main () {}")
(backward-char 1)
(let ((last-command-event ?\r))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main () {\n \n}"))))
(ert-deftest electric-layout-mode-newline-between-parens-without-e-p-m-2 ()
(ert-with-test-buffer ()
(plainer-c-mode)
(electric-layout-local-mode 1)
(electric-pair-local-mode -1) ;; ensure e-p-m mode is off
(electric-indent-local-mode 1)
(setq-local electric-layout-rules
'((lambda (char)
(when (and
(eq char ?\n)
(eq (save-excursion
(skip-chars-backward "\t\s")
(char-before (1- (point))))
(matching-paren (char-after))))
'(after-stay)))))
(insert "int main () {}")
(backward-char 1)
(let ((last-command-event ?\r))
(call-interactively (key-binding `[,last-command-event])))
(should (equal (buffer-string) "int main () {\n \n}"))))
(provide 'electric-tests)
;;; electric-tests.el ends here