*summary: Markdown-Texte im vi falten *

Endlich, endlich habe ich einen Weg gefunden Markdown-Texte einfach und schnell in GVim zu falten. Ich meine damit das Zusammenklappen und Aufklappen von Texten mit verschiedenen Headline-Tag-Ebenen (#) in Markdown.

Das meint, aus so einem Beispieltext:

# Buch zu Markdown

Hier wäre dann der Fließtext. Zum Beipiel ein Vorwort.
Und hier auch noch etwas Text.

##  Inhaltsverzeichnis
Kapitel 1 ...................... 5
Kapitel 1.1 .................... 9
Kapitel 2 ...................... 5

## Kapitel 1
Fließtext zu Kapitel 1...

### Kapitel 1.1 
Fließtext zu Kapitel 1.1  ...

## Kapitel 2
Fließtext zu Kapitel 2    ...

würde dann auf erster Faltungsebene beim Zusammenfalten in etwa dieses entstehen:

 # Buch zu Markdown  ------   18 Lines [100%]  

und beim Entfalten der ersten Ebene würde wiederum Folgendes entstehen, das man weiter auffalten kann, bis wieder der gesamte Text sichtbar wird:

# Buch zu Markdown  

Hier wäre dann der Fließtext. Zum Beipiel ein Vorwort.
Und hier auch noch etwas Text.

##  Inhaltsverzeichnis    ----- 5 Lines [27,8%] +--- 
## Kapitel 1              ----- 3 Lines [16,7%] +---
## Kapitel 1.1            ----- 3 Lines [16,7%] +---
## Kapitel 2              ----- 2 Lines [11,1%] +---

Mit der Leertaste oder ´za´ - gedrückt auf der Ebene mit dem ´#´ kann man Bereiche auffalten bzw. dann wiederum mit ´za´ zusammenfalten. ´zm´ faltet alle Ebenen wieder zusammen. ´zi´ faltet alles auf bzw. zusammen.

Der folgende Quelltext sorgt für das Falten:

" Markdown Folding 
" Function from
" Source: https://stackoverflow.com/questions/44097989/vim-change-folding-markdown-to-show-lines-and-number-of-words-using-vimrc

set foldcolumn=3
set foldmethod=expr
set foldexpr=MarkdownFoldText()

    function! MarkdownFolds()
	let thisline = getline(v:lnum)
	if match(thisline, '^##') >= 0
		return ">2"
	elseif match(thisline, '^#') >= 0
		return ">1"
	else
		return "="
	endif
endfunction

setlocal foldmethod=expr
setlocal foldexpr=MarkdownFolds()

function! MarkdownFoldText()
	"get first non-blank line
	let fs = v:foldstart
	  
	while getline(fs) =~ '^\s*$' | let fs = nextnonblank(fs + 1)
	endwhile
	  
	if fs > v:foldend
		let line = getline(v:foldstart)
	else
		let line = substitute(getline(fs), '\t', repeat(' ', &tabstop), 'g')
	endif

	let w = winwidth(0) - &foldcolumn - (&number ? 8 : 0)
	let foldSize = 1 + v:foldend - v:foldstart
	let foldWords = v:foldend,v:foldstart!wc -w
	let foldSizeStr = " " . foldSize . " lines "
	let foldWordsStr = " " . foldWords . " w "
	let foldLevelStr = repeat("+--", v:foldlevel)
	let lineCount = line("$")
	let foldPercentage = printf("[%.1f", (foldSize*1.0)/lineCount*100) . "%] "
	" let expansionString = "."
	let expansionString = repeat(".", w - strwidth(foldSizeStr.line.foldLevelStr.foldPercentage))
	return line . expansionString . foldSizeStr . foldPercentage . foldLevelStr
	" return line . expansionString . foldSizeStr . foldPercentage . foldWordsStr . foldLevelStr
	" return line . "......" . foldSizeStr . foldPercentage . foldLevelStr
endfunction

setlocal foldtext=MarkdownFoldText()

Ich bin davon begeistert. So kann ich meine strukturierten Texte, die ich sehr häufig in Markdown erfasse, übersichtlich am Bildschirm darstellen lassen.

Jede zusammengefaltete Ebene läßt sich dann sogar per Copy and paste (Yank und Put) wie eine einzelne Zeile behandeln, obwohl es sich dann um den gesamten zusammengefalteten Text handelt.