Gấp theo mẫu tìm kiếm regex


13

Tôi có một tệp văn bản đơn giản với các cột giá trị được phân tách bằng khoảng trắng. Như thế này:

AU 3030 .... ... ....  
AU 3031 .... ... ....  
AU 3032 .... ... .... 
AU 3033 .... ... .... 
IT 48100 ... .. .....
IT 40100 ... .. .....
IT 48123 ... .. .....
UK 3333 ... ... ..... 
UK 4444 ... ... .....
UK 5555 ... ... .....

Tôi cũng có regex này sẽ khớp với bất kỳ dòng liền kề nào có cùng giá trị trong cột đầu tiên (giả sử tệp được sắp xếp trên cột đầu tiên) ngoại trừ cuối cùng:

/^\(\([A-Z0-9]\+\)\s\+.*\n\)\(\2\)\@=

(hoặc để làm cho nó bớt "lông"):

/^\v([A-Z0-9]+)\s+.*\n(\1)@=

Có thể gấp các dòng trên dòng không phù hợp? Có kết quả này:

+-- 4 lines AU ....
+-- 3 lines IT ....
+-- 3 lines UK ....

Câu trả lời:


14

Làm set foldmethod=exprvà sử dụng 'foldexpr'để đặt biểu thức tập lệnh vim sẽ xác định điểm bắt đầu gấp.

set foldmethod=expr
set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'='

Điều này có vẻ phức tạp hơn so với thực tế, bởi vì chúng ta không thể dễ dàng sử dụng khoảng trắng trong :set, nhưng với khoảng trắng và dòng mới hoặc 2, nó trông giống như:

get(split(getline(v:lnum - 1)), 0, '') != get(split(getline(v:lnum)), 0, '')
    \ ? '>1'
    \ : '='

Tổng quat

Về cơ bản, điều này so sánh từ đầu tiên của mỗi dòng với dòng trước đó. Nếu các từ khác nhau thì dòng bắt đầu của nếp gấp >1. Nếu không, nó giữ cùng một mức độ gấp , =.

Vinh quang của chi tiết

  • set foldmethod=expr để bảo Vim sử dụng biểu thức vim script để xác định các nếp gấp
  • 'foldexpr' tùy chọn giữ biểu thức tập lệnh vim
  • Đánh giá điều kiện với một ternary trả về >1khi một nếp gấp sẽ bắt đầu và =khi mức độ gấp sẽ tiếp tục
  • v:lnumlà dòng hiện tại 'foldexpr'đang chạy để cập nhật các nếp gấp
  • Lấy nội dung dòng hiện tại ( v:lnum) và dòng trước ( v:lnum - 1) thông quagetline()
  • Tách từng dòng thành các từ thông qua split()
  • Sử dụng get()để có được chỉ mục đầu tiên của các từ mới chia
  • Sử dụng một giá trị mặc định ''trong trường hợp một dòng trống. ví dụget(words, 0, '')
  • So sánh từ đầu tiên của dòng hiện tại với từ đầu tiên của dòng trước đó trong phần điều kiện của ternary

Lưu ý: phương pháp này có thể có một số vấn đề về hiệu suất với các tài liệu rất lớn

Để được trợ giúp thêm xem:

:h 'foldmethod'
:h 'foldexpr'
:h getline(
:h v:lnum
:h split(
:h get(
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.