Vim函数切换替换光标下的字符

时间:2016-02-12 03:36:49

标签: vim

我试图改变" X"到" "反之亦然,在正常模式下标记降价文件中的复选框:

- [X] Zucchini
- [ ] Nutmeg

以下是我尝试的内容:

第一

function! ToggleComplete()
  if getline('.')[col('.')-1] == 'X'
    return ' '
  else
    return 'X'
  endif
endfunction

nnoremap <C-x> :call ToggleComplete()<CR>

第二

function! ToggleComplete()
  if getline('.')[col('.')-1] == 'X'
    return '\r\<Space>'
  else
    return '\rX'
  endif
endfunction

nnoremap <C-x> :call ToggleComplete()<CR>

1 个答案:

答案 0 :(得分:2)

这真的不能像这样工作;主要原因是你如何使用return语句:你的函数返回一个空格或一个X字符,但是返回的值从不使用,并且在你使用call ToggleComplete()时会丢失。实际上,您的代码中没有任何内容更改缓冲区的内容。

辅助点:您的if测试非常严格;它需要你的光标正好在行中的右边的char上才能工作(因为[col('.')-1])。也许这就是你想要的,但你也可以通过使用一个不依赖于光标列的测试来增加一些灵活性。

以下是做你想做的事的一种可能性:

function! ToggleComplete()
    " Get current line:
    let l:line = getline('.')

    " Get the char to test with the help of a pattern, ' ' or 'X':
    " \zs and \ze lets you retrieve only the part between themselves:
    let l:char = matchstr(l:line, '\[\zs.\ze]')

    " Invert the value:
    if l:char == 'X'
        let l:char = ' '
    else
        let l:char = 'X'
    endif

    " Replace the current line with a new one, with the right
    " char substituted:
    call setline(line('.'), substitute(l:line, '\[\zs.\ze]', l:char, ''))

    " Please note that this last line is doing the desired job. There is
    " no need to return anything
endfunction