46

I wonder is there a way to count highlighted symbols in vim (including white spaces)?

UPDATE

VIM visual mode

It shows rows count if my selection is on multiple rows. I need symbols count.

5 Answers 5

54

Unless I'm missing something, Vim already does that. If I highlight some text using the mouse or by typing v and moving the cursor, I see at the bottom of the screen

-- VISUAL --                                        12

If you don't see this add set showcmd to your .vimrc to enable it.

The number on the right is the number of highlighted characters. This only works if the selection is on a single row, otherwise it shows the row count.

You can also visually select some region of text and type g Ctrl-G which will show the number of lines, words and bytes selected.

6
  • 6
    (stunned) How the heck did I use Vim for so long and never notice that ? But in my defense, I was thinking about obtaining the number programmatically.
    – njd
    May 27, 2011 at 8:44
  • Good answer, but take a look at updated question. As well as @njd I did not notice that.
    – Nemoden
    May 27, 2011 at 9:28
  • 1
    @Nemoden: Try the second part of garyjohn's suggestion (g Ctrl-G). It should show a line like "Selected # of # Lines; # of # Words; # of # Bytes."
    – peth
    May 27, 2011 at 9:48
  • Oh. My bad. I don't know why I've skipped the second solution. It works. Thank you!
    – Nemoden
    May 27, 2011 at 9:50
  • 16
    This isn't enabled by default on some systems. Just add set showcmd to your vimrc to enable it. Mar 14, 2013 at 15:48
12

Vim flips between displaying character count and line count for visualised text depending on what and how you visualise (vim 7.4 patched to Sept 2015)

V will display line count
v$ will display character count

If you visualise more than one line it only displays line count

g-CTRL-G displays 'byte count' which seems to be 'char count' +1 per line
1
  • 2
    As the question says, even normal v switches from character-count to line-count if the selection spans multiple lines. However g CTRL-G does the job nicely. Feb 19, 2016 at 5:16
3

I see from your screenshot that you are running in Windows, so this answer may not help you as much. But for others...

An under-used (IMO) feature of Vim is to let external commands do the heavy lifting.

For this case, if you're on a UNIX-like system, you can use the wc command to do that.

The simplest way is to replace the selected text with the output of the command, by typing (with text selected):

:!wc

(then press enter).

This will show in your command line as:

'<,'>!wc

After you've read the info, you can undo with u to get back to where you started.

Note: This processing is done on whole lines only. If you want partial lines, I think @garyjohn's g_CTRL-G is your best bet.

You can avoid the need to undo by instead running:

:w !wc

This "writes" the selected lines to the command's standard input, and the output of the command will be displayed in a new temporary buffer, leaving the original untouched. See :help :write_c for more info.

Note: I got the :write_c info from: https://stackoverflow.com/questions/1237780/vim-execute-shell-command-without-filtering

Now, more generally:

This example with wc is pretty simplistic, but you can imagine how this is a powerful approach. UNIX has a lot of text processing commands available already, and you can use them inside Vim quite easily, without needing to touch Vimscript (yech).

Further, any commandline program you write that deals with stdin/stdout can now not only benefit you at your terminal, but also inside Vim.

I find myself, for example, running tidy and json-format from inside vim to make files I'm looking at more readable.

You can do the same on Windows, but Windows does not have such a rich set of commands built-in. You can always install GNUWin32 or similar to get those benefits, though.

2
:function VisualLength()
:  exe 'normal "xy'
:  echo "Visual: " . strlen(@x) . "\n"
:  exe 'normal gv'
:endfunction

:map ,q "xy:call VisualLength()<CR>
  1. First you yank the current selection (into buffer x)

  2. Then you display the length of that buffer: strlen(@x)
    (The -- VISUAL -- displayed in the status line obscures this, so we have to add a newline)

  3. Highlight the previous visual range: gv

This doesn't take account of whether the visual mode was line-, character- or block-mode, but it's enough for most cases.

1

For a programmatic way within vimscript, this worked for me when the selection is limited to within one line:

let amount = virtcol("'>") - virtcol("'<")

(Using virtcol(..) instead of col(..), such that it works as expected when :set ve=all is active.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .