"TODO print messages when on visual mode. I only see VISUAL, not the messages. "this is how you should view things: " " |BUFFER " | " |outside any header " | "a-+# a " | " |inside a " | "a-+ "b-+## b " | " |inside b " | "b-+ "c-+### c " | " |inside c " | "c-+ "d-|# d " | " |inside d " | "d-+ let s:headerExpr = '\v^#' "0 if not found fu! b:Markdown_GetLineNumCurHeader() retu search( s:headerExpr, 'bcnW' ) endf "- if inside a header goes to it " returns its hashes "- if on top level outside any headers, " print a warning " return '' fu! b:Markdown_GoCurHeaderGetHashes() let l:lineNum = b:Markdown_GetLineNumCurHeader() if l:lineNum != 0 cal cursor( l:lineNum, 1 ) retu matchstr( getline( lineNum ), '\v^#+' ) el retu '' en endf "- if inside a header goes to it " returns its line number "- if on top level outside any headers, " print a warning " return 0 fu! b:Markdown_GoCurHeader() let l:lineNum = b:Markdown_GetLineNumCurHeader() if l:lineNum != 0 cal cursor( l:lineNum, 1 ) el ec 'outside any header' "norm! gg en retu l:lineNum endf "goes to next header of any level " "if no there are no more headers print a warning fu! b:Markdown_GoNextHeader() if search( s:headerExpr, 'W' ) == 0 "norm! G ec 'no next header' en endf "goes to previous header of any level " "if it does not exist, print a warning fu! b:Markdown_GoPreviousHeader() let l:oldPos = getpos('.') let l:curHeaderLineNumber = b:Markdown_GoCurHeader() if l:curHeaderLineNumber == 0 cal setpos('.',l:oldPos) en if search( s:headerExpr, 'bW' ) == 0 "norm! gg cal setpos('.',l:oldPos) ec 'no previous header' en endf "goes to previous header of any level " "if it exists, return its lines number " "otherwise, print a warning and return 0 fu! b:Markdown_GoHeaderUp() let l:oldPos = getpos('.') let l:hashes = b:Markdown_GoCurHeaderGetHashes() if len( l:hashes ) > 1 cal search( '^' . l:hashes[1:] . '[^#]', 'b' ) el cal setpos('.',l:oldPos) ec 'already at top level' en endf "if no more next siblings, print error message and do nothing. fu! b:Markdown_GoNextSiblingHeader() let l:oldPos = getpos('.') let l:hashes = b:Markdown_GoCurHeaderGetHashes() let l:noSibling = 0 if l:hashes ==# '' let l:noSibling = 1 el let l:nhashes = len(l:hashes) if l:nhashes == 1 "special case, just add the largest possible value let l:nextLowerLevelLine = line('$') + 1 el let l:nextLowerLevelLine = search( '\v^#{1,' . ( l:nhashes - 1 ) . '}[^#]' , 'nW' ) en let l:nextSameLevelLine = search( '\v^' . l:hashes . '[^#]', 'nW' ) if ( \ l:nextSameLevelLine > 0 \ && \ ( \ l:nextLowerLevelLine == 0 \ || \ l:nextLowerLevelLine > l:nextSameLevelLine \ ) \ ) cal cursor( l:nextSameLevelLine, 1 ) el let l:noSibling = 1 en en if l:noSibling cal setpos('.',l:oldPos) ec 'no next sibling' en endf "if no more next siblings, print error message and do nothing. fu! b:Markdown_GoPreviousSiblingHeader() let l:oldPos = getpos('.') let l:hashes = b:Markdown_GoCurHeaderGetHashes() let l:noSibling = 0 if l:hashes ==# '' let l:noSibling = 1 el let l:nhashes = len(l:hashes) if l:nhashes == 1 "special case, just add the largest possible value let l:prevLowerLevelLine = -1 el let l:prevLowerLevelLine = search( '\v^#{1,' . ( l:nhashes - 1 ) . '}[^#]' , 'bnW' ) en let l:prevSameLevelLine = search( '\v^' . l:hashes . '[^#]', 'bnW' ) if ( \ l:prevSameLevelLine > 0 \ && \ ( \ l:prevLowerLevelLine == 0 \ || \ l:prevLowerLevelLine < l:prevSameLevelLine \ ) \ ) cal cursor( l:prevSameLevelLine, 1 ) el let l:noSibling = 1 en en if l:noSibling cal setpos('.',l:oldPos) ec 'no previous sibling' en endf "wrapper to do move commands in visual mode fu! s:VisMove(f) norm! gv cal function(a:f)() endf "map in both normal and visual modes fu! s:MapNormVis(rhs,lhs) exe 'nn ' . a:rhs . ' :cal ' . a:lhs . '()' exe 'vn ' . a:rhs . ' :cal VisMove(''' . a:lhs . ''')' endf cal MapNormVis( ']]', 'b:Markdown_GoNextHeader' ) cal MapNormVis( '[[', 'b:Markdown_GoPreviousHeader' ) cal MapNormVis( '][', 'b:Markdown_GoNextSiblingHeader' ) cal MapNormVis( '[]', 'b:Markdown_GoPreviousSiblingHeader' ) "menmonic: Up cal MapNormVis( ']u', 'b:Markdown_GoHeaderUp' ) "menmonic: Current cal MapNormVis( ']c', 'b:Markdown_GoCurHeader' )