Add file extension and size to sorting capabilities (#1029)

* Add ability to sort by extension and file size.

Use the tags [[extension]], [[size]], or [[-size]] in the
g:NERDTreeSortOrder list to accomplish this sorting.

* Prevent metadata tags being misused in getSortOrderIndex().

* Apply metadata tags only to files.

* Update NERDTreeSortOrder in help file.

* Update version number in CHANGELOG.
This commit is contained in:
Phil Runninger
2019-08-19 03:51:34 -04:00
committed by GitHub
parent 184fbb6ffe
commit c4a7ca084e
3 changed files with 58 additions and 29 deletions

View File

@@ -1,5 +1,7 @@
# Change Log # Change Log
#### 5.3...
- **.0**: Add file extension and size to sorting capabilities [#1029](https://github.com/scrooloose/nerdtree/pull/1029)
#### 5.2... #### 5.2...
- **.9**: Suppress events for intermediate window/tab/buffer changes [#1026](https://github.com/scrooloose/nerdtree/pull/1026) - **.9**: Suppress events for intermediate window/tab/buffer changes [#1026](https://github.com/scrooloose/nerdtree/pull/1026)
- **.8**: Revert [#1019](https://github.com/scrooloose/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/scrooloose/nerdtree/pull/1021) - **.8**: Revert [#1019](https://github.com/scrooloose/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/scrooloose/nerdtree/pull/1021)

View File

@@ -1043,28 +1043,31 @@ window. Use one of the follow lines for this setting: >
Values: a list of regular expressions. Values: a list of regular expressions.
Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$'] Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$']
This setting is a list of regular expressions which are used to specify the This setting is a list of regular expressions which are used to group or sort
order of nodes under their parent. the nodes under their parent.
For example, if the setting is: > For example, if the setting is: >
['\.vim$', '\.c$', '\.h$', '*', 'foobar'] ['\.vim$', '\.c$', '\.h$', '*', 'foobar']
< <
then all .vim files will be placed at the top, followed by all .c files then then all .vim files will be grouped at the top, followed by all .c files then
all .h files. All files containing the string 'foobar' will be placed at the all .h files. All files containing the string 'foobar' will be placed at the
end. The star is a special flag: it tells the script that every node that end. The star is a special flag: it tells the script that every node that
doesn't match any of the other regexps should be placed here. doesn't match any of the other regexps should be placed here.
If no star is present in NERDTreeSortOrder then one is automatically If no star is present in NERDTreeSortOrder, then one is automatically
appended to the array. appended to the end of the list.
The regex '\/$' should be used to match directory nodes. The regex '\/$' should be used to match directory nodes.
A special flag can be used to sort by the modification timestamps of files and Files can also be sorted by 1) the modification timestamp, 2) the size, or 3)
directories. It is either '[[timestamp]]' for ascending, or '[[-timestamp]]' the extension. Directories are always sorted by name. To accomplish this, the
for descending. If placed at the beginning of the list, files and directories following special flags are used:
are sorted by timestamp, and then by the remaining items in the sort order [[timestamp]] [[-timestamp]] [[size]] [[-size]] [[extension]]
list. If this flag is in any other position of the list, timestamp sorting is The hyphen specifies a descending sort; extensions are sorted in ascending
done secondarily. See examples 4, 5, and 6 below. order only. If placed at the beginning of the list, files are sorted according
to these flags first, and then grouped by the remaining items in the list. If
the flags are in any other position of the list, this special sorting is done
secondarily. See examples 4, 5, and 6 below.
After this sorting is done, the files in each group are sorted alphabetically. After this sorting is done, the files in each group are sorted alphabetically.
@@ -1072,20 +1075,20 @@ Examples: >
(1) ['*', '\/$'] (1) ['*', '\/$']
(2) [] (2) []
(3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$'] (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$']
(4) ['[[timestamp]]'] (4) ['[[-size]]']
(5) ['\/$', '*', '[[-timestamp]]'] (5) ['\/$', '*', '[[timestamp]]']
(6) ['\.md$', '\.c$', '[[-timestamp]]', '*'] (6) ['foo','\/$','[[extension]]']
< <
1. Directories will appear last, everything else will appear above. 1. Directories will appear last, everything else will appear above.
2. Everything will simply appear in alphabetical order. 2. Everything will simply appear in alphabetical order.
3. Dirs will appear first, then ruby and php. Swap files, bak files and vim 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. backup files will appear last with everything else preceding them.
4. All files and directories are sorted by timestamp, oldest first. If any 4. Everything is sorted by size, largest to smallest, with directories
files have identical timestamps, they are sorted alphabetically. considered to have size 0 bytes.
5. Directories are first, newest to oldest, then everything else, newest to 5. Directories will appear first alphabetically, followed by files, sorted by
oldest. timestamp, oldest first.
6. Markdown files first, followed by C source files, then everything else. 6. Files and directories matching 'foo' first, followed by other directories,
Each group is shown newest to oldest. then all other files. Each section of files is sorted by file extension.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*NERDTreeStatusline* *NERDTreeStatusline*

View File

@@ -380,7 +380,8 @@ endfunction
function! s:Path.getSortOrderIndex() function! s:Path.getSortOrderIndex()
let i = 0 let i = 0
while i < len(g:NERDTreeSortOrder) while i < len(g:NERDTreeSortOrder)
if self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i] if g:NERDTreeSortOrder[i] !~? '\[\[-\?\(timestamp\|size\|extension\)\]\]' &&
\ self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
return i return i
endif endif
let i = i + 1 let i = i + 1
@@ -407,15 +408,38 @@ endfunction
" FUNCTION: Path.getSortKey() {{{1 " FUNCTION: Path.getSortKey() {{{1
" returns a key used in compare function for sorting " returns a key used in compare function for sorting
function! s:Path.getSortKey() function! s:Path.getSortKey()
let l:ascending = index(g:NERDTreeSortOrder,'[[timestamp]]') if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder
let l:descending = index(g:NERDTreeSortOrder,'[[-timestamp]]') " Look for file metadata tags: [[timestamp]], [[extension]], [[size]]
if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder || l:ascending >= 0 || l:descending >= 0 let metadata = []
let self._sortKey = [self.getSortOrderIndex()] for tag in g:NERDTreeSortOrder
if tag =~? '\[\[-\?timestamp\]\]'
if self.isDirectory
call add(metadata, 0)
else
call add(metadata, (tag =~ '-' ? -1 : 1) * getftime(self.str()))
endif
elseif tag =~? '\[\[-\?size\]\]'
if self.isDirectory
call add(metadata, 0)
else
call add(metadata, (tag =~ '-' ? -1 : 1) * getfsize(self.str()))
endif
elseif tag =~? '\[\[extension\]\]'
if self.isDirectory
call add(metadata, '')
else
let extension = matchstr(self.getLastPathComponent(0), '[^.]\+\.\zs[^.]\+$')
call add(metadata, extension == '' ? nr2char(str2nr('0x10ffff',16)) : extension)
endif
endif
endfor
if l:descending >= 0 if g:NERDTreeSortOrder[0] =~ '\[\[.*\]\]'
call insert(self._sortKey, -getftime(self.str()), l:descending == 0 ? 0 : len(self._sortKey)) " Apply tags' sorting first if specified first.
elseif l:ascending >= 0 let self._sortKey = metadata + [self.getSortOrderIndex()]
call insert(self._sortKey, getftime(self.str()), l:ascending == 0 ? 0 : len(self._sortKey)) else
" Otherwise, do regex grouping first.
let self._sortKey = [self.getSortOrderIndex()] + metadata
endif endif
let path = self.getLastPathComponent(1) let path = self.getLastPathComponent(1)