changeset 2321:1902913f2049 vim73

Improved version of 2html.vim. Includes progress bar. Fix dynamic folding in diff view. (Benjamin Fritz)
author Bram Moolenaar <bram@vim.org>
date Fri, 16 Jul 2010 20:35:36 +0200
parents 966a5609669e
children 70be008dff4f
files runtime/autoload/tohtml.vim runtime/doc/syntax.txt runtime/ftplugin/help.vim runtime/plugin/tohtml.vim runtime/syntax/2html.vim runtime/syntax/help.vim
diffstat 6 files changed, 562 insertions(+), 221 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/autoload/tohtml.vim
+++ b/runtime/autoload/tohtml.vim
@@ -1,11 +1,22 @@
 " Vim autoload file for the tohtml plugin.
-" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2010 Jul 11
+" Maintainer: Ben Fritz <fritzophrenic@gmail.com>
+" Last Change: 2010 Jul 15
+"
+" Additional contributors:
 "
-" Diff2HTML() added by Christian Brabandt <cb@256bit.org>
+"             Original by Bram Moolenaar <Bram@vim.org>
+"             Diff2HTML() added by Christian Brabandt <cb@256bit.org>
+"
+"             See Mercurial change logs for more!
+ 
+" this file uses line continuations
+let s:cpo_sav = &cpo
+set cpo-=C
 
 func! tohtml#Convert2HTML(line1, line2)
-  if !&diff || exists("g:diff_one_file")
+  let old_vals = tohtml#OverrideUserSettings()
+
+  if !&diff || exists("g:html_diff_one_file")
     if a:line2 >= a:line1
       let g:html_start_line = a:line1
       let g:html_end_line = a:line2
@@ -17,27 +28,34 @@ func! tohtml#Convert2HTML(line1, line2)
   else
     let win_list = []
     let buf_list = []
-    windo | if (&diff) | call add(win_list, winbufnr(0)) | endif
+    windo | if &diff | call add(win_list, winbufnr(0)) | endif
     let save_hwf = exists("g:html_whole_filler")
     let g:html_whole_filler = 1
+    let g:html_diff_win_num = 0
     for window in win_list
       exe ":" . bufwinnr(window) . "wincmd w"
       let g:html_start_line = 1
       let g:html_end_line = line('$')
+      let g:html_diff_win_num += 1
       runtime syntax/2html.vim
       call add(buf_list, bufnr('%'))
+      "exec '%s#<span id=''\zsfold\d\+\ze''#win'.win_num.'\0#ge'
     endfor
+    unlet g:html_diff_win_num
     if !save_hwf
       unlet g:html_whole_filler
     endif
     call tohtml#Diff2HTML(win_list, buf_list)
   endif
 
+  call tohtml#RestoreUserSettings(old_vals)
+
   unlet g:html_start_line
   unlet g:html_end_line
 endfunc
 
 func! tohtml#Diff2HTML(win_list, buf_list)
+  " TODO: add logic for xhtml
   let style = []
   let html = []
   call add(html, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"')
@@ -45,12 +63,14 @@ func! tohtml#Diff2HTML(win_list, buf_lis
   call add(html, '<html>')
   call add(html, '<head>')
   call add(html, '<title>diff</title>')
-  call add(html, '<meta name="Generator" content="Vim/7.3">')
-  "call add(html, '<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">')
+  call add(html, '<meta name="Generator" content="Vim/'.v:version/100.'.'.v:version%100.'">')
+  " TODO: copy or move encoding logic from 2html.vim so generated markup can
+  " validate without warnings about encoding
+
   call add(html, '</head>')
   call add(html, '<body>')
   call add(html, '<table border="1" width="100%">')
-  "call add(html, '<font face="monospace">')
+
   call add(html, '<tr>')
   for buf in a:win_list
     call add(html, '<th>'.bufname(buf).'</th>')
@@ -61,6 +81,10 @@ func! tohtml#Diff2HTML(win_list, buf_lis
     let temp = []
     exe bufwinnr(buf) . 'wincmd w'
 
+    " If text is folded because of user foldmethod settings, etc. we don't want
+    " to act on everything in a fold by mistake.
+    setlocal nofoldenable
+
     " Grab the style information.  Some of this will be duplicated...
     1
     let style_start = search('^<style type="text/css">')
@@ -78,12 +102,15 @@ func! tohtml#Diff2HTML(win_list, buf_lis
     let temp = getline(1,'$')
     " undo deletion of start and end part
     " so we can later save the file as valid html
+    " TODO: restore using grabbed lines if undolevel is 1?
     normal 2u
-    call add(html, '<td nowrap valign="top">')
+    call add(html, '<td nowrap valign="top"><div>')
     let html += temp
-    call add(html, '</td>')
+    call add(html, '</div></td>')
 
     " Close this buffer
+    " TODO: the comment above says we're going to allow saving the file
+    " later...but here we discard it?
     quit!
   endfor
 
@@ -94,18 +121,122 @@ func! tohtml#Diff2HTML(win_list, buf_lis
 
   let i = 1
   let name = "Diff" . ".html"
+  " Find an unused file name if current file name is already in use
   while filereadable(name)
     let name = substitute(name, '\d*\.html$', '', '') . i . ".html"
     let i += 1
-  endw
-  exe "new " . name
-  set modifiable
+  endwhile
+  exe "topleft new " . name
+  setlocal modifiable
+
+  " just in case some user autocmd creates content in the new buffer, make sure
+  " it is empty before proceeding
+  %d
   call append(0, html)
+
   if len(style) > 0
     1
-    let style_start = search('^</head>')
-    call append(style_start, '</style>')
-    call append(style_start, style)
-    call append(style_start, '<style type="text/css">')
+    let style_start = search('^</head>')-1
+
+    " Insert javascript to toggle matching folds open and closed in all windows,
+    " if dynamic folding is active.
+    if exists("g:html_dynamic_folds")
+      call append(style_start, [
+            \  "<script type='text/javascript'>",
+            \  "  <!--",
+            \  "  function toggleFold(objID)",
+            \  "  {",
+            \  "    for (win_num = 1; win_num <= 2; win_num++)",
+            \  "    {",
+            \  "      var fold;",
+            \  '      fold = document.getElementById("win"+win_num+objID);',
+            \  "      if(fold.className == 'closed-fold')",
+            \  "      {",
+            \  "        fold.className = 'open-fold';",
+            \  "      }",
+            \  "      else if (fold.className == 'open-fold')",
+            \  "      {",
+            \  "        fold.className = 'closed-fold';",
+            \  "      }",
+            \  "    }",
+            \  "  }",
+            \  "  -->",
+            \  "</script>"
+            \ ])
+    endif
+
+    " Insert styles from all the generated html documents and additional styles
+    " for the table-based layout of the side-by-side diff. The diff should take
+    " up the full browser window (but not more), and be static in size,
+    " horizontally scrollable when the lines are too long. Otherwise, the diff
+    " is pretty useless for really long lines.
+    if exists("g:html_use_css")
+      call append(style_start, [
+            \ '<style type="text/css">']+
+            \  style+[
+            \ '<!--',
+            \ 'table { table-layout: fixed; }',
+            \ 'html, body, table, tbody { width: 100%; margin: 0; padding: 0; }',
+            \ 'th, td { width: '.printf("%.1f",100.0/len(a:win_list)).'%; }',
+            \ 'td div { overflow: auto; }',
+            \ '-->',
+            \  '</style>'
+            \ ])
+    endif
   endif
 endfunc
+
+func! tohtml#OverrideUserSettings()
+  let old_settings = {}
+  " make copies of the user-defined settings that we may overrule
+  let old_settings.html_dynamic_folds = exists("g:html_dynamic_folds")
+  let old_settings.html_hover_unfold = exists("g:html_hover_unfold")
+  let old_settings.html_use_css = exists("g:html_use_css")
+
+  " hover opening implies dynamic folding
+  if exists("g:html_hover_unfold")
+    let g:html_dynamic_folds = 1
+  endif
+
+  " dynamic folding with no foldcolumn implies hover opens
+  if exists("g:html_dynamic_folds") && exists("g:html_no_foldcolumn")
+    let g:html_hover_unfold = 1
+  endif
+
+  " ignore folding overrides dynamic folding
+  if exists("g:html_ignore_folding") && exists("g:html_dynamic_folds")
+    unlet g:html_dynamic_folds
+  endif
+
+  " dynamic folding implies css
+  if exists("g:html_dynamic_folds")
+    let g:html_use_css = 1
+  endif
+
+  return old_settings
+endfunc
+
+func! tohtml#RestoreUserSettings(old_settings)
+  " restore any overridden user options
+  if a:old_settings.html_dynamic_folds
+    let g:html_dynamic_folds = 1
+  else
+    unlet! g:html_dynamic_folds
+  endif
+  if a:old_settings.html_hover_unfold
+    let g:html_hover_unfold = 1
+  else
+    unlet! g:html_hover_unfold
+  endif
+  if a:old_settings.html_use_css
+    let g:html_use_css = 1
+  else
+    unlet! g:html_use_css
+  endif
+endfunc
+
+let &cpo = s:cpo_sav
+unlet s:cpo_sav
+
+" Make sure any patches will probably use consistent indent
+"   vim: sw=2 sts=2 et
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -380,51 +380,58 @@ Source the script to convert the current
 
 	:runtime! syntax/2html.vim
 <
-Warning: This is slow!
 							*:TOhtml*
 Or use the ":TOhtml" user command.  It is defined in a standard plugin.
 ":TOhtml" also works with a range and in a Visual area: >
 
 	:10,40TOhtml
 
+Warning: This is slow! The script must process every character of every line.
+Because it is so slow, by default a progress bar is displayed in the
+statusline for each step that usually takes a long time. If you don't like
+seeing this progress bar, you can disable it and get a very minor speed
+improvement with: >
+
+	let g:html_no_progress = 1
+
 ":TOhtml" has another special feature: if the window is in diff mode, it will
 generate HTML that shows all the related windows.  This can be disabled by
-setting the g:diff_one_file variable: >
-
-	let g:diff_one_file = 1
+setting the g:html_diff_one_file variable: >
+
+	let g:html_diff_one_file = 1
 
 After you save the resulting file, you can view it with any browser.  The
 colors should be exactly the same as you see them in Vim.
 
-To restrict the conversion to a range of lines set "html_start_line" and
-"html_end_line" to the first and last line to be converted.  Example, using
-the last set Visual area: >
-
-	:let html_start_line = line("'<")
-	:let html_end_line = line("'>")
+To restrict the conversion to a range of lines, use a range with the |:TOhtml|
+command, or set "g:html_start_line" and "g:html_end_line" to the first and
+last line to be converted.  Example, using the last set Visual area: >
+
+	:let g:html_start_line = line("'<")
+	:let g:html_end_line = line("'>")
 
 The lines are numbered according to 'number' option and the Number
 highlighting.  You can force lines to be numbered in the HTML output by
 setting "html_number_lines" to non-zero value: >
-   :let html_number_lines = 1
+   :let g:html_number_lines = 1
 Force to omit the line numbers by using a zero value: >
-   :let html_number_lines = 0
+   :let g:html_number_lines = 0
 Go back to the default to use 'number' by deleting the variable: >
-   :unlet html_number_lines
+   :unlet g:html_number_lines
 
 By default, HTML optimized for old browsers is generated.  If you prefer using
 cascading style sheets (CSS1) for the attributes (resulting in considerably
 shorter and valid HTML 4 file), use: >
-   :let html_use_css = 1
+   :let g:html_use_css = 1
 
 Closed folds are put in the HTML as they are displayed.  If you don't want
 this, use the |zR| command before invoking 2html, or use: >
-   :let html_ignore_folding = 1
+   :let g:html_ignore_folding = 1
 
 You may want to generate HTML that includes all the data within the folds, and
 allow the user to view the folded data similar to how they would in Vim. To
 generate this dynamic fold information, use: >
-   :let html_dynamic_folds = 1
+   :let g:html_dynamic_folds = 1
 
 Using html_dynamic_folds will imply html_use_css, because it would be far too
 difficult to do it for old browsers. However, html_ignore_folding overrides
@@ -435,7 +442,7 @@ similar to Vim's foldcolumn, that will u
 folds in the HTML document. The width of this foldcolumn starts at the current
 setting of |'foldcolumn'| but grows to fit the greatest foldlevel in your
 document. If you do not want to show a foldcolumn at all, use: >
-   :let html_no_foldcolumn = 1
+   :let g:html_no_foldcolumn = 1
 
 Using this option, there will be no foldcolumn available to open the folds in
 the HTML. For this reason, another option is provided: html_hover_unfold.
@@ -446,7 +453,7 @@ included to fall back to the normal CSS1
 correctly for this browser, but they will not be openable without a
 foldcolumn. Note that using html_hover_unfold will allow modern browsers with
 disabled javascript to view closed folds. To use this option, use: >
-   :let html_hover_unfold = 1
+   :let g:html_hover_unfold = 1
 
 Setting html_no_foldcolumn with html_dynamic_folds will automatically set
 html_hover_unfold, because otherwise the folds wouldn't be dynamic.
@@ -454,7 +461,7 @@ html_hover_unfold, because otherwise the
 By default "<pre>" and "</pre>" is used around the text.  This makes it show
 up as you see it in Vim, but without wrapping.	If you prefer wrapping, at the
 risk of making some things look a bit different, use: >
-   :let html_no_pre = 1
+   :let g:html_no_pre = 1
 This will use <br> at the end of each line and use "&nbsp;" for repeated
 spaces.
 
@@ -462,20 +469,20 @@ The current value of 'encoding' is used 
 file.  This only works for those values of 'encoding' that have an equivalent
 HTML charset name.  To overrule this set g:html_use_encoding to the name of
 the charset to be used: >
-   :let html_use_encoding = "foobar"
+   :let g:html_use_encoding = "foobar"
 To omit the line that specifies the charset, set g:html_use_encoding to an
 empty string: >
-   :let html_use_encoding = ""
+   :let g:html_use_encoding = ""
 To go back to the automatic mechanism, delete the g:html_use_encoding
 variable: >
-   :unlet html_use_encoding
+   :unlet g:html_use_encoding
 <
 For diff mode a sequence of more than 3 filler lines is displayed as three
 lines with the middle line mentioning the total number of inserted lines.  If
 you prefer to see all the inserted lines use: >
-    :let html_whole_filler = 1
+    :let g:html_whole_filler = 1
 And to go back to displaying up to three lines again: >
-    :unlet html_whole_filler
+    :unlet g:html_whole_filler
 <
 					    *convert-to-XML* *convert-to-XHTML*
 An alternative is to have the script generate XHTML (XML compliant HTML).  To
@@ -483,8 +490,6 @@ do this set the "use_xhtml" variable: >
     :let use_xhtml = 1
 To disable it again delete the variable: >
     :unlet use_xhtml
-The generated XHTML file can be used in DocBook XML documents.  See:
-	http://people.mech.kuleuven.ac.be/~pissaris/howto/src2db.html
 
 Remarks:
 - This only works in a version with GUI support.  If the GUI is not actually
--- a/runtime/ftplugin/help.vim
+++ b/runtime/ftplugin/help.vim
@@ -11,9 +11,9 @@ let b:did_ftplugin = 1
 let s:cpo_save = &cpo
 set cpo&vim
 
-let b:undo_ftplugin = "setl fo< tw<"
+let b:undo_ftplugin = "setl fo< tw< conc<"
 
-setlocal formatoptions+=tcroql textwidth=78
+setlocal formatoptions+=tcroql textwidth=78 conc=2
 
 let &cpo = s:cpo_save
 unlet s:cpo_save
--- a/runtime/plugin/tohtml.vim
+++ b/runtime/plugin/tohtml.vim
@@ -1,8 +1,9 @@
 " Vim plugin for converting a syntax highlighted file to HTML.
-" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2010 Jul 11
+" Maintainer: Ben Fritz <fritzophrenic@gmail.com>
+" Last Change: 2010 Jul 15
 "
-" The core of the code is in $VIMRUNTIME/autoload/tohtml.vim
+" The core of the code is in $VIMRUNTIME/autoload/tohtml.vim and
+" $VIMRUNTIME/syntax/2html.vim
 
 " Define the :TOhtml command when:
 " - 'compatible' is not set
@@ -11,3 +12,6 @@
 if !&cp && !exists(":TOhtml") && has("user_commands")
   command -range=% TOhtml :call tohtml#Convert2HTML(<line1>, <line2>)
 endif
+
+" Make sure any patches will probably use consistent indent
+"   vim: ts=2 sw=2 sts=2 et
--- a/runtime/syntax/2html.vim
+++ b/runtime/syntax/2html.vim
@@ -1,16 +1,25 @@
 " Vim syntax support file
-" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2009 Jul 14
-"	       (modified by David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>)
-"	       (XHTML support by Panagiotis Issaris <takis@lumumba.luc.ac.be>)
-"	       (made w3 compliant by Edd Barrett <vext01@gmail.com>)
-"	       (added html_font. Edd Barrett <vext01@gmail.com>)
-"	       (dynamic folding by Ben Fritz <fritzophrenic@gmail.com>)
+" Maintainer: Ben Fritz <fritzophrenic@gmail.com>
+" Last Change: 2010 July 15
+"
+" Additional contributors:
+"
+"	      Original by Bram Moolenaar <Bram@vim.org>
+"	      Modified by David Ne\v{c}as (Yeti) <yeti@physics.muni.cz>
+"	      XHTML support by Panagiotis Issaris <takis@lumumba.luc.ac.be>
+"	      Made w3 compliant by Edd Barrett <vext01@gmail.com>
+"	      Added html_font. Edd Barrett <vext01@gmail.com>
+"	      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 . "</u>" | endif
     if synIDattr(a:id, "italic") | let a = a . "</i>" | 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<?xml version=\"1.0\" encoding=\"" . s:html_encoding . "\"?>\n\e"
+    call add(s:lines, "<?xml version=\"1.0\" encoding=\"" . s:html_encoding . "\"?>")
   else
-    exe "normal! a<?xml version=\"1.0\"?>\n\e"
+    call add(s:lines, "<?xml version=\"1.0\"?>")
   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 <pre>
-  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<html>\n\e"
-exe "normal! a<head>\n<title>" . expand("%:p:~") . "</title>\n\e"
-exe "normal! a<meta name=\"Generator\" content=\"Vim/" . v:version/100 . "." . v:version %100 . '"' . s:tag_close . "\n\e"
+call extend(s:lines, [
+      \"<html>",
+      \"<head>",
+      \("<title>".expand("%:p:~")."</title>"),
+      \("<meta name=\"Generator\" content=\"Vim/".v:version/100.".".v:version%100.'"'.s:tag_close),
+      \])
 if s:html_encoding != ""
-  exe "normal! a<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:html_encoding . '"' . s:tag_close . "\n\e"
+  call add(s:lines, "<meta http-equiv=\"content-type\" content=\"text/html; charset=" . s:html_encoding . '"' . s:tag_close)
 endif
 
-if exists("s:html_use_css")
-  if exists("s:html_dynamic_folds")
-    if exists("s:html_hover_unfold")
+if exists("g:html_use_css")
+  if exists("g:html_dynamic_folds")
+    if exists("g:html_hover_unfold")
       " if we are doing hover_unfold, use css 2 with css 1 fallback for IE6
-      exe "normal! a".
-	  \ "<style type=\"text/css\">\n<!--\n".
-	  \ ".FoldColumn { text-decoration: none; white-space: pre; }\n\n".
-	  \ "body * { margin: 0; padding: 0; }\n".
-	  \ "\n".
-	  \ ".open-fold   > .Folded { display: none;  }\n".
-	  \ ".open-fold   > .fulltext { display: inline; }\n".
-	  \ ".closed-fold > .fulltext { display: none;  }\n".
-	  \ ".closed-fold > .Folded { display: inline; }\n".
-	  \ "\n".
-	  \ ".open-fold   > .toggle-open   { display: none;   }\n".
-	  \ ".open-fold   > .toggle-closed { display: inline; }\n".
-	  \ ".closed-fold > .toggle-open   { display: inline; }\n".
-	  \ ".closed-fold > .toggle-closed { display: none;   }\n"
-      exe "normal! a\n/* opening a fold while hovering won't be supported by IE6 and other\n".
-	  \ "similar browsers, but it should fail gracefully. */\n".
-	  \ ".closed-fold:hover > .fulltext { display: inline; }\n".
-	  \ ".closed-fold:hover > .toggle-filler { display: none; }\n".
-	  \ ".closed-fold:hover > .Folded { display: none; }\n"
-      exe "normal! a-->\n</style>\n"
-      exe "normal! a<!--[if lt IE 7]>".
-	  \ "<style type=\"text/css\">\n".
-	  \ ".open-fold   .Folded      { display: none; }\n".
-	  \ ".open-fold   .fulltext      { display: inline; }\n".
-	  \ ".open-fold   .toggle-open   { display: none; }\n".
-	  \ ".closed-fold .toggle-closed { display: inline; }\n".
-	  \ "\n".
-	  \ ".closed-fold .fulltext      { display: none; }\n".
-	  \ ".closed-fold .Folded      { display: inline; }\n".
-	  \ ".closed-fold .toggle-open   { display: inline; }\n".
-	  \ ".closed-fold .toggle-closed { display: none; }\n".
-	  \ "</style>\n".
-	  \ "<![endif]-->\n"
+      call extend(s:lines, [
+	    \ "<style type=\"text/css\">",
+	    \ "<!--",
+	    \ ".FoldColumn { text-decoration: none; white-space: pre; }",
+	    \ "",
+	    \ "body * { margin: 0; padding: 0; }", "",
+	    \ ".open-fold   > .Folded { display: none;  }",
+	    \ ".open-fold   > .fulltext { display: inline; }",
+	    \ ".closed-fold > .fulltext { display: none;  }",
+	    \ ".closed-fold > .Folded { display: inline; }",
+	    \ "",
+	    \ ".open-fold   > .toggle-open   { display: none;   }",
+	    \ ".open-fold   > .toggle-closed { display: inline; }",
+	    \ ".closed-fold > .toggle-open   { display: inline; }",
+	    \ ".closed-fold > .toggle-closed { display: none;   }",
+	    \ "", "",
+	    \ '/* opening a fold while hovering won''t be supported by IE6 and other',
+	    \ "similar browsers, but it should fail gracefully. */",
+	    \ ".closed-fold:hover > .fulltext { display: inline; }",
+	    \ ".closed-fold:hover > .toggle-filler { display: none; }",
+	    \ ".closed-fold:hover > .Folded { display: none; }",
+	    \ '-->',
+	    \ '<style>',
+	    \ "<!--[if lt IE 7]><style type=\"text/css\">",
+	    \ ".open-fold   .Folded      { display: none; }",
+	    \ ".open-fold   .fulltext      { display: inline; }",
+	    \ ".open-fold   .toggle-open   { display: none; }",
+	    \ ".closed-fold .toggle-closed { display: inline; }",
+	    \ "",
+	    \ ".closed-fold .fulltext      { display: none; }",
+	    \ ".closed-fold .Folded      { display: inline; }",
+	    \ ".closed-fold .toggle-open   { display: inline; }",
+	    \ ".closed-fold .toggle-closed { display: none; }",
+	    \ "</style>",
+	    \ "<![endif]-->",
+	    \])
     else
       " if we aren't doing hover_unfold, use CSS 1 only
-      exe "normal! a<style type=\"text/css\">\n<!--\n".
-	    \ ".FoldColumn { text-decoration: none; white-space: pre; }\n\n".
-	    \ ".open-fold   .Folded      { display: none; }\n".
-	    \ ".open-fold   .fulltext      { display: inline; }\n".
-	    \ ".open-fold   .toggle-open   { display: none; }\n".
-	    \ ".closed-fold .toggle-closed { display: inline; }\n".
-	    \ "\n".
-	    \ ".closed-fold .fulltext      { display: none; }\n".
-	    \ ".closed-fold .Folded      { display: inline; }\n".
-	    \ ".closed-fold .toggle-open   { display: inline; }\n".
-	    \ ".closed-fold .toggle-closed { display: none; }\n".
-	    \ "-->\n</style>\n"
+      call extend(s:lines, [
+	    \ "<style type=\"text/css\">",
+	    \ "<!--",
+	    \ ".FoldColumn { text-decoration: none; white-space: pre; }",
+	    \ ".open-fold   .Folded      { display: none; }",
+	    \ ".open-fold   .fulltext      { display: inline; }",
+	    \ ".open-fold   .toggle-open   { display: none; }",
+	    \ ".closed-fold .toggle-closed { display: inline; }",
+	    \ "",
+	    \ ".closed-fold .fulltext      { display: none; }",
+	    \ ".closed-fold .Folded      { display: inline; }",
+	    \ ".closed-fold .toggle-open   { display: inline; }",
+	    \ ".closed-fold .toggle-closed { display: none; }",
+	    \ '-->',
+	    \ '</style>'
+	    \])
     endif
   else
     " if we aren't doing any dynamic folding, no need for any special rules
-    exe "normal! a<style type=\"text/css\">\n<!--\n-->\n</style>\n\e"
+    call extend(s:lines, [
+	  \ "<style type=\"text/css\">",
+	  \ "<!--",
+	  \ '-->',
+	  \ "</style>",
+	  \])
   endif
 endif
 
 " insert javascript to toggle folds open and closed
-if exists("s:html_dynamic_folds")
-  exe "normal! a\n".
-	\ "<script type='text/javascript'>\n".
-	\ "<!--\n".
-	\ "function toggleFold(objID)\n".
-	\ "{\n".
-	\ "  var fold;\n".
-	\ "  fold = document.getElementById(objID);\n".
-	\ "  if(fold.className == 'closed-fold')\n".
-	\ "  {\n".
-	\ "    fold.className = 'open-fold';\n".
-	\ "  }\n".
-	\ "  else if (fold.className == 'open-fold')\n".
-	\ "  {\n".
-	\ "    fold.className = 'closed-fold';\n".
-	\ "  }\n".
-	\ "}\n".
-	\ "-->\n".
-	\ "</script>\n\e"
+if exists("g:html_dynamic_folds")
+  call extend(s:lines, [
+	\ "",
+	\ "<script type='text/javascript'>",
+	\ "<!--",
+	\ "function toggleFold(objID)",
+	\ "{",
+	\ "  var fold;",
+	\ "  fold = document.getElementById(objID);",
+	\ "  if(fold.className == 'closed-fold')",
+	\ "  {",
+	\ "    fold.className = 'open-fold';",
+	\ "  }",
+	\ "  else if (fold.className == 'open-fold')",
+	\ "  {",
+	\ "    fold.className = 'closed-fold';",
+	\ "  }",
+	\ "}",
+	\ '-->',
+	\ "</script>"
+	\])
 endif
 
 if exists("g:html_no_pre")
-  exe "normal! a</head>\n<body>\n\e"
+  call extend(s:lines, ["</head>", "<body>"])
 else
-  exe "normal! a</head>\n<body>\n<pre>\n\e"
+  call extend(s:lines, ["</head>", "<body>", "<pre>"])
 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."</span></span>"
@@ -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 . "<span id='fold".s:foldId."' class='".s:allfolds[0].type."'>"
+	let s:new .= "<span id='"
+	let s:new .= (exists('g:html_diff_win_num') ? "win".g:html_diff_win_num : "")
+	let s:new .= "fold".s:foldId."' class='".s:allfolds[0].type."'>"
+
 
 	" 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"), '</span>', s:HtmlEndline.'\r\0', '')
+	let s:new = s:new . substitute(s:HtmlFormat(s:numcol . foldtextresult(s:lnum), "Folded"), '</span>', s:HtmlEndline.'\n\0', '')
 	let s:new = s:new . "<span class='fulltext'>"
 
 	" 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
+
+  if !s:html_no_progress
+    call s:pgb.incr()
+  endif
 endwhile
-" Finish with the last line
-exe s:newwin . "wincmd w"
 
-if exists("s:html_dynamic_folds")
+if exists("g:html_dynamic_folds")
   " finish off any open folds
   while !empty(s:foldstack)
-    exe "normal! a</span></span>"
+    let s:lines[-1].="</span></span>"
     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 <body>
-if !exists("s:html_use_css")
-  exe "normal! a</font>\e"
+if !exists("g:html_use_css")
+  let s:lines[-1].="</font>"
 endif
 
 if exists("g:html_no_pre")
-  exe "normal! a</body>\n</html>\e"
+  call extend(s:lines, ["</body>", "</html>"])
 else
-  exe "normal! a</pre>\n</body>\n</html>\e"
+  call extend(s:lines, ["</pre>", "</body>", "</html>"])
 endif
 
+exe s:newwin . "wincmd w"
+call setline(1, s:lines)
+unlet s:lines
 
 " Now, when we finally know which, we define the colors and styles
-if exists("s:html_use_css")
+if exists("g:html_use_css")
   1;/<style type="text/+1
 endif
 
@@ -777,7 +945,7 @@ endif
 " Normal/global attributes
 " For Netscape 4, set <body> attributes too, though, strictly speaking, it's
 " incorrect.
-if exists("s:html_use_css")
+if exists("g:html_use_css")
   if exists("g:html_no_pre")
     execute "normal! A\nbody { color: " . s:fgc . "; background-color: " . s:bgc . "; font-family: ". s:htmlfont ."; }\e"
   else
@@ -792,7 +960,7 @@ endif
 
 " Line numbering attributes
 if s:numblines
-  if exists("s:html_use_css")
+  if exists("g:html_use_css")
     execute "normal! A\n.lnr { " . s:CSS1(hlID("LineNr")) . "}\e"
   else
     execute '%s+^<span class="lnr">\([^<]*\)</span>+' . s:HtmlOpening(hlID("LineNr")) . '\1' . s:HtmlClosing(hlID("LineNr")) . '+g'
@@ -800,18 +968,22 @@ if s:numblines
 endif
 
 " Gather attributes for all other classes
-let s:idlist = strpart(s:idlist, 1)
-while s:idlist != ""
+let s:idlist_str = s:idlist
+unlet s:idlist
+let s:idlist = split(s:idlist_str, ',')
+if !s:html_no_progress && !empty(s:idlist)
+  let s:pgb = s:ProgressBar("Processing classes:", len(s:idlist),s:newwin)
+endif
+while !empty(s:idlist)
   let s:attr = ""
-  let s:col = stridx(s:idlist, ",")
-  let s:id = strpart(s:idlist, 0, s:col)
-  let s:idlist = strpart(s:idlist, s:col + 1)
+  let s:id = remove(s:idlist, 0)
   let s:attr = s:CSS1(s:id)
   let s:id_name = synIDattr(s:id, "name", s:whatterm)
+
   " If the class has some attributes, export the style, otherwise DELETE all
   " its occurences to make the HTML shorter
   if s:attr != ""
-    if exists("s:html_use_css")
+    if exists("g:html_use_css")
       execute "normal! A\n." . s:id_name . " { " . s:attr . "}"
     else
       execute '%s+<span class="' . s:id_name . '">\([^<]*\)</span>+' . s:HtmlOpening(s:id) . '\1' . s:HtmlClosing(s:id) . '+g'
@@ -822,7 +994,17 @@ while s:idlist != ""
       1;/<style type="text/+1
     endif
   endif
+
+  if !s:html_no_progress
+    call s:pgb.incr()
+    if s:pgb.needs_redraw
+      redrawstatus
+      let s:pgb.needs_redraw = 0
+      sleep 50m
+    endif
+  endif
 endwhile
+unlet s:idlist_str
 
 " Add hyperlinks
 %s+\(https\=://\S\{-}\)\(\([.,;:}]\=\(\s\|$\)\)\|[\\"'<>]\|&gt;\|&lt;\|&quot;\)+<a href="\1">\1</a>\2+ge
@@ -842,49 +1024,68 @@ endif
 %s:\s\+$::e
 
 " Restore old settings
+let &l:foldmethod = s:old_fdm
 let &report = s:old_report
 let &title = s:old_title
 let &icon = s:old_icon
 let &paste = s:old_paste
 let &magic = s:old_magic
 let @/ = s:old_search
+let &more = s:old_more
 exe s:orgwin . "wincmd w"
 let &l:et = s:old_et
 exe s:newwin . "wincmd w"
+exec 'resize' s:old_winheight
+let &l:winfixheight = s:old_winfixheight
 
 " Reset old <pre> settings
 if exists("s:old_html_no_pre")
-  let html_no_pre = s:old_html_no_pre
+  let g:html_no_pre = s:old_html_no_pre
   unlet s:old_html_no_pre
 elseif exists("g:html_no_pre")
-  unlet html_no_pre
+  unlet g:html_no_pre
 endif
 
+call setwinvar(s:orgwin,'&stl', s:origwin_stl)
+call setwinvar(s:newwin,'&stl', s:newwin_stl)
+let &ls=s:ls
+
 " Save a little bit of memory (worth doing?)
 unlet s:htmlfont
-unlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search
-unlet s:whatterm s:idlist s:lnum s:end s:margin s:fgc s:bgc s:old_magic
+unlet s:old_et s:old_paste s:old_icon s:old_report s:old_title s:old_search s:old_magic s:old_more s:old_fdm s:old_winheight s:old_winfixheight
+unlet s:whatterm s:idlist s:lnum s:end s:margin s:fgc s:bgc
 unlet! s:col s:id s:attr s:len s:line s:new s:expandedtab s:numblines
-unlet! s:orgwin s:newwin s:orgbufnr s:idx s:i s:offset
+unlet! s:orgwin s:newwin s:orgbufnr s:idx s:i s:offset s:ls s:origwin_stl s:newwin_stl
 if !v:profiling
   delfunc s:HtmlColor
   delfunc s:HtmlFormat
   delfunc s:CSS1
-  if !exists("s:html_use_css")
+  if !exists("g:html_use_css")
     delfunc s:HtmlOpening
     delfunc s:HtmlClosing
   endif
+  if exists("g:html_dynamic_folds")
+    delfunc s:FoldCompare
+  endif
+
+  if !s:html_no_progress
+    delfunc s:ProgressBar
+    delfunc s:progressbar.paint
+    delfunc s:progressbar.incr
+    unlet s:pgb s:progressbar
+  endif
 endif
-silent! unlet s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn
+
+unlet! s:new_lnum s:diffattr s:difffillchar s:foldfillchar s:HtmlSpace s:LeadingSpace s:HtmlEndline s:firstfold s:foldcolumn
 unlet s:foldstack s:allfolds s:foldId s:numcol
 
-if exists("s:html_dynamic_folds")
-  delfunc s:FoldCompare
-endif
+unlet! s:html_no_progress
 
-silent! unlet s:html_dynamic_folds s:html_hover_unfold s:html_use_css
+call tohtml#RestoreUserSettings(s:old_html_settings)
+unlet s:old_html_settings
 
 let &cpo = s:cpo_sav
-unlet s:cpo_sav
+unlet! s:cpo_sav
 
-" vim: noet sw=2 sts=2
+" Make sure any patches will probably use consistent indent
+"   vim: noet sw=2 sts=2
--- a/runtime/syntax/help.vim
+++ b/runtime/syntax/help.vim
@@ -21,8 +21,8 @@ else
   syn match helpHyperTextEntry	"\*[#-)!+-~]\+\*\s"he=e-1 contains=helpStar
   syn match helpHyperTextEntry	"\*[#-)!+-~]\+\*$" contains=helpStar
 endif
-syn match helpBar		contained "|"
-syn match helpStar		contained "\*"
+syn match helpBar		contained "|" conceal
+syn match helpStar		contained "\*" conceal
 syn match helpNormal		"|.*====*|"
 syn match helpNormal		":|vim:|"	" for :help modeline
 syn match helpVim		"Vim version [0-9.a-z]\+"
@@ -30,7 +30,7 @@ syn match helpVim		"VIM REFERENCE.*"
 syn match helpOption		"'[a-z]\{2,\}'"
 syn match helpOption		"'t_..'"
 syn match helpHeader		"\s*\zs.\{-}\ze\s\=\~$" nextgroup=helpIgnore
-syn match helpIgnore		"." contained
+syn match helpIgnore		"." contained conceal
 syn keyword helpNote		note Note NOTE note: Note: NOTE: Notes Notes:
 syn match helpSpecial		"\<N\>"
 syn match helpSpecial		"\<N\.$"me=e-1