From 256ed8d8f2762b9a1ccd7c444b974db467874435 Mon Sep 17 00:00:00 2001 From: Rainer Gemulla Date: Thu, 31 Aug 2017 20:54:48 +0200 Subject: [PATCH 1/2] Ignore double backslashes (newlines) in Latex (#784) --- smartparens-latex.el | 95 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 18 deletions(-) diff --git a/smartparens-latex.el b/smartparens-latex.el index 339f2d20..b2704154 100644 --- a/smartparens-latex.el +++ b/smartparens-latex.el @@ -77,16 +77,34 @@ (delete-char 2) (forward-char 2)))) -(defun sp-latex-point-after-backslash (id action _context) - "Return t if point follows a backslash, nil otherwise. -This predicate is only tested on \"insert\" action. +(defun sp-number-of-backslashes-before-point () + (let ((p (point))) + (while (and (> p 0) (equal (char-before p) ?\\ )) + (setq p (- p 1))) + (- (point) p))) + +(defun sp--latex-backslash-skip-match (ms mb _me) + "Skips a match if preceeded by uneven number of backslashes." + (and ms + (save-excursion + (goto-char mb) + (not (evenp (sp-number-of-backslashes-before-point)))))) + +(defun sp-latex-point-after-backslash (id action context) + "Return t if point follows an uneven number of backslashes (a +double backslash is a newline; we'd like to ignore those), nil +otherwise. This predicate is only tested on \"insert\" action. ID, ACTION, CONTEXT." (when (eq action 'insert) - (let ((trigger (sp-get-pair id :trigger))) - (looking-back (concat "\\\\" (regexp-quote (if trigger trigger id))) nil)))) + (let* ((trigger (sp-get-pair id :trigger)) + (start (- (point) (length (if trigger trigger id))))) + (when (> start 1) + (save-excursion + (goto-char start) + (not (evenp (sp-number-of-backslashes-before-point)))))))) (add-to-list 'sp-navigate-skip-match - '((tex-mode plain-tex-mode latex-mode) . sp--backslash-skip-match)) + '((tex-mode plain-tex-mode latex-mode) . sp--latex-backslash-skip-match)) (sp-with-modes '( tex-mode @@ -100,7 +118,8 @@ ID, ACTION, CONTEXT." :unless '(sp-latex-point-after-backslash sp-in-math-p)) ;; math modes, yay. The :actions are provided automatically if ;; these pairs do not have global definitions. - (sp-local-pair "$" "$") + (sp-local-pair "$" "$" + :unless '(sp-latex-point-after-backslash)) (sp-local-pair "\\[" "\\]" :unless '(sp-latex-point-after-backslash)) @@ -117,72 +136,112 @@ ID, ACTION, CONTEXT." :post-handlers '(sp-latex-skip-double-quote)) ;; add the prefix function sticking to {} pair - (sp-local-pair "{" nil :prefix "\\\\\\(\\sw\\|\\s_\\)*") + (sp-local-pair "{" "}" + :prefix "\\\\\\(\\sw\\|\\s_\\)*" + :unless '(sp-latex-point-after-backslash)) ;; do not add more space when slurping - (sp-local-pair "{" "}") - (sp-local-pair "(" ")") - (sp-local-pair "[" "]") + (sp-local-pair "\\{" "\\}" + :unless '(sp-latex-point-after-backslash)) + (sp-local-pair "[" "]" + :unless '(sp-latex-point-after-backslash)) + (sp-local-pair "(" ")" + :unless '(sp-latex-point-after-backslash)) + (sp-local-pair "\\(" "\\)" + :unless '(sp-latex-point-after-backslash)) ;; pairs for big brackets. Needs more research on what pairs are ;; useful to add here. Post suggestions if you know some. (sp-local-pair "\\left(" "\\right)" :trigger "\\l(" :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\left[" "\\right]" :trigger "\\l[" :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\left\\{" "\\right\\}" :trigger "\\l{" :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\left|" "\\right|" :trigger "\\l|" :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\bigl(" "\\bigr)" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\biggl(" "\\biggr)" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\Bigl(" "\\Bigr)" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\Biggl(" "\\Biggr)" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\bigl[" "\\bigr]" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\biggl[" "\\biggr]" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\Bigl[" "\\Bigr]" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\Biggl[" "\\Biggr]" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\bigl\\{" "\\bigr\\}" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\biggl\\{" "\\biggr\\}" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\Bigl\\{" "\\Bigr\\}" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\Biggl\\{" "\\Biggr\\}" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\lfloor" "\\rfloor" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\lceil" "\\rceil" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\langle" "\\rangle" + :when '(sp-in-math-p) + :unless '(sp-latex-point-after-backslash) :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\lVert" "\\rVert" - :when '(sp-in-math-p) - :trigger "\\lVert" - :post-handlers '(sp-latex-insert-spaces-inside-pair)) + :when '(sp-in-math-p) + :trigger "\\lVert" + :post-handlers '(sp-latex-insert-spaces-inside-pair)) (sp-local-pair "\\lvert" "\\rvert" - :when '(sp-in-math-p) - :trigger "\\lvert" - :post-handlers '(sp-latex-insert-spaces-inside-pair)) + :when '(sp-in-math-p) + :trigger "\\lvert" + :post-handlers '(sp-latex-insert-spaces-inside-pair)) ;; some common wrappings - (sp-local-tag "\"" "``" "''" :actions '(wrap)) (sp-local-tag "\\b" "\\begin{_}" "\\end{_}") (sp-local-tag "bi" "\\begin{itemize}" "\\end{itemize}") (sp-local-tag "be" "\\begin{enumerate}" "\\end{enumerate}")) From 02d644538902c80eb88984b44679ad9711c49b15 Mon Sep 17 00:00:00 2001 From: rgemulla Date: Thu, 31 May 2018 11:15:40 +0200 Subject: [PATCH 2/2] Bugfix: do not rely on evenp from cl.el --- smartparens-latex.el | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/smartparens-latex.el b/smartparens-latex.el index b2704154..f7be9da5 100644 --- a/smartparens-latex.el +++ b/smartparens-latex.el @@ -83,12 +83,15 @@ (setq p (- p 1))) (- (point) p))) +(defun sp-evenp (num) + (eq (% num 2) 0)) + (defun sp--latex-backslash-skip-match (ms mb _me) "Skips a match if preceeded by uneven number of backslashes." (and ms (save-excursion (goto-char mb) - (not (evenp (sp-number-of-backslashes-before-point)))))) + (not (sp-evenp (sp-number-of-backslashes-before-point)))))) (defun sp-latex-point-after-backslash (id action context) "Return t if point follows an uneven number of backslashes (a @@ -101,7 +104,7 @@ ID, ACTION, CONTEXT." (when (> start 1) (save-excursion (goto-char start) - (not (evenp (sp-number-of-backslashes-before-point)))))))) + (not (sp-evenp (sp-number-of-backslashes-before-point)))))))) (add-to-list 'sp-navigate-skip-match '((tex-mode plain-tex-mode latex-mode) . sp--latex-backslash-skip-match))