[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/go-mode c020e2c 456/495: Fontify type names in more places
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/go-mode c020e2c 456/495: Fontify type names in more places. |
Date: |
Sat, 7 Aug 2021 09:06:08 -0400 (EDT) |
branch: elpa/go-mode
commit c020e2cba0f9684cc060cbbdc492d9a470420bf4
Author: Muir Manders <muir@mnd.rs>
Commit: Peter Sanford <psanford@sanford.io>
Fontify type names in more places.
We now fontify type names in var decls, const decls, and struct
definitions:
var foo, bar *string*
const baz *float64* = 123.4
type blah struct { foo *string* }
We achieve this with a dumb check that essentially just looks for
"<go-ident>[[:space:]]+<go-type-name>", but with some extra logic to
ignore keywords. This takes advantage of the fact that when you have
two identifiers separated by whitespace, the second is always(?) a
type name.
Fixes #256, fixes #51
Closes: #307 [via git-merge-pr]
---
go-mode.el | 43 +++++++++++++++++++-
test/go-font-lock-test.el | 100 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/go-mode.el b/go-mode.el
index e16556c..3cad755 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -410,9 +410,20 @@ For mode=set, all covered lines will have this weight."
;; we cannot use 'symbols in regexp-opt because GNU Emacs <24
;; doesn't understand that
(append
- `((go--match-func
+ `(
+ ;; Fontify types in function signatures.
+ (go--match-func
+ ;; The signature logic is "anchored" to a "func" keyword, so
+ ;; `go--match-func' must match all signature types in a single
+ ;; invocation since it can't remember if it is inside a "func"
+ ;; across invocations. So, it must have an explicit limit on the
+ ;; number of sub-expressions.
,@(mapcar (lambda (x) `(,x font-lock-type-face))
(number-sequence 1 go--font-lock-func-param-num-groups)))
+
+ ;; Fontify types in e.g. "var foo string".
+ (go--match-ident-type-pair 1 font-lock-type-face)
+
(,(concat "\\_<" (regexp-opt go-mode-keywords t) "\\_>") .
font-lock-keyword-face)
(,(concat "\\(\\_<" (regexp-opt go-builtins t) "\\_>\\)[[:space:]]*(") 1
font-lock-builtin-face)
(,(concat "\\_<" (regexp-opt go-constants t) "\\_>") .
font-lock-constant-face)
@@ -1257,6 +1268,36 @@ of last search. Return t if search succeeded."
(set-match-data (go--make-match-data regions))
t)))))
+(defun go--match-ident-type-pair (end)
+ "Search for identifier + type-name pairs.
+
+For example, this looks for the \"foo bar\" in \"var foo bar\",
+yielding match-data for \"bar\" since that is a type name to be
+fontified. This approach matches type names in var and const
+decls, and in struct definitions. Return non-nil if search
+succeeds."
+ (let (type-names found-match)
+ ;; Find the starting ident, e.g. "foo" in "var foo bar".
+ (while (and
+ (not found-match)
+ (re-search-forward (concat "\\_<" go-identifier-regexp "\\_>") end
t))
+ (cond
+ ;; Skip keywords, such as the "var" in "var foo bar".
+ ((member (match-string 0) go-mode-keywords))
+
+ ;; If our identifier is followed by a space.
+ ((> (skip-syntax-forward " ") 0)
+ (when (and
+ ;; And it looks like a type name.
+ (looking-at go-type-name-regexp)
+ ;; And it isn't a keyword.
+ (not (member (match-string 1) go-mode-keywords)))
+ (setq found-match t)))))
+
+ ;; Return whether we found an ident/type pair. match-data will be
+ ;; that of the final looking-at call.
+ found-match))
+
(defun go--match-func-type-names (end)
(cond
;; Function declaration (e.g. "func foo(")
diff --git a/test/go-font-lock-test.el b/test/go-font-lock-test.el
new file mode 100644
index 0000000..96f33ed
--- /dev/null
+++ b/test/go-font-lock-test.el
@@ -0,0 +1,100 @@
+;;; go-indentation-test.el
+
+;; Copyright 2019 The go-mode Authors. All rights reserved. Use of
+;; this source code is governed by a BSD-style license that can be
+;; found in the LICENSE file.
+
+(require 'ert)
+(require 'go-mode)
+(require 'cl-lib)
+
+(ert-deftest go--fontify-signature ()
+ (should-fontify "KfuncK FfooF() { }")
+ (should-fontify "KfuncK FfooF(TaT) { }")
+ (should-fontify "KfuncK FfooF(TaT, TbT) { }")
+ (should-fontify "KfuncK FfooF(TaT) TaT { }")
+ (should-fontify "KfuncK FfooF(a TbT) (a TbT) { }")
+ (should-fontify "KfuncK FfooF(a, b TcT) (a TbT, c TdT) { }")
+
+ (should-fontify "KfuncK (TbT) FfooF(a, b TcT) TdT { }")
+ (should-fontify "KfuncK (a TbT) FfooF(a TbT) (TdT) { }")
+
+ (should-fontify "foo := KfuncK(a TbT) TcT { }"))
+
+(ert-deftest go--fontify-decls ()
+ (should-fontify "KvarK foo TintT")
+ (should-fontify "KvarK foo *[3]TintT")
+ (should-fontify "KvarK foo Tfmt.StringerT")
+ (should-fontify "KvarK foo, bar Tfmt.StringerT")
+
+ (should-fontify "
+KvarK (
+ a TbT
+ a, b TbT
+ a KfuncK(b TcT)
+)")
+
+ (should-fontify "
+KconstK (
+ a = 1
+ a TintT = 1
+)"))
+
+(ert-deftest go--fontify-struct ()
+ (should-fontify "KstructK { i TintT }")
+ (should-fontify "KstructK { a, b TintT }")
+
+ (should-fontify "
+KstructK {
+ a TboolT
+ c KstructK { f *Tfmt.StringerT }
+}"))
+
+(defun should-fontify (contents)
+ "Verify fontification.
+
+CONTENTS is a template that uses single capital letters to
+represent expected font lock face names. For example:
+
+BmakeB([]TintT, 0)
+
+expects \"make\" to be a (B)uiltin and \"int\" to be a (T)type."
+ (with-temp-buffer
+ (go-mode)
+ (insert contents)
+ (goto-char (point-min))
+
+ ;; First pass through buffer looks for the face tags. We delete
+ ;; the tags and record the expected face ranges in `faces'.
+ (let ((case-fold-search nil) faces start start-pos)
+ (while (re-search-forward "[TBKCF]" nil t)
+ (let ((found-char (char-before)))
+ (backward-delete-char 1)
+ (if start
+ (progn
+ (should (= found-char start))
+ (let ((face (cl-case found-char
+ (?T 'font-lock-type-face)
+ (?B 'font-lock-builtin-face)
+ (?K 'font-lock-keyword-face)
+ (?C 'font-lock-constant-face)
+ (?F 'font-lock-function-name-face))))
+ (setq faces (append faces `((,face ,start-pos ,(point))))))
+ (setq start nil))
+ (setq start found-char)
+ (setq start-pos (point)))))
+
+ ;; Fontify buffer now that we have removed the tags.
+ (font-lock-fontify-buffer)
+ (goto-char (point-min))
+
+ ;; Go through buffer one character at a time making sure the
+ ;; character's face is correct.
+ (let ((face (pop faces)))
+ (while (not (eobp))
+ (while (and face (>= (point) (nth 2 face)))
+ (setq face (pop faces)))
+ (if (and face (>= (point) (nth 1 face)))
+ (should (eq (nth 0 face) (get-text-property (point) 'face)))
+ (should (eq nil (get-text-property (point) 'face))))
+ (forward-char))))))
- [nongnu] elpa/go-mode 7eb5b3d 409/495: Delete go-mode-autoloads.el, (continued)
- [nongnu] elpa/go-mode 7eb5b3d 409/495: Delete go-mode-autoloads.el, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 2d1d33a 407/495: Fix off-by-one in point calculations, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 7f87c32 416/495: Permit empty guru scope, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode be9186c 417/495: Support remote files in `gofmt', ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 287595a 420/495: Don't traverse symlinks when recursing directories, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode b990645 425/495: Fix call expr indenting after dangling operator., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode ac6dd8c 430/495: Fix go-remove-unused-imports, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode e8674fe 437/495: Expand electric indent config a bit, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 6a64cbf 439/495: Fix indentation for composite literal keys., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode fb1272c 441/495: indent: fix performance in giant comments, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode c020e2c 456/495: Fontify type names in more places.,
ELPA Syncer <=
- [nongnu] elpa/go-mode 2a1584f 454/495: Readme: add note recommending goimports, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 57becfb 460/495: Fontify type names in interface declarations, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode cf53daa 459/495: Fix indentation in naked blocks., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode f872781 466/495: Fontify variable names., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode acec0aa 471/495: Fix Content-Type for https://play.golang.org/share, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode cad6d0a 472/495: Fix fontification performance issue, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 1fbe6a8 490/495: Fix comment filling at start of buffer., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 5186c83 491/495: Support basic indenting in multiline comments., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode c576513 494/495: Fix fontification of multiplicand after index expr., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 49a5380 493/495: Trivial fix of docstring and comment spelling typos., ELPA Syncer, 2021/08/07