Vim 9 script question

71 views
Skip to first unread message

Yu Lang Chiang

unread,
Jun 3, 2025, 2:45:56 AMJun 3
to vim_use
Recently I've been trying to learn Vim 9 script by rewriting Vim plugins into Vim 9 script. While attempting to modify *vim-unimpaired*, I discovered that functions related to setting up mappings do not work properly when ported to Vim 9 script. For example, in the `plugin/unimpaired.vim` file, the function `MapNextFamilty` is problematic.

**Original version:**

```vim
execute 'nnoremap <silent> '.prefix.'previous) :<C-U>exe "'.cmd.'previous'.end
execute 'nnoremap <silent> '.prefix.'next)     :<C-U>exe "'.cmd.'next'.end
execute 'nnoremap '.prefix.'first)    :<C-U><C-R>=v:count ? v:count . "' . a:current . '" : "' . a:cmd . 'first"<CR><CR>' . zv
execute 'nnoremap '.prefix.'last)     :<C-U><C-R>=v:count ? v:count . "' . a:current . '" : "' . a:cmd . 'last"<CR><CR>' . zv
execute 'nnoremap <silent> '.map.'Previous :<C-U>exe "'.cmd.'previous'.end
execute 'nnoremap <silent> '.map.'Next     :<C-U>exe "'.cmd.'next'.end
execute 'nnoremap <silent> '.map.'First    :<C-U>exe "'.cmd.'first'.end
execute 'nnoremap <silent> '.map.'Last     a:<C-U>exe "'.cmd.'last'.end
```

**Vim 9 script version:**

```vim
execute 'nnoremap <silent> ' .. prefix .. 'previous) :<C-U>exe "' .. tcmd .. 'previous' .. end
execute 'nnoremap <silent> ' .. prefix .. 'next)     :<C-U>exe "' .. tcmd .. 'next' .. end
execute 'nnoremap ' .. prefix .. 'first)    :<C-U><C-R>=v:count ? v:count . "' .. current .. '" : "' .. cmd .. 'first"<CR><CR>' .. zv
execute 'nnoremap ' .. prefix .. 'last)     :<C-U><C-R>=v:count ? v:count . "' .. current .. '" : "' .. cmd .. 'last"<CR><CR>' .. zv
execute 'nnoremap <silent> ' .. tmap .. 'Previous :<C-U>exe "' .. tcmd .. 'previous' .. end
execute 'nnoremap <silent> ' .. tmap .. 'Next     :<C-U>exe "' .. tcmd .. 'next' .. end
execute 'nnoremap <silent> ' .. tmap .. 'First    :<C-U>exe "' .. tcmd .. 'first' .. end
execute 'nnoremap <silent> ' .. tmap .. 'Last     :<C-U>exe "' .. tcmd .. 'last' .. end
```

When inspecting the mappings using:

```vim
echo maparg('<Plug>('unimpaired-commmand')', 'n')
```

you find that both versions produce identical mappings. For example:

- **Original version:**

  ```
  :<C-U>exe "".(v.count ? v:count : "")."bprevious"<CR>
  ```

- **Vim 9 script version:**

  ```
  :<C-U>exe "".(v.count ? v:count : "")."bprevious"<CR>
  ```

Despite the mappings appearing the same, the one defined in the Vim 9 script version does not work. Even after removing `<silent>`, no error messages are reported. Any advice?

**Test Environment:**

- **OS:** Fedora Linux 42 (x86-64)
- **Vim:** 9.1.1418

My repository is https://github.com/seanexplus/vim-unimpaired/tree/master . All vim 9 script rewriting is in vim-9-test branch.

Maxim Kim

unread,
Jun 10, 2025, 11:05:08 PMJun 10
to vim_use
vim9script enforces spaces between operators,  your mappings are defined in vim9script context so it expects spaces between concatenation operator .

:<C-U>exe "" . (v.count ? v:count : "") . "bprevious"<CR>

Yu Lang Chiang

unread,
Jun 11, 2025, 8:21:19 AMJun 11
to vim...@googlegroups.com
I tried the following combinations:

<C-U>exe "" . (v.count ? v:count : "") . "bprevious"<CR>
<C-U>exe "” .. (v.count ? v:count : "") .. "bprevious"<CR>
<C-U>execute "” .. (v.count ? v:count : "") .. "bprevious"<CR>
<C-U>execute "” . (v.count ? v:count : "") . "bprevious"<CR>


None of them work.

Vim has been updated to version 9.1.1435

-- 
-- 
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/vim_use/98ea42d5-faba-46f9-b642-f1c82d957d71n%40googlegroups.com.

Salman Halim

unread,
Jun 11, 2025, 8:45:51 AMJun 11
to Vim Users
Use .. in Vim 9 (mappings 2 and 3 below). Also, you have v.count and v:count. They probably aren't both correct (all of them have that). 

What happens when you just type the whole thing on the command line directly?

Salman

Yu Lang Chiang

unread,
Jun 12, 2025, 5:16:45 AMJun 12
to vim...@googlegroups.com
I've identified that the root cause was in another part of the code, and it's now resolved. Thank you all for your assistance.

Salman Halim <salma...@gmail.com> 於 2025年6月11日 週三 下午8:45寫道:

Eric Marceau

unread,
Jun 13, 2025, 3:59:48 PMJun 13
to vim...@googlegroups.com

Hello Lang Chiang,

Good to hear your problem is solved!

Could you share with all of us 

  • exactly where the problem's root cause was, and
  • the how of way it was resolved?

I am sure that would benefit many of us.

Thank you,


Eric

Yu Lang Chiang

unread,
Jun 14, 2025, 10:00:14 AMJun 14
to vim...@googlegroups.com

I found that I had mistakenly removed execute from all Map(.....) portions, causing them to fail to map to actual keys.

I've now completed testing and fixing most of the functionality. During this process, I learned:

Some Vim script patterns that use strings to define actions must be converted to lambda syntax in Vim 9 script, such as filter() and substitute().

When using substitute() in Vim 9 script, if the lambda includes expressions like nr2char(submatch(1)), it must be rewritten as nr2char(str2nr(submatch(1))).

In Vim script, you can simply use +/- to move to the next/previous line, but in Vim 9 script you must use the cursor() function.

In Vim script, you can operate on registers using @@, but in Vim 9 script you have to use setreg()/getreg().
In Vim script, you can use {funcname}(param) to call function by name, but in Vim 9 script you have to use function(funcname)(param)
Where <sfile> is used in Vim script, <script>/<stack> must be used in Vim 9 script.

Reply all
Reply to author
Forward
0 new messages