playground/vimscript/md.vim

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