2010-04-04 25 views
41

Tôi muốn đường dẫn văn bản đã chọn thành lệnh trình bao và nhận đầu ra một dòng từ lệnh shell này trên dòng lệnh/thông tin vim?Vim: Văn bản được chọn ống thành cmd vỏ và nhận đầu ra trên thông tin vim/dòng lệnh

Những gì tôi thực sự cố gắng làm: Đặt văn bản đã chọn thành lệnh shell loại pastebin và tôi muốn nhận đầu ra của shell cmd (là liên kết http đến pastebin). Điều này có thể không?

+0

Các câu hỏi liên quan để cung cấp văn bản đã chọn là 'STDIN' cho lệnh shell: [Thay thế văn bản gốc đã chọn bằng đầu ra] (http://stackoverflow.com/questions/6932382/replace-vim-selection-with -output-of-shell-command) và [Piping đến và từ trình bao, làm việc với toàn bộ bộ đệm] (http://stackoverflow.com/questions/7867356/piping-buffer-to-external-command-in-vim) – user1129682

Trả lời

15

tôi sẽ làm điều đó như thế này:

Nơi chức năng này trong vimrc của bạn:

function Test() range 
    echo system('echo '.shellescape(join(getline(a:firstline, a:lastline), "\n")).'| pbcopy') 
endfunction 

này sẽ cho phép bạn gọi chức năng này bằng cách thực hiện:

:'<,'>call Test() 

Sau đó, bạn có thể cũng lập bản đồ như thế này (ngay dưới khai báo hàm trong vimrc của bạn):

com -range=% -nargs=0 Test :<line1>,<line2>call Test() 

Vì vậy, bạn có thể gọi hàm làm điều này:

:'<,'>Test 

Lưu ý::<','> là selectors phạm vi, để sản xuất ra chúng chỉ cần chọn các dòng cần thiết trong chế độ hình ảnh và sau đó đi đến lệnh mode (nhấn phím đại tràng)

+0

Câu trả lời hay và nó hoạt động. Điều duy nhất là nó không giải thích các dòng mới trong vim trên pastebin. Vì vậy, nếu tôi có nhiều dòng được chọn trong vim, nó sẽ hiển thị dưới dạng một dòng lớn trên thùng dán. Có cách nào để khắc phục điều đó không? – ikwyl6

+2

Và đối với tôi, nó tạo ra: http://pastebin.com/8XuqTr1K («\» ở cuối mỗi dòng). Tôi đang sử dụng pastebin-0.6.1 từ kho lưu trữ Gentoo và zsh. – ZyX

+0

Tôi đang sử dụng sprunge.us và tập lệnh tôi tự tạo: while read data; do paste="$paste $data" done curl -sF "sprunge=$paste" http://sprunge.us | xclip && echo 'xclip -o'?sh ikwyl6

4

Có lẽ bạn nên sử dụng một cái gì đó giống như

:echo system('echo '.shellescape(@").' | YourCommand') 

Bắt đầu từ một số phiên bản vim-7.4 nó là tốt hơn để sử dụng

:echo system('YourCommand', getreg('"', 1, 1)) 

. Về cơ bản, đây là cách duy nhất để giữ cho các byte NUL bị ảnh hưởng nếu chúng có mặt trong tệp. Việc chuyển @" theo một cách khác sẽ chuyển đổi NUL byte thành NL (dòng mới).

+0

Điều này có vẻ tốt. Một điều nhỏ nhặt là sau khi chọn văn bản, bạn phải 'yank' bằng 'y', trước khi chạy lệnh đó. Chỉ cần chọn văn bản trong chế độ trực quan và chạy lệnh đó cho 'E481: Không có phạm vi nào được phép' – davr

+0

Ý tưởng cơ bản này có thể được đơn giản hóa thành ': call system ('YourCommand', @") '. Tất cả cùng nhau, nó trông giống như: 'bản đồ y "9y: hệ thống gọi ('YourCommand', @") ' điểm chính là 'hệ thống() 'nhận một đối số thứ 2, được ghi vào chương trình trên stdin, do đó, nó tránh tất cả các vấn đề thoát. –

+1

@TimSmith Bạn nói đúng, nhưng '@" 'không phải là ý tưởng tốt nhất. Xem câu trả lời được cập nhật. – ZyX

23

Đơn giản chỉ cần làm nổi bật các dòng bằng cách sử dụng dòng trực quan chọn shift-v, nhấn:! và gõ lệnh bạn muốn gửi lệnh đến. Kết quả đầu ra sau đó sẽ thay thế văn bản đã chọn của bạn.

Khi bạn gõ lệnh của bạn sẽ xuất hiện ở phía dưới như:

:'<,'>!somecmd 

của <, '> được chỉ ra rằng phạm vi bạn đã chọn trực quan sẽ được chuyển đến lệnh quy định sau!

+0

Bạn cũng có thể cung cấp các đối số cho lệnh cũng như –

+5

Điều này chỉ thay thế văn bản đã chọn với kết quả đầu ra từ lệnh ghép cmd – ikwyl6

+0

Xin lỗi, đã đọc sai câu hỏi. Tôi nghĩ đó là những gì bạn muốn làm. –

1

Một câu trả lời:

function Pastebin() range 
    let [email protected]" 
    silent execute a:firstline.",".a:lastline."yank" 
    python import vim, subprocess 
    python p=subprocess.Popen(["pastebin"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
    python p.stdin.write(vim.eval('@"')) 
    let @"=savedreg 
    python p.stdin.close() 
    python retstatus=p.poll() 
    python print p.stdout.read() 
endfunction 

Yêu cầu hỗ trợ python. Sử dụng nó giống như chức năng của matias.

77

Đối với phiên bản đa dòng bạn có thể làm được điều này sau khi chọn văn bản:

:'<,'>:w !command<CR> 

Bạn có thể bản đồ nó sang chế độ tắt hình ảnh đơn giản như thế này:

xnoremap <leader>c <esc>:'<,'>:w !command<CR> 

chủ chốt lãnh đạo Hit + c trong hình ảnh để gửi văn bản đã chọn tới stdin của lệnh. stdout của lệnh sẽ được in dưới thanh trạng thái của vim.

dụ thế giới thực với CoffeeScript:

https://github.com/epeli/vimconfig/commit/4047839c4e1c294ec7e15682f68563a0dbf0ee6d

+2

Đây là câu trả lời được ưu tiên. Cảm ơn! –

+15

FYI: bỏ ': w' sẽ thay thế vùng chọn bằng đầu ra của lệnh. –

+3

Tôi không hiểu cú pháp và phương thức hành động của ': w' này. Có phải lệnh "viết" bình thường không? ':' Thứ hai là gì? Bạn có thể giải thích nó được không? Cảm ơn! – schoettl

1

@matias 's giải pháp không làm việc tốt đối với tôi, vì nó có vẻ shellescape sẽ nối \ với từng ngành nghề.

Vì vậy, tôi sử dụng sed để thực hiện việc này và nó hoạt động tốt!

"dump selected lines 
function! DumpLines() range 
    echo system('sed -n '.a:firstline.','.a:lastline.'p '.expand('%')) 
endfunction 

com! -range=% -nargs=0 Dump :<line1>,<line2>call DumpLines() 
Các vấn đề liên quan