diff --git a/autoload/flog.vim b/autoload/flog.vim index 5ccc834..9a5d098 100644 --- a/autoload/flog.vim +++ b/autoload/flog.vim @@ -66,6 +66,10 @@ function! flog#split_limit(limit) abort return [a:limit[: l:start - 1], a:limit[l:start :]] endfunction +function! flog#get_sort_type(name) abort + return filter(copy(g:flog_sort_types), 'v:val.name ==# ' . string(a:name))[0] +endfunction + function! flog#get(dict, key, ...) abort if type(a:dict) != v:t_dict return v:null @@ -209,6 +213,7 @@ function! flog#get_internal_default_args() abort \ 'no_graph': v:false, \ 'no_patch': v:false, \ 'skip': v:null, + \ 'sort': v:null, \ 'max_count': v:null, \ 'open_cmd': 'tabedit', \ 'search': v:null, @@ -319,6 +324,10 @@ function! flog#parse_set_args(args, current_args, defaults) abort let a:current_args.skip = flog#parse_arg_opt(l:arg) elseif l:arg ==# '-skip=' let a:current_args.skip = a:defaults.skip + elseif l:arg =~# '^-sort=.\+' + let a:current_args.sort = flog#parse_arg_opt(l:arg) + elseif l:arg ==# '-sort=' + let a:current_args.sort = a:defaults.sort elseif l:arg =~# '^-max-count=\d\+' let a:current_args.max_count = flog#parse_arg_opt(l:arg) elseif l:arg ==# '-max-count=' @@ -613,6 +622,12 @@ function! flog#complete_author(arg_lead) abort return flog#filter_completions(a:arg_lead, l:authors) endfunction +function! flog#complete_sort(arg_lead) abort + let [l:lead, l:name] = flog#split_single_completable_arg(a:arg_lead) + let l:sort_types = flog#escape_completions(l:lead, map(copy(g:flog_sort_types), 'v:val.name')) + return flog#filter_completions(a:arg_lead, l:sort_types) +endfunction + function! flog#complete(arg_lead, cmd_line, cursor_pos) abort if a:cmd_line[:a:cursor_pos] =~# ' -- ' return [] @@ -636,6 +651,8 @@ function! flog#complete(arg_lead, cmd_line, cursor_pos) abort return flog#complete_rev(a:arg_lead) elseif a:arg_lead =~# '^-path=' return flog#complete_path(a:arg_lead) + elseif a:arg_lead =~# '^-sort=' + return flog#complete_sort(a:arg_lead) endif return flog#filter_completions(a:arg_lead, copy(g:flog_default_completion)) endfunction @@ -824,6 +841,9 @@ function! flog#build_log_args() abort if l:opts.skip != v:null let l:args .= ' --skip=' . shellescape(l:opts.skip) endif + if l:opts.sort != v:null + let l:sort_type = flog#get_sort_type(l:opts.sort) + let l:args .= ' ' . l:sort_type.args endif if l:opts.max_count != v:null let l:args .= ' --max-count=' . shellescape(l:opts.max_count) @@ -1123,6 +1143,9 @@ function! flog#set_graph_buffer_title() abort if l:opts.skip != v:null let l:title .= ' [skip=' . l:opts.skip . ']' endif + if l:opts.sort != v:null + let l:title .= ' [sort=' . l:opts.sort . ']' + endif if l:opts.max_count != v:null let l:title .= ' [max_count=' . l:opts.max_count . ']' endif @@ -1315,6 +1338,30 @@ function! flog#change_skip_by_max_count(multiplier) abort call flog#populate_graph_buffer() endfunction +function! flog#set_sort_option(sort) abort + let l:state = flog#get_state() + let l:state.sort = a:sort + call flog#populate_graph_buffer() +endfunction + +function! flog#cycle_sort_option() abort + let l:state = flog#get_state() + + if l:state.sort == v:null + let l:state.sort = g:flog_sort_types[0].name + else + let l:sort_type = flog#get_sort_type(l:state.sort) + let l:sort_index = index(g:flog_sort_types, l:sort_type) + if l:sort_index == len(g:flog_sort_types) - 1 + let l:state.sort = g:flog_sort_types[0].name + else + let l:state.sort = g:flog_sort_types[l:sort_index + 1].name + endif + endif + + call flog#populate_graph_buffer() +endfunction + " }}} " Graph buffer update hook {{{ diff --git a/doc/flog.txt b/doc/flog.txt index 1e084e6..f6df5bd 100644 --- a/doc/flog.txt +++ b/doc/flog.txt @@ -57,6 +57,10 @@ COMMANDS *flog-commands* Instead of manually specifying this argument, you can also use a range or visually select some lines and type ":Flog". + -sort= Sort by one of , where type is in "date", + "author", or "topo". These correspond to the options + "--date-order", "--author-order", and "--topo-order" + respectfully. -rev= The git revision to pass to the log command. Can be specified more than once. When "-limit=" is specified, only the first revision is used. @@ -246,6 +250,27 @@ gp *flog-gp* Toggle the "--no-patch" argument. Useful while the "-limit" option is specified. +gss *(FlogCycleSort)* + *flog-gss* + + Cycle through the different sort options; "--date-order", + "--author-date-order", and "--topo-order". + +gsd *(FlogSortDate)* + *flog-gsd* + + Set the "--date-order" option. Conflicts with other sort options. + +gsa *(FlogSortAuthor)* + *flog-gsa* + + Set the "--author-date-order" option. Conflicts with other sort options. + +gst *(FlogSortTopo)* + *flog-gst* + + Set the "--topo-order" option. Conflicts with other sort options. + gsr *(FlogToggleReverse)* *flog-gsr* diff --git a/ftplugin/floggraph.vim b/ftplugin/floggraph.vim index 6e3b63c..b8a25a6 100644 --- a/ftplugin/floggraph.vim +++ b/ftplugin/floggraph.vim @@ -157,6 +157,26 @@ if !hasmapto('(FlogPatchSearch)') endif nnoremap (FlogPatchSearch) :Flogsetargs -patch-search= +if !hasmapto('(FlogCycleSort)') + nmap gss (FlogCycleSort) +endif +nnoremap (FlogCycleSort) :call flog#cycle_sort_option() + +if !hasmapto('(FlogSortDate)') + nmap gsd (FlogSortDate) +endif +nnoremap (FlogSortDate) :call flog#set_sort_option('date') + +if !hasmapto('(FlogSortAuthor)') + nmap gsa (FlogSortAuthor) +endif +nnoremap (FlogSortAuthor) :call flog#set_sort_option('author') + +if !hasmapto('(FlogSortTopo)') + nmap gst (FlogSortTopo) +endif +nnoremap (FlogSortTopo) :call flog#set_sort_option('topo') + " }}} " Commit/branch mappings {{{ diff --git a/plugin/flog.vim b/plugin/flog.vim index 9bea7d2..aa4e47b 100644 --- a/plugin/flog.vim +++ b/plugin/flog.vim @@ -67,6 +67,16 @@ let g:flog_log_data_hash_index = 1 " }}} +" Sorting type data {{{ + +let g:flog_sort_types = [ + \ { 'name': 'date', 'args': '--date-order' }, + \ { 'name': 'author', 'args': '--author-date-order' }, + \ { 'name': 'topo', 'args': '--topo-order' }, + \ ] + +" }}} + " Completion data {{{ let g:flog_default_completion = [ @@ -88,7 +98,8 @@ let g:flog_default_completion = [ \ '-rev=', \ '-reverse', \ '-search=', - \ '-skip=' + \ '-skip=', + \ '-sort=', \ ] let g:flog_date_formats = [