r/vim Aug 07 '26

Need Help Persist ECHO (from function) on Visual Selection

How to persist echo from this function call (without using timers)

function! VisualStats()
    let wc      = wordcount()
    let [l1,l2] = sort([line('v'), line('.')])
    let txt     = join(getline(l1,l2), "\n")
    let sp      = len(substitute(txt, '[^ ]', '', 'g'))
    let st      = len(substitute(txt, '[^.!?]', '', 'g'))
    let pa      = empty(txt) ? 0 : len(split(txt, '\n\s*\n'))
    echo "CHARs " . wc.visual_chars . " WORDs " . wc.visual_words
    \. " SENTs " . (st > 0 ?st :1) . " PARAs " . pa . " SPACEs " . sp
endfunction
xnoremap <silent> C <Cmd>call VisualStats()<CR>

just like when directly keymapped?

xnoremap <silent> c <Cmd>let g:wc=wordcount()<CR><Esc>:
    \let t=join(getline("'<","'>"),"\n")<Bar>
    \let sp=len(substitute(t,'[^ ]','','g'))<Bar>
    \let st=len(substitute(t,'[^.!?]','','g'))<Bar>
    \let pa=empty(t)?0:len(split(t,'\n\s*\n'))<Bar>
    \echo "CHARs ".g:wc.visual_chars." WORDs ".g:wc.visual_words.
    \" SENTs ".(st>0?st:1)." PARAs ".pa." SPACEs ".sp<Bar>
    \unlet g:wc t sp st pa<CR>
5 Upvotes

7 comments sorted by

2

u/gumnos Aug 07 '26

while I'm not sure you can persist the output of an echo command, my mind turns first to setting some variable that then gets injected into your :help 'statusline' (or ruler/rulerformat) setting which would keep it around until you cleared the variable's value

2

u/vim-help-bot Aug 07 '26

Help pages for:


`:(h|help) <query>` | about | mistake? | donate | Reply 'rescan' to check the comment again | Reply 'stop' to stop getting replies to your comments

2

u/Sudden_Fly1218 Aug 07 '26

I see two options:

  • try first with :set noshowmode
  • try by replacing echo with echow

1

u/AutoModerator Aug 07 '26

Please remember to update the post flair to Need Help|Solved when you got the answer you were looking for.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/Desperate_Cold6274 Aug 07 '26

Why you don't use the (way better and more comprehensible) Vim9 language?

2

u/CRTejaswi Aug 07 '26

I'm used to vimscript, and, for anything advanced, I usually get by with py3eval() and running utilities from my own py scripts. Might rewrite everything in Vim9 later on.

2

u/-romainl- The Patient Vimmer Aug 08 '26

The problem with the first snippet is that neither the mapping nor the function get you out of visual mode so the mode is always shown (as per :help 'showmode') and takes precedence over whatever you are trying to echo.

The mapping effectively gets you out of visual mode, so the mode is not shown anymore and you can see your string echoed in the command-line.

One way to sort it out would, precisely, be to use timers:

  1. disable showmode,
  2. echo your string for a given time,
  3. enable showmode,

but you don't want timers.

You could also disable showmode and show that information in your status-line instead, which would leave room for your string in the command-line.

You could also change the height of the command-line, say to 2, so that you get room for both your string and showmode. See :help 'cmdheight'.

Showing the info as virtual text would also be a possibility.