+" Progress bar based off code from "progressbar widget" plugin by
+" Andreas Politz, heavily modified:
+" http://www.vim.org/scripts/script.php?script_id=2006
+"
+" See Mercurial change logs for more!
" Transform a file into HTML, using the current syntax highlighting.
" this file uses line continuations
let s:cpo_sav = &cpo
+let s:ls = &ls
set cpo-=C
" Number lines when explicitely requested or when `number' is set
@@ -20,43 +29,23 @@ else
let s:numblines = &number
endif
+let s:end=line('$')
+" default to using the progress bar
+if exists("g:html_no_progress")
+ let s:html_no_progress = g:html_no_progress
+else
+ let s:html_no_progress = 0
+endif
+
" Font
if exists("g:html_font")
- let s:htmlfont = html_font . ", monospace"
+ let s:htmlfont = "'". html_font . "', monospace"
else
let s:htmlfont = "monospace"
endif
-" make copies of the user-defined settings that we may overrule
-if exists("g:html_dynamic_folds")
- let s:html_dynamic_folds = 1
-endif
-if exists("g:html_hover_unfold")
- let s:html_hover_unfold = 1
-endif
-if exists("g:html_use_css")
- let s:html_use_css = 1
-endif
-
-" hover opening implies dynamic folding
-if exists("s:html_hover_unfold")
- let s:html_dynamic_folds = 1
-endif
-
-" dynamic folding with no foldcolumn implies hover opens
-if exists("s:html_dynamic_folds") && exists("g:html_no_foldcolumn")
- let s:html_hover_unfold = 1
-endif
-
-" ignore folding overrides dynamic folding
-if exists("g:html_ignore_folding") && exists("s:html_dynamic_folds")
- unlet s:html_dynamic_folds
-endif
-
-" dynamic folding implies css
-if exists("s:html_dynamic_folds")
- let s:html_use_css = 1
-endif
+" do any option overrides that are needed for current user settings
+let s:old_html_settings = tohtml#OverrideUserSettings()
" When not in gui we can only guess the colors.
if has("gui_running")
@@ -98,7 +87,7 @@ else
endfun
endif
-if !exists("s:html_use_css")
+if !exists("g:html_use_css")
" Return opening HTML tag for given highlight id
function! s:HtmlOpening(id)
let a = ""
@@ -121,7 +110,7 @@ if !exists("s:html_use_css")
endfun
" Return closing HTML tag for given highlight id
- function s:HtmlClosing(id)
+ function! s:HtmlClosing(id)
let a = ""
if synIDattr(a:id, "underline") | let a = a . "" | endif
if synIDattr(a:id, "italic") | let a = a . "" | endif
@@ -186,8 +175,7 @@ function! s:CSS1(id)
return a
endfun
-if exists("s:html_dynamic_folds")
-
+if exists("g:html_dynamic_folds")
" compares two folds as stored in our list of folds
" A fold is "less" than another if it starts at an earlier line number,
" or ends at a later line number, ties broken by fold level
@@ -208,7 +196,7 @@ endif
" Figure out proper MIME charset from the 'encoding' option.
if exists("g:html_use_encoding")
- let s:html_encoding = html_use_encoding
+ let s:html_encoding = g:html_use_encoding
else
let s:vim_encoding = &encoding
if s:vim_encoding =~ '^8bit\|^2byte'
@@ -247,32 +235,54 @@ let s:old_icon = &icon
let s:old_et = &l:et
let s:old_report = &report
let s:old_search = @/
+let s:old_more = &more
set notitle noicon
setlocal et
+set nomore
set report=1000000
" Split window to create a buffer with the HTML file.
let s:orgbufnr = winbufnr(0)
+let s:origwin_stl = &l:stl
if expand("%") == ""
new Untitled.html
else
new %.html
endif
+
+" Resize the new window to very small in order to make it draw faster
+let s:old_winheight = winheight(0)
+let s:old_winfixheight = &l:winfixheight
+if s:old_winheight > 2
+ resize 1 " leave enough room to view one line at a time
+ norm! G
+ norm! zt
+endif
+setlocal winfixheight
+
+let s:newwin_stl = &l:stl
+
+" on the new window, set the least time-consuming fold method
+let s:old_fdm = &foldmethod
+setlocal foldmethod=manual
+
let s:newwin = winnr()
let s:orgwin = bufwinnr(s:orgbufnr)
-set modifiable
+setlocal modifiable
%d
let s:old_paste = &paste
set paste
let s:old_magic = &magic
set magic
+let s:lines = []
+
if exists("g:use_xhtml")
if s:html_encoding != ""
- exe "normal! a\n\e"
+ call add(s:lines, "")
else
- exe "normal! a\n\e"
+ call add(s:lines, "")
endif
let s:tag_close = ' />'
else
@@ -281,12 +291,12 @@ endif
" Cache html_no_pre in case we have to turn it on for non-css mode
if exists("g:html_no_pre")
- let s:old_html_no_pre = html_no_pre
+ let s:old_html_no_pre = g:html_no_pre
endif
-if !exists("s:html_use_css")
+if !exists("g:html_use_css")
" Can't put font tags in
- let html_no_pre=1
+ let g:html_no_pre=1
endif
let s:HtmlSpace = ' '
@@ -300,97 +310,114 @@ endif
" HTML header, with the title and generator ;-). Left free space for the CSS,
" to be filled at the end.
-exe "normal! a\n\e"
-exe "normal! a\n" . expand("%:p:~") . "\n\e"
-exe "normal! a",
+ \"",
+ \("".expand("%:p:~").""),
+ \("\n\n\n"
- exe "normal! a\n"
+ call extend(s:lines, [
+ \ "",
+ \ "",
+ \])
else
" if we aren't doing hover_unfold, use CSS 1 only
- exe "normal! a\n"
+ call extend(s:lines, [
+ \ "'
+ \])
endif
else
" if we aren't doing any dynamic folding, no need for any special rules
- exe "normal! a\n\e"
+ call extend(s:lines, [
+ \ "",
+ \])
endif
endif
" insert javascript to toggle folds open and closed
-if exists("s:html_dynamic_folds")
- exe "normal! a\n".
- \ "\n\e"
+if exists("g:html_dynamic_folds")
+ call extend(s:lines, [
+ \ "",
+ \ ""
+ \])
endif
if exists("g:html_no_pre")
- exe "normal! a\n\n\e"
+ call extend(s:lines, ["", ""])
else
- exe "normal! a\n\n\n\e"
+ call extend(s:lines, ["", "", ""])
endif
exe s:orgwin . "wincmd w"
@@ -398,23 +425,132 @@ exe s:orgwin . "wincmd w"
" List of all id's
let s:idlist = ","
+" set up progress bar in the status line
+if !s:html_no_progress && has("statusline")
+ " ProgressBar Indicator
+ let s:progressbar={}
+
+ " Progessbar specific functions
+ 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' : 'DiffDelete' , '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 exists("g:html_dynamic_folds")
+ " to process folds we make two passes through each line
+ let s:pgb = s:ProgressBar("Processing folds:", line('$')*2, s:orgwin)
+ endif
+else
+ let s:html_no_progress=1
+endif
+
" 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 exists("s:html_dynamic_folds")
+if exists("g:html_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
- set 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
+ 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
@@ -429,6 +565,13 @@ if exists("s:html_dynamic_folds")
" open the fold so we can find any contained folds
execute s:lnum."foldopen"
else
+ if !s:html_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
@@ -439,7 +582,7 @@ if exists("s:html_dynamic_folds")
" 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
+ 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
@@ -457,6 +600,13 @@ if exists("s:html_dynamic_folds")
" open the fold so we can find any contained folds
execute s:lnum."foldopen"
else
+ if !s:html_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
@@ -465,11 +615,11 @@ if exists("s:html_dynamic_folds")
" list of folds
call sort(s:allfolds, "s:FoldCompare")
- let &foldtext = s:foldtext_save
+ 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!
+ silent! %foldclose!
endif
" Now loop over all lines in the original text to convert to html.
@@ -494,6 +644,10 @@ endif
" stack to keep track of all the folds containing the current line
let s:foldstack = []
+if !s:html_no_progress
+ let s:pgb = s:ProgressBar("Processing lines:", s:end - s:lnum + 1, s:orgwin)
+endif
+
if s:numblines
let s:margin = strlen(s:end) + 1
else
@@ -539,9 +693,7 @@ while s:lnum <= s:end
" Indent if line numbering is on; must be after escaping.
let s:new = repeat(s:LeadingSpace, s:margin) . s:new
endif
- exe s:newwin . "wincmd w"
- exe "normal! a" . s:new . s:HtmlEndline . "\n\e"
- exe s:orgwin . "wincmd w"
+ call add(s:lines, s:new.s:HtmlEndline)
let s:n = s:n - 1
endwhile
@@ -558,7 +710,7 @@ while s:lnum <= s:end
let s:new = ""
- if has('folding') && !exists('g:html_ignore_folding') && foldclosed(s:lnum) > -1 && !exists('s:html_dynamic_folds')
+ if has('folding') && !exists('g:html_ignore_folding') && foldclosed(s:lnum) > -1 && !exists('g:html_dynamic_folds')
"
" This is the beginning of a folded block (with no dynamic folding)
"
@@ -571,7 +723,13 @@ while s:lnum <= s:end
let s:new = s:HtmlFormat(s:new, "Folded")
" Skip to the end of the fold
- let s:lnum = foldclosedend(s:lnum)
+ let s:new_lnum = foldclosedend(s:lnum)
+
+ if !s:html_no_progress
+ call s:pgb.incr(s:new_lnum - s:lnum)
+ endif
+
+ let s:lnum = s:new_lnum
else
"
@@ -580,7 +738,7 @@ while s:lnum <= s:end
let s:line = getline(s:lnum)
let s:len = strlen(s:line)
- if exists("s:html_dynamic_folds")
+ if exists("g:html_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.""
@@ -591,7 +749,10 @@ while s:lnum <= s:end
let s:firstfold = 1
while !empty(s:allfolds) && get(s:allfolds,0).firstline == s:lnum
let s:foldId = s:foldId + 1
- let s:new = s:new . ""
+ let s:new .= ""
+
" Unless disabled, add a fold column for the opening line of a fold.
"
@@ -632,7 +793,7 @@ while s:lnum <= s:end
" add fold text, moving the span ending to the next line so collapsing
" of folds works correctly
- let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded"), '', s:HtmlEndline.'\r\0', '')
+ let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded"), '', s:HtmlEndline.'\n\0', '')
let s:new = s:new . ""
" open the fold now that we have the fold text to allow retrieval of
@@ -725,18 +886,22 @@ while s:lnum <= s:end
endwhile
endif
- exe s:newwin . "wincmd w"
- exe "normal! a" . s:new . s:HtmlEndline . "\n\e"
- exe s:orgwin . "wincmd w"
+ call extend(s:lines, split(s:new.s:HtmlEndline, '\n'))
+ if !s:html_no_progress && s:pgb.needs_redraw
+ redrawstatus
+ let s:pgb.needs_redraw = 0
+ endif
let s:lnum = s:lnum + 1
-endwhile
-" Finish with the last line
-exe s:newwin . "wincmd w"
-if exists("s:html_dynamic_folds")
+ if !s:html_no_progress
+ call s:pgb.incr()
+ endif
+endwhile
+
+if exists("g:html_dynamic_folds")
" finish off any open folds
while !empty(s:foldstack)
- exe "normal! a"
+ let s:lines[-1].=""
call remove(s:foldstack, 0)
endwhile
@@ -748,19 +913,22 @@ if exists("s:html_dynamic_folds")
endif
" Close off the font tag that encapsulates the whole
-if !exists("s:html_use_css")
- exe "normal! a\e"
+if !exists("g:html_use_css")
+ let s:lines[-1].=""
endif
if exists("g:html_no_pre")
- exe "normal! a\n\e"
+ call extend(s:lines, ["", ""])
else
- exe "normal! a
\n\n