[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/gnuplot 0d9c0af 025/184: Better method for scanning string
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/gnuplot 0d9c0af 025/184: Better method for scanning strings/comments. |
Date: |
Sun, 29 Aug 2021 11:03:08 -0400 (EDT) |
branch: elpa/gnuplot
commit 0d9c0af63bf525b6b8eb86c0181482ff3255fcd5
Author: Jonathan Oddie <j.j.oddie@gmail.com>
Commit: Jonathan Oddie <j.j.oddie@gmail.com>
Better method for scanning strings/comments.
Instead of using syntactic-keywords, we scan the entire buffer once through
at the beginning with `gnuplot-scan-after-change' and then put it in the
`after-change-functions' hook to repeat when necessary.
I can't get this to work in XEmacs because it doesn't have Emacs' "generic
string delimiter" and "generic comment delimiter" syntax classes.
---
gnuplot.el | 264 +++++++++++++++++++++++++++++++------------------------------
1 file changed, 135 insertions(+), 129 deletions(-)
diff --git a/gnuplot.el b/gnuplot.el
index d5118eb..8fce68d 100644
--- a/gnuplot.el
+++ b/gnuplot.el
@@ -1508,50 +1508,48 @@ static char *help_btn[] = {
;;; --- syntax colorization, syntax table
-(defvar gnuplot-mode-syntax-table nil
+(defvar gnuplot-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?* "." table)
+ (modify-syntax-entry ?+ "." table)
+ (modify-syntax-entry ?- "." table)
+ (modify-syntax-entry ?/ "." table)
+ (modify-syntax-entry ?% "." table)
+ (modify-syntax-entry ?= "." table)
+ (modify-syntax-entry ?: "." table)
+ (modify-syntax-entry ?& "." table ) ; rarely used
+ (modify-syntax-entry ?^ "." table ) ; operators
+ (modify-syntax-entry ?| "." table ) ; in gnuplot,
+ (modify-syntax-entry ?& "." table ) ; (by me,
+ (modify-syntax-entry ?? "." table ) ; anyway...)
+ (modify-syntax-entry ?~ "." table ) ;
+
+ (modify-syntax-entry ?_ "w" table )
+
+ ;; In GNU Emacs we scan for strings and comments ourselves in
+ ;; `gnuplot-scan-after-change'. I can't get this to work in xemacs,
+ ;; so there we'll make ", ', and # delimiters as normal, and use the
+ ;; built-in parser
+ (if (featurep 'xemacs)
+ (progn
+ (modify-syntax-entry ?\' "\"" table)
+ (modify-syntax-entry ?# "<" table)
+ (modify-syntax-entry ?\n ">" table)
+ (modify-syntax-entry ?\\ "\\" table))
+
+ ;; GNU Emacs: Make ", ', and # punctuation, so the built-in parser
+ ;; doesn't interfere with them
+ (modify-syntax-entry ?\" "." table)
+ (modify-syntax-entry ?\' "." table)
+ (modify-syntax-entry ?` "." table)
+ (modify-syntax-entry ?\\ "." table))
+
+ table)
+
"Syntax table in use in `gnuplot-mode' buffers.
This is the same as the standard syntax table except that ` and _
are word characters, and math operators are punctuation
characters.")
-(unless gnuplot-mode-syntax-table
- (setq gnuplot-mode-syntax-table (make-syntax-table))
-
- (modify-syntax-entry ?* "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?+ "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?- "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?/ "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?% "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?= "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?: "." gnuplot-mode-syntax-table)
- ;;(modify-syntax-entry ?& "." gnuplot-mode-syntax-table ) ; rarely used
- ;;(modify-syntax-entry ?^ "." gnuplot-mode-syntax-table ) ; operators
- ;;(modify-syntax-entry ?| "." gnuplot-mode-syntax-table ) ; in gnuplot,
- ;;(modify-syntax-entry ?& "." gnuplot-mode-syntax-table ) ; (by me,
- ;;(modify-syntax-entry ?? "." gnuplot-mode-syntax-table ) ; anyway...)
- ;;(modify-syntax-entry ?~ "." gnuplot-mode-syntax-table ) ;
-
- (modify-syntax-entry ?_ "w" gnuplot-mode-syntax-table )
-
- ;; gnuplot's shell-like rules for string quoting (and comments)
- ;; are not what the Emacs sexp parser expects, so in GNU Emacs
- ;; we can do better by scanning for strings and comments
- ;; explicitly in `gnuplot-scan-multiline'. Make the character
- ;; class of `"', `'', and `\' punctuation so the parser doesn't
- ;; interfere with this. <jjo>
- ;;
- ;; I don't know if the hooks to make this work exist in
- ;; Xemacs, so in that case we'll rely on the built-in
- ;; parser :-(
- (if (featurep 'xemacs)
- (progn
- (modify-syntax-entry ?\' "\"" gnuplot-mode-syntax-table)
- (modify-syntax-entry ?# "<" gnuplot-mode-syntax-table)
- (modify-syntax-entry ?\n ">" gnuplot-mode-syntax-table))
-
- (modify-syntax-entry ?\" "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?\' "w" gnuplot-mode-syntax-table)
- (modify-syntax-entry ?` "." gnuplot-mode-syntax-table)
- (modify-syntax-entry ?\\ "." gnuplot-mode-syntax-table)))
;; Macro to generate efficient regexps for keyword matching (at
;; compile-time if byte-compiling)
@@ -1633,14 +1631,8 @@ These are highlighted using `font-lock-reference-face'.")
;; other common commands
(cons (gnuplot-make-regexp gnuplot-keywords-misc)
font-lock-reference-face)
- (cons "!.*$" font-lock-reference-face)))
-
- ;; Comments and strings are colorized syntactically after
- ;; scanning with `gnuplot-scan-multiline', see below <jjo>
- (setq gnuplot-font-lock-syntactic-keywords
- '((gnuplot-scan-strings (1 "|" nil t) (2 "|" nil t))
- (gnuplot-scan-comments (1 "!" nil t) (2 "!" nil t))))
-
+ (cons "!.*$" font-lock-reference-face))) ; what is this for? jjo
+
(setq gnuplot-font-lock-defaults
'(gnuplot-font-lock-keywords
nil ; Use syntactic fontification
@@ -1652,67 +1644,74 @@ These are highlighted using
`font-lock-reference-face'.")
;; Set up font-lock for Xemacs
;; For GNU Emacs, this is done in `gnuplot-mode'
- (if (and gnuplot-xemacs-p (featurep 'font-lock))
+ (if gnuplot-xemacs-p
(put 'gnuplot-mode 'font-lock-defaults
gnuplot-font-lock-defaults)))
-;; Scanning functions for font-lock
-(defun gnuplot-scan-strings (limit)
- (gnuplot-scan-multiline 'string limit))
-
-(defun gnuplot-scan-comments (limit)
- (gnuplot-scan-multiline 'comment limit))
-
-(defun gnuplot-scan-multiline (type limit)
- "Function used by font-lock to search for strings and comments
-in gnuplot buffers.
-
-TYPE should be either 'string or 'comment. LIMIT is the search
-limit passed by font-lock."
- ;; Gnuplot shell-like strings and comments don't quite agree with
- ;; Emacs' built-in sexp parser:
- ;;
- ;; - strings can continue over several lines, but only by using a
- ;; backslash to escape the newline
- ;;
- ;; - double quoted strings can contain escaped quotes \" and escaped
- ;; backslashes \\, but there's no way to quote the delimiter in
- ;; single quoted strings
- ;;
- ;; - strings can end at newline without needing a closing delimiter
- ;;
- ;; - comments continue over continuation lines
- ;;
- ;; Trying to write a regexp to match these rules is horrible, so we
- ;; use this matching function instead <jjo>
-
- (let* ((searching-for-string-p (eq type 'string))
- (re (cond (searching-for-string-p "'\\|\"")
- (t "#")))
- (begin (search-forward-regexp re limit t)))
- ;; Skip over anything which is already inside a string
- (when (> (point) (point-min))
- (while (and (gnuplot-in-string (1- (point)))
- (setq begin (search-forward-regexp re limit t)))))
-
+;; Gnuplot's shell-like strings and comments don't quite agree with
+;; Emacs' built-in sexp parser:
+;;
+;; - strings can continue over several lines, but only by using a
+;; backslash to escape the newline
+;;
+;; - double quoted strings can contain escaped quotes \" and escaped
+;; backslashes \\, but there's no way to quote the delimiter in
+;; single quoted strings
+;;
+;; - strings can end at newline without needing a closing delimiter
+;;
+;; - comments continue over continuation lines
+;;
+;; Trying to write a regexp to match these rules is horrible, so we
+;; use this matching function instead (in GNU Emacs - I can't figure out
+;; how to do this in XEmacs.)
+(defun gnuplot-scan-after-change (begin end &optional unused)
+ "Scan a gnuplot script buffer for strings and comments.
+
+This is called once on the whole buffer when gnuplot-mode is turned on,
+and installed as a hook in `after-change-functions'."
+ (save-excursion
+ (setq end (progn
+ (goto-char end)
+ (gnuplot-point-at-end-of-continuation))
+ begin (progn
+ (goto-char begin)
+ (gnuplot-beginning-of-continuation)
+ (point)))
+
+ (remove-text-properties begin (min (1+ end) (point-max))
+ '(syntax-table nil))
+
+ (while (gnuplot-scan-next-string-or-comment end))))
+
+(defun gnuplot-scan-next-string-or-comment (limit)
+ "Put appropriate syntax-table text properties on the next comment or string.
+
+Scans forward from point as far as LIMIT (which should be at the
+end of a line). Leaves point at the end of the comment or string,
+or at LIMIT if nothing was found. Returns t if a comment or
+string was found, otherwise nil."
+ (let ((begin (search-forward-regexp "[#'\"]" limit 'go-to-limit)))
(if (not begin)
- nil ; Nothing found on this line
- (let ((begin (1- begin))
- (limit (point-at-eol))
- (end nil) (end-at-eobp nil)
- (re
- (cond ((not searching-for-string-p) nil)
- ((string= (match-string 0) "'") "'")
- ((string= (match-string 0) "\"")
"\\\\\"\\|\\\\\\\\\\|\""))))
+ nil
+ (let* ((begin (1- begin))
+ (end nil)
+ (opener (match-string 0))
+ (limit (point-at-eol))
+ (end-at-eob-p nil)
+ (re
+ (cond ((string= opener "#") nil)
+ ((string= opener "'") "'")
+ ((string= opener "\"") "\\\\\"\\|\\\\\\\\\\|\""))))
(while (not end)
- (if (and (bolp) (eolp)) ; Empty continuation line:
- (setq end (1+ (point))) ; end at newline
- (if searching-for-string-p
+ (if (and (not (eobp)) (bolp) (eolp)) ; Empty continuation line:
+ (setq end (point)) ; end at newline
+ (if re
(setq end (search-forward-regexp re limit 'go-to-limit))
(end-of-line)) ; Comments end only at end-of-line
(if end
- (when (and searching-for-string-p
+ (when (and re
(or (string= (match-string 0) "\\\"")
(string= (match-string 0) "\\\\")))
(setq end nil)) ; Skip over escapes and look again
@@ -1720,57 +1719,55 @@ limit passed by font-lock."
;; We got to EOL without finding an ending delimiter
(if (eobp)
(setq end (point)
- end-at-eobp t) ; string/comment ends at EOB
+ end-at-eob-p t) ; string/comment ends at EOB
;; Otherwise see if the line is continued with a backslash
(if (save-excursion (backward-char) (looking-at "\\\\"))
(progn ; yes, check out next line
(beginning-of-line 2)
(setq limit (point-at-eol)))
- (setq end (point-at-eol))))))) ; no, string ends at EOL
+ (setq end (1+ (point-at-eol)))))))) ; no, string ends at EOL
- ;; Set the match data: (match-string 0) is the whole
- ;; string with delimiters, (match-string 1) is the opening
- ;; quote or #, (match-string 2) is the closing quote or
- ;; newline.
+ ;; Set the syntax properties
(let ((begin-marker (copy-marker begin))
(begin-quote-marker (copy-marker (1+ begin)))
(end-quote-marker (copy-marker (1- end)))
(end-marker (copy-marker end)))
- (if end-at-eobp
- (set-match-data ; Don't mark an end of construct at EOB
- (list begin-marker end-marker
- begin-marker begin-quote-marker))
- (set-match-data
- (list begin-marker end-marker
- begin-marker begin-quote-marker
- end-quote-marker end-marker)))
+ (let ((syntax (if (string= opener "#")
+ '(syntax-table (14)) ; 'comment fence'
+ '(syntax-table (15))))) ; 'string fence'
+ (add-text-properties begin-marker begin-quote-marker syntax)
+ (unless end-at-eob-p
+ (add-text-properties end-quote-marker end-marker syntax)))
+
;; Mark multiline constructs for font-lock
- (and (> (count-lines begin-marker end-marker) 1)
- (add-text-properties begin-marker end-marker
'(font-lock-multiline t)))
+ (add-text-properties begin-marker end-marker '(font-lock-multiline
t))))
- ;; Let font-lock know we found a match
- t)))))
+ ;; We found something
+ t)))
+
+
+;; Parsing utilities to tell if we are inside a string or comment
;; XEmacs doesn't have syntax-ppss
(if (featurep 'xemacs)
- (defun syntax-ppss (&optional pos)
+ (defun gnuplot-syntax-ppss (&optional pos)
(save-excursion
(unless pos (setq pos (point)))
(let ((begin
(save-excursion
(goto-char pos)
(gnuplot-point-at-beginning-of-continuation))))
- (parse-partial-sexp begin pos)))))
+ (parse-partial-sexp begin pos))))
+ (defalias 'gnuplot-syntax-ppss 'syntax-ppss))
-;; Parsing utilities to tell if we are inside a string or comment
(defun gnuplot-in-string (&optional where)
"Returns non-nil if the text at WHERE is within a string.
If WHERE is omitted, defaults to text at point.
This is a simple wrapper for `syntax-ppss'."
(save-excursion
- (let ((parse-state (syntax-ppss where)))
+ (let ((parse-state (gnuplot-syntax-ppss where)))
(nth 3 parse-state))))
(defun gnuplot-in-comment (&optional where)
@@ -1779,12 +1776,19 @@ This is a simple wrapper for `syntax-ppss'."
If WHERE is omitted, defaults to text at point.
This is a simple wrapper for `syntax-ppss'."
(save-excursion
- (let ((parse-state (syntax-ppss where)))
+ (let ((parse-state (gnuplot-syntax-ppss where)))
(nth 4 parse-state))))
(defun gnuplot-in-string-or-comment (&optional where)
- (or (gnuplot-in-string where)
- (gnuplot-in-comment where)))
+ "Returns non-nil if the text at WHERE is within a string or comment.
+
+If WHERE is omitted, defaults to text at point.
+This is a simple wrapper for `syntax-ppss'."
+
+ (save-excursion
+ (let ((parse-state (gnuplot-syntax-ppss where)))
+ (or (nth 3 parse-state)
+ (nth 4 parse-state)))))
;; these two lines get rid of an annoying compile time error
;; message. that function gets non-trivially defalias-ed in
@@ -2033,7 +2037,8 @@ buffer."
(if (fboundp 'turn-on-font-lock) (turn-on-font-lock))
(progn
(setq font-lock-defaults gnuplot-font-lock-defaults)
- (set (make-local-variable 'parse-sexp-lookup-properties) t)))
+ (set (make-local-variable 'parse-sexp-lookup-properties) t)
+ (add-hook 'after-change-functions 'gnuplot-scan-after-change nil t)))
;; XEmacs needs the call to make-local-hook
(when (and (featurep 'xemacs)
@@ -2870,11 +2875,12 @@ a list:
(hilit-string-find ?\\ string)))))
(if gnuplot-xemacs-p ; deal with font-lock
- (if (fboundp 'turn-on-font-lock) (turn-on-font-lock))
+ (when (fboundp 'turn-on-font-lock)
+ (turn-on-font-lock))
(progn
+ (gnuplot-scan-after-change (point-min) (point-max))
+ (add-hook 'after-change-functions 'gnuplot-scan-after-change nil t)
(setq font-lock-defaults gnuplot-font-lock-defaults)
- (set (make-local-variable 'font-lock-syntactic-keywords)
- gnuplot-font-lock-syntactic-keywords)
(set (make-local-variable 'font-lock-multiline) t)
(set (make-local-variable 'parse-sexp-lookup-properties) t)))
- [nongnu] elpa/gnuplot 496c6e4 145/184: Change LICENSE; GPLv2 -> GPLv3, (continued)
- [nongnu] elpa/gnuplot 496c6e4 145/184: Change LICENSE; GPLv2 -> GPLv3, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 290c332 162/184: Revert "[WIP] Remove Xemacs support", ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot f73abe1 165/184: Merge pull request #57 from dkogan/fix-comint-process-echoes, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot fc302fd 167/184: set fail-fast strategy as false, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot ac8ab77 173/184: Move changelog to a dedicated org file., ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 1488629 174/184: Fix font-lock not loading., ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 5fd785c 178/184: Fix test runner, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 65b58b2 175/184: Fix cl deprecation (#68), ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 6a192ef 176/184: Fix more deprecated functions., ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 58a1cf5 024/184: Fixed horrible bug in gnuplot-in-string/gnuplot-in-comment, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 0d9c0af 025/184: Better method for scanning strings/comments.,
ELPA Syncer <=
- [nongnu] elpa/gnuplot 84933f0 029/184: Allow single quoted strings to include '' as an escape for ', ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot c97f028 078/184: use a defsubst instead of defmacro in debug-context, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot f710394 057/184: Add keys C-M-x (evaluate region) and C-j (evaluate line and newline), ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 54f3882 070/184: Silence another compiler warning by using with-current-buffer, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 35f3f8d 080/184: Avoid having text syntax-property changes mark buffer as modified, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot fdd3e1e 101/184: * README.org: update installation section for el-get users., ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 35a8a19 108/184: Check for `syntax-propertize-function' when defining syntax-table, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 4cd89ab 109/184: Replace ad-hoc scanning with syntax-propertize-rules, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot 09ff207 131/184: Remove un-needed `gnuplot-context-mode-p` function, ELPA Syncer, 2021/08/29
- [nongnu] elpa/gnuplot d6f8598 121/184: Cleanup inline-image mode, ELPA Syncer, 2021/08/29