diff --git a/lisp/doom-editor.el b/lisp/doom-editor.el index a6c23f051..98acb5b62 100644 --- a/lisp/doom-editor.el +++ b/lisp/doom-editor.el @@ -604,8 +604,6 @@ current buffer." :hook (doom-first-buffer . smartparens-global-mode) :commands sp-pair sp-local-pair sp-with-modes sp-point-in-comment sp-point-in-string :config - (add-to-list 'doom-point-in-string-functions 'sp-point-in-string) - (add-to-list 'doom-point-in-comment-functions 'sp-point-in-comment) ;; smartparens recognizes `slime-mrepl-mode', but not `sly-mrepl-mode', so... (add-to-list 'sp-lisp-modes 'sly-mrepl-mode) ;; Load default smartparens rules for various languages diff --git a/lisp/lib/help.el b/lisp/lib/help.el index b25962f09..b61a5f29b 100644 --- a/lisp/lib/help.el +++ b/lisp/lib/help.el @@ -355,9 +355,8 @@ without needing to check if they are available." (defun doom--help-current-module-str () (cond ((save-excursion - (require 'smartparens) (ignore-errors - (sp-beginning-of-sexp) + (thing-at-point--beginning-of-sexp) (unless (eq (char-after) ?\() (backward-char)) (let ((sexp (sexp-at-point))) diff --git a/lisp/lib/text.el b/lisp/lib/text.el index cef1a098b..dc00d2e45 100644 --- a/lisp/lib/text.el +++ b/lisp/lib/text.el @@ -1,18 +1,32 @@ ;;; lisp/lib/text.el -*- lexical-binding: t; -*- -;;;###autoload -(defvar doom-point-in-comment-functions () - "List of functions to run to determine if point is in a comment. +(defvar-local doom--sppss-memo-last-point nil) +(defvar-local doom--sppss-memo-last-result nil) -Each function takes one argument: the position of the point. Stops on the first -function to return non-nil. Used by `doom-point-in-comment-p'.") +(defun doom--sppss-memo-reset-h (&rest _ignored) + "Reset memoization as a safety precaution. + +IGNORED is a dummy argument used to eat up arguments passed from +the hook where this is executed." + (setq doom--sppss-memo-last-point nil + doom--sppss-memo-last-result nil)) ;;;###autoload -(defvar doom-point-in-string-functions () - "List of functions to run to determine if point is in a string. +(defun doom-syntax-ppss (&optional p) + "Memoize the last result of `syntax-ppss'. -Each function takes one argument: the position of the point. Stops on the first -function to return non-nil. Used by `doom-point-in-string-p'.") +P is the point at which we run `syntax-ppss'" + (let ((p (or p (point))) + (mem-p doom--sppss-memo-last-point)) + (if (and (eq p (nth 0 mem-p)) + (eq (point-min) (nth 1 mem-p)) + (eq (point-max) (nth 2 mem-p))) + doom--sppss-memo-last-result + ;; Add hook to reset memoization if necessary + (unless doom--sppss-memo-last-point + (add-hook 'before-change-functions #'doom--sppss-memo-reset-h t t)) + (setq doom--sppss-memo-last-point (list p (point-min) (point-max)) + doom--sppss-memo-last-result (syntax-ppss p))))) ;;;###autoload (defun doom-surrounded-p (pair &optional inline balanced) @@ -40,22 +54,49 @@ lines, above and below, with only whitespace in between." (= (- pt nbeg) (- nend pt)))))))))))) ;;;###autoload -(defun doom-point-in-comment-p (&optional pos) - "Return non-nil if POS is in a comment. -POS defaults to the current position." - (let ((pos (or pos (point)))) - (if doom-point-in-comment-functions - (run-hook-with-args-until-success 'doom-point-in-comment-functions pos) - (nth 4 (syntax-ppss pos))))) +(defun doom-point-in-comment-p (&optional pt) + "Return non-nil if point is in a comment. +PT defaults to the current position." + (let ((pt (or pt (point)))) + (ignore-errors + (save-excursion + ;; We cannot be in a comment if we are inside a string + (unless (nth 3 (doom-syntax-ppss pt)) + (or (nth 4 (doom-syntax-ppss pt)) + ;; this also test opening and closing comment delimiters... we + ;; need to chack that it is not newline, which is in "comment + ;; ender" class in elisp-mode, but we just want it to be treated + ;; as whitespace + (and (< pt (point-max)) + (memq (char-syntax (char-after pt)) '(?< ?>)) + (not (eq (char-after pt) ?\n))) + ;; we also need to test the special syntax flag for comment + ;; starters and enders, because `syntax-ppss' does not yet know if + ;; we are inside a comment or not (e.g. / can be a division or + ;; comment starter...). + (when-let ((s (car (syntax-after pt)))) + (or (and (/= 0 (logand (ash 1 16) s)) + (nth 4 (syntax-ppss (+ pt 2)))) + (and (/= 0 (logand (ash 1 17) s)) + (nth 4 (syntax-ppss (+ pt 1)))) + (and (/= 0 (logand (ash 1 18) s)) + (nth 4 (syntax-ppss (- pt 1)))) + (and (/= 0 (logand (ash 1 19) s)) + (nth 4 (syntax-ppss (- pt 2)))))))))))) ;;;###autoload -(defun doom-point-in-string-p (&optional pos) - "Return non-nil if POS is in a string." - ;; REVIEW Should we cache `syntax-ppss'? - (let ((pos (or pos (point)))) - (if doom-point-in-string-functions - (run-hook-with-args-until-success 'doom-point-in-string-functions pos) - (nth 3 (syntax-ppss pos))))) +(defun doom-point-in-string-p (&optional pt) + "Return non-nil if point is inside string. + +This function actually returns the 3rd element of `syntax-ppss' +which can be a number if the string is delimited by that +character or t if the string is delimited by general string +fences. + +If optional argument PT is present test this instead of point." + (ignore-errors + (save-excursion + (nth 3 (doom-syntax-ppss pt))))) ;;;###autoload (defun doom-point-in-string-or-comment-p (&optional pos) diff --git a/modules/editor/evil/autoload/advice.el b/modules/editor/evil/autoload/advice.el index eecd72153..1cf4e5aa4 100644 --- a/modules/editor/evil/autoload/advice.el +++ b/modules/editor/evil/autoload/advice.el @@ -78,10 +78,9 @@ more information on modifiers." (defun +evil--insert-newline (&optional above _noextranewline) (let ((pos (save-excursion (beginning-of-line-text) (point))) comment-auto-fill-only-comments) - (require 'smartparens) (evil-narrow-to-field (if above - (if (save-excursion (nth 4 (sp--syntax-ppss pos))) + (if (save-excursion (nth 4 (doom-syntax-ppss pos))) (evil-save-goal-column (setq evil-auto-indent nil) (goto-char pos) @@ -103,7 +102,7 @@ more information on modifiers." (forward-line -1) (back-to-indentation)) (evil-move-end-of-line) - (cond ((sp-point-in-comment pos) + (cond ((doom-point-in-comment-p pos) (setq evil-auto-indent nil) (if comment-line-break-function (funcall comment-line-break-function nil) diff --git a/modules/editor/evil/autoload/embrace.el b/modules/editor/evil/autoload/embrace.el index 6090112ea..cf1c6a925 100644 --- a/modules/editor/evil/autoload/embrace.el +++ b/modules/editor/evil/autoload/embrace.el @@ -18,7 +18,7 @@ (if (eq char 27) (cons "" "") (let* ((pair (+evil--embrace-get-pair (string char))) - (escape (if (sp-point-in-string) "\\\\" "\\")) + (escape (if (doom-point-in-string-p) "\\\\" "\\")) (escape (format "\\1%s" (regexp-quote escape)))) (cons (replace-regexp-in-string "^\\( *\\)" escape (car pair)) (replace-regexp-in-string "^\\( *\\)" escape (cdr pair))))))) diff --git a/modules/editor/evil/autoload/unimpaired.el b/modules/editor/evil/autoload/unimpaired.el index b698b56ea..04100f35c 100644 --- a/modules/editor/evil/autoload/unimpaired.el +++ b/modules/editor/evil/autoload/unimpaired.el @@ -57,13 +57,13 @@ See `+evil/next-preproc-directive' for details." (require 'newcomment) (dotimes (_ (abs count)) (cond ((> count 0) - (while (and (not (eobp)) (sp-point-in-comment)) + (while (and (not (eobp)) (doom-point-in-comment-p)) (forward-line 1)) (unless (comment-search-forward (point-max) 'noerror) (goto-char orig-pt) (user-error "No comment after point"))) (t - (while (and (not (bobp)) (sp-point-in-comment)) + (while (and (not (bobp)) (doom-point-in-comment-p)) (forward-line -1)) (unless (comment-search-backward nil 'noerror) (goto-char orig-pt)