Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support syntax highlighting for bracketed expression in fmt string #1634

Merged
merged 4 commits into from
Jan 4, 2018

Conversation

e-zhang
Copy link
Contributor

@e-zhang e-zhang commented Jan 2, 2018

Per the go docs for the fmt package, there is a bracket expression that is supported in format strings.

For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22) fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)

Should all be valid syntax highlighted format strings.

@arp242
Copy link
Contributor

arp242 commented Jan 3, 2018

Thanks! Seems to work well judging from looking at fmt/fmt_test.go in Vim. I added a commit to support %F too, as that didn't work either.

The only pattersn that don't work yet are:

{"%.f", 0i, "(0+0i)"},
{"% .f", 0i, "( 0+0i)"},
{"%+.f", 0i, "(+0+0i)"},
{"% +.f", 0i, "(+0+0i)"},

I tried to fix it, but leaning toothpick syndrome hurts by brain at this hour. I think we can make this more readable by some strategic insertions of \v and such.

I also wonder if there's a good way to split this across multiple lines, preferably with comments like in Python or Ruby:

 pattern = """
    ^                   # beginning of string
    M{0,4}              # thousands - 0 to 4 M's
    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                        #            or 500-800 (D, followed by 0 to 3 C's)
    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                        #        or 50-80 (L, followed by 0 to 3 X's)
    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                        #        or 5-8 (V, followed by 0 to 3 I's)
    $                   # end of string
    """

That would make it much easier to maintain!

@arp242 arp242 closed this Jan 3, 2018
@arp242 arp242 reopened this Jan 3, 2018
@e-zhang
Copy link
Contributor Author

e-zhang commented Jan 3, 2018

I will take a look at those and learn to run the units as well. Thanks for the feedback, I'll try to update this PR with those changes as soon as a I can.

@arp242
Copy link
Contributor

arp242 commented Jan 3, 2018

Here's the best I could come up with:

diff --git i/syntax/go.vim w/syntax/go.vim
index 89b0e9a..a7bc2e1 100644
--- i/syntax/go.vim
+++ w/syntax/go.vim
@@ -202,7 +202,19 @@ else
 endif
 
 if g:go_highlight_format_strings != 0
-  syn match       goFormatSpecifier   /\([^%]\(%%\)*\)\@<=%[-#0 +]*\%(\%(\%(\[\d\]\)\=\*\)\|\d\+\)\=\%(\.\%(\%(\%(\[\d\]\)\=\*\)\|\d\+\)\)\=\%(\[\d\]\)\=[vTtbcdoqxXUeEfFgGsp]/ contained containedin=goString,goRawString
+  " 1. Match a literal % not preceded by a %.
+  " 2. Match -, #, 0, space, or +
+  " 3. ??
+  " 4. ??
+  " 5. ??
+  " 6. Match formatting verb.
+  syn match       goFormatSpecifier   /\
+                  \([^%]\(%%\)*\)\
+                  \@<=%[-#0 +]*\
+                  \%(\%(\%(\[\d\]\)\=\*\)\|\d\+\)\=\
+                  \%(\.\%(\%(\%(\[\d\]\)\=\*\)\|\d\+\)\)\=\
+                  \%(\[\d\]\)\
+                  \=[vTtbcdoqxXUeEfFgGsp]/ contained containedin=goString,goRawString
   hi def link     goFormatSpecifier   goSpecialString
 endif

Vim is very finicky about where you can place the \ though, and it doesn't always work :-(

Maybe a better solution is to use string concatenation (untested):

" Match a literal % not preceded by a %.
let s:p = '\([^%]\(%%\)*\)\'

" Match -, #, 0, space, or +
let s:p .= '\@<=%[-#0 +]*\'

[...]

exe 'syn match goFormatSpecifier /' . s:p . '/ contained containedin=goString,goRawString'

@e-zhang
Copy link
Contributor Author

e-zhang commented Jan 3, 2018

Took your suggestion for doing multi-line continuation and added comments. I think everything in fmt/fmt_test.go is highlighted correctly now.

I'm not familiar enough with the \v option in vim, so I punted on doing that for now.

@arp242
Copy link
Contributor

arp242 commented Jan 4, 2018

Thanks! Works well, and much more readable/maintainable like this, even though it's still a long/ugly regex :-)

@arp242 arp242 merged commit 3ceecc2 into fatih:master Jan 4, 2018
@fatih
Copy link
Owner

fatih commented Jan 4, 2018

Nice addition 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants