Могу ли я перенести файл в Vim? - PullRequest
13 голосов
/ 01 апреля 2009

Я знаю, что могу использовать AWK, но я на Windows box. Я делаю функцию для других, которые могут не иметь AWK. Я также знаю, что могу написать программу на C, но мне не хотелось бы создавать и поддерживать что-то для небольшой утилиты Vim, которую я делаю.

Исходный файл может быть

THE DAY WAS LONG 
THE WAY WAS FAST

и он станет

TT
HH
EE

DW
AA
YY

WW
AA
SS

LF
OA
NS
GT

ОБНОВЛЕНИЕ: правила выбора гольфа применяются для выбора правильного ответа.

ОБНОВЛЕНИЕ: Поклонники Python должны проверить ответ мистера Даффи ниже.

Ответы [ 6 ]

12 голосов
/ 01 апреля 2009

Вот команда на языке Vim. Так что вам не нужно компилировать Vim с поддержкой + python.

function! s:transpose()
    let maxcol = 0
    let lines = getline(1, line('$'))

    for line in lines
        let len = len(line)
        if len > maxcol 
            let maxcol = len
        endif
    endfor

    let newlines = []
    for col in range(0, maxcol - 1)
        let newline = ''
        for line in lines
            let line_with_extra_spaces = printf('%-'.maxcol.'s', line)
            let newline .= line_with_extra_spaces[col]
        endfor
        call add(newlines, newline)
    endfor

    1,$"_d
    call setline(1, newlines)
endfunction

command! TransposeBuffer call s:transpose()

Поместите это во вновь созданный файл .vim внутри директории vim / plugin или поместите в [._] vimrc.
Выполните :TransposeBuffer, чтобы транспонировать текущий буфер

10 голосов
/ 01 апреля 2009

Поддержка Vim для ряда встроенных языков сценариев - см. интерфейс Python .

Просто измените vim.current.buffer, и все готово.

Чтобы быть немного более конкретным:

function! Rotate()
python <<EOF
import vim, itertools
max_len = max((len(n) for n in vim.current.buffer))

vim.current.buffer[:] = [
    ''.join(n) for n in itertools.izip(
        *( n + ' ' * (max_len - len(n))
           for n in vim.current.buffer))]
EOF
endfunction
5 голосов
/ 01 апреля 2009

Если сценарии не делают этого за вас, вы можете записать действия в регистр (возврат каретки добавлен для удобства чтения):

qa
1G0
xGo<Esc>p
1G0j
xGp
q

Это даст вам макрос, который вы можете запустить в приведенном выше примере, или любые двухстрочные строки одинаковой длины. Вам нужно знать только длину строки, чтобы вы могли выполнить итерацию нужное количество раз

16@a

Довольно простое решение, но оно работает.

1 голос
/ 06 сентября 2011

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

fu!T()
let[m,n,@s]=[0,line('$'),"lDG:pu\r``j@s"]
g/^/let m=max([m,col('$')])
exe'%norm!'.m."A \e".m.'|D'
sil1norm!@s
exe'%norm!'.n.'gJ'
endf

Ниже приведена однострочная версия,

let[m,n,@s]=[0,line('$'),"lDG:pu\r``j@s"]|exe'g/^/let m=max([m,col("$")])'|exe'%norm!'.m."A \e".m.'|D'|exe'sil1norm!@s'|exe'%norm!'.n.'gJ'
0 голосов
/ 06 мая 2012

Я разработал плагин vim для этого. Вы можете найти это здесь . Запустите :Transpose, чтобы транспонировать весь файл.

0 голосов
/ 06 сентября 2011

Код Чарльза Даффи можно сократить / улучшить, используя izip_longest вместо izip:

function! Rotate()
    :py import vim, itertools
    :py vim.current.buffer[:] = [''.join(c) for c in itertools.izip_longest(*vim.current.buffer, fillvalue=" ")]
endfunction
...