207 lines
5.4 KiB
VimL
207 lines
5.4 KiB
VimL
function! PromoteHeading()
|
|
" Promote a heading to next level
|
|
let line = getline(".")
|
|
if (line =~ "^##* ") == 1
|
|
call setline(".", "#" . line)
|
|
endif
|
|
endfunction
|
|
|
|
function! DemoteHeading()
|
|
" Demote a heading to previous level
|
|
let line = getline(".")
|
|
if (line =~ "^###* ") == 1
|
|
let modedline = strcharpart(line, 1)
|
|
call setline(".", modedline)
|
|
endif
|
|
endfunction
|
|
|
|
function! PrevHeading()
|
|
" Like C-c C-p in emacs org-mode
|
|
let linenum = line(".") - 1
|
|
while linenum > 0
|
|
let line = getline(linenum)
|
|
if (line =~ "^##* ") == 1
|
|
echo linenum
|
|
call cursor(linenum, 0)
|
|
break
|
|
endif
|
|
let linenum -= 1
|
|
endwhile
|
|
endfunction
|
|
|
|
function! NextHeading()
|
|
" Like C-c C-n in emacs org-mode
|
|
let linenum = line(".") + 1
|
|
let linemax = line("$") + 1
|
|
while linenum < linemax
|
|
let line = getline(linenum)
|
|
if (line =~ "^##* ") == 1
|
|
echo linenum
|
|
call cursor(linenum, 0)
|
|
break
|
|
endif
|
|
let linenum += 1
|
|
endwhile
|
|
endfunction
|
|
|
|
function! FoldTitleContent()
|
|
py3 << EOF
|
|
from typing import Tuple
|
|
import re
|
|
|
|
def fold_subtree(lines: "vim.buffer", curlinenum: int) -> Tuple[int, int]:
|
|
"""
|
|
Accept current line number and return the line numbers corresponding
|
|
to the subtree to be folded.
|
|
|
|
Assume that indexing starts from zero for all line indices.
|
|
Including current line number and return values.
|
|
|
|
Args:
|
|
lines: a vim buffer object
|
|
curlinenum: current line number
|
|
"""
|
|
heading_re = r"^#+ "
|
|
|
|
# Find startline
|
|
startline = None
|
|
for linenum in range(curlinenum, -1, -1):
|
|
matchobj = re.match(heading_re, lines[linenum])
|
|
if matchobj:
|
|
startline = linenum + 1
|
|
hnum = len(matchobj.group(0))
|
|
break
|
|
if startline is None:
|
|
# Not part of any heading (maybe top-most part outside of all headings)
|
|
return None
|
|
|
|
# Find endline
|
|
endline = None
|
|
#for linenum, line in enumerate(lines[curlinenum+1:]):
|
|
for linenum in range(curlinenum+1, len(lines)):
|
|
matchobj = re.match(heading_re, lines[linenum])
|
|
if matchobj is not None and hnum >= len(matchobj.group(0)):
|
|
endline = linenum - 1
|
|
break
|
|
if endline is None:
|
|
# This heading is the last heading
|
|
endline = len(lines) - 1
|
|
|
|
return startline, endline
|
|
|
|
curlinenum = int(vim.eval("line('.')"))
|
|
start, end = fold_subtree(vim.current.buffer, curlinenum - 1)
|
|
start += 1
|
|
end += 1
|
|
vim.command(f"{start},{end}fo")
|
|
EOF
|
|
endfunction
|
|
|
|
"py3 << EOF
|
|
"import vim
|
|
"import re
|
|
"
|
|
"def fold_title_content():
|
|
" curbuf = vim.current.buffer
|
|
" curline = int(vim.eval("line('.')")) - 1
|
|
" startline = None
|
|
" for linenum in range(curline, -1, -1):
|
|
" line = curbuf[linenum]
|
|
" matchobj = re.match(r"^#+", line)
|
|
" if matchobj:
|
|
" startline = linenum + 1 # no need to fold the heading as well
|
|
" matchstr = matchobj.group(0)
|
|
" break
|
|
"
|
|
" if startline is not None:
|
|
" # Found startline by this point
|
|
" pattern = "^" + matchstr
|
|
" maxlinenum = len(curbuf)
|
|
" endline = None
|
|
" for linenum in range(curline+1, maxlinenum+1):
|
|
" line = curbuf[linenum]
|
|
" matchobj = re.match(pattern, line)
|
|
" if matchobj:
|
|
" endline = linenum - 1
|
|
" break
|
|
" if endline is None:
|
|
" endline = maxlinenum
|
|
"
|
|
" # Translating Python indexing to vim indexing
|
|
" startline += 1
|
|
" endline += 1
|
|
" vim.command(f"{startline},{endline}fold")
|
|
"
|
|
"fold_title_content()
|
|
"EOF
|
|
|
|
"function! FoldTitleContent()
|
|
" " Find heading section start
|
|
" let startline = -1
|
|
" let linenum = line(".")
|
|
" while linenum > 0
|
|
" let line = getline(linenum)
|
|
" if (line =~ "^##* ") == 1
|
|
" startline = linenum + 1 " got to fold next line onwards
|
|
" break
|
|
" endif
|
|
" endwhile
|
|
"
|
|
" " No heading found before current cursor position
|
|
" if startline != -1
|
|
" " get the starting of header including the space
|
|
" let heading = matchstr(line, "^##* ")
|
|
" let pattern = "^" . heading
|
|
"
|
|
" " Find heading section end
|
|
" let lastlinenum = line("$")
|
|
" let endline = -1
|
|
" linenum = line(".") + 1
|
|
" while linenum <= lastlinenum
|
|
" line = getline(linenum)
|
|
" if (line =~ pattern) == 1
|
|
" endline = linenum - 1 " got to fold till before next heading
|
|
" break
|
|
" endif
|
|
" endwhile
|
|
"
|
|
" if endline == -1
|
|
" endline = line("$")
|
|
" endif
|
|
" endif
|
|
"endfunction
|
|
"
|
|
" let astrsk_count = strchars(matchstr(line, "^##* ") - 1)
|
|
" if astrsk_count > 0
|
|
"
|
|
" endif
|
|
"
|
|
"
|
|
"function! PrevNextHeading(incr)
|
|
" let linenum = line(".") + a:incr
|
|
" while linenum > 0
|
|
" while linenum < max
|
|
" let line = getline(linenum)
|
|
" if (line =~ "^##* ") == 1
|
|
" echo linenum
|
|
" call cursor(linenum, 0)
|
|
" break
|
|
" endif
|
|
" let linenum += a:incr
|
|
" endwhile
|
|
"endfunction
|
|
|
|
"nnoremap <C-Left> :call DemoteHeading()<cr>
|
|
"nnoremap <C-Right> :call PromoteHeading()<cr>
|
|
nnoremap <Left> :call DemoteHeading()<cr>
|
|
nnoremap <Right> :call PromoteHeading()<cr>
|
|
nnoremap <Up> :call PrevHeading()<cr>
|
|
nnoremap <Down> :call NextHeading()<cr>
|
|
nnoremap <Tab> :call FoldTitleContent()<cr>
|
|
|
|
|
|
|
|
function! Co()
|
|
" 3,5fo
|
|
endfunction
|