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

Vim: multiline :syn-match patterns #2

Open
dkearns opened this issue Jan 4, 2024 · 0 comments
Open

Vim: multiline :syn-match patterns #2

dkearns opened this issue Jan 4, 2024 · 0 comments

Comments

@dkearns
Copy link

dkearns commented Jan 4, 2024

G'day Benjamin,

I just noticed the following comment in one of the Vim syntax files.

"| *** VMSCRIPT BUG ALERT ***
"| The regular expression below causes errors when split into separate strings
"|
"| syn match m2Base10Num
"| \ "\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)" .
"| \ "\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?"
"|
"| E475: Invalid argument: m2Base10Num "\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)"
"| . "\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?"
"|
"| However, the same regular expression works just fine as a sole string.
"|
"| As a consequence, we have no choice but to put it all into a single line
"| which greatly diminishes readability and thereby increases the opportunity
"| for error during maintenance. Ideally, regular expressions should be split
"| into small human readable pieces with interleaved comments that explain
"| precisely what each piece is doing. Vimscript imposes poor design. :-(
syn match m2Base10Num
\ "\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?"

The m2Base10Num pattern is not a string literal. The quotes in this case are just pattern delimiters, any character can be used. So, if you wish, it can be split over multiple lines using a normal line continuation and insert comments with a leading "\ sequence (trailing space required - see :help line-continuation-comment).

syn match m2Base10Num
  \ /\(\(0[bux]\@!\|[1-9]\)[0-9]*\('[0-9]\+\)*\)
  "\ a comment
  \\(\.[0-9]\+\('[0-9]\+\)*\(e[+-]\?[0-9]\+\('[0-9]\+\)*\)\?\)\?/

Alternatively you could use something like the following to interleave comments as described.

" a comment for part 1
let part1 = '\(\(0[bux]\@!\|[1-9]\)[0-9]*\(''[0-9]\+\)*\)'
" a comment for part 2
let part2 = '\(\.[0-9]\+\(''[0-9]\+\)*\(e[+-]\?[0-9]\+\(''[0-9]\+\)*\)\?\)\?'

exe $"syn match m2Base10Num2 /{part1}{part2}/"

Obviously, neither of these are as nice as Perl's x modifier but maybe they're of some use to you.

Regards,
Doug

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

No branches or pull requests

1 participant