2016-02-12 7 views
1

Я пытаюсь изменить «X» в «», и наоборот, чтобы отметить флажок в уценки файл в обычном режиме:Vim функция переключения заменить символ под курсором

- [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

Почему не просто 'rX' и' 'г ? – romainl

+0

Это для плагина vimwiki? Если это так, 'nmap VimwikiToggleListItem' должен это сделать. – Amadan

+0

и что не сработало? Здесь я не вижу проблемы. –

ответ

2

Это действительно не может работать так; основная причина заключается в том, как вы используете оператор return: ваша функция возвращает пробел или символ X, но возвращаемое значение никогда не используется и теряется при использовании call ToggleComplete(). На самом деле в коде нет ничего, что изменяет содержимое вашего буфера.

Вторичный пункт: ваш if тест очень ограничительный; он требует, чтобы ваш курсор был точно на нулевом символе в строке, чтобы работать (из-за [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 
+0

Спасибо yolenoyer. Да, казалось, что возвращение ничего не сделало бы, если бы вы не были в режиме вставки, поэтому спасибо за разъяснение, что я вообще не знаю Vimscript. Я ценю прокомментированный код, но теперь возникает новая проблема: я могу переключать «» на X, но не могу вернуться с X на «». – djv

+0

Является ли ваш символ «X» действительно прописным? – yolenoyer

+0

Да, он изменяется от '[]' до '[X]', но не '[X]' to '[]'. Спасибо за то, что вы сияли какой-то свет, чтобы не оказаться в точной колонке, это здорово. – djv