Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore double backslashes (newlines) in Latex (#784) #792

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 80 additions & 18 deletions smartparens-latex.el
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,37 @@
(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-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 (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
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 (sp-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
Expand All @@ -100,7 +121,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))

Expand All @@ -117,72 +139,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}"))
Expand Down