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

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.