0

How to determine if the cursor is placed on the last character of the word under the cursor?

I can get information about the word under cursor like determining if the length of the word under the cursor is 1 character:

strlen(expand('<cword>'))==1

But as far as I see the expression expand('<cword>') only returns the word itself with no information about the cursor position.

Any help pointing towards a potential solution is appreciated.

2 Answers 2

1

I'd take a more experimental approach that @Karl Yngve Lervåg does in his answer:

This works by moving the cursor back a word and then forwards again and then seeing if the cursor is in the same place. If it is, then the cursor was on the end of a <word>.

Using this technique saves you having to reverse-engineer and reimplement Vim's <word> algorithm in VimScript.

function! EndWord() abort
  let pos = getpos('.')
  normal! gee
  if pos == getpos('.')
    return v:true
  else
    call setpos('.', pos)
    return v:false
  endif
endfunction
2
  • Thank you for sharing this answer. Tested it and it seems to work for what I had in mind. Commented Dec 5, 2018 at 22:37
  • @KarolisKoncevičius Glad I could help!
    – Rich
    Commented Dec 5, 2018 at 22:39
2

I would get the characters on the current line from the cursor and on and check if they match the end-of-word atom, i.e. something like this:

map <silent> q :call Test()<cr>

function! Test() abort
  return strcharpart(getline('.'), virtcol('.')-1, 3) =~# '^\w\>'
endfunction

Here I've added a map for making it easy to test. You can adjust the function, resource the file and then use q to test the function.

I use virtcol and strcharpart to support multibyte characters.

3
  • Thank you for the answer it definitely goes in the right direction. One thing that I am still missing (and it is my fault for not specifying it in the question) is - it doesn't work on non-word characters, like : or ). Maybe you have any quick pointers about how to make it behave in-tune with vim's word motion definition? I tried replacing \w with \k in your example, but it didn't help: when the cursor is on a loose ":" for example - it doesn't consider that a "word". Commented Dec 2, 2018 at 19:55
  • It's a bit unclear exactly what you want to consider a word. Do you want to adhere to :help word? Or perhaps :help WORD? The first thing to try is to change \w with \S, i.e. any non space character. Commented Dec 3, 2018 at 8:01
  • Thank you for the reply. Yep, I would like to adhere to :word or in other words - any character where vim's e motion stops on should return "1" for the "end of word" test. I found that there is \k for "iskeyword" but it didn't get me anywhere. Commented Dec 3, 2018 at 9:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.