Сохранять позицию курсора при использовании ==

Я пытаюсь сделать линии отступа Vim такими же, как Emacs (то есть «сделать текущую строку правильным отступом» вместо «вставить символ табуляции»). Vim может сделать это с помощью = (или ==) для одной строки). У меня есть imap <Tab> <Esc>==i в моем .vimrc, но это заставляет курсор двигаться к первому непробельному символу в строке. Я хотел бы, чтобы положение курсора сохранялось, чтобы я мог просто нажать вкладку и вернуться к вводу текста без необходимости снова настраивать курсор. Это возможно?

Пример

  • Что у меня есть сейчас (| представляет курсор):

    function f() {
    doso|mething();
    }
    

    Вкладка

    function f() {
        |dosomething();
    }
    
  • Что я хотел бы:

    function f() {
    doso|mething();
    }
    

    Вкладка

    function f() {
        doso|mething();
    }
    

    Также

    function f() {
     |  dosomething();
    }
    

    Вкладка

    function f() {
       |dosomething();
    }
    

person Johnny Test    schedule 02.07.2013    source источник


Ответы (3)


Я не верю, что есть "простой" способ сделать это (то есть со строго встроенной функциональностью), но простая функция делает это просто отлично. В вашем файле .vimrc:

function! DoIndent()       
    " Check if we are at the *very* end of the line
    if col(".") == col("$") - 1
        let l:needsAppend = 1
    else
        let l:needsAppend = 0
    endif

    " Move to location where insert mode was last exited
    normal `^

    " Save the distance from the first nonblank column
    let l:colsFromBlank = col(".")
    normal ^
    let l:colsFromBlank = l:colsFromBlank - col(".")

    " If that distance is less than 0 (cursor is left of nonblank col) make it 0
    if l:colsFromBlank < 0                            
        let l:colsFromBlank = 0
    endif

    " Align line
    normal ==

    " Move proper number of times to the right if needed
    if l:colsFromBlank > 0
        execute "normal " . l:colsFromBlank . "l"
    endif

    " Start either insert or line append
    if l:needsAppend == 0
        startinsert
    else
        startinsert!
    endif
endfunction                                   

" Map <Tab> to call this function                                          
inoremap <Tab> <ESC>:call DoIndent()<CR>
person ravron    schedule 02.07.2013
comment
Большое спасибо за ваше время. Раньше это почти работало, но ваше последнее редактирование сделало его немного шатким. До того, как вы его отредактировали, он работал, за исключением случаев, когда курсор находился в конце строки или в начале. - person Johnny Test; 03.07.2013
comment
Хрм. Позвольте мне проверить это немного более строго. Дай мне минуту. - person ravron; 03.07.2013
comment
@Джонни, я думаю, теперь это исправлено. - person ravron; 03.07.2013
comment
И спасибо за комментарии, сейчас я пытаюсь изменить его так, чтобы он работал и в обычном режиме, а комментарии значительно облегчают работу. - person Johnny Test; 03.07.2013
comment
Для будущих посетителей добавление строки nnoremap <Tab> i<ESC>:call DoIndent()<CR><ESC>l в конце, похоже, заставит его работать так же хорошо в обычном режиме. Еще раз спасибо, Райли, хотел бы я проголосовать несколько раз. - person Johnny Test; 03.07.2013

Всегда есть <C-T> и <C-D> (то есть CtrlT и CtrlD) в режиме вставки для отступа и отступа на муха.

Они не меняют положение курсора и являются встроенными функциями.

person glts    schedule 02.07.2013
comment
Это не совсем то, что мне нужно, я ищу волшебный отступ Emacs, а не добавление/вычитание отступа. - person Johnny Test; 03.07.2013

Попробуйте использовать отметку последнего режима вставки и используйте команду добавления, чтобы вернуть курсор туда, где он был раньше, например:

:imap <Tab> <Esc>==`^a
person Birei    schedule 02.07.2013
comment
Беглое тестирование показывает, что это не работает, поскольку метка основана на столбце, в котором она установлена, а не на фактическом тексте в строке. Таким образом, он не возвращается в нужное место. - person ravron; 03.07.2013
comment
@Райли: ты прав. Этот ответ неверен. Ответ glts мне подходит. - person Birei; 03.07.2013