Calling a vim9script function with a range

36 views
Skip to first unread message

Russell Shaw

unread,
Jul 22, 2025, 5:47:50 AMJul 22
to v...@vim.org
Hi,

In "Comment()", how can i tell if the mapping "\c" was called with a visual
range or not ?

I want to call "Comment()" only once, without resorting to a legacy function,
and without resorting to an intermediate ex command.

I want access to the first and last visual lines, or else the current line (for
non-visual, first==last).

---------------------------------
vim9script

def g:Comment()
echo "a"
enddef

map \c :<C-U>call Comment()<CR>
---------------------------------

Igbanam Ogbuluijah

unread,
Jul 22, 2025, 8:42:13 AMJul 22
to vim...@googlegroups.com, v...@vim.org
May not be the most efficient way but… I'll accept a "mode" in g:Comment() as g:Comment(mode: string). Then in the mappings, I'd explicitly map modes with their strings

vmap \c :<C-U>call Comment("visual")<CR>


Igbanam

--
--
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/a3ef458e-d463-4e2c-b109-5342d9e54078%40netspace.net.au.

Lifepillar

unread,
Jul 22, 2025, 5:03:52 PMJul 22
to vim...@googlegroups.com
I have something like this in my vimrc:

vim9script
nnoremap <silent> Q :set opfunc=libtext#ToggleComment<cr>g@
vnoremap <silent> Q <scriptcmd> libtext.ToggleComment(visualmode(), true)<cr>

Then, in autoload/libtext.vim:

export def ToggleComment(visualMode: string, visual: bool = false)
# Comment/uncomment a region of text. See also :help map-operator.
#
# visualMode: one of "line", "char", or "block". See :help g@.
# visual: whether the function is called directly when in Visual mode (true)
# as opposed to being called via opfunc (false).
var first: number
var last: number

if visual
var lnum1 = line("v")
var lnum2 = line(".")

if lnum1 < lnum2
first = lnum1
last = lnum2
else
first = lnum2
last = lnum1
endif
else
first = line("'[")
last = line("']")
endif

# Do something with getline(first, last)
enddef

Depending on your goal, you may also want to look at Vim's comment
plugin at $VIMRUNTIME/pack/dist/opt/comment.

Hope this help,
Life.


Russell Shaw

unread,
Jul 23, 2025, 5:18:53 AMJul 23
to vim...@googlegroups.com
On 23/7/25 07:03, Lifepillar wrote:
> On 2025-07-21, 'Russell Shaw' via vim_use <vim...@googlegroups.com> wrote:
>> Hi,
>>
>> In "Comment()", how can i tell if the mapping "\c" was called with a visual
>> range or not ?
...

> Depending on your goal, you may also want to look at Vim's comment
> plugin at $VIMRUNTIME/pack/dist/opt/comment.

Hi all, i was trying to port a comment function i was using in legacy
script. Thanks for the ideas. I'll look at that plugin.

russell shaw

unread,
Jul 27, 2025, 2:42:21 AMJul 27
to vim...@googlegroups.com
On 22/7/25 22:41, Igbanam Ogbuluijah wrote:
> May not be the most efficient way but… I'll accept a "mode" in g:Comment() as
> g:Comment(mode: string). Then in the mappings, I'd explicitly map modes with
> their strings
>
> vmap \c :<C-U>call Comment("visual")<CR>

vim9script
map <F5> :echo "N" .. mode()<CR>
vmap <F5> :<C-U>echo "V" .. mode()<CR>

In normal mode, pressing F5 gives "Nn", in visual mode, pressing F5 gives "Vn".

Why doesn't mode() print "v" in the visual mode ?
Reply all
Reply to author
Forward
0 new messages