summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2020-12-28 20:42:25 +0000
committerAlan Mackenzie <acm@muc.de>2020-12-28 20:42:25 +0000
commitd180a41dbb8e4e8d94d30a023c2d86d92c73c4f1 (patch)
tree5b811a6f87e0aac22483430215942a6add985852
parentc7fdf8688388f137dbfab2f372fa33c24241b83a (diff)
downloademacs-d180a41dbb8e4e8d94d30a023c2d86d92c73c4f1.tar.gz
CC Mode: Add newish AWK Mode facilities, as used in gawk-4.
* lisp/progmodes/cc-awk.el (c-awk-font-lock-invalid-namespace-separators): New function. (c-awk-context-expand-fl-region): New function. (awk-font-lock-keywords): Enhance handling of function declarations to include :: tokens. Fontify new system variable names FPAT, FUNCTAB, PREC, ROUNDMODE, SYNTAB. Fontify new keywords BEGINFILE and ENDFILE. Fontify new system functions asorti, dcngettext, isarray, patsplit, typeof. Fontify the new directives @include, @load, @namespace. Call c-awk-font-lock-invalid-namespace-separators as a matcher. * lisp/progmodes/cc-fonts.el (top level): No longer require 'cc-awk. * lisp/progmodes/cc-langs.el (c-before-context-fontification-functions): Give AWK the value c-awk-context-expand-fl-region rather than nil. * lisp/progmodes/cc-mode.el (top level): Declare awk-mode-syntax-table as a variable.
-rw-r--r--lisp/progmodes/cc-awk.el101
-rw-r--r--lisp/progmodes/cc-fonts.el3
-rw-r--r--lisp/progmodes/cc-langs.el2
-rw-r--r--lisp/progmodes/cc-mode.el1
4 files changed, 89 insertions, 18 deletions
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index 52e6da6f4ac..841c3a4bb6d 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -49,9 +49,11 @@
(load "cc-bytecomp" nil t)))
(cc-require 'cc-defs)
+(cc-require-when-compile 'cc-langs)
+(cc-require-when-compile 'cc-fonts)
+(cc-require 'cc-engine)
;; Silence the byte compiler.
-(cc-bytecomp-defvar font-lock-mode) ; Checked with boundp before use.
(cc-bytecomp-defvar c-new-BEG)
(cc-bytecomp-defvar c-new-END)
@@ -649,6 +651,46 @@
;; several lines back. The elisp "advice" feature is used on these functions
;; to allow this.
+(defun c-awk-font-lock-invalid-namespace-separators (limit)
+ ;; This function will be called from font-lock for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ ;;
+ ;; This function gives invalid GAWK namepace separators (::)
+ ;; font-lock-warning-face. "Invalid" here means there are spaces, etc.,
+ ;; around a separator, or there are more than one of them in an identifier.
+ ;; Invalid separators inside function declaration parentheses are handled
+ ;; elsewhere.
+ (while (and
+ (< (point) limit)
+ (c-syntactic-re-search-forward
+ (eval-when-compile
+ (concat "\\([^" (c-lang-const c-symbol-chars awk) "]::\\)"
+ "\\|"
+ ;; "\\(::[^" (c-lang-const c-symbol-start awk) "]\\)"
+ "\\(::[^" c-alpha "_" "]\\)"
+ "\\|"
+ "\\(::[" (c-lang-const c-symbol-chars awk) "]*::\\)"))
+ limit 'bound))
+ (cond
+ ((match-beginning 1) ; " ::"
+ (c-put-font-lock-face (1+ (match-beginning 1)) (match-end 1)
+ 'font-lock-warning-face)
+ (goto-char (- (match-end 1) 2)))
+ ((match-beginning 2) ; ":: "
+ (c-put-font-lock-face (match-beginning 2) (1- (match-end 2))
+ 'font-lock-warning-face)
+ (goto-char (1- (match-end 2))))
+ (t ; "::foo::"
+ (c-put-font-lock-face (match-beginning 3) (+ 2 (match-beginning 3))
+ 'font-lock-warning-face)
+ (c-put-font-lock-face (- (match-end 3) 2) (match-end 3)
+ 'font-lock-warning-face)
+ (goto-char (- (match-end 3) 2)))))
+ nil)
+
(defun c-awk-beginning-of-logical-line (&optional pos)
;; Go back to the start of the (apparent) current line (or the start of the
;; line containing POS), returning the buffer position of that point. I.e.,
@@ -900,6 +942,13 @@
(goto-char c-new-BEG)
(c-awk-set-syntax-table-properties c-new-END)))
+(defun c-awk-context-expand-fl-region (beg end)
+ ;; Return a cons (NEW-BEG . NEW-END), where NEW-BEG is the beginning of the
+ ;; logical line BEG is on, and NEW-END is the beginning of the line after
+ ;; the end of the logical line that END is on.
+ (cons (save-excursion (c-awk-beginning-of-logical-line beg))
+ (c-awk-beyond-logical-line end)))
+
;; Awk regexps written with help from Peter Galbraith
;; <galbraith@mixing.qc.dfo.ca>.
;; Take GNU Emacs's 'words out of the following regexp-opts. They don't work
@@ -907,18 +956,34 @@
(defconst awk-font-lock-keywords
(eval-when-compile
(list
- ;; Function names.
- '("^\\s *\\(func\\(tion\\)?\\)\\>\\s *\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
- ;;
+ ;; Function declarations.
+ `(,(c-make-font-lock-search-function
+ "^\\s *\\(func\\(tion\\)?\\)\\s +\\(\\(\\sw+\\(::\\sw+\\)?\\)\\s *\\)?\\(([^()]*)\\)?"
+ '(1 font-lock-keyword-face t)
+ ;; We can't use LAXMATCH in `c-make-font-lock-search-function', so....
+ '((when (match-beginning 4)
+ (c-put-font-lock-face
+ (match-beginning 4) (match-end 4) font-lock-function-name-face)
+ nil))
+ ;; Put warning face on any use of :: inside the parens.
+ '((when (match-beginning 6)
+ (goto-char (1+ (match-beginning 6)))
+ (let ((end (1- (match-end 6))))
+ (while (and (< (point) end)
+ (c-syntactic-re-search-forward "::" end t))
+ (c-put-font-lock-face (- (point) 2) (point)
+ 'font-lock-warning-face)))
+ nil))))
+
;; Variable names.
(cons
(concat "\\<"
(regexp-opt
'("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON"
- "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE"
- "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PROCINFO" "RLENGTH"
- "RS" "RSTART" "RT" "SUBSEP" "TEXTDOMAIN") t) "\\>")
+ "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FPAT" "FS" "FUNCTAB"
+ "IGNORECASE" "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PREC"
+ "PROCINFO" "RLENGTH" "ROUNDMODE" "RS" "RSTART" "RT" "SUBSEP"
+ "SYNTAB" "TEXTDOMAIN") t) "\\>")
'font-lock-variable-name-face)
;; Special file names. (acm, 2002/7/22)
@@ -949,7 +1014,8 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
;; Keywords.
(concat "\\<"
(regexp-opt
- '("BEGIN" "END" "break" "case" "continue" "default" "delete"
+ '("BEGIN" "BEGINFILE" "END" "ENDFILE"
+ "break" "case" "continue" "default" "delete"
"do" "else" "exit" "for" "getline" "if" "in" "next"
"nextfile" "return" "switch" "while")
t) "\\>")
@@ -959,16 +1025,20 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
,(concat
"\\<"
(regexp-opt
- '("adump" "and" "asort" "atan2" "bindtextdomain" "close"
- "compl" "cos" "dcgettext" "exp" "extension" "fflush"
- "gensub" "gsub" "index" "int" "length" "log" "lshift"
- "match" "mktime" "or" "print" "printf" "rand" "rshift"
+ '("adump" "and" "asort" "asorti" "atan2" "bindtextdomain" "close"
+ "compl" "cos" "dcgettext" "dcngettext" "exp" "extension" "fflush"
+ "gensub" "gsub" "index" "int" "isarray" "length" "log" "lshift"
+ "match" "mktime" "or" "patsplit" "print" "printf" "rand" "rshift"
"sin" "split" "sprintf" "sqrt" "srand" "stopme"
"strftime" "strtonum" "sub" "substr" "system"
- "systime" "tolower" "toupper" "xor") t)
+ "systime" "tolower" "toupper" "typeof" "xor")
+ t)
"\\>")
0 c-preprocessor-face-name))
+ ;; Directives
+ '("@\\(include\\|load\\|namespace\\)\\>" 0 c-preprocessor-face-name)
+
;; gawk debugging keywords. (acm, 2002/7/21)
;; (Removed, 2003/6/6. These functions are now fontified as built-ins)
;; (list (concat "\\<" (regexp-opt '("adump" "stopme") t) "\\>")
@@ -980,6 +1050,9 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
c-awk-escaped-nls*-with-space* "(")
(0 'font-lock-warning-face))
+ ;; Double :: tokens, or the same with space(s) around them.
+ #'c-awk-font-lock-invalid-namespace-separators
+
;; Space after \ in what looks like an escaped newline. 2002/5/31
'("\\\\\\s +$" 0 font-lock-warning-face t)
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index e403c49e398..94e087f38e0 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -76,9 +76,6 @@
(cc-require-when-compile 'cc-langs)
(cc-require 'cc-vars)
(cc-require 'cc-engine)
-(cc-require-when-compile 'cc-awk) ; Change from cc-require, 2003/6/18 to
-;; prevent cc-awk being loaded when it's not needed. There is now a (require
-;; 'cc-awk) in (defun awk-mode ..).
;; Avoid repeated loading through the eval-after-load directive in
;; cc-mode.el.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 4d1aeaa5cb9..9b13cedc988 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -549,7 +549,7 @@ parameters (point-min), (point-max) and <buffer size>.")
(c-lang-defconst c-before-context-fontification-functions
t 'c-context-expand-fl-region
- awk nil)
+ awk 'c-awk-context-expand-fl-region)
;; For documentation see the following c-lang-defvar of the same name.
;; The value here may be a list of functions or a single function.
(c-lang-defvar c-before-context-fontification-functions
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index f6d36f5670c..2f1885e5b61 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -113,6 +113,7 @@
;; Silence the compiler.
(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1
+(cc-bytecomp-defvar awk-mode-syntax-table)
;; We set this variable during mode init, yet we don't require
;; font-lock.