"TODO get working on visual mode "- if inside a header " goes to the nearest head before current position " returns its initial hashes (#) "- else " goes to beginning of document " returns '' fu! b:Markdown_GoCurHeader() if search( '^#', 'bcW' ) != 0 return matchstr( getline('.'), '\v^#+' ) el norm! gg ec 'outside any header' return '' en endf "same as `b:Markdown_GoCurHeader`:function: but does not change cursor position fu! b:Markdown_GetHashesCurHeader() let line = search( '\v^#', 'nW' ) != 0 retu matchstr( getline(line) '\v^#+' ) endf "goes to next header of any level "returns its hashes fu! b:Markdown_GoNextHeader() if search( '\v^#', 'W' ) != 0 return matchstr( getline('.'), '\v^#+' ) el "norm! G ec 'no more headers' return '' en endf "goes to previous header of any level " "if there is no previous header, only print a warning " "if the cursor is not exactly at the header, "it goes to exactly the header. So this could be used "if you want to go to the current header line. fu! b:Markdown_GoPreviousHeader() if search( '^#', 'bW' ) != 0 return matchstr( getline('.'), '\v^#+' ) el "norm! gg ec 'no more headers' return '' en endf "if already at top level, go to beginning of buffer fu! b:Markdown_GoHeaderUp() let l:hashes = b:Markdown_GoCurHeader() if len( l:hashes ) > 1 cal search( '^' . l:hashes[1:] . '[^#]', 'b' ) el norm! gg en endf fu! b:Markdown_GoNextHeaderSameLevel() let l:hashes = b:Markdown_GoCurHeader() "go to next occurrence of that number of hashes cal search( '^' . l:hashes . '[^#]', 'W' ) endf "if no more next siblings, print error message and do nothing. fu! b:Markdown_GoNextSiblingHeader() let l:hashes = b:Markdown_GoCurHeader() if l:hashes ==# '' retu en 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, 0 ) el ec 'no more siblings' en endf fu! b:Markdown_GoPreviousHeaderSameLevel() let l:hashes = b:Markdown_GoCurHeader() "go to next occurrence of that number of hashes cal search( '^' . l:hashes . '[^#]', 'bW' ) endf "if no more next siblings, print error message and do nothing. fu! b:Markdown_GoPreviousSiblingHeader() let l:hashes = b:Markdown_GoCurHeader() if l:hashes ==# '' retu en 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, 0 ) el ec 'no more siblings' en endf "mnemonics: ']' next (like a right arrow) nn ]] :cal b:Markdown_GoNextHeader() "vnoremap ]] /^#:nohlgv "mnemonics: '[' next (like a left arrow) nn ][ :cal b:Markdown_GoNextSiblingHeader() "vnoremap ][ :cal b:Markdown_GoNextHeaderSameLevel() nn [] :cal b:Markdown_GoPreviousSiblingHeader() nn [[ :cal b:Markdown_GoPreviousHeader() "vnoremap [[ ?^#:nohlgv "go up one level. Menmonic: Up. nn ]u :cal b:Markdown_GoHeaderUp()