Commits

ZyX_I committed 4da57bf

Added sorting capabilities
Fixed TreeData syntax definition

Comments (0)

Files changed (2)

macros/fstree.vim

     let path=s:_r.os.path.join(a:tdata.path)
     return getfperm(path)
 endfunction
+function s:F.namecmp(a, b)
+    let a=substitute(a:a, '\W', '', 'g')
+    let b=substitute(a:b, '\W', '', 'g')
+    return ((a is? b)?(0):((a>?b)?(1):(-1)))
+endfunction
+function s:F.sizecmp(a, b)
+    let a=+a:a
+    let b=+a:b
+    return ((a==b)?(0):((a>b)?(1):(-1)))
+endfunction
 call s:_f.tree.add('fs', s:F.get, {'columns': s:columns,
             \                   'coldefault': ['name', 'size'],
             \                      'options': {'colopts':
             \                                   {'size':
             \                                       {'align': 'right',
             \                                        'title': 'Size',
-            \                                       'talign': 'left'}},
+            \                                       'talign': 'left',
+            \                                          'cmp': s:F.sizecmp,},
+            \                                    'name': {'cmp': s:F.namecmp},},
             \                                  'treechars': ' ╻╹┃╺┏┗┣╸┓┛┫━┳┻╋',
             \                                  'header': '# Header',
             \                                  'footer': "# Multiline\n# Footer",}})

plugin/gtregen.vim

         let tree.coldefault=['name']+sort(filter(keys(tree.columns),
                     \                            'v:val isnot# "name"'))
     endif
+    let tree.defsortby=get(a:options, 'defsortby', 'name')
     let tree.options=get(a:options, 'options', 0)
     augroup Gtregen
         execute 'autocmd BufReadCmd '.tree.pattern.' '.
             \                               ' minw   range 0 inf'.
             \                               ' title  type ""'.
             \                               ' talign (in aligns)'.
+            \                               ' cmp    (|isfunc)'.
             \                               '}}'.
             \       ' treechars (type ""  match /\v^%(%(\t)@!\p){16}$/ '.
             \                   '?=(@%@.p._r.strdisplaywidth(@.@)==16))'.
             \       ' header    type ""'.
             \       ' footer    type ""'.
+            \       ' sortby    either is =(0), type ""'.
             \       '}'
 let s:tree.cons.add['@FWC']=
             \['_ _ (match @\v^[^:/\\\x0a]+$@ #treeex(.) not key trees) '.
             \               '(dict {?match /\v^\w+$/  (|isfunc)}) '.
             \           'coldefault  (value @^ haskey columns '.
             \                        'list either is "name", key @^^.columns)'.
+            \           'defsortby   (value @^ haskey columns '.
+            \                        'either is "name", key @^.columns)'.
             \           'write       (|isfunc) '.
             \           'pattern     type "" '.
             \           'options     either ((|isfunc), '.
 let s:tree.cons.del=s:_f.wrapfunc(s:tree.cons.del)
 "▶1 Register feature
 call s:_f.newfeature('tree', s:tree)
+"▶1 defcmp :: str, str → -1|0|1
+function s:F.defcmp(a, b)
+    return ((a:a is# a:b)?(0):((a:a>#a:b)?(1):(-1)))
+endfunction
+"▶1 sorter :: node, node → -1|0|1
+function s:F.sorter(...)
+    let sb=self.sortby
+    let tree=self.tree
+    return call(self.cmp, map(copy(a:000),
+                \             '((has_key(v:val.columns, '''.sb.'''))?'.
+                \                   '(v:val.columns.'.sb.'):'.
+                \                   '(call(tree.columns.'.sb.', [v:val], {})'.
+                \                   '))'), self)
+endfunction
+"▶1 sortcols :: tree, [node], options → [node] + [node]
+function s:F.sortcols(tree, nodes, options)
+    if empty(a:options.sortby)
+        return a:nodes
+    endif
+    let d  =  {'sortby': a:options.sortby,
+                \ 'cmp': get(a:options.colopts[a:options.sortby], 'cmp',
+                \           s:F.defcmp),
+                \'tree': a:tree}
+    " TODO workaround for older vims not supporting sort(..., dict)
+    return sort(a:nodes, s:F.sorter, d)
+endfunction
 "▶1 gencolumns :: tree, tdata, options, level → [Number:[String]]
 function s:F.gencolumns(tree, tdata, options, level)
     let columns=copy(a:options.columns)
             call extend(a:tdata, a:tree.get(join(a:tdata.path, '/')))
         endif
         call map(a:tdata.nodes, 's:F.proctdata(a:tree, v:val)')
+        call s:F.sortcols(a:tree, a:tdata.nodes, a:options)
         for node in a:tdata.nodes
             let r+=s:F.gencolumns(a:tree, node, a:options, a:level+1)
         endfor
         let options.treechars=((&encoding is# 'utf-8')?(s:uchars):
                     \                                  (s:nuchars))
     endif
+    if !has_key(options, 'sortby')
+        let options.sortby=tree.defsortby
+    endif
     if !has_key(options, 'columns')
         let options.columns=tree.coldefault
     endif
         execute 'syntax match TreeTitles /\v%'.(bvar.cstart-1).'l^.*/ '.
                     \                   'contains=@TreeTitle'
     endif
-    execute 'syntax match TreeData /\v%>'.(bvar.cstart-1).'l^.*/ '.
+    execute 'syntax match TreeData /\v%>'.(bvar.cstart-1).'l'.
+                \                    '%<'.(bvar.cend+1).'l^.*/ '.
                 \                 'contains=@TreeColumn'
     let i=0
     for column in bvar.options.columns