diff --git a/ftplugin/vo_base.vim b/ftplugin/vo_base.vim index 6176830..0f70c32 100644 --- a/ftplugin/vo_base.vim +++ b/ftplugin/vo_base.vim @@ -98,168 +98,6 @@ setlocal iskeyword=@,39,45,48-57,_,129-255 if !exists("loaded_vimoutliner_functions") let loaded_vimoutliner_functions=1 -" Sorting {{{2 -" IsParent(line) {{{3 -" Return 1 if this line is a parent -function! IsParent(line) - return (Ind(a:line)+1) == Ind(a:line+1) -endfunction -"}}}3 -" FindParent(line) {{{3 -" Return line if parent, parent line if not -function! FindParent(line) - if IsParent(a:line) - return a:line - else - let l:parentindent = Ind(a:line)-1 - let l:searchline = a:line - while (Ind(l:searchline) != l:parentindent) && (l:searchline > 0) - let l:searchline = l:searchline-1 - endwhile - return l:searchline - endif -endfunction -"}}}3 -" FindLastChild(line) {{{3 -" Return the line number of the last decendent of parent line -function! FindLastChild(line) - let l:parentindent = Ind(a:line) - let l:searchline = a:line+1 - while Ind(l:searchline) > l:parentindent - let l:searchline = l:searchline+1 - endwhile - return l:searchline-1 -endfunction -"}}}3 -" MoveDown() {{{3 -" Move a heading down by one -" Used for sorts and reordering of headings -function! MoveDown() - call cursor(line("."),0) - del x - put x -endfunction -"}}}3 -" DelHead() {{{3 -" Delete a heading -" Used for sorts and reordering of headings -function! DelHead(line) - let l:fstart = foldclosed(a:line) - if l:fstart == -1 - let l:execstr = a:line . "del x" - else - let l:fend = foldclosedend(a:line) - let l:execstr = l:fstart . "," . l:fend . "del x" - endif - exec l:execstr -endfunction -" PutHead() {{{3 -" Put a heading -" Used for sorts and reordering of headings -function! PutHead(line) - let l:fstart = foldclosed(a:line) - if l:fstart == -1 - let l:execstr = a:line . "put x" - exec l:execstr - else - let l:fend = foldclosedend(a:line) - let l:execstr = l:fend . "put x" - exec l:execstr - endif -endfunction -"}}}3 -" NextHead(line) {{{3 -" Return line of next heanding -" Used for sorts and reordering of headings -function! NextHead(line) - let l:fend = foldclosedend(a:line) - if l:fend == -1 - return a:line+1 - else - return l:fend+1 - endif -endfunction -"}}}3 -" CompHead(line) {{{3 -" Compare this heading and the next -" Return 1: next is greater, 0 next is same, -1 next is less -function! CompHead(line) - let l:thisline=getline(a:line) - let l:nextline=getline(NextHead(a:line)) - if l:thisline <# l:nextline - return 1 - elseif l:thisline ># l:nextline - return -1 - else - return 0 - endif -endfunction -"}}}3 -" Sort1Line(line) {{{3 -" Compare this heading and the next and swap if out of order -" Dir is 0 for forward, 1 for reverse -" Return a 1 if a change was made -function! Sort1Line(line,dir) - if (CompHead(a:line) == -1) && (a:dir == 0) - call DelHead(a:line) - call PutHead(a:line) - return 1 - elseif (CompHead(a:line) == 1) && (a:dir == 1) - call DelHead(a:line) - call PutHead(a:line) - return 1 - else - return 0 - endif -endfunction -"}}}3 -" Sort1Pass(start,end,dir) {{{3 -" Compare this heading and the next and swap if out of order -" Dir is 0 for forward, 1 for reverse -" Return a 0 if no change was made, other wise return the change count -function! Sort1Pass(fstart,fend,dir) - let l:i = a:fstart - let l:changed = 0 - while l:i < a:fend - let l:changed = l:changed + Sort1Line(l:i,a:dir) - let l:i = NextHead(l:i) - endwhile - return l:changed -endfunction -"}}}3 -" Sort(start,end,dir) {{{3 -" Sort this range of headings -" dir: 0 = ascending, 1 = decending -function! SortRange(fstart,fend,dir) - let l:changed = 1 - while l:changed != 0 - let l:changed = Sort1Pass(a:fstart,a:fend,a:dir) - endwhile -endfunction -"}}}3 -" SortChildren(dir) {{{3 -" Sort the children of a parent -" dir: 0 = ascending, 1 = decending -function! SortChildren(dir) - let l:oldcursor = line(".") - let l:fstart = FindParent(line(".")) - let l:fend = FindLastChild(l:fstart) - let l:fstart = l:fstart - if l:fend <= l:fstart + 1 - return - endif - call append(line("$"),"Temporary last line for sorting") - mkview - let l:execstr = "set foldlevel=" . foldlevel(l:fstart) - exec l:execstr - call SortRange(l:fstart + 1,l:fend,a:dir) - call cursor(line("$"),0) - del x - loadview - call cursor(l:oldcursor,0) -endfunction -"}}}3 -"}}}2 " MakeChars() {{{2 " Make a string of characters " Used for strings of repeated characters @@ -559,11 +397,6 @@ nmap t $:call InsertSpaceTime() imap t ~x:call InsertTime(0)a nmap T ^:call InsertTime(1)a -" sort a list naturally -map s :call SortChildren(0) -" sort a list, but you supply the options -map S :call SortChildren(1) - " invoke the file explorer map f :e . imap f :e . diff --git a/vimoutliner/plugin/vo_sort.otl b/vimoutliner/plugin/vo_sort.otl new file mode 100644 index 0000000..56d7632 --- /dev/null +++ b/vimoutliner/plugin/vo_sort.otl @@ -0,0 +1,44 @@ +documentation + what ? + the goal of this plugin is to let you have s simple way to sort the outlines at the same level + within one keystropke. Children of these siblings are moved with their aprents and not alterned in any ways. + This pkugin is also interesting as a tempate plugin for people who would want to implement custom sort functions + with respect of the outlines. + how ? + you place on one of the siblings you want sorted, and hit ',,s' or ',,S' and there you are, they sorted + keys + ,,s sort alphanumerically (ascending) + ,,S sort alphanumerically (descending) + checkboxes + at the moment of this writing, checkboxes are taken as literal text when sorting, + I need to change that. +sort status + [X] sorting ascending + [X] sorting descending + [X] jostein patch + [_] sorting checkbox + [_] sorting ascending + [_] X is <# _ + [_] sorting descending + [_] as a plugin + [X] in my vo_base + [_] with official one +test + ruth + b + plaf + a + plop + plip + c + plop + e + plouf + ruth2 + [X] b + [X] plaf + [_] a + [_] plop + [_] plip + [_] c + [_] plouf diff --git a/vimoutliner/plugin/vo_sort.vim b/vimoutliner/plugin/vo_sort.vim new file mode 100644 index 0000000..5956cd0 --- /dev/null +++ b/vimoutliner/plugin/vo_sort.vim @@ -0,0 +1,192 @@ +" VimOutliner {{{1 +"######################################################################### +"# ftplugin/vo_sort.vim: VimOutliner sort plugin +"# +"# extracted from core vimoutliner to ease leveraging, optionnality +"# visibility aso... +"# +"# Copyright (C) 2001,2003 by Steve Litt (slitt@troubleshooters.com) +"# Copyright (C) 2004 by Noel Henson (noel@noels-lab.com) +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"# +"# You should have received a copy of the GNU General Public License +"# along with this program; if not, write to the Free Software +"# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +"# +"# Steve Litt, slitt@troubleshooters.com, http://www.troubleshooters.com +"######################################################################### +"}}}1 +" Functions {{{1 +" IsParent(line) {{{2 +" Return 1 if this line is a parent +function! s:IsParent(line) + return (Ind(a:line)+1) == Ind(a:line+1) +endfunction +"}}}2 +" FindParent(line) {{{2 +" Return line if parent, parent line if not +function! s:FindParent(line) + let l:parentindent = Ind(a:line)-1 + let l:searchline = a:line + while (Ind(l:searchline) != l:parentindent) && (l:searchline > 0) + let l:searchline -= 1 + endwhile + return l:searchline +endfunction +"}}}2 +" FindLastChild(line) {{{2 +" Return the line number of the last decendent of parent line +function! s:FindLastChild(line) + let l:parentindent = Ind(a:line) + let l:searchline = a:line+1 + while Ind(l:searchline) > l:parentindent + let l:searchline += 1 + endwhile + return l:searchline-1 +endfunction +"}}}2 +" MoveHead() {{{2 +" Move the heading one heading down +function! s:MoveHead(line) + let l:fstart = foldclosed(a:line) + if l:fstart == -1 + let l:execstr = a:line + else + let l:execstr = l:fstart . "," . foldclosedend(a:line) + endif + exec l:execstr . "del x" + + let l:fstart = foldclosed(a:line) + if l:fstart == -1 + let l:execstr = a:line + else + let l:execstr = foldclosedend(a:line) + endif + exec l:execstr . "put x" +endfunction +"}}}2 +" NextHead(line) {{{2 +" Return line of next heanding +" Used for sorts and reordering of headings +function! s:NextHead(line) + let l:fend = foldclosedend(a:line) + if l:fend == -1 + return a:line+1 + endif + return l:fend+1 +endfunction +"}}}2 +" GetHeadContent(line) {{{2 +" get the line contents, removing checkboxes, percent if necesssary +let g:reCheckBox = "\\[\[^]\]*\\]" +let g:reCheckBoxContent = "\\[\[^]\]*\\] \\%(\\d*% \\)\\?\\(.*\\)" +let g:reLineContent = "\\s*\\(.*\\)" +function! s:GetHeadContent(line) + let l:content = getline(a:line) + if match(l:content,g:reCheckBox) != -1 + return matchlist(l:content,g:reCheckBoxContent)[1] + endif + return matchlist(l:content,g:reLineContent)[1] +endfunction +"}}}2 +" CompHead(line) {{{2 +" Compare this heading and the next +" Return 1: next is greater, 0 next is same, -1 next is less +function! s:CompHead(line,nexthead) + " no more headers in this range, nothing to do + if (a:line <= 0) || (a:nexthead <= 0) + return 0 + endif + let l:thisline=s:GetHeadContent(a:line) + let l:nextline=s:GetHeadContent(a:nexthead) + if l:thisline <# l:nextline + return -1 + elseif l:thisline ># l:nextline + return 1 + else + return 0 + endif +endfunction +"}}}2 +" Sort1Line(line) {{{2 +" Compare this heading and the next and swap if out of order +" Dir is 1 for forward, -1 for reverse +" Return a 1 if a change was made +function! s:Sort1Line(line,dir,max) + let l:nexthead = s:NextHead(a:line) + if (l:nexthead > a:max) + return 0 + endif + let l:comphead = s:CompHead(a:line,l:nexthead) + if (l:comphead == 0) + return 0 + endif + if (l:comphead == a:dir) + call s:MoveHead(a:line) + return 1 + endif + return 0 +endfunction +"}}}2 +" Sort1Pass(start,end,dir) {{{2 +" Compare this heading and the next and swap if out of order +" Dir is 1 for forward, -1 for reverse +" Return the change count +function! s:Sort1Pass(fstart,fend,dir) + let l:i = a:fstart + let l:changed = 0 + while l:i < a:fend + let l:changed += s:Sort1Line(l:i,a:dir,a:fend) + let l:i = s:NextHead(l:i) + endwhile + return l:changed +endfunction +"}}}2 +" SortRange(start,end,dir) {{{2 +" Sort this range of headings +" dir: 0 = ascending, 1 = decending +function! s:SortRange(fstart,fend,dir) + let l:changed = 1 + while l:changed != 0 + let l:changed = s:Sort1Pass(a:fstart,a:fend,a:dir) + endwhile +endfunction +"}}}2 +" SortChildren(dir) {{{2 +" Sort the children of a parent +" dir: 0 = ascending, 1 = decending +function! SortChildren(dir) + let l:oldcursor = line(".") + let l:fstart = s:FindParent(line(".")) + let l:fend = s:FindLastChild(l:fstart) + let l:fstart = l:fstart + if l:fend <= l:fstart + 1 + return + endif + call append(line("$"),"Temporary last line for sorting") + mkview + exec "set foldlevel=" . foldlevel(l:fstart) + call s:SortRange(l:fstart + 1,l:fend,a:dir) + call cursor(line("$"),0) + del x + loadview + call cursor(l:oldcursor,0) +endfunction +"}}}2 +"}}}1 +" Key Mappings {{{1 +" sort a list naturally +map s :call SortChildren(1) +" sort a list, but you supply the options +map S :call SortChildren(-1) +"}}}1 +" vim:set fdm=marker: diff --git a/vimoutliner/plugin/vo_sort.vim.withdebug b/vimoutliner/plugin/vo_sort.vim.withdebug new file mode 100644 index 0000000..4550da2 --- /dev/null +++ b/vimoutliner/plugin/vo_sort.vim.withdebug @@ -0,0 +1,210 @@ +" VimOutliner {{{1 +"######################################################################### +"# ftplugin/vo_sort.vim: VimOutliner sort plugin +"# +"# extracted from core vimoutliner to ease leveraging, optionnality +"# visibility aso... +"# +"# Copyright (C) 2001,2003 by Steve Litt (slitt@troubleshooters.com) +"# Copyright (C) 2004 by Noel Henson (noel@noels-lab.com) +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"# +"# You should have received a copy of the GNU General Public License +"# along with this program; if not, write to the Free Software +"# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +"# +"# Steve Litt, slitt@troubleshooters.com, http://www.troubleshooters.com +"######################################################################### +"}}}1 +" Functions {{{1 +" IsParent(line) {{{2 +" Return 1 if this line is a parent +function! s:IsParent(line) + return (Ind(a:line)+1) == Ind(a:line+1) +endfunction +"}}}2 +" FindParent(line) {{{2 +" Return line if parent, parent line if not +function! s:FindParent(line) + let l:parentindent = Ind(a:line)-1 + let l:searchline = a:line + while (Ind(l:searchline) != l:parentindent) && (l:searchline > 0) + let l:searchline -= 1 + endwhile + return l:searchline +endfunction +"}}}2 +" FindLastChild(line) {{{2 +" Return the line number of the last decendent of parent line +function! s:FindLastChild(line) + let l:parentindent = Ind(a:line) + let l:searchline = a:line+1 + while Ind(l:searchline) > l:parentindent + let l:searchline += 1 + endwhile + return l:searchline-1 +endfunction +"}}}2 +" MoveHead() {{{2 +" Move the heading one heading down +function! s:MoveHead(line) + let l:fstart = foldclosed(a:line) + if l:fstart == -1 + let l:execstr = a:line + else + let l:execstr = l:fstart . "," . foldclosedend(a:line) + endif + exec l:execstr . "del x" + + let l:fstart = foldclosed(a:line) + if l:fstart == -1 + let l:execstr = a:line + else + let l:execstr = foldclosedend(a:line) + endif + exec l:execstr . "put x" +endfunction +"}}}2 +" NextHead(line) {{{2 +" Return line of next heanding +" Used for sorts and reordering of headings +function! s:NextHead(line) + echomsg " XXX Next for ".a:line + let l:fend = foldclosedend(a:line) + if l:fend == -1 + echomsg " XXX Next is (line)".(a:line+1) + return a:line+1 + endif + echomsg " XXX Next is (fold)".(l:fend+1) + return l:fend+1 +endfunction +"}}}2 +" GetHeadContent(line) {{{2 +" get the line contents, removing checkboxes, percent if necesssary +let g:reCheckBox = "\\[\[^]\]*\\]" +let g:reCheckBoxContent = "\\[\[^]\]*\\] \\%(\\d*% \\)\\?\\(.*\\)" +let g:reLineContent = "\\s*\\(.*\\)" +function! s:GetHeadContent(line) + let l:content = getline(a:line) + if match(l:content,g:reCheckBox) != -1 + return matchlist(l:content,g:reCheckBoxContent)[1] + endif + return matchlist(l:content,g:reLineContent)[1] +endfunction +"}}}2 +" CompHead(line) {{{2 +" Compare this heading and the next +" Return 1: next is greater, 0 next is same, -1 next is less +function! s:CompHead(line,nexthead) + " no more headers in this range, nothing to do + echomsg "XXX ??? '".a:line."' / '".a:nexthead."'" + if (a:line <= 0) || (a:nexthead <= 0) + return 0 + endif + let l:thisline=s:GetHeadContent(a:line) + let l:nextline=s:GetHeadContent(a:nexthead) + echomsg "XXX --- ".a:line ." : ".l:thisline + echomsg "XXX +++ ".a:nexthead." : ".l:nextline + if l:thisline <# l:nextline + echomsg "XXX === -1" + return -1 + elseif l:thisline ># l:nextline + echomsg "XXX === 1" + return 1 + else + echomsg "XXX === 0" + return 0 + endif +endfunction +"}}}2 +" Sort1Line(line) {{{2 +" Compare this heading and the next and swap if out of order +" Dir is 1 for forward, -1 for reverse +" Return a 1 if a change was made +function! s:Sort1Line(line,dir,max) + echomsg "XXX Sort1Line -1" + let l:nexthead = s:NextHead(a:line) + if (l:nexthead > a:max) + return 0 + endif + echomsg "XXX Sort1Line 0" + let l:comphead = s:CompHead(a:line,l:nexthead) + if (l:comphead == 0) + return 0 + endif + echomsg "XXX Sort1Line 1" + if (l:comphead == a:dir) + call s:MoveHead(a:line) + return 1 + endif + return 0 +endfunction +"}}}2 +" Sort1Pass(start,end,dir) {{{2 +" Compare this heading and the next and swap if out of order +" Dir is 1 for forward, -1 for reverse +" Return the change count +function! s:Sort1Pass(fstart,fend,dir) + echomsg "XXX Sort1Pass 0" + let l:i = a:fstart + let l:changed = 0 + while l:i < a:fend + echomsg "XXX Sort1Pass 1 : ".l:i."/".a:fend + let l:changed += s:Sort1Line(l:i,a:dir,a:fend) + let l:i = s:NextHead(l:i) + endwhile + return l:changed +endfunction +"}}}2 +" SortRange(start,end,dir) {{{2 +" Sort this range of headings +" dir: 0 = ascending, 1 = decending +function! s:SortRange(fstart,fend,dir) + echomsg "XXX SortRange 0" + let l:changed = 1 + while l:changed != 0 + echomsg "XXX SortRange 1 : ".l:changed + let l:changed = s:Sort1Pass(a:fstart,a:fend,a:dir) + endwhile +endfunction +"}}}2 +" SortChildren(dir) {{{2 +" Sort the children of a parent +" dir: 0 = ascending, 1 = decending +function! SortChildren(dir) + echomsg "XXX SortChildren 0" + let l:oldcursor = line(".") + let l:fstart = s:FindParent(line(".")) + let l:fend = s:FindLastChild(l:fstart) + let l:fstart = l:fstart + if l:fend <= l:fstart + 1 + return + endif + call append(line("$"),"Temporary last line for sorting") + mkview + exec "set foldlevel=" . foldlevel(l:fstart) + call s:SortRange(l:fstart + 1,l:fend,a:dir) + call cursor(line("$"),0) + del x + loadview + call cursor(l:oldcursor,0) + echomsg "XXX SortChildren 1" +endfunction +"}}}2 +"}}}1 +" Key Mappings {{{1 +" sort a list naturally +map s :call SortChildren(1) +" sort a list, but you supply the options +map S :call SortChildren(-1) +"}}}1 +" vim:set fdm=marker: