Làm cách nào để thiết lập Vim để làm việc với một câu trên mỗi dòng?


17

Tôi hiện đang viết rất nhiều văn bản đơn giản (và LaTeX với định dạng tối thiểu trong đoạn văn) và thật tuyệt nếu tôi có thể thiết lập vim để giữ mỗi câu (để đơn giản, văn bản bị chấm dứt bởi một '.', '!' hoặc '?'; đó là dấu chấm câu kết thúc bằng dấu cách để tránh phá vỡ các số thập phân) trên dòng riêng của nó để các khác biệt của VCS sẽ hữu ích hơn.

Tối thiểu, tôi muốn gqđịnh dạng văn bản từ:

He lay flat on the brown, pine-needled floor of the forest, his chin on his
folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he
could see the dark of the oiled road winding through the pass. There was a
stream alongside the road and far down the pass he saw a mill beside the
stream and the falling water of the dam, white in the summer sunlight. 

Đến:

He lay flat on the brown, pine-needled floor of the forest, his chin on his folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he could see the dark of the oiled road winding through the pass.
There was a stream alongside the road and far down the pass he saw a mill beside the stream and the falling water of the dam, white in the summer sunlight.

Nhưng thật tuyệt nếu vim cũng thực hiện định dạng này khi tôi gõ (giống như với phản xạ băng thông văn bản). Điều này có thể không?

Giải pháp hiện tại của tôi là tham gia một đoạn với J, sau đó chạy :'<,'>s/\. /.\r/gkhá tốt vì có vài dấu chấm than và dấu hỏi, nhưng sẽ tốt hơn nhiều nếu tôi có thể làm cho gq thông minh hơn một chút.

Câu trả lời:


23

các 'formatexpr'tùy chọn

Bạn có thể đạt được điều này bằng cách sử dụng 'formatexpr'tùy chọn. Từ sự giúp đỡ:

Biểu thức được ước tính để định dạng một phạm vi dòng cho toán tử gq hoặc định dạng tự động (xem 'định dạng'). Khi tùy chọn này trống, 'formatprg' được sử dụng.

Cài đặt 'formatexpr'chính xác của bạn sẽ hoạt động cả khi sử dụng gqvà trong khi chèn văn bản.

Một ví dụ đơn giản

Đây là một hàm VimScript đơn giản và 'formatexpr'giá trị tương ứng sẽ thực hiện công việc. Tôi đã không kiểm tra nó xung quanh tất cả các trường hợp cạnh, nhưng nó hoạt động tốt cho các thử nghiệm đơn giản của tôi.

function! MyFormatExpr(start, end)
    silent execute a:start.','.a:end.'s/[.!?]\zs /\r/g'
endfunction

set formatexpr=MyFormatExpr(v:lnum,v:lnum+v:count-1)

Giải trình

Biểu thức là một lời gọi đến hàm MyFormatExpr(), chuyển qua các dòng bắt đầu và kết thúc mà định dạng sẽ được áp dụng. Các dòng này được tính toán bằng cách sử dụng các biến được điền tự động v:lnum(dòng đầu tiên được định dạng) và v:count(số lượng dòng được định dạng).

Các MyFormatExpr()chức năng xây dựng một :substitutelệnh với các thông qua trong phạm vi, và thay thế một khoảng trắng sau dấu chấm câu end-of-câu ( ., !hoặc ?) với một dòng mới ( \r).

Hãy cẩn thận

  • Các MyFormatExpr()chức năng không bảo tồn thụt đầu dòng. Một số logic tinh vi hơn sẽ cần thiết để khắc phục điều đó.
  • Có thể có các trường hợp cạnh khác mà điều này sụp đổ. Cung cấp cho nó một ổ đĩa thử nghiệm và tinh chỉnh khi cần thiết!

Ồ, vâng, đây hoàn toàn là con đường để đi, bỏ qua câu trả lời của tôi.
Sukima

Điều này thật tuyệt! Điều tôi ước tôi có thể làm là để hàm chạy macro, như "chuyển sang câu tiếp theo )và chèn một dòng mới; lặp lại cho đến khi bạn đi đến cuối phạm vi." Sau đó, nó có lẽ sẽ áp dụng bất kỳ quy tắc thụt đầu dòng. Nhưng Vim-fu của tôi quá yếu cho việc đó. :)
Nathan Long

Điều này phân chia trên ví dụ e.g. blah, và Blah et al. 2018đó là một chút khó chịu. Bạn có thể ghép các mẫu như thế với một cái gì đó như thế 's/\(e\.g\|\<al\)\@<![.!?]\zs /\r/g'. Chỉ cần thêm nhiều mẫu vào nhóm đầu tiên để tránh những thứ khác mà bạn không muốn tách ra. Nếu không, điều này là siêu hữu ích, cảm ơn. Tôi đã không bắt gặp gqtrước đây và cực kỳ gqiphữu ích cho việc định dạng văn bản mà các biên tập viên văn bản của đồng tác giả đã đọc sai.
ness101

Có cách nào để thêm hành vi này vào hành vi mặc định không? Tôi muốn có thể gói ở một độ rộng văn bản nhất định, cũng như phân tách ở cuối câu ..
naught101

1

Vâng, bạn có thể thiết lập một số bản đồ và autocommands:

function! AddSentenceMaps()
  imap .<Space> .<CR>
  imap !<Space> !<CR>
  imap ?<Space> ?<CR>
  exec "nmap gq vipJ:s/\\([.!?]\\)\\s\\+/\\1\\r/g<CR>"
endfunction

autocmd Filetype customtxt call AddSentenceMaps()

Sau đó, chỉ cần đặt loại tệp thành customtxt hoặc gọi AddSentenceMapshàm theo cách thủ công.


0

Tôi muốn thêm suy nghĩ của tôi về vấn đề này. Thông thường mọi người muốn loại tính năng này vì nhảy qua các dòng được bọc khi những người điều hướng qua mã với jkcác lệnh là hành vi mặc định của Vim. Đối với điều hướng thông qua các dòng bọc tôi sử dụng gj- di chuyển xuống và gk- di chuyển lên. Ngoài ra còn có khả năng sắp xếp lại tiêu chuẩn jklệnh trên các bản sao có tiền tố g, nhưng IMHO sẽ là quá mức cần thiết.


hoặc có một chìa khóa để thực hiện việc sửa chữa đó jkđến gjgkkhi bạn muốn nó ;-)
anthony

0

Nó không trả lời câu hỏi cụ thể của bạn về định dạng lại, nhưng 'set quấn' cùng với 'set linebreak' có thể giúp chỉnh sửa các dòng dài dễ chịu hơn nhiều. Kết hợp điều này với gj và gk để điều hướng trong các dòng được bọc. Tôi ánh xạ các mũi tên lên và xuống tương ứng với gj và gk để tôi có lựa chọn giữa việc di chuyển lên và xuống các đường thẳng thực hoặc đường thị giác. Giống như khôn ngoan cho Trang chủ / Kết thúc với g0 / g $.

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.