2013-04-05 19 views
7

Có cách nào dễ dàng bằng cách sử dụng hàm macro hoặc ~ 10 (không có plugin!) Để căn giữa một số văn bản giữa từ đầu tiên và cuối cùng (= chuỗi ký tự không trống) trên một dòng? Ví dụ. để biếnMột cách dễ dàng để căn giữa văn bản giữa từ đầu tiên và cuối cùng không phải màu trắng trong vim?

 >>> No user serviceable parts below.    <<< 

vào

 >>>  No user serviceable parts below.   <<< 

bằng cách cân bằng không gian +/- 1? Bạn có thể giả sử không có tab và kết quả không được chứa tab, nhưng lưu ý rằng từ đầu tiên có thể không bắt đầu trong cột 1. (EDIT: ... trên thực tế, cả hai dấu phân cách cũng như phần đầu và cuối của văn bản vào giữa có thể nằm trên các cột tùy ý.)

+0

Có chiều rộng cố định? – jcbwlkr

+0

Bạn đã thử gì? – romainl

+0

@ jacobwalker0814 Không có chiều rộng cố định. romainl: Tôi đã thử ': trung tâm trợ giúp' và tìm các plugin nhưng đối với một tác vụ đơn giản như vậy, plugin sẽ xuất hiện quá mức cần thiết. – Jens

Trả lời

7

nguồn chức năng này:

fun! CenterInSpaces() 
    let l = getline('.') 
    let lre = '\v^\s*\S+\zs\s*\ze' 
    let rre = '\v\zs\s*\ze\S+\s*$' 
    let sp = matchstr(l,lre) 
    let sp = sp.matchstr(l,rre) 
    let ln = len(sp) 
    let l = substitute(l,lre,sp[:ln/2-1],'') 
    let l = substitute(l,rre,sp[ln/2:],'') 
    call setline('.',l) 
endf 

lưu ý

  • chức năng điều này có thể KHÔNG làm việc trong mọi trường hợp. Tôi chỉ viết nó nhanh cho trường hợp thông thường. đây không phải là plugin sau khi tất cả các dòng mã

  • có thể được giảm bằng cách kết hợp các cuộc gọi chức năng. nhưng tôi nghĩ rằng nó là rõ ràng theo cách này, vì vậy tôi chỉ để nó như thế này.

  • nếu nó làm việc cho bạn, bạn có thể tạo ra một bản đồ

  • nó hoạt động như thế này: (hai dòng cuối cùng tôi đã gõ @: lặp lại cuộc gọi cmd)

enter image description here

+0

Tuyệt vời. Làm thế nào bạn tạo ra gif? – jcbwlkr

+0

Tuyệt vời, và chỉ có * chín * dòng :-) – Jens

+0

Hai lệnh gọi 'getline ('.')' Trong các phép gán cho 'sp' có được thay thế bằng' l' không? – Jens

1

Tôi không biết cách nào tốt. Tôi thường làm điều đó một cách bán tự động, bằng cách sử dụng :center trên một dòng văn bản chỉ chứa các phần được căn giữa và sau đó di chuyển kết quả vào dòng chứa các phần xung quanh.

Nếu không ai khác có câu trả lời hay hơn, có lẽ boxes có thể giúp bạn nếu bạn cần thực hiện nhiều việc như vậy.

3

Bạn có thể sử dụng lệnh :s với biểu thức phụ thay thế là \=.

:s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.escape(submatch(2),'~&\').'\2','')# 

Tổng quan

Chụp văn bản (bao gồm màu trắng-không gian) giữa >>><<< dấu. Chia không gian trắng trên cả hai mặt của văn bản thành một nửa và thay thế trong văn bản không phải khoảng trắng ở giữa. Hành động cân bằng trắng không gian này được thực hiện thông qua backtracking của động cơ regex bởi vì toán học là khó. Chúng ta hãy đi mua sắm!

Ghi chú:

  • sử dụng \v hoặc very magic chế độ để giảm thoát như lệnh này là đủ lâu đã
  • sử dụng # như một tách thay thế thay vì thông thường / cho :s/pat/sub/ với hy vọng để làm cho nó một chút dễ đọc hơn

Mẫu phù hợp

:s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#... 
  • :s không có phạm vi cung cấp chỉ làm sự thay thế trên dòng hiện tại.
  • ^\s*\S+ khớp với khoảng trắng bắt đầu theo sau là khoảng trống trắng. >>> trong trường hợp này.
  • (\s+)(.{-})(\s+) khớp với khoảng trắng, theo sau là "văn bản" theo sau là khoảng trắng
  • 3 nhóm chụp: 1) khoảng trắng đầu, 2) "văn bản" và 3) dấu cách trắng. Những sau đó sẽ được tham chiếu bởi submatch(1), submatch(2), và submatch(3) tương ứng
  • .{-} được vim-nói cho phù hợp không tham lam hay .*? trong perl-nói
  • mà không có sự phi tham lam phù hợp với nhóm chụp thứ hai sẽ bao gồm quá nhiều màu trắng -space lúc kết thúc của nó
  • \S+\s*$ trận đấu không phải da trắng không gian (ví dụ: <<<) và bất kỳ đuôi trắng-không gian
  • Sử dụng \zsze để chỉ sự bắt đầu và kết thúc của trận đấu phải được thay thế

Thay

\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.escape(submatch(2),'~&\').'\2','') 
  • \= nói vim mà thay thế sẽ là một biểu thức vim. Cũng cho phép việc sử dụng các chức năng submatch()
  • substitute({str}, {pat}, {sub}, {flags}) biểu hiện của chúng tôi sẽ là một lồng nhau thay
  • substitute(submatch(1).submatch(3), ...) làm một sự thay thế trong vòng nối của đầu và đuôi trắng khoảng cách bị bắt trong submatch(1)submatch(3)
  • Các {pat}^(\s*)(\1\s=)$. Phù hợp với một số khoảng trắng, theo sau là khoảng trắng có cùng chiều dài với ký tự đầu tiên hoặc dài hơn 1 ký tự. Chụp cả hai nửa.
  • escape(submatch(2),'~&\') thoát submatch(2) cho bất kỳ ký tự đặc biệt nào. ví dụ. ~, &, \1, ...
  • {sub}'\1'.escape(submatch(2),'~&\').'\2'. Thay thế bằng số thoát submatch(2) (tức làcác "văn bản" chúng tôi muốn đến trung tâm) ở giữa nửa của màu trắng-không gian, \1\2 từ {pat}
  • Không {flag} 's là cần thiết để ''

Cách sử dụng

Nếu bạn sử dụng thường xuyên này tôi sẽ đề nghị tạo một lệnh và đặt nó trong ~/.vimrc.

command! -range -bar -nargs=0 CenterBetween <line1>,<line2>s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.submatch(2).'\2','')#` 

Nếu không, hãy sử dụng điều này một lần và sau đó lặp lại thay thế cuối cùng qua & trên mỗi dòng cần thiết.

Để được trợ giúp nhiều hơn thấy

:h :s/ 
:h :s/\= 
:h sub-replace-\= 
:h submatch(
:h substitute(
:h escape(
:h /\v 
:h /\S 
:h /\{- 
:h /\zs 
:h & 

EDIT bởi Kent

Đừng ghen tuông, câu trả lời của bạn có nó quá.^_^

Tôi không thay đổi lệnh, chỉ cần cp/paste vào vim của tôi. chỉ thêm |noh ở cuối để tắt đánh dấu.

Nếu thực hiện lệnh này, nó trông giống như:

enter image description here

+1

+1 Tôi không nhận thấy câu trả lời này. thay thế tốt đẹp. btw, tôi đã thực hiện một gif cho bạn .. sẽ chỉnh sửa câu trả lời của bạn và thêm nó sớm, loại bỏ nó nếu bạn không thích. :) – Kent

+1

Cảm ơn bạn. Tôi sẽ phải học cách làm gif một ngày nào đó. –

+0

bạn không phải học, chỉ là một công cụ nhỏ. google byzanz, bạn sẽ thấy, nó thực sự dễ sử dụng. – Kent

Các vấn đề liên quan