"])
endif
else
call extend(s:lines, ["
"])
endif
exe s:orgwin .. "wincmd w"
" caches of style data
" initialize to include line numbers if using them
if s:settings.number_lines
let s:stylelist = { s:LINENR_ID : ".LineNr { " .. s:CSS1( s:LINENR_ID ) .. "}" }
else
let s:stylelist = {}
endif
let s:diffstylelist = {
\ s:DIFF_A_ID : ".DiffAdd { " .. s:CSS1( s:DIFF_A_ID ) .. "}",
\ s:DIFF_C_ID : ".DiffChange { " .. s:CSS1( s:DIFF_C_ID ) .. "}",
\ s:DIFF_D_ID : ".DiffDelete { " .. s:CSS1( s:DIFF_D_ID ) .. "}",
\ s:DIFF_T_ID : ".DiffText { " .. s:CSS1( s:DIFF_T_ID ) .. "}"
\ }
" set up progress bar in the status line
if !s:settings.no_progress
" ProgressBar Indicator
let s:progressbar={}
" Progressbar specific functions
func! s:SetProgbarColor()
if hlID("TOhtmlProgress") != 0
hi! link TOhtmlProgress_auto TOhtmlProgress
elseif hlID("TOhtmlProgress_auto")==0 ||
\ !exists("s:last_colors_name") || !exists("g:colors_name") ||
\ g:colors_name != s:last_colors_name
let s:last_colors_name = exists("g:colors_name") ? g:colors_name : "none"
let l:diffatr = synIDattr(hlID("DiffDelete")->synIDtrans(), "reverse", s:whatterm) ? "fg#" : "bg#"
let l:stlatr = synIDattr(hlID("StatusLine")->synIDtrans(), "reverse", s:whatterm) ? "fg#" : "bg#"
let l:progbar_color = synIDattr(hlID("DiffDelete")->synIDtrans(), l:diffatr, s:whatterm)
let l:stl_color = synIDattr(hlID("StatusLine")->synIDtrans(), l:stlatr, s:whatterm)
if "" == l:progbar_color
let l:progbar_color = synIDattr(hlID("DiffDelete")->synIDtrans(), "reverse", s:whatterm) ? s:fgc : s:bgc
endif
if "" == l:stl_color
let l:stl_color = synIDattr(hlID("StatusLine")->synIDtrans(), "reverse", s:whatterm) ? s:fgc : s:bgc
endif
if l:progbar_color == l:stl_color
if s:whatterm == 'cterm'
if l:progbar_color >= (&t_Co/2)
let l:progbar_color-=1
else
let l:progbar_color+=1
endif
else
let l:rgb = map(matchlist(l:progbar_color, '#\zs\x\x\ze\(\x\x\)\(\x\x\)')[:2], 'str2nr(v:val, 16)')
let l:avg = (l:rgb[0] + l:rgb[1] + l:rgb[2])/3
if l:avg >= 128
let l:avg_new = l:avg
while l:avg - l:avg_new < 0x15
let l:rgb = map(l:rgb, 'v:val * 3 / 4')
let l:avg_new = (l:rgb[0] + l:rgb[1] + l:rgb[2])/3
endwhile
else
let l:avg_new = l:avg
while l:avg_new - l:avg < 0x15
let l:rgb = map(l:rgb, 'min([max([v:val, 4]) * 5 / 4, 255])')
let l:avg_new = (l:rgb[0] + l:rgb[1] + l:rgb[2])/3
endwhile
endif
let l:progbar_color = printf("#%02x%02x%02x", l:rgb[0], l:rgb[1], l:rgb[2])
endif
echomsg "diff detected progbar color set to" l:progbar_color
endif
exe "hi TOhtmlProgress_auto" s:whatterm.."bg="..l:progbar_color
endif
endfun
func! s:ProgressBar(title, max_value, winnr)
let pgb=copy(s:progressbar)
let pgb.title = a:title..' '
let pgb.max_value = a:max_value
let pgb.winnr = a:winnr
let pgb.cur_value = 0
let pgb.items = { 'title' : { 'color' : 'Statusline' },
\'bar' : { 'color' : 'Statusline' , 'fillcolor' : 'TOhtmlProgress_auto' , 'bg' : 'Statusline' } ,
\'counter' : { 'color' : 'Statusline' } }
let pgb.last_value = 0
let pgb.needs_redraw = 0
" Note that you must use len(split) instead of len() if you want to use
" unicode in title.
"
" Subtract 3 for spacing around the title.
" Subtract 4 for the percentage display.
" Subtract 2 for spacing before this.
" Subtract 2 more for the '|' on either side of the progress bar
let pgb.subtractedlen=len(split(pgb.title, '\zs'))+3+4+2+2
let pgb.max_len = 0
set laststatus=2
return pgb
endfun
" Function: progressbar.calculate_ticks() {{{1
func! s:progressbar.calculate_ticks(pb_len)
if a:pb_len<=0
let pb_len = 100
else
let pb_len = a:pb_len
endif
let self.progress_ticks = map(range(pb_len+1), "v:val * self.max_value / pb_len")
endfun
"Function: progressbar.paint()
func! s:progressbar.paint()
" Recalculate widths.
let max_len = winwidth(self.winnr)
let pb_len = 0
" always true on first call because of initial value of self.max_len
if max_len != self.max_len
let self.max_len = max_len
" Progressbar length
let pb_len = max_len - self.subtractedlen
call self.calculate_ticks(pb_len)
let self.needs_redraw = 1
let cur_value = 0
let self.pb_len = pb_len
else
" start searching at the last found index to make the search for the
" appropriate tick value normally take 0 or 1 comparisons
let cur_value = self.last_value
let pb_len = self.pb_len
endif
let cur_val_max = pb_len > 0 ? pb_len : 100
" find the current progress bar position based on precalculated thresholds
while cur_value < cur_val_max && self.cur_value > self.progress_ticks[cur_value]
let cur_value += 1
endwhile
" update progress bar
if self.last_value != cur_value || self.needs_redraw || self.cur_value == self.max_value
let self.needs_redraw = 1
let self.last_value = cur_value
let t_color = self.items.title.color
let b_fcolor = self.items.bar.fillcolor
let b_color = self.items.bar.color
let c_color = self.items.counter.color
let stl = "%#".t_color."#%-( ".self.title." %)".
\"%#".b_color."#".
\(pb_len>0 ?
\ ('|%#'.b_fcolor."#%-(".repeat(" ",cur_value)."%)".
\ '%#'.b_color."#".repeat(" ",pb_len-cur_value)."|"):
\ ('')).
\"%=%#".c_color."#%( ".printf("%3.d ",100*self.cur_value/self.max_value)."%% %)"
call setwinvar(self.winnr, '&stl', stl)
endif
endfun
func! s:progressbar.incr( ... )
let self.cur_value += (a:0 ? a:1 : 1)
" if we were making a general-purpose progress bar, we'd need to limit to a
" lower limit as well, but since we always increment with a positive value
" in this script, we only need limit the upper value
let self.cur_value = (self.cur_value > self.max_value ? self.max_value : self.cur_value)
call self.paint()
endfun
" }}}
if s:settings.dynamic_folds
" to process folds we make two passes through each line
let s:pgb = s:ProgressBar("Processing folds:", line('$')*2, s:orgwin)
endif
call s:SetProgbarColor()
endif
let s:build_fun_lines = []
call add(s:build_fun_lines, [])
let s:build_fun_lines[-1] =<< trim ENDLET
func! s:Add_diff_fill(lnum)
let l:filler = diff_filler(a:lnum)
if l:filler > 0
let l:to_insert = l:filler
while l:to_insert > 0
let l:new = repeat(s:difffillchar, 3)
if l:to_insert > 2 && l:to_insert < l:filler && !s:settings.whole_filler
let l:new = l:new .. " " .. l:filler .. " inserted lines "
let l:to_insert = 2
endif
ENDLET
call add(s:build_fun_lines, [])
if !s:settings.no_pre
let s:build_fun_lines[-1] =<< trim ENDLET
" HTML line wrapping is off--go ahead and fill to the margin
" TODO: what about when CSS wrapping is turned on?
let l:new = l:new .. repeat(s:difffillchar, &columns - strlen(l:new) - s:margin)
ENDLET
else
let s:build_fun_lines[-1] =<< trim ENDLET
let l:new = l:new .. repeat(s:difffillchar, 3)
ENDLET
endif
call add(s:build_fun_lines, [])
let s:build_fun_lines[-1] =<< trim ENDLET
let l:new = s:HtmlFormat_d(l:new, s:DIFF_D_ID, 0)
ENDLET
if s:settings.number_lines
call add(s:build_fun_lines, [])
let s:build_fun_lines[-1] =<< trim ENDLET
" Indent if line numbering is on. Indent gets style of line number
" column.
let l:new = s:HtmlFormat_n(repeat(' ', s:margin), s:LINENR_ID, 0, 0) .. l:new
ENDLET
endif
if s:settings.dynamic_folds && !s:settings.no_foldcolumn
call add(s:build_fun_lines, [])
let s:build_fun_lines[-1] =<< trim ENDLET
if s:foldcolumn > 0
" Indent for foldcolumn if there is one. Assume it's empty, there should
" not be a fold for deleted lines in diff mode.
let l:new = s:FoldColumn_fill() .. l:new
endif
ENDLET
endif
" Ignore this comment, just bypassing a highlighting issue: if
call add(s:build_fun_lines, [])
let s:build_fun_lines[-1] =<< trim ENDLET
call add(s:lines, l:new..s:HtmlEndline)
let l:to_insert = l:to_insert - 1
endwhile
endif
endfun
ENDLET
exec join(flatten(s:build_fun_lines), "\n")
" First do some preprocessing for dynamic folding. Do this for the entire file
" so we don't accidentally start within a closed fold or something.
let s:allfolds = []
if s:settings.dynamic_folds
let s:lnum = 1
let s:end = line('$')
" save the fold text and set it to the default so we can find fold levels
let s:foldtext_save = &foldtext
setlocal foldtext&
" we will set the foldcolumn in the html to the greater of the maximum fold
" level and the current foldcolumn setting
let s:foldcolumn = &foldcolumn
" get all info needed to describe currently closed folds
while s:lnum <= s:end
if foldclosed(s:lnum) == s:lnum
" default fold text has '+-' and then a number of dashes equal to fold
" level, so subtract 2 from index of first non-dash after the dashes
" in order to get the fold level of the current fold
let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2
" store fold info for later use
let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"}
call add(s:allfolds, s:newfold)
" open the fold so we can find any contained folds
execute s:lnum.."foldopen"
else
if !s:settings.no_progress
call s:pgb.incr()
if s:pgb.needs_redraw
redrawstatus
let s:pgb.needs_redraw = 0
endif
endif
let s:lnum = s:lnum + 1
endif
endwhile
" close all folds to get info for originally open folds
silent! %foldclose!
let s:lnum = 1
" the originally open folds will be all folds we encounter that aren't
" already in the list of closed folds
while s:lnum <= s:end
if foldclosed(s:lnum) == s:lnum
" default fold text has '+-' and then a number of dashes equal to fold
" level, so subtract 2 from index of first non-dash after the dashes
" in order to get the fold level of the current fold
let s:level = match(foldtextresult(s:lnum), '+-*\zs[^-]') - 2
let s:newfold = {'firstline': s:lnum, 'lastline': foldclosedend(s:lnum), 'level': s:level,'type': "closed-fold"}
" only add the fold if we don't already have it
if empty(s:allfolds) || index(s:allfolds, s:newfold) == -1
let s:newfold.type = "open-fold"
call add(s:allfolds, s:newfold)
endif
" open the fold so we can find any contained folds
execute s:lnum.."foldopen"
else
if !s:settings.no_progress
call s:pgb.incr()
if s:pgb.needs_redraw
redrawstatus
let s:pgb.needs_redraw = 0
endif
endif
let s:lnum = s:lnum + 1
endif
endwhile
" sort the folds so that we only ever need to look at the first item in the
" list of folds
call sort(s:allfolds, "s:FoldCompare")
let &l:foldtext = s:foldtext_save
unlet s:foldtext_save
" close all folds again so we can get the fold text as we go
silent! %foldclose!
" Go through and remove folds we don't need to (or cannot) process in the
" current conversion range
"
" If a fold is removed which contains other folds, which are included, we need
" to adjust the level of the included folds as used by the conversion logic
" (avoiding special cases is good)
"
" Note any time we remove a fold, either all of the included folds are in it,
" or none of them, because we only remove a fold if neither its start nor its
" end are within the conversion range.
let leveladjust = 0
for afold in s:allfolds
let removed = 0
if exists("g:html_start_line") && exists("g:html_end_line")
if afold.firstline < g:html_start_line
if afold.lastline <= g:html_end_line && afold.lastline >= g:html_start_line
" if a fold starts before the range to convert but stops within the
" range, we need to include it. Make it start on the first converted
" line.
let afold.firstline = g:html_start_line
else
" if the fold lies outside the range or the start and stop enclose
" the entire range, don't bother parsing it
call remove(s:allfolds, index(s:allfolds, afold))
let removed = 1
if afold.lastline > g:html_end_line
let leveladjust += 1
endif
endif
elseif afold.firstline > g:html_end_line
" If the entire fold lies outside the range we need to remove it.
call remove(s:allfolds, index(s:allfolds, afold))
let removed = 1
endif
elseif exists("g:html_start_line")
if afold.firstline < g:html_start_line
" if there is no last line, but there is a first line, the end of the
" fold will always lie within the region of interest, so keep it
let afold.firstline = g:html_start_line
endif
elseif exists("g:html_end_line")
" if there is no first line we default to the first line in the buffer so
" the fold start will always be included if the fold itself is included.
" If however the entire fold lies outside the range we need to remove it.
if afold.firstline > g:html_end_line
call remove(s:allfolds, index(s:allfolds, afold))
let removed = 1
endif
endif
if !removed
let afold.level -= leveladjust
if afold.level+1 > s:foldcolumn
let s:foldcolumn = afold.level+1
endif
endif
endfor
" if we've removed folds containing the conversion range from processing,
" getting foldtext as we go won't know to open the removed folds, so the
" foldtext would be wrong; open them now.
"
" Note that only when a start and an end line is specified will a fold
" containing the current range ever be removed.
while leveladjust > 0
exe g:html_start_line.."foldopen"
let leveladjust -= 1
endwhile
endif
" Now loop over all lines in the original text to convert to html.
" Use html_start_line and html_end_line if they are set.
if exists("g:html_start_line")
let s:lnum = html_start_line
if s:lnum < 1 || s:lnum > line("$")
let s:lnum = 1
endif
else
let s:lnum = 1
endif
if exists("g:html_end_line")
let s:end = html_end_line
if s:end < s:lnum || s:end > line("$")
let s:end = line("$")
endif
else
let s:end = line("$")
endif
" stack to keep track of all the folds containing the current line
let s:foldstack = []
if !s:settings.no_progress
let s:pgb = s:ProgressBar("Processing lines:", s:end - s:lnum + 1, s:orgwin)
endif
if s:settings.number_lines
let s:margin = strlen(s:end) + 1
else
let s:margin = 0
endif
if has('folding') && !s:settings.ignore_folding
let s:foldfillchar = &fillchars[matchend(&fillchars, 'fold:')]
if s:foldfillchar == ''
let s:foldfillchar = '-'
endif
endif
let s:difffillchar = &fillchars[matchend(&fillchars, 'diff:')]
if s:difffillchar == ''
let s:difffillchar = '-'
endif
let s:foldId = 0
if !s:settings.expand_tabs
" If keeping tabs, add them to printable characters so we keep them when
" formatting text (strtrans() doesn't replace printable chars)
let s:old_isprint = &isprint
setlocal isprint+=9
endif
while s:lnum <= s:end
" If there are filler lines for diff mode, show these above the line.
call s:Add_diff_fill(s:lnum)
" Start the line with the line number.
if s:settings.number_lines
let s:numcol = repeat(' ', s:margin - 1 - strlen(s:lnum)) .. s:lnum .. ' '
endif
let s:new = ""
if has('folding') && !s:settings.ignore_folding && foldclosed(s:lnum) > -1 && !s:settings.dynamic_folds
"
" This is the beginning of a folded block (with no dynamic folding)
let s:new = foldtextresult(s:lnum)
if !s:settings.no_pre
" HTML line wrapping is off--go ahead and fill to the margin
let s:new = s:new .. repeat(s:foldfillchar, &columns - strlen(s:new))
endif
" put numcol in a separate group for sake of unselectable text
let s:new = (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0, s:lnum): "") .. s:HtmlFormat_t(s:new, s:FOLDED_ID, 0)
" Skip to the end of the fold
let s:new_lnum = foldclosedend(s:lnum)
if !s:settings.no_progress
call s:pgb.incr(s:new_lnum - s:lnum)
endif
let s:lnum = s:new_lnum
else
"
" A line that is not folded, or doing dynamic folding.
"
let s:line = getline(s:lnum)
let s:len = strlen(s:line)
if s:settings.dynamic_folds
" First insert a closing for any open folds that end on this line
while !empty(s:foldstack) && get(s:foldstack,0).lastline == s:lnum-1
let s:new = s:new..""
call remove(s:foldstack, 0)
endwhile
" Now insert an opening for any new folds that start on this line
let s:firstfold = 1
while !empty(s:allfolds) && get(s:allfolds,0).firstline == s:lnum
let s:foldId = s:foldId + 1
let s:new ..= ""
" Unless disabled, add a fold column for the opening line of a fold.
"
" Note that dynamic folds require using css so we just use css to take
" care of the leading spaces rather than using in the case of
" html_no_pre to make it easier
if !s:settings.no_foldcolumn
" add fold column that can open the new fold
if s:allfolds[0].level > 1 && s:firstfold
let s:new = s:new .. s:FoldColumn_build('|', s:allfolds[0].level - 1, 0, "",
\ 'toggle-open FoldColumn','javascript:toggleFold("fold'..s:foldstack[0].id..s:settings.id_suffix..'");')
endif
" add the filler spaces separately from the '+' char so that it can be
" shown/hidden separately during a hover unfold
let s:new = s:new .. s:FoldColumn_build("+", 1, 0, "",
\ 'toggle-open FoldColumn', 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
" If this is not the last fold we're opening on this line, we need
" to keep the filler spaces hidden if the fold is opened by mouse
" hover. If it is the last fold to open in the line, we shouldn't hide
" them, so don't apply the toggle-filler class.
let s:new = s:new .. s:FoldColumn_build(" ", 1, s:foldcolumn - s:allfolds[0].level - 1, "",
\ 'toggle-open FoldColumn'.. (get(s:allfolds, 1, {'firstline': 0}).firstline == s:lnum ?" toggle-filler" :""),
\ 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
" add fold column that can close the new fold
" only add extra blank space if we aren't opening another fold on the
" same line
if get(s:allfolds, 1, {'firstline': 0}).firstline != s:lnum
let s:extra_space = s:foldcolumn - s:allfolds[0].level
else
let s:extra_space = 0
endif
if s:firstfold
" the first fold in a line has '|' characters from folds opened in
" previous lines, before the '-' for this fold
let s:new ..= s:FoldColumn_build('|', s:allfolds[0].level - 1, s:extra_space, '-',
\ 'toggle-closed FoldColumn', 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
else
" any subsequent folds in the line only add a single '-'
let s:new = s:new .. s:FoldColumn_build("-", 1, s:extra_space, "",
\ 'toggle-closed FoldColumn', 'javascript:toggleFold("fold'..s:foldId..s:settings.id_suffix..'");')
endif
let s:firstfold = 0
endif
" Add fold text, moving the span ending to the next line so collapsing
" of folds works correctly.
" Put numcol in a separate group for sake of unselectable text.
let s:new = s:new .. (s:settings.number_lines ? s:HtmlFormat_n(s:numcol, s:FOLDED_ID, 0, 0) : "") .. substitute(s:HtmlFormat_t(foldtextresult(s:lnum), s:FOLDED_ID, 0), '', s:HtmlEndline..'\n\0', '')
let s:new = s:new .. ""
" open the fold now that we have the fold text to allow retrieval of
" fold text for subsequent folds
execute s:lnum.."foldopen"
call insert(s:foldstack, remove(s:allfolds,0))
let s:foldstack[0].id = s:foldId
endwhile
" Unless disabled, add a fold column for other lines.
"
" Note that dynamic folds require using css so we just use css to take
" care of the leading spaces rather than using in the case of
" html_no_pre to make it easier
if !s:settings.no_foldcolumn
if empty(s:foldstack)
" add the empty foldcolumn for unfolded lines if there is a fold
" column at all
if s:foldcolumn > 0
let s:new = s:new .. s:FoldColumn_fill()
endif
else
" add the fold column for folds not on the opening line
if get(s:foldstack, 0).firstline < s:lnum
let s:new = s:new .. s:FoldColumn_build('|', s:foldstack[0].level, s:foldcolumn - s:foldstack[0].level, "",
\ 'FoldColumn', 'javascript:toggleFold("fold'..s:foldstack[0].id..s:settings.id_suffix..'");')
endif
endif
endif
endif
" Now continue with the unfolded line text
if s:settings.number_lines
let s:new = s:new .. s:HtmlFormat_n(s:numcol, s:LINENR_ID, 0, s:lnum)
elseif s:settings.line_ids
let s:new = s:new .. s:HtmlFormat_n("", s:LINENR_ID, 0, s:lnum)
endif
" Get the diff attribute, if any.
let s:diffattr = diff_hlID(s:lnum, 1)
" initialize conceal info to act like not concealed, just in case
let s:concealinfo = [0, '']
" Loop over each character in the line
let s:col = 1
" most of the time we won't use the diff_id, initialize to zero
let s:diff_id = 0
while s:col <= s:len || (s:col == 1 && s:diffattr)
let s:startcol = s:col " The start column for processing text
if !s:settings.ignore_conceal && has('conceal')
let s:concealinfo = synconcealed(s:lnum, s:col)
endif
if !s:settings.ignore_conceal && s:concealinfo[0]
let s:col = s:col + 1
" Speed loop (it's small - that's the trick)
" Go along till we find a change in the match sequence number (ending
" the specific concealed region) or until there are no more concealed
" characters.
while s:col <= s:len && s:concealinfo == synconcealed(s:lnum, s:col) | let s:col = s:col + 1 | endwhile
elseif s:diffattr
let s:diff_id = diff_hlID(s:lnum, s:col)
let s:id = synID(s:lnum, s:col, 1)
let s:col = s:col + 1
" Speed loop (it's small - that's the trick)
" Go along till we find a change in hlID
while s:col <= s:len && s:id == synID(s:lnum, s:col, 1)
\ && s:diff_id == diff_hlID(s:lnum, s:col) |
\ let s:col = s:col + 1 |
\ endwhile
if s:len < &columns && !s:settings.no_pre
" Add spaces at the end of the raw text line to extend the changed
" line to the full width.
let s:line = s:line .. repeat(' ', &columns - virtcol([s:lnum, s:len]) - s:margin)
let s:len = &columns
endif
else
let s:id = synID(s:lnum, s:col, 1)
let s:col = s:col + 1
" Speed loop (it's small - that's the trick)
" Go along till we find a change in synID
while s:col <= s:len && s:id == synID(s:lnum, s:col, 1) | let s:col = s:col + 1 | endwhile
endif
if s:settings.ignore_conceal || !s:concealinfo[0]
" Expand tabs if needed
let s:expandedtab = strpart(s:line, s:startcol - 1, s:col - s:startcol)
if s:settings.expand_tabs
let s:offset = 0
let s:idx = stridx(s:expandedtab, "\t")
let s:tablist = split(&vts,',')
if empty(s:tablist)
let s:tablist = [ &ts ]
endif
let s:tabidx = 0
let s:tabwidth = 0
while s:idx >= 0
if s:startcol + s:idx == 1
let s:i = s:tablist[0]
else
" Get the character, which could be multiple bytes, which falls
" immediately before the found tab. Extract it by matching a
" character just prior to the column where the tab matches.
" We'll use this to get the byte index of the character
" immediately preceding the tab, so we can then look up the
" virtual column that character appears in, to determine how
" much of the current tabstop has been used up.
if s:idx == 0
" if the found tab is the first character in the text being
" processed, we need to get the character prior to the text,
" given by startcol.
let s:prevc = matchstr(s:line, '.\%' .. (s:startcol + s:offset) .. 'c')
else
" Otherwise, the byte index of the tab into s:expandedtab is
" given by s:idx.
let s:prevc = matchstr(s:expandedtab, '.\%' .. (s:idx + 1) .. 'c')
endif
let s:vcol = virtcol([s:lnum, s:startcol + s:idx + s:offset - len(s:prevc)])
" find the tabstop interval to use for the tab we just found. Keep
" adding tabstops (which could be variable) until we would exceed
" the virtual screen position of the start of the found tab.
while s:vcol >= s:tabwidth + s:tablist[s:tabidx]
let s:tabwidth += s:tablist[s:tabidx]
if s:tabidx < len(s:tablist)-1
let s:tabidx = s:tabidx+1
endif
endwhile
let s:i = s:tablist[s:tabidx] - (s:vcol - s:tabwidth)
endif
" update offset to keep the index within the line corresponding to
" actual tab characters instead of replaced spaces; s:idx reflects
" replaced spaces in s:expandedtab, s:offset cancels out all but
" the tab character itself.
let s:offset -= s:i - 1
let s:expandedtab = substitute(s:expandedtab, '\t', repeat(' ', s:i), '')
let s:idx = stridx(s:expandedtab, "\t")
endwhile
end
" get the highlight group name to use
let s:id = synIDtrans(s:id)
else
" use Conceal highlighting for concealed text
let s:id = s:CONCEAL_ID
let s:expandedtab = s:concealinfo[1]
endif
" Output the text with the same synID, with class set to the highlight ID
" name, unless it has been concealed completely.
if strlen(s:expandedtab) > 0
let s:new = s:new .. s:HtmlFormat(s:expandedtab, s:id, s:diff_id, "", 0)
endif
endwhile
endif
call extend(s:lines, split(s:new..s:HtmlEndline, '\n', 1))
if !s:settings.no_progress && s:pgb.needs_redraw
redrawstatus
let s:pgb.needs_redraw = 0
endif
let s:lnum = s:lnum + 1
if !s:settings.no_progress
call s:pgb.incr()
endif
endwhile
" Diff filler is returned based on what needs inserting *before* the given line.
" So to get diff filler at the end of the buffer, we need to use last line + 1
call s:Add_diff_fill(s:end+1)
if s:settings.dynamic_folds
" finish off any open folds
while !empty(s:foldstack)
let s:lines[-1]..=""
call remove(s:foldstack, 0)
endwhile
" add fold column to the style list if not already there
let s:id = s:FOLD_C_ID
if !has_key(s:stylelist, s:id)
let s:stylelist[s:id] = '.FoldColumn { ' .. s:CSS1(s:id) .. '}'
endif
endif
if s:settings.no_pre
if !s:settings.use_css
" Close off the font tag that encapsulates the whole
call extend(s:lines, [""])
else
call extend(s:lines, ["
"])
endif
else
call extend(s:lines, [""])
endif
if !s:settings.no_doc
call extend(s:lines, ["", ""])
endif
exe s:newwin .. "wincmd w"
call setline(1, s:lines)
unlet s:lines
" Mangle modelines so Vim doesn't try to use HTML text as a modeline if editing
" this file in the future; need to do this after generating all the text in case
" the modeline text has different highlight groups which all turn out to be
" stripped from the final output.
%s!\v(%(^|\s+)%([Vv]i%(m%([<=>]?\d+)?)?|ex)):!\1\:!ge
" The generated HTML is admittedly ugly and takes a LONG time to fold.
" Make sure the user doesn't do syntax folding when loading a generated file,
" using a modeline.
if !s:settings.no_modeline
call append(line('$'), "")
endif
" Now, when we finally know which, we define the colors and styles
if s:settings.use_css && !s:settings.no_doc
1;/