lacygoill / vim9-syntax

16 stars 1 forks source link

Sometimes RHS of mapping is highlighted as vim9MarkCmdArgInvalid #3

Closed bfrg closed 2 years ago

bfrg commented 2 years ago

I have quite a few motion mappings similar to the following:

vim9script
# Jump to next/previous git conflict marker
nnoremap ]x <scriptcmd>mark `<bar>range(v:count1)->map((_, _) => search('^\(<\\|=\\|>\)\{7}\([^=].\+\)\?$', 'W'))<cr>
nnoremap [x <scriptcmd>mark `<bar>range(v:count1)->map((_, _) => search('^\(<\\|=\\|>\)\{7}\([^=].\+\)\?$', 'bW'))<cr>
xnoremap ]x <scriptcmd>mark `<bar>range(v:count1)->map((_, _) => search('^\(<\\|=\\|>\)\{7}\([^=].\+\)\?$', 'W'))<cr>
xnoremap [x <scriptcmd>mark `<bar>range(v:count1)->map((_, _) => search('^\(<\\|=\\|>\)\{7}\([^=].\+\)\?$', 'bW'))<cr>

Unfortunately, after the mark the syntax file highlights some parts of the RHS as vim9MarkCmdArgInvalid.

Screenshot: screenshot-2022-09-29_005244

Adding a ` to mark_valid fixes the issue, but only if we also add a whitespace before the <bar>:

diff --git a/import/vim9Language.vim b/import/vim9Language.vim
index 7f5e6aa..cd0d56b 100644
--- a/import/vim9Language.vim
+++ b/import/vim9Language.vim
@@ -1472,7 +1472,7 @@ export const logical_not: string = '/\w\@1<!![~=]\@!!*/'

 # mark_valid {{{1

-export const mark_valid: string = '[a-zA-Z''[\]<>0-9"^.(){}]'
+export const mark_valid: string = '[a-zA-Z`''[\]<>0-9"^.(){}]'

 # maybe_dict_literal_key {{{1

screenshot-2022-09-29_005226

An improvement would be to add <bar> to the regex in the syntax match vim9MarkCmdArg, but I don't know if you want to further complicate the regex:

diff --git a/syntax/vim.vim b/syntax/vim.vim
index f0288c8..1ef0ca0 100644
--- a/syntax/vim.vim
+++ b/syntax/vim.vim
@@ -1511,7 +1511,7 @@ syntax keyword vim9MarkCmd ma[rk]
     \ skipwhite

 syntax match vim9MarkCmdArgInvalid /[^ \t|]\+/ contained
-execute 'syntax match vim9MarkCmdArg /\s\@1<=' .. lang.mark_valid .. '\_s\@=/ contained'
+execute 'syntax match vim9MarkCmdArg /\s\@1<=' .. lang.mark_valid .. '\%(\_s\|<bar>\)\@=/ contained'

 # :nnoremap {{{3

screenshot-2022-09-29_005849

lacygoill commented 2 years ago

An improvement would be to add to the regex in the syntax match vim9MarkCmdArg, but I don't know if you want to further complicate the regex:

There are other locations where the plugin needs to allow for a keycode like <Bar>, <CR>. I think for those, < is allowed. So, to be consistent, I did the same thing; I just allowed < in this commit. Maybe, it's not accurate enough. But for now, that should be enough.

bfrg commented 2 years ago

Thank you. It fixes the issue with the white space. But what about the backtick? It's still not contained in mark_vaild.

bfrg commented 2 years ago

It looks like the backtick doesn't even change anything. I thought it would also save the column position but that's not the case. Anyway, it's fixed as far as I'm concerned.

lacygoill commented 2 years ago

It looks like the backtick doesn't even change anything. I thought it would also save the column position but that's not the case.

Yes, most Ex commands operate linewise. They are not aware of the column cursor position, which is why I prefer the single quote as an argument in a :mark command (it's less misleading). For a column-aware command, :normal can be used instead (because it simulates a keypress):

                       v------------------v
nnoremap ]x <scriptcmd>execute 'normal! m`'<bar>range(v:count1)->map((_, _) => search('^\(<\\|=\\|>\)\{7}\([^=].\+\)\?$', 'W'))<cr>
bfrg commented 2 years ago

The problem with execute 'normal! m`' is that the count doesn't work anymore. I should probably just use a separate function after all.

Thanks anyway!

lacygoill commented 2 years ago

The problem with execute 'normal! m`' is that the count doesn't work anymore.

Not sure, but maybe :help v:prevcount could help retrieve the old count.

I should probably just use a separate function after all.

Yes, as soon as the RHS becomes a little complicated, I turn it into a function; it's easier to read and maintain later.