emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/go-mode dac200f 469/495: Fix font locking in nested signat


From: ELPA Syncer
Subject: [nongnu] elpa/go-mode dac200f 469/495: Fix font locking in nested signatures.
Date: Sat, 7 Aug 2021 09:06:11 -0400 (EDT)

branch: elpa/go-mode
commit dac200f7a8de7bf22793d39b5dd46756cbadb295
Author: Muir Manders <muir@mnd.rs>
Commit: Peter Sanford <psanford@sanford.io>

    Fix font locking in nested signatures.
    
    We weren't font locking nested signatures such as:
    
    func foo(i int, f func(b bool) string) float32
    
    I fixed the param list fontification to jump back to the opening "("
    after fontifying the list. This allows it to match param lists
    contained within the outer list.
    
    I also fixed the "single result" rule to properly match the "string"
    in the above example. I had to break it out into a function to avoid
    consuming the ")" after "string", which prevented it from matching the
    following float32 result type.
    
    Closes: #318 [via git-merge-pr]
---
 go-mode.el                | 47 +++++++++++++++++++++++++++++++++++++++++++----
 test/go-font-lock-test.el |  3 +++
 2 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/go-mode.el b/go-mode.el
index 44b53cd..f1a207e 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -416,7 +416,8 @@ For mode=set, all covered lines will have this weight."
       (go--fontify-param
        ;; Pre-match form that runs before the first sub-match.
        (go--fontify-param-pre)
-       nil ;; We don't use the post-match form.
+       ;; Post-match form that runs after last sub-match.
+       (go--fontify-param-post)
        ;; Subexp 1 is the param variable name, if any.
        (1 font-lock-variable-name-face)
        ;; Subexp 2 is the param type name, if any. We set the LAXMATCH
@@ -425,7 +426,7 @@ For mode=set, all covered lines will have this weight."
 
      ;; Special case to match non-parenthesized function results. For
      ;; example, "func(i int) string".
-     (,(concat ")[[:space:]]+" go-type-name-regexp "\\([[:space:]]\\|$\\)") 1 
font-lock-type-face)
+     (go--match-single-func-result 1 font-lock-type-face)
 
      ;; Match name+type pairs, such as "foo bar" in "var foo bar".
      (go--match-ident-type-pair 2 font-lock-type-face)
@@ -1266,8 +1267,13 @@ INDENT is the normal indent of this line, i.e. that of 
the case body."
 
 This is used during fontification of function signatures.")
 
+(defvar go--fontify-param-beg nil
+  "Position of \"(\" starting param list.
+
+This is used during fontification of function signatures.")
+
 (defun go--fontify-param-pre ()
-  "Set `go--fontify-param-has-name' appropriately.
+  "Set `go--fontify-param-has-name' and `go--fontify-param-beg' appropriately.
 
 This is used as an anchored font lock keyword PRE-MATCH-FORM. We
 must set `go--fontify-param-has-name' ahead of time because you
@@ -1283,15 +1289,29 @@ func foo(i, j int) {}
   (setq go--fontify-param-has-name (eq
                                     (go--parameter-list-type (point-max))
                                     'present))
+
+  ;; Remember where our match started so we can continue our serach
+  ;; from here.
+  (setq go--fontify-param-beg (point))
+
   ;; Return position of closing paren so we process the entire
   ;; multiline param list.
   (save-excursion
     (let ((depth (go-paren-level)))
       (while (and
               (re-search-forward ")" nil t)
-              (> (go-paren-level) depth))))
+              (>= (go-paren-level) depth))))
     (point)))
 
+(defun go--fontify-param-post ()
+  "Move point back to opening paren.
+
+This is used as an anchored font lock keyword POST-MATCH-FORM. We
+move point back to the opening \"(\" so we find nested param
+lists.
+"
+  (goto-char go--fontify-param-beg))
+
 (defun go--match-param-start (end)
   "Search for the starting of param lists.
 
@@ -1520,6 +1540,25 @@ succeeds."
 
     found-match))
 
+(defconst go--single-func-result-re (concat ")[[:space:]]+" 
go-type-name-regexp "\\(?:$\\|[[:space:]),]\\)"))
+
+(defun go--match-single-func-result (end)
+  "Match single result types.
+
+Parenthetical result lists are handled by the param list keyword,
+so we need a separate keyword to handle singular reuslt types
+such as \"string\" in:
+
+func foo(i int) string"
+  (let (found-match)
+    (while (and
+            (not found-match)
+            (re-search-forward go--single-func-result-re end t))
+      (when (not (member (match-string 1) go-mode-keywords))
+        (setq found-match t)
+        (goto-char (match-end 1))))
+    found-match))
+
 (defconst go--type-alias-re
   (concat "^[[:space:]]*\\(type\\)?[[:space:]]*" go-identifier-regexp 
"[[:space:]]*=[[:space:]]*" go-type-name-regexp))
 
diff --git a/test/go-font-lock-test.el b/test/go-font-lock-test.el
index 9fb5ae3..417fdf6 100644
--- a/test/go-font-lock-test.el
+++ b/test/go-font-lock-test.el
@@ -27,6 +27,9 @@
 
   (should-fontify "KfuncK(KinterfaceK { FfooF() }, TstringT) KinterfaceK{}")
 
+  (should-fontify "KfuncK(VaV TbT, VcV KfuncK(VdV *TeT) TdT) TfT")
+  (should-fontify "KfuncK(VaV KfuncK() TbT, VcV TdT)")
+
   (should-fontify "
 KfuncK FfooF(
   VaV TcatT, VbV KinterfaceK { FbarkF() },



reply via email to

[Prev in Thread] Current Thread [Next in Thread]