Một cách dễ dàng để gắn kết văn bản trong cột là sử dụng Tabular hoặc Align plugin. Nếu không có trong số này đã sẵn sàng trong tay, người ta có thể sử dụng sau đây hơi phức tạp (và một chút cồng kềnh tìm kiếm) nhưng hoàn toàn làm việc (cho các trường hợp trong câu hỏi) lệnh. 1,2
:let m=0|g/\ze -- /let m=max([m,searchpos(@/,'c')[1]])
:%s//\=repeat(' ',m-col('.'))
Mục đích của lệnh đầu tiên là để xác định độ rộng của cột để bên trái của dấu phân cách (mà tôi giả định là --
đây). Chiều rộng là được tính là độ dài tối đa của văn bản trong cột đầu tiên trong số tất cả các dòng. Lệnh :global
được sử dụng để liệt kê các dòng chứa dấu tách (các dòng khác không yêu cầu căn chỉnh). Nguyên mẫu \ze
nằm ngay sau đầu mẫu, đặt kết thúc trận đấu ở cùng vị trí bắt đầu (xem :help \ze
). Thay đổi đường biên của trận đấu không ảnh hưởng đến cách hoạt động của lệnh :global
, mẫu được viết theo cách như vậy chỉ để phù hợp với nhu cầu của lệnh thay thế tiếp theo: Vì hai lệnh này có thể chia sẻ cùng một mẫu, được bỏ qua trong phần thứ hai.
Lệnh được chạy trên các dòng phù hợp,
:let m=max([m,searchpos(@/,'c')[1]])
gọi searchpos()
chức năng để tìm kiếm các mô hình sử dụng trong các phụ huynh :global
lệnh, và để có được vị trí cột của trận đấu. Mẫu được gọi là @/
bằng cách sử dụng thanh ghi mẫu tìm kiếm cuối cùng (xem :help "/
). Điều này lợi dụng thực tế là lệnh :global
cập nhật số đăng ký /
ngay khi bắt đầu thực thi. Cờ c
được chuyển thành đối số thứ hai trong cuộc gọi searchpos()
cho phép khớp tại số đầu tiên của một dòng (:global
định vị con trỏ ở đầu dòng để thực thi lệnh), bởi vì nó có thể ở đó không có văn bản ở bên trái của dấu phân cách. Hàm searchpos()
trả về một danh sách, phần tử đầu tiên là là số dòng của vị trí phù hợp, và thứ hai là vị trí cột.Nếu lệnh được chạy trên một dòng, dòng khớp với mẫu của lệnh có chứa :global
. Khi searchpos()
là để tìm kiếm cùng một mẫu, chắc chắn có một kết quả phù hợp trên dòng đó. Do đó, chỉ có cột bắt đầu trận đấu được quan tâm, do đó, nó được trích xuất từ danh sách trả về theo số chỉ số [1]
. Vị trí này rất bằng với chiều rộng của văn bản trong cột đầu tiên của dòng, cộng với một. Vì vậy, m
được đặt thành giá trị hiện tại tối đa và vị trí cột đó.
Lệnh thứ hai,
:%s//\=repeat(' ',m-col('.'))
miếng đệm sự xuất hiện đầu tiên của tách trên tất cả các dòng có chứa nó, với số lượng không gian mà là mất tích để làm cho văn bản trước khi tách lấy m
ký tự, trừ một ký tự. Lệnh này là một toàn cầu thay thay thế một khoảng trống ngay trước khi tách (xem bình luận về :global
lệnh trên) với kết quả đánh giá của biểu thức (xem :help sub-replace-\=
)
repeat(' ',m-col('.'))
Các repeat()
lặp chức năng đối số đầu tiên của nó (dưới dạng chuỗi) số của lần được đưa ra trong đối số thứ hai. Vì mỗi lần thay thế con trỏ là được di chuyển đến đầu của kết hợp mẫu, m-col('.')
bằng với số lượng không gian cần thiết để chuyển dấu phân tách sang phải để căn chỉnh các cột (col('.')
trả về vị trí cột hiện tại của con trỏ).
Dưới đây là phiên bản một dòng của cặp lệnh này.
:let m=0|exe'g/\ze -- /let m=max([m,searchpos(@/,"c")[1]])'|%s//\=repeat(' ',m-col('.'))
Trong các phiên bản trước đó của câu trả lời các lệnh sử dụng để được như sau.
:let p=[0]|%s/^\ze\(.*\) -- /\=map(p,'max([v:val,len(submatch(1))+1])')[1:0]/
:exe'%s/\ze\%<'.p[0].'c -- /\=repeat(" ",'.p[0].'-col("."))'
Những người quan tâm đến các lệnh cụ thể này có thể tìm thấy mô tả chi tiết trong lịch sử chỉnh sửa.
bản sao có thể có của [Cách chèn dấu cách lên cột X để xếp hàng mọi thứ trong cột?] (Http://stackoverflow.com/questions/6154306/how-to-insert-spaces-up-to-column- x-to-line-up-vật-trong-cột) – DocMax