1

I want to create a {} completion myself, and I did:

inoremap <CR> if_open_curly_on_left()? <CR>}<ESC>O : <CR> function! s:if_open_curly_on_left() abort let col = col('.') - 1 return !col || getline('.')[col - 1] =~# '{' endfunction 

which is modified by other's code, since I don't really understand the meaning inside the function.

When I typed enter I got:

enter image description here

How to fix this?

2 Answers 2

1

The logic is wrong here:

getline('.')[col - 1] =~# '{' 

This is saying anywhere before my cursor do I have a { character.

Probably want something that says does the end have a { character

getline('.')[col - 1] =~# '{$' getline('.')[col - 1] == '{' 

Although in theory that could still be weird if you put your insert cursor between {} characters and hit <cr>. So I imagine this needs to be adjusted a bit to become more robust

Maybe you the logic and be something like:

col('.') == (col('$') - 1) && strpart(getline('.'), -1) == '{' 

This will check that your in the final column and it ends with {

Aside:

Why col('.')-2 to get the previous character?

TL;DR: column position is 1-indexed and strings/arrays are 0-indexed

col('.') give you the current cursor position with the first column being 1

getline('.') will return a string or an array of characters with the first index being 0

Assume the following line and you cursor on the r:

bar 

So if we do a getline('.') and split it e.g. split(getline('.'), '\zs') we get:

['b', 'a', 'r'] 

Since we are on the r character then col('.') gives us 3 which is outside the bounds of our array by one. We compensate for the column starting on position one by subtracting one, col('.') - 1, to give the current position. To give the "previous character" then subtract by 2

1
  • By your kind hint at last line(, after many try-and-error), I got: return line[col] != '}' && line[col-1] == '}'. Regarding the original one, why it's col-1 in getline('.')[col-1] when I already did let col = col('.')-1? Commented Mar 29, 2021 at 21:51
1

After some search this work(, but might be simplified further):

" My try inoremap <silent><expr> <CR> \ <SID>if_open_curly_on_left()? "\<CR>}\<ESC>O": \ "\<CR>" function! s:if_open_curly_on_left() abort let col = col('.') - 1 return getline('.')[col - 1] == '{' endfunction 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.