Subject: [PATCH] syntax-is-{comment|string}-p

From: Alex Branham <[email-masked]>
Date: Wed, 22 Aug 2018 15:05:35 -0500

Hello -

I got tired of checking/remembering whether (nth 3 (syntax-ppss)) was a
string or a comment, so I've created two simple functions that wrap that
in a more descriptive name. I've noticed that there are a handful of
these that other modes have written, so evidently others wanted them as
well at some point.

There are two patches attached. The first creates new functions
syntax-is-comment-p and syntax-is-string-p.

The second changes most of the uses of (nth 3 (syntax-ppss)) and (nth 4
(syntax-ppss)) to use these new functions. I'm attaching it as a
separate patch since I'm not sure if yall will want it or not; it's easy
to squash if you do.

Thanks,
Alex

------------------------------------------------------------

>From 393f55de705513f5514a3e0250d81053e838c447 Mon Sep 17 00:00:00 2001
From: Alex Branham <[email-masked]>
Date: Wed, 22 Aug 2018 14:44:26 -0500
Subject: [PATCH 1/2] Add new functions syntax-is-{comment|string}-p

* lisp/emacs-lisp/syntax.el (syntax-is-comment-p, syntax-is-string-p):
  New functions
* doc/lispref/syntax.texi: Add documentation for new functions
---
 doc/lispref/syntax.texi   | 10 ++++++++++
 etc/NEWS                  |  4 ++++
 lisp/emacs-lisp/syntax.el | 12 ++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi
index dcfade3f67..e6220e5cf9 100644
--- a/doc/lispref/syntax.texi
+++ b/doc/lispref/syntax.texi
@@ -790,6 +790,16 @@ Position Parse
 Hooks}).
 @end defun
 
+@defun syntax-is-comment-p &optional pos
+This function returns non-nil when @code{POS} (which defaults to
+point) is in a comment accord to @code{syntax-ppss}
+@end defun
+
+@defun syntax-is-string-p &optional pos
+This function returns non-nil when @code{POS} (which defaults to
+point) is in a string accord to @code{syntax-ppss}
+@end defun
+
 @node Parser State
 @subsection Parser State
 @cindex parser state
diff --git a/etc/NEWS b/etc/NEWS
index d757f52466..e138105e72 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -963,6 +963,10 @@ versions.
 The new variable 'comment-use-syntax-ppss' can be set to nil to recover the old
 behavior if needed.
 
+** New functions 'syntax-is-comment-p' and 'syntax-is-string-p'.
+These can be used as a shorthand instead of checking, for example,
+(nth 3 (syntax-ppss)).
+
 ** The 'server-name' and 'server-socket-dir' variables are set when a
 socket has been passed to Emacs.
 
diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el
index ad1a9665ff..2a262c6036 100644
--- a/lisp/emacs-lisp/syntax.el
+++ b/lisp/emacs-lisp/syntax.el
@@ -616,6 +616,18 @@ syntax-ppss
        ;; a nil state.
        (parse-partial-sexp (point-min) pos))))))
 
+(defun syntax-is-comment-p (&optional pos)
+  "Return non-nil if POS is inside a comment.
+POS defaults to `point'."
+  (let ((pos (or pos (point))))
+    (nth 4 (syntax-ppss pos))))
+
+(defun syntax-is-string-p (&optional pos)
+  "Return non-nil if POS is inside a string.
+POS defaults to `point'."
+  (let ((pos (or pos (point))))
+    (nth 3 (syntax-ppss pos))))
+
 ;; Debugging functions
 
 (defun syntax-ppss-debug ()
-- 
2.18.0

>From 393f55de705513f5514a3e0250d81053e838c447 Mon Sep 17 00:00:00 2001
From: Alex Branham <[email-masked]>
Date: Wed, 22 Aug 2018 14:44:26 -0500
Subject: [PATCH 1/2] Add new functions syntax-is-{comment|string}-p

* lisp/emacs-lisp/syntax.el (syntax-is-comment-p, syntax-is-string-p):
  New functions
* doc/lispref/syntax.texi: Add documentation for new functions
---
 doc/lispref/syntax.texi   | 10 ++++++++++
 etc/NEWS                  |  4 ++++
 lisp/emacs-lisp/syntax.el | 12 ++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi
index dcfade3f67..e6220e5cf9 100644
--- a/doc/lispref/syntax.texi
+++ b/doc/lispref/syntax.texi
@@ -790,6 +790,16 @@ Position Parse
 Hooks}).
 @end defun
 
+@defun syntax-is-comment-p &optional pos
+This function returns non-nil when @code{POS} (which defaults to
+point) is in a comment accord to @code{syntax-ppss}
+@end defun
+
+@defun syntax-is-string-p &optional pos
+This function returns non-nil when @code{POS} (which defaults to
+point) is in a string accord to @code{syntax-ppss}
+@end defun
+
 @node Parser State
 @subsection Parser State
 @cindex parser state
diff --git a/etc/NEWS b/etc/NEWS
index d757f52466..e138105e72 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -963,6 +963,10 @@ versions.
 The new variable 'comment-use-syntax-ppss' can be set to nil to recover the old
 behavior if needed.
 
+** New functions 'syntax-is-comment-p' and 'syntax-is-string-p'.
+These can be used as a shorthand instead of checking, for example,
+(nth 3 (syntax-ppss)).
+
 ** The 'server-name' and 'server-socket-dir' variables are set when a
 socket has been passed to Emacs.
 
diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el
index ad1a9665ff..2a262c6036 100644
--- a/lisp/emacs-lisp/syntax.el
+++ b/lisp/emacs-lisp/syntax.el
@@ -616,6 +616,18 @@ syntax-ppss
        ;; a nil state.
        (parse-partial-sexp (point-min) pos))))))
 
+(defun syntax-is-comment-p (&optional pos)
+  "Return non-nil if POS is inside a comment.
+POS defaults to `point'."
+  (let ((pos (or pos (point))))
+    (nth 4 (syntax-ppss pos))))
+
+(defun syntax-is-string-p (&optional pos)
+  "Return non-nil if POS is inside a string.
+POS defaults to `point'."
+  (let ((pos (or pos (point))))
+    (nth 3 (syntax-ppss pos))))
+
 ;; Debugging functions
 
 (defun syntax-ppss-debug ()
-- 
2.18.0

>From eff51e05fef4d452e52c81ed7259b51612d7917a Mon Sep 17 00:00:00 2001
From: Alex Branham <[email-masked]>
Date: Wed, 22 Aug 2018 14:51:58 -0500
Subject: [PATCH 2/2] Prefer using new syntax-is-{comment|string}-p functions

* lisp/emacs-lisp/smie.el:
* lisp/ffap.el:
* lisp/progmodes/js.el:
* lisp/progmodes/meta-mode.el:
* lisp/progmodes/octave.el:
* lisp/progmodes/opascal.el:
* lisp/progmodes/pascal.el:
* lisp/progmodes/perl-mode.el:
* lisp/progmodes/prolog.el:
* lisp/progmodes/ruby-mode.el:
* lisp/progmodes/sh-script.el:
* lisp/simple.el:
* lisp/textmodes/tex-mode.el:
* lisp/thingatpt.el:
* lisp/vc/smerge-mode.el: Use new syntax-is-{comment|string}-p
  functions rather than checking (nth 3|4 (syntax-ppss))
---
 lisp/emacs-lisp/smie.el     |  8 ++++----
 lisp/ffap.el                |  2 +-
 lisp/progmodes/js.el        |  4 ++--
 lisp/progmodes/meta-mode.el |  4 ++--
 lisp/progmodes/octave.el    | 10 ++++------
 lisp/progmodes/opascal.el   |  2 +-
 lisp/progmodes/pascal.el    |  2 +-
 lisp/progmodes/perl-mode.el |  4 ++--
 lisp/progmodes/prolog.el    |  4 ++--
 lisp/progmodes/ruby-mode.el |  2 +-
 lisp/progmodes/sh-script.el | 10 +++++-----
 lisp/simple.el              |  2 +-
 lisp/textmodes/tex-mode.el  |  4 ++--
 lisp/thingatpt.el           | 12 +++---------
 lisp/vc/smerge-mode.el      |  2 +-
 15 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index c01a40172b..a82a6e2c99 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -1644,7 +1644,7 @@ smie-indent-comment-continue
   (let ((continue (and comment-continue
                        (comment-string-strip comment-continue t t))))
     (and (< 0 (length continue))
-         (looking-at (regexp-quote continue)) (nth 4 (syntax-ppss))
+         (looking-at (regexp-quote continue)) (syntax-is-comment-p)
          (let ((ppss (syntax-ppss)))
            (save-excursion
              (forward-line -1)
@@ -1660,7 +1660,7 @@ smie-indent-comment-close
        (not (looking-at " \t*$"))       ;Not just a \n comment-closer.
        (looking-at comment-end-skip)
        (let ((end (match-string 0)))
-         (and (nth 4 (syntax-ppss))
+         (and (syntax-is-comment-p)
               (save-excursion
                 (goto-char (nth 8 (syntax-ppss)))
                 (and (looking-at comment-start-skip)
@@ -1674,11 +1674,11 @@ smie-indent-comment-close
                          (current-column)))))))))
 
 (defun smie-indent-comment-inside ()
-  (and (nth 4 (syntax-ppss))
+  (and (syntax-is-comment-p)
        'noindent))
 
 (defun smie-indent-inside-string ()
-  (and (nth 3 (syntax-ppss))
+  (and (syntax-is-string-p)
        'noindent))
 
 (defun smie-indent-after-keyword ()
diff --git a/lisp/ffap.el b/lisp/ffap.el
index b51929d260..5272735147 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -1161,7 +1161,7 @@ ffap-string-at-point
            (null region-selected)
            ;; Check if END character is part of a comment.
            (save-excursion
-             (nth 4 (syntax-ppss end))))
+             (syntax-is-comment-p end)))
       ;; Move BEG to beginning of comment (after the comment start
       ;; characters), or END, whichever comes first.
       (save-excursion
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index f30e591b15..49020fec05 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -1837,7 +1837,7 @@ js--continued-expression-p
     (if (js--looking-at-operator-p)
         (if (eq (char-after) ?/)
             (prog1
-                (not (nth 3 (syntax-ppss (1+ (point)))))
+                (not (syntax-is-string-p (1+ (point))))
               (forward-char -1))
           (or
            (not (memq (char-after) '(?- ?+)))
@@ -1982,7 +1982,7 @@ js--multi-line-declaration-indentation
           (when (looking-at js--indent-operator-re)
             (goto-char (match-end 0)))
           ;; The "operator" is probably a regexp literal opener.
-          (when (nth 3 (syntax-ppss))
+          (when (syntax-is-string-p)
             (goto-char pt)))
         (while (and (not at-opening-bracket)
                     (not (bobp))
diff --git a/lisp/progmodes/meta-mode.el b/lisp/progmodes/meta-mode.el
index e207d22ff4..2475867adc 100644
--- a/lisp/progmodes/meta-mode.el
+++ b/lisp/progmodes/meta-mode.el
@@ -562,7 +562,7 @@ meta-indent-calculate
 
 (defun meta-indent-in-string-p ()
   "Tell if the point is in a string."
-  (or (nth 3 (syntax-ppss))
+  (or (syntax-is-string-p)
       (eq (get-text-property (point) 'face) font-lock-string-face)))
 
 (defun meta-indent-looking-at-code (regexp)
@@ -636,7 +636,7 @@ meta-indent-current-nesting
 		      nil t)
 		;; If we aren't in a string or in a comment, we've found something.
 		(unless (or (meta-indent-in-string-p)
-			    (nth 4 (syntax-ppss)))
+			    (syntax-is-comment-p))
 		  (cond ((= (char-after) ?\()
 			 (setq to-add (+ to-add meta-indent-level)))
 			((= (char-after) ?\))
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index 984bb73c73..ec4eaa5fe5 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -995,13 +995,11 @@ inferior-octave-track-window-width-change
 
 ;;; Miscellaneous useful functions
 
-(defun octave-in-comment-p ()
-  "Return non-nil if point is inside an Octave comment."
-  (nth 4 (syntax-ppss)))
+(defalias 'octave-in-comment-p 'syntax-is-comment-p
+  "Return non-nil if point is inside an Octave comment.")
 
-(defun octave-in-string-p ()
-  "Return non-nil if point is inside an Octave string."
-  (nth 3 (syntax-ppss)))
+(defalias 'octave-in-string-p 'syntax-is-string-p
+  "Return non-nil if point is inside an Octave string.")
 
 (defun octave-in-string-or-comment-p ()
   "Return non-nil if point is inside an Octave string or comment."
diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el
index 4606621951..7f5f5f4dea 100644
--- a/lisp/progmodes/opascal.el
+++ b/lisp/progmodes/opascal.el
@@ -1705,7 +1705,7 @@ opascal--syntax-propertize
    ("(\\(\\/\\)" (1 (prog1 ". 1c" (forward-char -1) nil)))
    ;; Pascal uses '' and "" rather than \' and \" to escape quotes.
    ("''\\|\"\"" (0 (if (save-excursion
-                         (nth 3 (syntax-ppss (match-beginning 0))))
+                         (syntax-is-string-p (match-beginning 0)))
                        (string-to-syntax ".")
                      ;; In case of 3 or more quotes in a row, only advance
                      ;; one quote at a time.
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index 6d13d328c5..f196bcdeb4 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -190,7 +190,7 @@ pascal--syntax-propertize
    ("(\\(\\/\\)" (1 (prog1 ". 1c" (forward-char -1) nil)))
    ;; Pascal uses '' and "" rather than \' and \" to escape quotes.
    ("''\\|\"\"" (0 (if (save-excursion
-                         (nth 3 (syntax-ppss (match-beginning 0))))
+                         (syntax-is-string-p (match-beginning 0)))
                        (string-to-syntax ".")
                      ;; In case of 3 or more quotes in a row, only advance
                      ;; one quote at a time.
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index b96aad7a6e..a217d4f85a 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -231,8 +231,8 @@ perl-syntax-propertize-function
       ;; check that it occurs inside a '..' string.
       ("\\(\\$\\)[{']" (1 (unless (and (eq ?\' (char-after (match-end 1)))
                                        (save-excursion
-                                         (not (nth 3 (syntax-ppss
-                                                      (match-beginning 0))))))
+                                         (not (syntax-is-string-p
+                                               (match-beginning 0)))))
                             (string-to-syntax ". p"))))
       ;; Handle funny names like $DB'stop.
       ("\\$ ?{?^?[_[:alpha:]][_[:alnum:]]*\\('\\)[_[:alpha:]]" (1 "_"))
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index a895a77796..23aed9bafe 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -2291,7 +2291,7 @@ prolog-guess-fill-prefix
   ;; fill 'txt entities?
   (when (save-excursion
           (end-of-line)
-          (nth 4 (syntax-ppss)))
+          (syntax-is-comment-p))
     (let* ((bounds (prolog-comment-limits))
            (cbeg (car bounds))
            (type (nth 2 bounds))
@@ -2755,7 +2755,7 @@ prolog-get-predspec
     (let ((state (prolog-clause-info))
           (object (prolog-in-object)))
       (if (or (equal (nth 0 state) "")
-              (nth 4 (syntax-ppss)))
+              (syntax-is-comment-p))
           nil
         (if (and (eq prolog-system 'sicstus)
                  object)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index fad7bc1fb8..abc66d3f85 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1849,7 +1849,7 @@ ruby-syntax-propertize
       ;; ?' ?" ?` are character literals (one-char strings in 1.9+).
       ("\\([?$]\\)[#\"'`:?]"
        (1 (if (save-excursion
-                (nth 3 (syntax-ppss (match-beginning 0))))
+                (syntax-is-string-p (match-beginning 0)))
               ;; Within a string, skip.
               (ignore
                (goto-char (match-end 1)))
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index aaa86b5816..26c276504c 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1882,7 +1882,7 @@ sh-smie-sh-forward-token
            (save-excursion
              (skip-chars-backward " \t")
              (not (bolp))))
-      (if (and (match-end 1) (not (nth 3 (syntax-ppss))))
+      (if (and (match-end 1) (not (syntax-is-string-p)))
           ;; Right before a here-doc.
           (let ((forward-sexp-function nil))
             (forward-sexp 1)
@@ -1931,7 +1931,7 @@ sh-smie-sh-backward-token
     (cond
      ((and (bolp) (not (bobp))
            (equal (syntax-after (1- (point))) (string-to-syntax "|"))
-           (not (nth 3 (syntax-ppss))))
+           (not (syntax-is-string-p)))
       ;; Right after a here-document.
       (let ((forward-sexp-function nil))
         (forward-sexp -1)
@@ -2169,7 +2169,7 @@ sh-smie-rc-forward-token
            (save-excursion
              (skip-chars-backward " \t")
              (not (bolp))))
-      (if (and (match-end 1) (not (nth 3 (syntax-ppss))))
+      (if (and (match-end 1) (not (syntax-is-string-p)))
           ;; Right before a here-doc.
           (let ((forward-sexp-function nil))
             (forward-sexp 1)
@@ -2211,7 +2211,7 @@ sh-smie-rc-backward-token
     (cond
      ((and (bolp) (not (bobp))
            (equal (syntax-after (1- (point))) (string-to-syntax "|"))
-           (not (nth 3 (syntax-ppss))))
+           (not (syntax-is-string-p)))
       ;; Right after a here-document.
       (let ((forward-sexp-function nil))
         (forward-sexp -1)
@@ -2827,7 +2827,7 @@ sh-get-indent-info
       ;; Note: setting result to t means we are done and will return nil.
       ;;(This function never returns just t.)
       (cond
-       ((or (nth 3 (syntax-ppss (point)))
+       ((or (syntax-is-string-p)
 	    (eq (get-text-property (point) 'face) 'sh-heredoc))
 	;; String continuation -- don't indent
 	(setq result t)
diff --git a/lisp/simple.el b/lisp/simple.el
index 0ccf2f1d22..fb44c4fac9 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -7264,7 +7264,7 @@ internal-auto-fill
   "The function called by `self-insert-command' to perform auto-filling."
   (when (or (not comment-start)
             (not comment-auto-fill-only-comments)
-            (nth 4 (syntax-ppss)))
+            (syntax-is-comment-p))
     (funcall auto-fill-function)))
 
 (defvar normal-auto-fill-function 'do-auto-fill
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index c223af4769..b6ebc1e3be 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -1328,7 +1328,7 @@ tex-insert-quote
   ;;
   (if (or arg (memq (char-syntax (preceding-char)) '(?/ ?\\))
           (eq (get-text-property (point) 'face) 'tex-verbatim)
-          (nth 4 (syntax-ppss)) ; non-nil if point is in a TeX comment
+          (syntax-is-comment-p)
           ;; Discover if a preceding occurrence of `tex-open-quote'
           ;; should be morphed to a normal double quote.
           ;;
@@ -1487,7 +1487,7 @@ tex-handle-newline
 unless prefix arg INHIBIT-VALIDATION is non-nil to inhibit the checking.
 Otherwise (in a comment), just insert a single continued comment line."
   (interactive "*P")
-  (if (nth 4 (syntax-ppss)) ; non-nil if point is in a TeX comment
+  (if (syntax-is-comment-p)
       (comment-indent-new-line)
     (tex-terminate-paragraph inhibit-validation)))
 
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 679401eef1..41185a778e 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -180,19 +180,13 @@ end-of-thing
 
 ;;  Sexps
 
-(defun in-string-p ()
-  "Return non-nil if point is in a string."
-  (declare (obsolete "use (nth 3 (syntax-ppss)) instead." "25.1"))
-  (let ((orig (point)))
-    (save-excursion
-      (beginning-of-defun)
-      (nth 3 (parse-partial-sexp (point) orig)))))
+(define-obsolete-function-alias 'in-string-p 'syntax-is-string-p "25.1")
 
 (defun thing-at-point--end-of-sexp ()
   "Move point to the end of the current sexp."
   (let ((char-syntax (syntax-after (point))))
     (if (or (eq char-syntax ?\))
-	    (and (eq char-syntax ?\") (nth 3 (syntax-ppss))))
+	    (and (eq char-syntax ?\") (syntax-is-string-p)))
 	(forward-char 1)
       (forward-sexp 1))))
 
@@ -206,7 +200,7 @@ thing-at-point--beginning-of-sexp
   "Move point to the beginning of the current sexp."
   (let ((char-syntax (char-syntax (char-before))))
     (if (or (eq char-syntax ?\()
-	    (and (eq char-syntax ?\") (nth 3 (syntax-ppss))))
+	    (and (eq char-syntax ?\") (syntax-is-string-p)))
 	(forward-char -1)
       (forward-sexp -1))))
 
diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el
index ff41473435..056bb4f46d 100644
--- a/lisp/vc/smerge-mode.el
+++ b/lisp/vc/smerge-mode.el
@@ -621,7 +621,7 @@ smerge-resolve
            ;; Idem, when the conflict is contained within a single comment.
            ((save-excursion
               (and m2e
-                   (nth 4 (syntax-ppss m0b))
+                   (syntax-is-comment-p m0b)
                    ;; If there's a conflict earlier in the file,
                    ;; syntax-ppss is not reliable.
                    (not (re-search-backward smerge-begin-re nil t))
-- 
2.18.0