Можно ли перенести файл в Vim?

Я знаю, что могу использовать AWK, но я нахожусь в окне Windows. Я делаю функцию для других, у которых, возможно, нет 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 должны проверить ответ г-на Даффи ниже.

Ответ 1

Вот команда на языке 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 для переноса текущего буфера

Ответ 2

Поддержка 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

Ответ 3

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

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

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

[email protected]

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

Ответ 4

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

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

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

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

Ответ 5

код Чарльза Даффи может быть сокращен/улучшен с использованием 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

Ответ 6

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