Просмотр исходного кода

Implement `fullpath` sort based on `buf.fullpath`.

This eliminates anomalies caused by sorting based on the displayed text.

- The sort order no longer changes when toggling `Absolute`/`Relative`
  and `Split`/`Full` display options.

- For `Relative Split path` view, files below the current working
  directory now remain grouped together.  For example, launching Vim via
  this invocation:

      vim README.md LICENSE doc/bufexplorer.txt plugin/bufexplorer.vim \
        ~/.vimrc /etc/passwd

  Previously would lead to this order when sorting by `fullpath`, where
  the files of `bufexplorer/` are not kept together:

      2  h    LICENSE         .      line 1
      1 %a    README.md       .      line 1
      6 #h=   passwd          /etc   line 1
      3  h    bufexplorer.txt doc    line 1
      4  h    bufexplorer.vim plugin line 1
      5  h    .vimrc          ~      line 1

  They are now sorted by the overall `fullpath`:

      6       passwd          /etc   line 0
      5       .vimrc          ~      line 0
      3       bufexplorer.txt doc    line 0
      2       LICENSE         .      line 0
      4       bufexplorer.vim plugin line 0
      1 %a    README.md       .      line 16
Michael Henry 10 месяцев назад
Родитель
Сommit
35dcf4f0ef
1 измененных файлов с 32 добавлено и 6 удалено
  1. 32 6
      plugin/bufexplorer.vim

+ 32 - 6
plugin/bufexplorer.vim

@@ -1146,6 +1146,37 @@ function! s:MRUCmp(line1, line2)
     return index(s:MRUList, str2nr(a:line1)) - index(s:MRUList, str2nr(a:line2))
 endfunction
 
+" Key_fullpath {{{2
+function! s:Key_fullpath(line)
+    let _bufnr = str2nr(a:line)
+    let buf = s:raw_buffer_listing[_bufnr]
+    let key = [buf.fullname]
+    return key
+endfunction
+
+" SortByKeyFunc {{{2
+function! s:SortByKeyFunc(keyFunc)
+    let keyedLines = []
+    for line in getline(s:firstBufferLine, "$")
+        let key = eval(a:keyFunc . '(line)')
+        call add(keyedLines, join(key + [line], "\1"))
+    endfor
+
+    " Ignore case when sorting by passing `1`:
+    call sort(keyedLines, 1)
+
+    if g:bufExplorerReverseSort
+        call reverse(keyedLines)
+    endif
+
+    let lines = []
+    for keyedLine in keyedLines
+        call add(lines, split(keyedLine, "\1")[-1])
+    endfor
+
+    call setline(s:firstBufferLine, lines)
+endfunction
+
 " SortReverse {{{2
 function! s:SortReverse()
     let g:bufExplorerReverseSort = !g:bufExplorerReverseSort
@@ -1195,12 +1226,7 @@ function! s:SortListing()
             execute sort 'ir /\zs[^\/\\]\+\ze\s*line/'
         endif
     elseif g:bufExplorerSortBy == "fullpath"
-        if g:bufExplorerSplitOutPathName
-            " Sort twice - first on the file name then on the path.
-            execute sort 'ir /\d.\{7}\zs\f\+\ze/'
-        endif
-
-        execute sort 'ir /\zs\f\+\ze\s\+line/'
+        call s:SortByKeyFunc("<SID>Key_fullpath")
     elseif g:bufExplorerSortBy == "extension"
         " Sort by full path...
         execute sort 'ir /\zs\f\+\ze\s\+line/'