Posso trasporre un file con Vim?
-
22-08-2019 - |
Domanda
So che posso usare AWK, ma io sono su una macchina Windows.Sto creando una funzione per gli altri che non possono avere AWK.So, inoltre, sono in grado di scrivere un programma in C, ma mi piacerebbe non dover creare mantenere e compilare qualcosa per un po ' di Vim utilità sto facendo.
Il file originale potrebbe essere
THE DAY WAS LONG
THE WAY WAS FAST
e sarebbe diventata
TT
HH
EE
DW
AA
YY
WW
AA
SS
LF
OA
NS
GT
AGGIORNAMENTO:Golf si applicano le regole per la selezione della risposta corretta.
AGGIORNAMENTO:I fan di Python dovrebbe verificare il SignorDuffy risposta qui sotto.
Soluzione
Qui è un comando in Vim lingua.Così non dovrai compilare Vim +supporto 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()
Mettere questo in appena creato .vim file all'interno di vim/plugin dir o mettere questo al vostro [._]vimrc.
Eseguire :TransposeBuffer
di recepire il buffer corrente
Altri suggerimenti
Vim supporto per un numero di linguaggi di scripting costruito nel vedere -- l'interfaccia Python come esempio.
Basta modificare vim.current.buffer
in modo appropriato e sei a posto.
Per essere un po più specifico:
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
Se gli script non fanno per voi, è possibile registrare le azioni di un registro (i ritorni a capo vengono aggiunti per migliorare la leggibilità):
qa
1G0
xGo<Esc>p
1G0j
xGp
q
Questo vi darà una macro che è possibile eseguire il contro esempio precedente, o di qualsiasi linea 2 stringhe della stessa lunghezza.Hai solo bisogno di conoscere la lunghezza della stringa in modo che si può scorrere l'operazione il numero corretto di tempo
16@a
Un semplice soluzione, ma funziona.
La seguente funzione esegue necessarie operazioni di editing per "recepire" il contenuto del buffer corrente.
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
Qui di seguito è la sua versione della linea,
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'
Charles Duffy codice potrebbe essere abbreviato/migliorata utilizzando izip_longest
invece di izip
:
function! Rotate()
:py import vim, itertools
:py vim.current.buffer[:] = [''.join(c) for c in itertools.izip_longest(*vim.current.buffer, fillvalue=" ")]
endfunction
Ho sviluppato un vim plugin per farlo.Lo si può trovare qui.Eseguire :Transpose
di recepire l'intero file.