Làm thế nào để chèn kết quả của một lệnh vào văn bản trong vim?


42

Chẳng hạn, :echo strftime(%c)sẽ hiển thị thời gian hiện tại ở phía dưới, nhưng làm thế nào để chèn chuỗi thời gian này vào văn bản (ngay sau con trỏ)?


1
Tôi tin rằng OP có nghĩa là "Làm thế nào để chèn kết quả của biểu thức Vim vào văn bản?"
Alastair Irvine

Điều đáng nói là đây không phải là câu hỏi tương tự như Viết hàm vim để chèn một khối văn bản tĩnh , tuy nhiên một số câu trả lời vẫn được áp dụng.
Alastair Irvine

Ví dụ của bạn là trường hợp sử dụng của tôi và tôi chào bạn cho nó.
Joe

Xem thêm chuyển hướng vào một đăng ký: stackoverflow.com/questions/2573021/
Khăn

Câu trả lời:


49

Bạn có thể sử dụng thanh ghi biểu thức "=, với p(hoặc P) ở chế độ bình thường hoặc <C-R>ở chế độ chèn:

Ở chế độ bình thường:
( <C-M>ở đây có nghĩa là Control+ M, hoặc chỉ nhấn Enter/ Return)

"=strftime('%c')<C-M>p

Trong chế độ chèn:
( <C-M>có cùng ý nghĩa như trên, <C-R>có nghĩa là Control+ R)

<C-R>=strftime('%c')<C-M>

Nếu bạn muốn chèn kết quả của cùng một biểu thức nhiều lần, thì bạn có thể muốn ánh xạ chúng vào các phím trong .vimrc:
(ở đây <C-M><C-R>nên được nhập theo nghĩa đen (một chuỗi gồm năm ký tự có thể in được Vim sẽ dịch chúng bên trong))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>

2
Khóa học +1! Các "=đăng ký. : - /
Mười

2
để lấy giá trị của biến vim (ví dụ: sessionoptions): <C-R>=&sessionoptions- nó thậm chí còn hoàn thành tab wildmode!
Justin M. Keyes

2
: put = strftime ('% c') <CM>
brunch875

Trong chế độ chèn, sử dụng <c-r>=lệnh chậm cho lệnh có thể có nhiều đầu ra và cũng có thể ngắt thụt lề để văn bản đầu ra không thể đọc được. Ví dụ, <c-r>=execute('nmap')đầu ra sẽ được viết từng dòng, rất chậm.
jdhao

22

:r!date +\%c

xem :help :r!


1
datelà một lệnh bên ngoài và !gọi các lệnh bên ngoài trong khi OP yêu cầu các lệnh vim.
Eelvex

@eelvex không anh không. và ! là một vim, và vi, lệnh. Đây là phương pháp kinh điển. Làm việc cho nhiều thứ khác là tốt.
Keith

5
@Keith: yes !là lệnh vi (m) gọi các lệnh bên ngoài . Bạn có thể đúng OP không muốn chỉ xuất các lệnh vim nhưng nếu (các) anh ta làm, !sẽ không làm.
Eelvex

11

Các lệnh này sẽ chèn đầu ra strftime("%c")bên phải nơi con trỏ của bạn:

:exe ":normal i" . strftime("%c")

:call feedkeys("i". strftime("%c"))

Có nhiều cách khác để làm những gì bạn muốn (ví dụ như những câu trả lời của Mikel ).

Chỉnh sửa : Thậm chí tốt hơn, để chèn tại chỗ, hãy sử dụng thanh =ghi như Chris Johnsen mô tả


10

Nếu bạn muốn chèn đầu ra của lệnh vim (trái ngược với giá trị trả về của một lệnh gọi hàm ), bạn phải nắm bắt nó. Điều này được thực hiện thông qua :redirlệnh, cho phép bạn chuyển hướng tương đương với đầu ra tiêu chuẩn của vim thành một biến, tệp, đăng ký hoặc mục tiêu khác.

:redirlà loại bất tiện đau đớn để sử dụng; Tôi sẽ viết một hàm để đóng gói chức năng của nó theo cách thuận tiện hơn, đại loại như

funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    return output
endfunct!

Khi bạn đã khai báo một hàm như vậy, bạn có thể sử dụng thanh ghi biểu thức (như được giải thích bởi Chris Johnsen) để chèn đầu ra của lệnh tại vị trí con trỏ. Vì vậy, từ chế độ bình thường, nhấn i^R=Exec('ls')để chèn danh sách bộ đệm hiện tại của vim.

Xin lưu ý rằng lệnh sẽ thực thi trong không gian tên hàm, vì vậy nếu bạn sử dụng biến toàn cục, bạn sẽ phải xác định không gian tên một cách rõ ràng bằng cách thêm tiền tố vào g:. Cũng lưu ý rằng Exec(), như được viết ở trên, sẽ nối một dòng mới kết thúc vào đầu ra một dòng. Bạn có thể muốn thêm một cuộc gọi substitute()vào chức năng để tránh điều này.

Đồng thời xem https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-civerse-buffer-or-file/2573054#2573054 để biết thêm thông tin về redirvà liên kết đến một lệnh liên quan.


2
Điều này làm việc tuyệt vời. Tôi đã thêm một set pastelệnh trước khi trả lại đầu ra và set nopastesau đó, để tránh thụt lề cầu thang khi các dòng bắt đầu bằng khoảng trống. Trên thực tế, tôi muốn lưu giá trị của tùy chọn dán hiện tại và trả lại nhưng tôi không thể làm như vậy.
Juan Lanus

1
@JuanLanus Không set nopastenên làm việc sau return output, bởi vì câu lệnh return là một điểm thoát khỏi hàm. Tôi đã đặt giải pháp của mình cho vấn đề này như một câu trả lời riêng trên trang này.
Evgeni Sergeev

4
:call append(line('.'), strftime("%c"))

Sẽ đặt nó trên dòng tiếp theo, sau đó bạn có thể nhấn J( Shift+ J) để nối nó với vị trí hiện tại.

Hoặc nếu bạn cần tất cả trong một lệnh, bạn có thể làm

:call setline(line('.'), getline(line('.')) . strftime("%c"))

hoặc là

:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))

tùy thuộc vào việc bạn có muốn một không gian được chèn trước ngày hay không.


4

Cải thiện câu trả lời @intuited để tránh sự cố với khoảng trắng hàng đầu và thụt lề ngày càng tăng:

"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    let @o = output
    execute "put o"
    return ''
endfunct!

Điều này chỉ đơn giản sẽ chèn tại vị trí hiện tại trong tệp khi bạn :call Exec('command')từ chế độ bình thường. Như đã lưu ý trong nhận xét , =Exec('command')cách tiếp cận Ctrl + R ban đầu (chế độ chèn) với Exec(..)trả về một chuỗi có thể được sửa một phần bằng cách sử dụng set paste, nhưng không cung cấp cơ hội để đặt set nopastebất cứ nơi nào.

Các let @o = outputcú pháp đặt đăng ký ocác nội dung của biến output, như đã giải thích ở đây: https://stackoverflow.com/a/22738310/1143274

Các return ''dòng là để các giá trị trả về mặc định của 0tôi không nhận được chèn vào bộ đệm.


2

Đây là cách tôi làm điều đó. Nó đặt nó ngay sau con trỏ bởi vì nó sử dụng p.

" save previous yank
let reg_save = @@

" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"

" restore previous yank
let @@ = reg_save
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.