2012-11-25 31 views
10

Tôi có một tập tin mà trông giống như sau:Sorting Vim Folds

dog{{{ 
blah blah blah 
}}} 
cat{{{ 
blah blah 
}}} 
aardvark{{{ 
blah blah blah blah 
}}} 

Trong vimrc của tôi, tôi có set foldmethod=marker, do đó nội dung của file đều gấp tại dấu ngoặc nhọn. Câu hỏi của tôi là, làm cách nào để sắp xếp tệp dựa trên tiêu đề gấp? Tôi muốn phần aarvaark xuất hiện trước, sau đó cat, sau đó dog.

Một số phần được gấp có các nếp gấp khác bên trong chúng. Tôi không muốn sắp xếp những cấp độ thấp hơn. Tệp chỉ nên được sắp xếp theo cấp độ 1 lần.

Trả lời

2

Với tất cả các nếp gấp được đóng (zM hoặc :set foldlevel=0), bạn có thể sử dụng xóa dd và dán p để thay đổi các khối được gấp theo cách thủ công. Điều này là ổn cho một lượng nhỏ văn bản.

Đối với các văn bản lớn, bạn phải tự viết chức năng sắp xếp, vì Vim không cung cấp chức năng như vậy. Bạn có thể sử dụng thuật toán sau:

  1. Tham gia tất cả các dòng gấp cùng với dấu tách không tồn tại trong văn bản (ví dụ: <Nul>).
  2. Thực hiện lệnh :sort.
  3. Bỏ tham gia phạm vi trên dấu tách đặc biệt.

Với việc xử lý lỗi và các trường hợp góc, thực tế nó thực sự là một chút nỗ lực thực hiện. Tôi đã thực hiện một nỗ lực ở đây: https://gist.github.com/4145501

1

Một cách tiếp cận sẽ như sau:

  1. tìm kiếm và thay thế kết thúc dòng để các cấp một nếp gấp là mỗi trên cùng một dòng (tức là thay thế dòng kết thúc bằng một chuỗi duy nhất không xuất hiện ở nơi khác trong tệp).

  2. Sử dụng :sort để sắp xếp các dòng trong tệp như thường lệ.

  3. Đảo ngược tìm kiếm và thay thế từ Bước 1 để giới thiệu lại dòng kết thúc.

Tất cả điều này có thể được ghi lại dưới dạng macro Vim.

Bước 1 và 3 sẽ đơn giản nếu không có nếp gấp lồng nhau hoặc nếu có cách dễ dàng để phân biệt nếp gấp cấp cao nhất với nếp gấp đầu tiên (ví dụ: nếu dòng {{{và}}} cấp một được tuôn ra bên trái và những người khác có không gian hàng đầu). Nếu đây không phải là trường hợp, nó có lẽ vẫn còn có thể nhưng khó khăn hơn nhiều.

1

Tôi sẽ sử dụng sức mạnh của macro Vim.

Giả sử bạn không có bất kỳ nhân viên nào khác trong tệp của bạn ngoại trừ hồ sơ và hồ sơ đầu tiên bắt đầu trên dòng đầu tiên. Và rằng bạn không có bắt đầu cấp 1 và kết thúc trên cùng một dòng. Và tất cả {} của bạn đều phù hợp.

Chuyển đến mục đầu tiên và ghi lại một macro để đăng ký một (qa - bắt đầu ghi q - stop)

/{^MV%k:s/\n/EEEEEE/^Mj^ 

mỏ Sao chép hoặc tốt hơn kỷ lục đó cho mình: (^ M - viết tắt của literal nhập)

  • /{^ M tìm tới {
  • V% k chọn dòng vise đến hết cấp 1 nhưng không phải là dòng kết thúc với}}}
  • : s/\ n/EEEEEE/^ M thay đổi ký hiệu 'cuối dòng' thành một số chuỗi duy nhất bên trong lựa chọn
  • j^chuyển một dòng xuống và để xin dòng trong trường hợp bản ghi trước có không gian hàng đầu.

Chạy macro bắt đầu từ dòng thứ hai (giả sử rằng lần đầu tiên được xử lý khi bạn đã ghi macro.) Ở chế độ bình thường 100000 @ a - sử dụng số bất kỳ lớn hơn số lượng hồ sơ của bạn. Macro sẽ tự dừng khi tất cả các dòng được xử lý nếu bản ghi đầu tiên nằm trong dòng đầu tiên của tệp. Như một tác dụng phụ, nó sẽ trực quan chọn dòng đầu tiên - bỏ chọn nó.

Sắp xếp các tập tin

:sort 

Restore cuối dòng: :% s/EEEEEE/^ M/g

Note^M nên đen nhập. Để nhập, hãy sử dụng Ctrl-V Nhập

Tính năng này hoạt động với các cấp lồng nhau vì% chuyển đến kết thúc phù hợp}. Đó là lý do tại sao điều quan trọng là bạn có tất cả {} phù hợp tốt.

Macro sẽ dừng khi không thể đi lên với k đó là lý do tại sao bạn phải có bản ghi đầu tiên trên dòng đầu tiên. Dòng trống hoặc bất kỳ thứ gì không phải là bản ghi giữa các bản ghi sẽ bị macro bỏ qua.

Phương thức trên sẽ hoạt động tốt cho tệp của bạn. Nếu bạn muốn có một cách tiếp cận tổng quát hơn với nếp gấp sau đó sử dụng các lệnh sau trong vĩ mô thay vì/{và%

Thứ nhất mở tất cả các nếp gấp

zj - đi đến sự bắt đầu của lần mở tiếp theo

] z - chuyển đến cuối màn hình hiện tại.

Phần còn lại của macro giống nhau. Phương pháp này tổng quát hơn nhưng tôi thấy nó kém đáng tin cậy hơn vì nó phụ thuộc vào tất cả các nếp gấp, gấp cho phép và vân vân.

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