2012-11-25 69 views
10

我有一個看起來是這樣的文件:排序Vim的褶皺

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

在我的vimrc我有set foldmethod=marker,使文件的內容都摺疊在大括號內。我的問題是,如何根據摺疊標題對文件進行排序?我想aarvaark部分先來,然後cat,然後dog

一些摺疊的部分在其中有其他摺疊。我不想對這些較低的摺疊級別進行排序。該文件應該按級別1摺疊排序。

回答

2

隨着所有的摺疊閉合(zM:set foldlevel=0),則可以使用刪除dd並粘貼p手動換檔周圍摺疊塊。對於少量文本,這是可以的。

對於巨大的文本,你必須親自編寫一個排序函數,因爲Vim不提供這樣的功能。可以使用以下算法:

  1. 將所有摺疊的行連同文本中不存在的分隔符(例如<Nul>)一起連接。執行:sort命令。
  2. 在特殊分隔符上取消加入範圍。

有了錯誤處理和角落案例,它實際上是相當多的實現工作。我在這裏作出了嘗試:https://gist.github.com/4145501

1

一種方法是如下:

  1. 搜索和替換行尾,這樣的水平,一個褶皺均在同一行(即替換線以不在文件其他地方出現的唯一字符串結尾)。

  2. 使用:sort像往常一樣對文件中的行進行排序。

  3. 反向搜索並從步驟1中進行替換以重新引入行尾。

這可以全部記錄爲Vim宏。

如果沒有嵌套摺疊,或者有一個區分頂層摺疊和嵌套摺疊的簡單方法,步驟1和3將很簡單(例如,如果一級{{{和}}}行左邊齊平,其他領先空間)。如果情況並非如此,那可能還是可能的,但要困難得多。

1

我會使用Vim宏的力量。

假設您的文件中沒有任何其他人員,只有記錄和第一條記錄從第一行開始。而且你沒有開始第一級並且在同一條線上結束。你的{}匹配得很好。

轉到第一項,並錄製宏註冊(qa - 開始錄製q - 停止)

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

複製礦井或更好的戰績它自己:(^ M - 代表文字輸入)

  • /{^ M找到下一個{
  • V(%)ķ選擇線-臺鉗直到級別1的端部,但不與收線}}}
  • :s/\ n/EEEEEE/^ M將符號'行尾'更改爲選擇內的某個唯一字符串
  • j ^一行​​往下,在前一個記錄具有前導空格的情況下行乞。

運行從第二行宏開始(假設您錄製的宏第一種是已經處理過。) 在正常模式100000 @一 - 使用任何數字比你的記錄數量。如果第一條記錄位於文件的第一行,宏將在處理完所有行後自行停止。作爲副作用,它會直觀地選擇第一行 - 取消選擇它。

排序文件

:sort 

恢復線的端: :%S/EEEEEE/^ M /克

注^ M應該是文字輸入。鍵入它使用Ctrl-V輸入

它與嵌套級別一起工作,因爲%跳轉到匹配關閉}。這就是爲什麼您的所有匹配很重要。

當無法跟上k時,宏將停止,這就是爲什麼您必須在第一行有第一條記錄。空行或任何不是記錄之間的記錄的宏將被宏忽略。

上述方法應該適用於您的文件。如果你想與褶皺一個更通用的方法,然後使用宏來代替/ {和%

以下命令首先打開所有的摺疊

ZJ - 去到下一個打開的摺疊的開始

] z - 轉到當前摺疊的結尾。

宏的其餘部分是相同的。 這種方法更一般,但我發現它不太可靠,因爲它取決於所有摺疊打開,摺疊啓用等。