2012-02-02 3 views
4

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

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

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

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

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

ответ

5

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

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

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

nnoremap <silent> <leader>> :call Preserve('%s/^\s*/&&/')<cr> 
nnoremap <silent> <leader><lt> :call Preserve('%s/^\(\s*\)\1/\1/')<cr> 
function! Preserve(cmd) 
    let [s, c] = [@/, getpos('.')] 
    exe a:cmd 
    let @/ = s 
    call setpos('.', c) 
endfunction 
+0

Красивая! Я пробовал что-то вроде этого, но я не знал, что вы можете использовать '\ 1' в первом блоке-заменителе. Простой и эффективный! –

+0

@PrinceGoulash: Спасибо! Это несколько идиоматический тип узоров. Замечательным примером, о котором вы, вероятно, знаете, является регулярное выражение, которое можно использовать для проверки того, является ли неотрицательное целое число простым числом. В скрипте Vim тест будет выглядеть как 'repeat ('1', n)! ~ '^ 1 \? $ \ |^\ (1 \ {- 2,} \) \ 1 \ + $'', где ' n' - число, о котором идет речь. –

+0

Спасибо, это действительно изящное решение. –

2

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

%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/setpos/reg функции гораздо более надежный способ поддержания позиции курсора и регистрации. Затем вы можете сопоставить эти функции по своему усмотрению:

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

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

+0

Спасибо. Работает отлично.Я также решил использовать функции, как вы предлагали. (Я новичок в этом этапе, когда вы на самом деле пытаетесь персонализировать Vim в соответствии с вашими потребностями и вкусами, поэтому это первые функции (внешние плагины), которые я использую). –

+0

Добро пожаловать! Здесь Vim становится очень мощным. Это довольно полезные функции для изучения, поскольку они вводят переменные и выполняют обычные команды Vim. (Обратите внимание, что я отредактировал свой ответ, чтобы удалить определения '_s2', которые не нужны.) –

+0

@GoranNovosel: Несмотря на то, что эта проблема решается, эта реализация задает пример чрезмерно спроектированного и повторяющегося сценария Vim: команда substitute, уменьшающая наполовину начальные пробелы может быть более идиоматичным и [почти в пять раз короче] (http://stackoverflow.com/a/9124761/254635); функции сохранения состояния могут быть [обобщены, чтобы избежать повторения] (http://stackoverflow.com/a/9124761/254635). –