From 6251ab1e6377f302c0c9b9337af6855b3638db98 Mon Sep 17 00:00:00 2001 From: Maxim Bublis Date: Tue, 19 Jan 2016 00:21:13 -0800 Subject: [PATCH] Add support for natural sorting order. --- autoload/nerdtree.vim | 28 ++++++++++++++++++++++++++-- doc/NERD_tree.txt | 30 ++++++++++++++++++++++++++++++ lib/nerdtree/path.vim | 29 +++++++++++++++++++++-------- plugin/NERD_tree.vim | 1 + 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/autoload/nerdtree.vim b/autoload/nerdtree.vim index 3ad2a03..24fbe9c 100644 --- a/autoload/nerdtree.vim +++ b/autoload/nerdtree.vim @@ -36,9 +36,33 @@ endfunction "FUNCTION: nerdtree#compareNodesBySortKey(n1, n2) {{{2 function! nerdtree#compareNodesBySortKey(n1, n2) - if a:n1.path.getSortKey() <# a:n2.path.getSortKey() + let sortKey1 = a:n1.path.getSortKey() + let sortKey2 = a:n2.path.getSortKey() + + let i = 0 + while i < min([len(sortKey1), len(sortKey2)]) + " Compare chunks upto common length. + " If chunks have different type, the one which has + " integer type is the lesser. + if type(sortKey1[i]) == type(sortKey2[i]) + if sortKey1[i] <# sortKey2[i] + return - 1 + elseif sortKey1[i] ># sortKey2[i] + return 1 + endif + elseif sortKey1[i] == type(0) + return -1 + elseif sortKey2[i] == type(0) + return 1 + endif + let i = i + 1 + endwhile + + " Keys are identical upto common length. + " The key which has smaller chunks is the lesser one. + if len(sortKey1) < len(sortKey2) return -1 - elseif a:n1.path.getSortKey() ># a:n2.path.getSortKey() + elseif len(sortKey1) > len(sortKey2) return 1 else return 0 diff --git a/doc/NERD_tree.txt b/doc/NERD_tree.txt index 1ad8e18..d09ee32 100644 --- a/doc/NERD_tree.txt +++ b/doc/NERD_tree.txt @@ -618,6 +618,9 @@ NERD tree. These options should be set in your vimrc. |'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case sensitive or not when sorting nodes. +|'NERDTreeNaturalSort'| Tells the NERD tree whether to use + natural sort order or not when sorting nodes. + |'NERDTreeSortHiddenFirst'| Tells the NERD tree whether to take the dot at the beginning of the hidden file names into account when sorting nodes. @@ -734,6 +737,33 @@ account. The above nodes would then be sorted like this: > blarg.c boner.c < +------------------------------------------------------------------------------ + *'NERDTreeNaturalSort'* +Values: 0 or 1. +Default: 0. + +By default the NERD tree does not sort nodes in natural sort order, i.e. nodes +could appear like this: > + z1.txt + z10.txt + z100.txt + z11.txt + z110.txt + z2.txt + z20.txt + z3.txt +< +But if you set this option to 1 then the natural sort order will be used. The +above nodes would then be sorted like this: > + z1.txt + z2.txt + z3.txt + z10.txt + z11.txt + z20.txt + z100.txt + z110.txt +< ------------------------------------------------------------------------------ *'NERDTreeChDirMode'* diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim index df18505..fc067a1 100644 --- a/lib/nerdtree/path.vim +++ b/lib/nerdtree/path.vim @@ -1,12 +1,6 @@ "we need to use this number many times for sorting... so we calculate it only "once here let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') -" used in formating sortKey, e.g. '%04d' -if exists("log10") - let s:sortKeyFormat = "%0" . float2nr(ceil(log10(len(g:NERDTreeSortOrder)))) . "d" -else - let s:sortKeyFormat = "%04d" -endif "CLASS: Path "============================================================ @@ -365,8 +359,23 @@ function! s:Path.getSortOrderIndex() return s:NERDTreeSortStarIndex endfunction +"FUNCTION: Path._splitChunks(path) {{{1 +"returns a list of path chunks +function! s:Path._splitChunks(path) + let chunks = split(a:path, '\(\D\+\|\d\+\)\zs') + let i = 0 + while i < len(chunks) + "convert number literals to numbers + if match(chunks[i], '^\d\+$') == 0 + let chunks[i] = str2nr(chunks[i]) + endif + let i = i + 1 + endwhile + return chunks +endfunction + "FUNCTION: Path.getSortKey() {{{1 -"returns a string used in compare function for sorting +"returns a key used in compare function for sorting function! s:Path.getSortKey() if !exists("self._sortKey") let path = self.getLastPathComponent(1) @@ -376,7 +385,11 @@ function! s:Path.getSortKey() if !g:NERDTreeCaseSensitiveSort let path = tolower(path) endif - let self._sortKey = printf(s:sortKeyFormat, self.getSortOrderIndex()) . path + if !g:NERDTreeNaturalSort + let self._sortKey = [self.getSortOrderIndex(), path] + else + let self._sortKey = [self.getSortOrderIndex()] + self._splitChunks(path) + endif endif return self._sortKey diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim index bbcc55f..8d41be7 100644 --- a/plugin/NERD_tree.vim +++ b/plugin/NERD_tree.vim @@ -46,6 +46,7 @@ endfunction call s:initVariable("g:NERDTreeAutoCenter", 1) call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) +call s:initVariable("g:NERDTreeNaturalSort", 0) call s:initVariable("g:NERDTreeSortHiddenFirst", 1) call s:initVariable("g:NERDTreeChDirMode", 0) call s:initVariable("g:NERDTreeMinimalUI", 0)