2009-04-01 24 views
12

AWK kullanabileceğimi biliyorum, ancak bir Windows kutusu üzerindeyim. AWK olmayan başkaları için bir işlev yapıyorum. Ayrıca bir C programı yazabileceğimi de biliyorum ama yapmakta olduğum küçük bir Vim programı için bir şey oluşturmak ve düzenlemek zorunda kalmamayı çok isterim.Bir dosyayı Vim'e dönüştürebilir miyim?

orijinal dosya

THE DAY WAS LONG 
THE WAY WAS FAST 

olabilir ve

TT 
HH 
EE 

DW 
AA 
YY 

WW 
AA 
SS 

LF 
OA 
NS 
GT 

GÜNCELLEME olacaktı: Golf kuralları doğru cevabı seçerek için geçerlidir.

GÜNCELLEME: Python hayranları, Bay Duffy'nin cevabını aşağıda kontrol etmelidir.

+0

Pardon - "golf"? –

+2

En düşük karakter sayısı ... en düşük puan bir şey kazanır. – ojblass

+0

Çözünürlük yalnızca seçilen metni aktarırsa daha iyi olurdu ...Ama, tamam, mevcut çözüm benim için yeterince iyi. :) –

cevap

12

Vim dilde bir komuttur. Yani, Vim'i + python desteğiyle derlemeniz gerekmez.

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/eklenti dir içine yeni oluşturulan .vim dosyasında bu koyun ya senin [._] vimrc bu koydu.
komut sizin için bunu yapmayın, bir kayıt eylemler kayıt olabilir

+0

Pure vim sizi nod yapar. Çok teşekkür ederim! – ojblass

+0

Gereksiz yere kötü bir çözüm, bence. Bu arada, teknik olarak sizin çözümünüz işe yaramıyor, çünkü '1, $' _ d 'yapmak istediğinizi yapmazsınız. Bu satırı' sil% d_ 'olarak yazarım. –

+0

@ib neden söylüyorsunuz Benim için çalışıyor ve tüm dosyayı anonim bir sicil içine siliyor, değil mi? –

10

Vim desteği, yerleşik bir dizi komut dili için destek - bkz. the Python interface.

vim.current.buffer'u uygun şekilde değiştirin ve ayarlandıysanız.

biraz daha spesifik olmak gerekirse:

İşte
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 
+1

++ oooh - vim'in vimscript'den daha fazla desteklenmediğinin farkında değildi! Ayrıca perl, tcl ve ruby ​​- harika! – guns

+1

Bu komut dosyalarını destekler, ancak varsayılan olarak değil. Yapım sırasında onları açmak zorundasınız. –

+0

Sağ. Hemen hemen her dağıtım bir vim-tam veya vim-geliştirilmiş bir sürümü vardır ve ben Windows gvim –

5

akım tamponu da aktarması :TransposeBuffer Yürütme (satırbaşları okunabilmesi için eklenir):

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

Bu verecektir Yukarıdaki örneğe veya aynı uzunlukta 2 satırlık dizelere karşı çalıştırabileceğiniz bir makro. Eğer çalışma süresi

[email protected] 

Oldukça basit bir çözüm doğru sayıda yineleme böylece yalnızca dize uzunluğunu bilmemiz gerekir, ama işe yarıyor.

+1

Girdi etki alanı, aynı uzunluktaki iki satırdan fazla olabilir. – ojblass

0

Charles Duffy's codeizip_longest yerine izip kullanılarak/geliştirilmiş kısaltılabilir:

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

İzleyen fonksiyon, mevcut tamponun içeriği "devrik" düzenleme işlemleri gerekli gerçekleştirir.

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 

Aşağıda

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' 
+0

@ojblass : Bu betik şu ana kadarki en kısa Vim çözümü değil (cevaplar için bir karar verme kuralı olarak belirttiğiniz "golf" anlamında), şimdiye kadar gönderilenler arasında değil mi? –

0

bunu yapmak için bir vim eklenti geliştirdik, onun tek satırlık versiyonudur. here'u bulabilirsiniz. Tüm dosyayı aktarmak için :Transpose'u çalıştırın.