Getting the ascii / hex code of the character under the cursor in Vim is harder than I thought...
- The simplest way to get it is to just show it on the
statusline(or equivalently in lightline) with
%B, as visible in the docs or in this Vim Tips entry.
- The problem is that I can't get the value into a Vim variable this way.
- Another way is to simply yank the damn thing with something like
"zyl, which will put the value in the
@zregister, as described here.
virtualeditis set to anything, then this will return a
spaceif there is no character under the cursor, for any mode in which
- What's more is that I may very well not want to run a
normalcommand like this, especially in
- Another way is to do something like
let ch = getline('.')[col('.') - 1], which is also described here.
- This doesn't respect unicode characters because their length is "interesting".
So here's what I eventually tried:
function! LightLineCharacter() " Save what's in the `z` register and clear it let x = @z let @z = "" " Redirect output to the `z` register redir @z " Run the `ascii` command to get all of the interesting character information silent! ascii redir END " Clean up the output and split the line let line = substitute(substitute(@z, '^.*> ', '', ''), ',', '', 'g') let list = split(line) " Reset the `z` register let @z = x " `dec` and `hex` hold the values I want let dec = 0 let hex = 0 " If we've split something reasonable, then get decimal and hex values if len(list) >= 4 let dec = list let hex = list endif " Return it the way I want return dec . "/0x" . hex endfunction
However, as I was researching the links for this post, I found the "real" answer:
let dec = char2nr(matchstr(getline('.'), '\%' . col('.') . 'c.'))
You can find the explanation in one of the comments in the StackOverflow post but I'll also explain it here.
getline('.')returns the entire line that cursor is sitting on.
col('.')returns the column number that the cursor is sitting on.
- The regular expression
\%ncmatches a specific given column where
nis that column.
- The '
.' regular expression matches exactly one character.
So, let's assume that the column the cursor is currently on is
31. Then the above code evaluates to:
let dec = char2nr(matchstr(getline('.'), '\%31c.'))
which means that you're going to match the single character (multi-byte or otherwise) at position
31 in the string returned by
char2nr() is going to transform the character to a decimal number.
It's really not always that easy to figure out what needs writing when you're in Vimscript!