Уменьшить вдвое количество пробелов в начале каждой строки в Vim - PullRequest
4 голосов
/ 02 февраля 2012

Может кто-нибудь сказать мне, как сделать противоположность этому отображению в Vim:

nnoremap <leader>iw :let _s=@/<Bar>:let _s2=line(".")<Bar>:%s/^\s*/&&/ge<Bar>:let @/=_s<Bar>:nohl<Bar>exe ':'._s2<CR>

Как пояснение, это отображение удваивает (&& часть) количество пробелов в начале каждой строки.Это касается только пробелов перед первым обычным символом.Текущая строка поиска сохраняется (переменная _s).Положение восстанавливается после этого преобразования (переменная _s2)

Так что в основном я ищу отображение, которое отменит это, если они выполняются один за другим.

У меня естьпроблема в выяснении, как ограничить эту новую операцию, чтобы она работала только с пробелами перед первым обычным символом.

Ответы [ 2 ]

5 голосов
/ 03 февраля 2012

Следующая команда замены заменяет эффект своего аналога удвоение ведущих пробелов.

:%s/^\(\s*\)\1/\1/

Отображение, которое должно быть построено для этой команды, должно следовать тем же шаблон, который использовался в постановке вопроса (за исключением замену выполнить, конечно). Чтобы уменьшить повторение в определения, можно разделить сохраняющий состояние код на небольшой Функция:

nnoremap <silent> <leader>>    :call PinnedCursorDo('%s/^\s*/&&/')<cr>
nnoremap <silent> <leader><lt> :call PinnedCursorDo('%s/^\(\s*\)\1/\1/')<cr>
function! PinnedCursorDo(cmd)
    let [s, c] = [@/, getpos('.')]
    exe a:cmd
    let @/ = s
    call setpos('.', c)
endfunction
2 голосов
/ 03 февраля 2012

Ваша первоначальная замена такова (я заменил разделители / на # для удобства чтения):

%s#^\s*#&&#

А вот моя предложенная обратная замена (сделайте глубокий вдох ...):

%s#^\s*#\=matchstr(submatch(0),'^.\{'.string(float2nr(len(submatch(0))/2)).'\}')#

Допустим, совпадающая строка (submatch(0)) содержит n пробельных символов.Что я делаю, так это вычисляю половину этого числа (n/2 = string(float2nr(len(submatch(0))/2))), а затем извлекаю столько символов из соответствия (по сути matchstr(n/2)).Это гарантирует, что мы получим ровно половину пробела, с которого мы начали (который может быть смесью пробелов и табуляций).

Если вы знаете, что пробел будет содержать ТОЛЬКО пробелы или ТОЛЬКО вкладки, это можно несколько упростить, например:

%s#^\s*#\=repeat(" ",indent(".")/2)#

С другой стороны, я бы порекомендовал переформулировать ваши карты, чтобы сделать ихболее читабельный и, следовательно, его легче модифицировать и поддерживатьМой подход заключается в определении двух функций:

function! DoubleWS()
    let pos = getpos('.')
    let reg = getreg('@')
    exe '%s/^\s*/&&/e'
    call setreg('@',reg)
    call setpos('.',pos)
endfunction

function! HalfWS()
    let pos = getpos('.')
    let reg = getreg('@')
    exe '%s#^\s*#\=matchstr(submatch(0),"^.\\{".string(float2nr(len(submatch(0))/2))."\}")#e'
    call setreg('@',reg)
    call setpos('.',pos)
endfunction

Обратите внимание, что функции get/set pos/reg являются гораздо более надежным способом поддержания позиции и регистра курсора.Затем вы можете отобразить эти функции по своему желанию:

nnoremap <silent> <leader>iw :call DoubleWS()<CR>
nnoremap <silent> <leader>rw :call HalfWS()<CR>

Надеюсь, это поможет!

...