From 388623e702ce7df7d642e4e69d4d0328667751f2 Mon Sep 17 00:00:00 2001 From: Phil Runninger Date: Wed, 24 Oct 2018 22:18:18 -0400 Subject: [PATCH] Support sorting files and directories by modification time. (#901) * Introduce a flag to to sort by the node's modification time. This flag is part of the NERDTreeSortOrder list. '[[timestamp]]' sorts oldest to newest, while '[[-timestamp]]' sorts newest to oldest. Its position in the array determines whether it is the primary sort (first position) or secondary sort (any other position). The remaining elements in the array describe the other sort level following all prior rules. If needed, a tertiary sort is done alphabetically on the filename. Examples: ['[[timestamp]]'] - oldest to newest ['\/$','*','[[-timestamp]]'] - dirs, then files, each newest first. When using this flag, performance is slowed a little because the sortKey is always recalculated with every sort. Why? Because if a file is saved (either in vim or by an outside program), NERDTree needs to go back out to the shell to get the new modification time. * Update NERDTreeSortOrder documentation. The new `[[timestamp]]' and '[[-timestamp]]' flags are added to support sorting by modification time. * Fix the inequality. Must be >= to force recalculation of _sortKey. * Move `let path=` closer to where it's used. --- doc/NERDTree.txt | 16 ++++++++++++++++ lib/nerdtree/path.vim | 20 +++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/doc/NERDTree.txt b/doc/NERDTree.txt index 8f214cb..42c31cc 100644 --- a/doc/NERDTree.txt +++ b/doc/NERDTree.txt @@ -995,17 +995,33 @@ appended to the array. The regex '\/$' should be used to match directory nodes. +A special flag can be used to sort by the modification timestamps of files and +directories. It is either '[[timestamp]]' for ascending, or '[[-timestamp]]' +for descending. If placed at the beginning of the list, files and directories +are sorted by timestamp, and then by the remaining items in the sort order +list. If this flag is in any other position of the list, timestamp sorting is +done secondarily. See examples 4, 5, and 6 below. + After this sorting is done, the files in each group are sorted alphabetically. Other examples: > (1) ['*', '\/$'] (2) [] (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$'] + (4) ['[[timestamp]]'] + (5) ['\/$', '*', '[[-timestamp]]'] + (6) ['\.md$', '\.c$', '[[-timestamp]]', '*'] < 1. Directories will appear last, everything else will appear above. 2. Everything will simply appear in alphabetical order. 3. Dirs will appear first, then ruby and php. Swap files, bak files and vim backup files will appear last with everything else preceding them. +4. All files and directories are sorted by timestamp, oldest first. If any + files have identical timestamps, they are sorted alphabetically. +5. Directories are first, newest to oldest, then everything else, newest to + oldest. +6. Markdown files first, followed by C source files, then everything else. + Each group is shown newest to oldest. ------------------------------------------------------------------------------ *'NERDTreeStatusline'* diff --git a/lib/nerdtree/path.vim b/lib/nerdtree/path.vim index 912c537..32c9cdb 100644 --- a/lib/nerdtree/path.vim +++ b/lib/nerdtree/path.vim @@ -392,7 +392,17 @@ endfunction " FUNCTION: Path.getSortKey() {{{1 " returns a key used in compare function for sorting function! s:Path.getSortKey() - if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder + let l:ascending = index(g:NERDTreeSortOrder,'[[timestamp]]') + let l:descending = index(g:NERDTreeSortOrder,'[[-timestamp]]') + if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder || l:ascending >= 0 || l:descending >= 0 + let self._sortKey = [self.getSortOrderIndex()] + + if l:descending >= 0 + call insert(self._sortKey, -getftime(self.str()), l:descending == 0 ? 0 : len(self._sortKey)) + elseif l:ascending >= 0 + call insert(self._sortKey, getftime(self.str()), l:ascending == 0 ? 0 : len(self._sortKey)) + endif + let path = self.getLastPathComponent(1) if !g:NERDTreeSortHiddenFirst let path = substitute(path, '^[._]', '', '') @@ -400,13 +410,9 @@ function! s:Path.getSortKey() if !g:NERDTreeCaseSensitiveSort let path = tolower(path) endif - if !g:NERDTreeNaturalSort - let self._sortKey = [self.getSortOrderIndex(), path] - else - let self._sortKey = [self.getSortOrderIndex()] + self._splitChunks(path) - endif - endif + call extend(self._sortKey, (g:NERDTreeNaturalSort ? self._splitChunks(path) : [path])) + endif return self._sortKey endfunction