Bạn có thể thử lệnh sau:
:let c=0 | g/^* /let c+=1 | s//\=c.'. '
Đầu tiên, nó khởi tạo biến c
( let c=0
), sau đó nó thực thi lệnh toàn cầu g
tìm mẫu ^*
(bắt đầu dòng, theo sau là dấu hoa thị và dấu cách).
Bất cứ khi nào một dòng chứa mẫu này được tìm thấy, lệnh toàn cục sẽ thực thi lệnh:
let c+=1 | s//\=c.'. '
Nó tăng biến c
( let c+=1
), sau đó ( |
) nó thay thế ( s
) mẫu tìm kiếm trước đó ( //
) bằng cách đánh giá biểu thức ( \=
):
nội dung của biến được c
nối ( .
) với chuỗi'. '
Nếu bạn không muốn sửa đổi tất cả các dòng từ bộ đệm của mình, nhưng chỉ một đoạn cụ thể, bạn có thể chuyển một phạm vi cho lệnh toàn cục. Ví dụ: để chỉ sửa đổi các dòng có số nằm trong khoảng từ 5 đến 10:
:let c=0 | 5,10g/^* /let c+=1 | s//\=c.'. '
Nếu bạn có một tệp chứa một số danh sách tương tự mà bạn muốn chuyển đổi, ví dụ như một cái gì đó như thế này:
some random stuff some random stuff
* foo 1. foo
* bar 2. bar
* baz 3. baz
some other random stuff some other random stuff
==>
some random stuff some random stuff
* foo 1. foo
* bar 2. bar
* baz 3. baz
* qux 4. qux
some other random stuff some other random stuff
Bạn có thể làm điều đó với lệnh sau:
:let [c,d]=[0,0] | g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
Nó chỉ là một biến thể của lệnh trước, nó đặt lại biến c
khi bạn chuyển sang danh sách khác. Để phát hiện xem bạn có trong danh sách khác hay không, biến d
được sử dụng để lưu trữ số dòng cuối cùng nơi thay thế được thực hiện.
Lệnh toàn cầu so sánh số dòng hiện tại ( line('.')
) với d+1
. Nếu chúng giống nhau, điều đó có nghĩa là chúng ta nằm trong cùng một danh sách như trước vì vậy c
được tăng ( c+1
), nếu không, điều đó có nghĩa là chúng ta nằm trong một danh sách khác, do đó, c
được đặt lại ( 1
).
Bên trong một hàm, lệnh let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')]
có thể được viết lại như thế này:
let c = line('.') == d+1 ? c+1 : 1
let d = line('.')
Hoặc như thế này:
if line('.') == d+1
let c = c+1
else
let c = 1
endif
let d = line('.')
Để lưu một số tổ hợp phím, bạn cũng có thể xác định lệnh tùy chỉnh :NumberedLists
, chấp nhận một phạm vi có giá trị mặc định là 1,$
( -range=%
):
command! -range=% NumberedLists let [c,d]=[0,0] | <line1>,<line2>g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
Khi nào :NumberedLists
sẽ được thực thi <line1>
và <line2>
sẽ được tự động thay thế bằng phạm vi bạn đã sử dụng.
Vì vậy, để chuyển đổi tất cả các danh sách trong bộ đệm, bạn sẽ gõ: :NumberedLists
Chỉ các danh sách giữa dòng 10 và 20: :10,20NumberedLists
Chỉ có lựa chọn trực quan: :'<,'>NumberedLists
Để biết thêm thông tin, xem:
:help :range
:help :global
:help :substitute
:help sub-replace-expression
:help list-identity (section list unpack)
:help expr1
:help :command