summaryrefslogtreecommitdiffstats
path: root/.vim
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xssn.at>2010-12-04 23:01:02 +0100
committerFlorian Pritz <bluewind@xssn.at>2010-12-04 23:01:02 +0100
commit70f0ef31d89e361cb7c37de9b1b73a829c41c9a4 (patch)
treece5b4a5c9c20732e28676c913bca97ef26669360 /.vim
parentaaeadcdc572d127939e239a93bec09fa1a7475a3 (diff)
downloaddotfiles-70f0ef31d89e361cb7c37de9b1b73a829c41c9a4.tar.gz
dotfiles-70f0ef31d89e361cb7c37de9b1b73a829c41c9a4.tar.xz
vim: add new plugins; add movement keymappings
Signed-off-by: Florian Pritz <bluewind@xssn.at>
Diffstat (limited to '.vim')
-rw-r--r--.vim/autoload/rainbow_parenthsis.vim172
-rw-r--r--.vim/doc/rainbow_parenthsis.txt88
-rw-r--r--.vim/doc/tags32
-rwxr-xr-x.vim/ftplugin/html/sparkup.py1087
-rw-r--r--.vim/ftplugin/html/sparkup.vim76
-rw-r--r--.vim/plugin/NERD_commenter.vim2786
-rw-r--r--.vim/plugin/rainbow_parenthsis.vim40
-rw-r--r--.vim/rainbow_parenthsis_options.vim55
8 files changed, 4336 insertions, 0 deletions
diff --git a/.vim/autoload/rainbow_parenthsis.vim b/.vim/autoload/rainbow_parenthsis.vim
new file mode 100644
index 0000000..ffbd4fe
--- /dev/null
+++ b/.vim/autoload/rainbow_parenthsis.vim
@@ -0,0 +1,172 @@
+"------------------------------------------------------------------------------
+" Description: Rainbow colors for parenthsis
+" $Id: rainbow_parenthsis.vim 50 2007-10-08 18:42:51Z krischik@users.sourceforge.net $
+" Copyright: Copyright (C) 2007 Martin Krischik
+" Maintainer: Martin Krischik (krischik@users.sourceforge.net)
+" John Gilmore
+" Luc Hermitte (hermitte@free.fr)
+" $Author: krischik@users.sourceforge.net $
+" $Date: 2007-10-08 20:42:51 +0200 (Mo, 08 Okt 2007) $
+" Version: 4.0
+" $Revision: 50 $
+" $HeadURL: https://vim-scripts.googlecode.com/svn/trunk/1561%20Rainbow%20Parenthsis%20Bundle/autoload/rainbow_parenthsis.vim $
+" History: 24.05.2006 MK Unified Headers
+" 15.10.2006 MK Bram's suggestion for runtime integration
+" 06.09.2007 LH Buffer friendly (can be used in different buffers),
+" can be toggled
+" 09.09.2007 MK Use on LH's suggestion but use autoload to
+" impove memory consumtion and startup performance
+" 09.10.2007 MK Now with round, square brackets, curly and angle
+" brackets.
+" Usage: copy to autoload directory.
+"------------------------------------------------------------------------------
+" This is a simple script. It extends the syntax highlighting to
+" highlight each matching set of parens in different colors, to make
+" it visually obvious what matches which.
+"
+" Obviously, most useful when working with lisp or Ada. But it's also nice other
+" times.
+"------------------------------------------------------------------------------
+
+" Section: highlight {{{1
+
+function rainbow_parenthsis#Activate()
+ highlight default level1c ctermbg=LightGray ctermfg=brown guibg=WhiteSmoke guifg=RoyalBlue3
+ highlight default level2c ctermbg=LightGray ctermfg=Darkblue guibg=WhiteSmoke guifg=SeaGreen3
+ highlight default level3c ctermbg=LightGray ctermfg=darkgray guibg=WhiteSmoke guifg=DarkOrchid3
+ highlight default level4c ctermbg=LightGray ctermfg=darkgreen guibg=WhiteSmoke guifg=firebrick3
+ highlight default level5c ctermbg=LightGray ctermfg=darkcyan guibg=AntiqueWhite guifg=RoyalBlue3
+ highlight default level6c ctermbg=LightGray ctermfg=darkred guibg=AntiqueWhite guifg=SeaGreen3
+ highlight default level7c ctermbg=LightGray ctermfg=darkmagenta guibg=AntiqueWhite guifg=DarkOrchid3
+ highlight default level8c ctermbg=LightGray ctermfg=brown guibg=AntiqueWhite guifg=firebrick3
+ highlight default level9c ctermbg=LightGray ctermfg=gray guibg=LemonChiffon guifg=RoyalBlue3
+ highlight default level10c ctermbg=LightGray ctermfg=black guibg=LemonChiffon guifg=SeaGreen3
+ highlight default level11c ctermbg=LightGray ctermfg=darkmagenta guibg=LemonChiffon guifg=DarkOrchid3
+ highlight default level12c ctermbg=LightGray ctermfg=Darkblue guibg=LemonChiffon guifg=firebrick3
+ highlight default level13c ctermbg=LightGray ctermfg=darkgreen guibg=AliceBlue guifg=RoyalBlue3
+ highlight default level14c ctermbg=LightGray ctermfg=darkcyan guibg=AliceBlue guifg=SeaGreen3
+ highlight default level15c ctermbg=LightGray ctermfg=darkred guibg=AliceBlue guifg=DarkOrchid3
+ highlight default level16c ctermbg=LightGray ctermfg=red guibg=AliceBlue guifg=firebrick3
+ let rainbow_parenthesis#active = 1
+endfunction
+
+function rainbow_parenthsis#Clear()
+ let i = 0
+ while i != 16
+ let i = i + 1
+ exe 'highlight clear level' . i . 'c'
+ endwhile
+ let rainbow_parenthesis#active = 0
+endfunction
+
+function rainbow_parenthsis#Toggle ()
+ if ! exists('rainbow_parenthesis#active')
+ call rainbow_parenthsis#LoadRound ()
+ endif
+ if rainbow_parenthesis#active != 0
+ call rainbow_parenthsis#Clear ()
+ else
+ call rainbow_parenthsis#Activate ()
+ endif
+endfunction
+
+" Section: syntax {{{1
+"
+" Subsection: parentheses or round brackets: {{{2
+"
+function rainbow_parenthsis#LoadRound ()
+ syntax region level1 matchgroup=level1c start=/(/ end=/)/ contains=TOP,level1,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level2 matchgroup=level2c start=/(/ end=/)/ contains=TOP,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level3 matchgroup=level3c start=/(/ end=/)/ contains=TOP,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level4 matchgroup=level4c start=/(/ end=/)/ contains=TOP,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level5 matchgroup=level5c start=/(/ end=/)/ contains=TOP,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level6 matchgroup=level6c start=/(/ end=/)/ contains=TOP,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level7 matchgroup=level7c start=/(/ end=/)/ contains=TOP,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level8 matchgroup=level8c start=/(/ end=/)/ contains=TOP,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level9 matchgroup=level9c start=/(/ end=/)/ contains=TOP,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level10 matchgroup=level10c start=/(/ end=/)/ contains=TOP,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level11 matchgroup=level11c start=/(/ end=/)/ contains=TOP,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level12 matchgroup=level12c start=/(/ end=/)/ contains=TOP,level12,level13,level14,level15, level16,NoInParens
+ syntax region level13 matchgroup=level13c start=/(/ end=/)/ contains=TOP,level13,level14,level15, level16,NoInParens
+ syntax region level14 matchgroup=level14c start=/(/ end=/)/ contains=TOP,level14,level15, level16,NoInParens
+ syntax region level15 matchgroup=level15c start=/(/ end=/)/ contains=TOP,level15, level16,NoInParens
+ syntax region level16 matchgroup=level16c start=/(/ end=/)/ contains=TOP,level16,NoInParens
+ let rainbow_parenthesis#active = 0
+endfunction
+
+" Subsection: box brackets or square brackets: {{{2
+"
+function rainbow_parenthsis#LoadSquare ()
+ syntax region level1 matchgroup=level1c start=/\[/ end=/\]/ contains=TOP,level1,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level2 matchgroup=level2c start=/\[/ end=/\]/ contains=TOP,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level3 matchgroup=level3c start=/\[/ end=/\]/ contains=TOP,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level4 matchgroup=level4c start=/\[/ end=/\]/ contains=TOP,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level5 matchgroup=level5c start=/\[/ end=/\]/ contains=TOP,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level6 matchgroup=level6c start=/\[/ end=/\]/ contains=TOP,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level7 matchgroup=level7c start=/\[/ end=/\]/ contains=TOP,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level8 matchgroup=level8c start=/\[/ end=/\]/ contains=TOP,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level9 matchgroup=level9c start=/\[/ end=/\]/ contains=TOP,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level10 matchgroup=level10c start=/\[/ end=/\]/ contains=TOP,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level11 matchgroup=level11c start=/\[/ end=/\]/ contains=TOP,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level12 matchgroup=level12c start=/\[/ end=/\]/ contains=TOP,level12,level13,level14,level15, level16,NoInParens
+ syntax region level13 matchgroup=level13c start=/\[/ end=/\]/ contains=TOP,level13,level14,level15, level16,NoInParens
+ syntax region level14 matchgroup=level14c start=/\[/ end=/\]/ contains=TOP,level14,level15, level16,NoInParens
+ syntax region level15 matchgroup=level15c start=/\[/ end=/\]/ contains=TOP,level15, level16,NoInParens
+ syntax region level16 matchgroup=level16c start=/\[/ end=/\]/ contains=TOP,level16,NoInParens
+ let rainbow_parenthesis#active = 0
+endfunction
+
+" Subsection: curly brackets or braces: {{{2
+"
+function rainbow_parenthsis#LoadBraces ()
+ syntax region level1 matchgroup=level1c start=/{/ end=/}/ contains=TOP,level1,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level2 matchgroup=level2c start=/{/ end=/}/ contains=TOP,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level3 matchgroup=level3c start=/{/ end=/}/ contains=TOP,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level4 matchgroup=level4c start=/{/ end=/}/ contains=TOP,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level5 matchgroup=level5c start=/{/ end=/}/ contains=TOP,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level6 matchgroup=level6c start=/{/ end=/}/ contains=TOP,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level7 matchgroup=level7c start=/{/ end=/}/ contains=TOP,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level8 matchgroup=level8c start=/{/ end=/}/ contains=TOP,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level9 matchgroup=level9c start=/{/ end=/}/ contains=TOP,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level10 matchgroup=level10c start=/{/ end=/}/ contains=TOP,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level11 matchgroup=level11c start=/{/ end=/}/ contains=TOP,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level12 matchgroup=level12c start=/{/ end=/}/ contains=TOP,level12,level13,level14,level15, level16,NoInParens
+ syntax region level13 matchgroup=level13c start=/{/ end=/}/ contains=TOP,level13,level14,level15, level16,NoInParens
+ syntax region level14 matchgroup=level14c start=/{/ end=/}/ contains=TOP,level14,level15, level16,NoInParens
+ syntax region level15 matchgroup=level15c start=/{/ end=/}/ contains=TOP,level15, level16,NoInParens
+ syntax region level16 matchgroup=level16c start=/{/ end=/}/ contains=TOP,level16,NoInParens
+ let rainbow_parenthesis#active = 0
+endfunction
+
+" Subsection: angle brackets or chevrons: {{{2
+"
+function rainbow_parenthsis#LoadChevrons ()
+ syntax region level1 matchgroup=level1c start=/</ end=/>/ contains=TOP,level1,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level2 matchgroup=level2c start=/</ end=/>/ contains=TOP,level2,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level3 matchgroup=level3c start=/</ end=/>/ contains=TOP,level3,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level4 matchgroup=level4c start=/</ end=/>/ contains=TOP,level4,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level5 matchgroup=level5c start=/</ end=/>/ contains=TOP,level5,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level6 matchgroup=level6c start=/</ end=/>/ contains=TOP,level6,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level7 matchgroup=level7c start=/</ end=/>/ contains=TOP,level7,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level8 matchgroup=level8c start=/</ end=/>/ contains=TOP,level8,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level9 matchgroup=level9c start=/</ end=/>/ contains=TOP,level9,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level10 matchgroup=level10c start=/</ end=/>/ contains=TOP,level10,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level11 matchgroup=level11c start=/</ end=/>/ contains=TOP,level11,level12,level13,level14,level15, level16,NoInParens
+ syntax region level12 matchgroup=level12c start=/</ end=/>/ contains=TOP,level12,level13,level14,level15, level16,NoInParens
+ syntax region level13 matchgroup=level13c start=/</ end=/>/ contains=TOP,level13,level14,level15, level16,NoInParens
+ syntax region level14 matchgroup=level14c start=/</ end=/>/ contains=TOP,level14,level15, level16,NoInParens
+ syntax region level15 matchgroup=level15c start=/</ end=/>/ contains=TOP,level15, level16,NoInParens
+ syntax region level16 matchgroup=level16c start=/</ end=/>/ contains=TOP,level16,NoInParens
+ let rainbow_parenthesis#active = 0
+endfunction
+
+ " }}}1
+finish
+
+"------------------------------------------------------------------------------
+" Copyright (C) 2006 Martin Krischik
+"
+" Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab
+" vim: filetype=vim foldmethod=marker
diff --git a/.vim/doc/rainbow_parenthsis.txt b/.vim/doc/rainbow_parenthsis.txt
new file mode 100644
index 0000000..c8f15ec
--- /dev/null
+++ b/.vim/doc/rainbow_parenthsis.txt
@@ -0,0 +1,88 @@
+*rainbow_parenthsis.txt* Colorize Parenthsis
+
+Author: Martin Krischik (krischik@users.sourceforge.net)
+ John Gilmore
+ Luc Hermitte (hermitte@free.fr)
+
+For Vim version 7.0 and above
+Last change: 09 Oct, 2007
+
+1. Overview |rainbow_parenthsis-about|
+2. Commands |rainbow_parenthsis-commands|
+2. Functions |rainbow_parenthsis-functions|
+3. Configuration |rainbow_parenthsis-configure|
+
+==============================================================================
+ *rainbow_parenthsis-about*
+1. Overview~
+
+rainbow_parenthsis allows you to view the contents of a file in real time. When a
+change in the file is detected, the window displaying the file is updated and
+repositioned to the last line.
+
+The update is not exactly real time, but usually updates within a few seconds
+of the file change. The update interval of the output is determined by the
+|updatetime| parameter, along with continued usage of Vim. This means that if
+you are not doing any editing or motion commands, the preview window will not
+be updated. See |CursorHold| for more information.
+
+Because this window becomes the preview window, it will accept all related
+commands. For more information, see |preview-window|.
+
+==============================================================================
+ *rainbow_parenthsis-commands*
+2. Commands~
+
+The rainbow_parenthsis plugin does not create any automatic mappings, but provides the
+following commands:
+
+ *:ToggleRaibowParenthesis*
+|:ToggleRaibowParenthesis|
+ Manualy start rainbow parenthesis.. If no bracket type has been loaded
+ yet then round brackets will be loaded by default.
+
+==============================================================================
+ *rainbow_parenthsis-functions*
+2. Functions~
+
+|rainbow_parenthsis#Activate()| *rainbow_parenthsis#Activate()*
+ Acticate the loaded parenthsis
+
+|rainbow_parenthsis#Clear()| *rainbow_parenthsis#Clear()*
+ Deactivate rainbow parenthesis
+
+|rainbow_parenthsis#Toggle()| *rainbow_parenthsis#Toggle()*
+ Toogles rainbow parenthesis status. If no bracket type has been loaded
+ yet then round brackets will be loaded.
+
+|rainbow_parenthsis#LoadRound()| *rainbow_parenthsis#LoadRound()*
+ Load syntax for parenthesis or round brackets '(' ')' - This will be
+ loaded by default if nothing else has been loaded.
+
+|rainbow_parenthsis#LoadSquare()| *rainbow_parenthsis#LoadSquare()*
+ Load syntax for box brackets or square brackets '[' ']'
+
+|rainbow_parenthsis#LoadBraces()| *rainbow_parenthsis#LoadBraces()*
+ Load syntax for curly brackets or braces '{' '}'
+
+|rainbow_parenthsis#LoadChevrons()| *rainbow_parenthsis#LoadChevrons()*
+ Load syntax for angle brackets or chevrons '<' '>'
+
+==============================================================================
+ *rainbow_parenthsis-configure*
+3. Configuration~
+
+The best way to use rainbow_parenthsis is to add it to sytax plugin of any
+filetype used:
+>
+ >if exists("g:btm_rainbow_color") && g:btm_rainbow_color
+ > call rainbow_parenthsis#LoadSquare ()
+ > call rainbow_parenthsis#LoadRound ()
+ > call rainbow_parenthsis#Activate ()
+ >endif
+>
+This way you don't need to load all options available but only those which
+are of importance to the actual filetype.
+
+==============================================================================
+vim:textwidth=78:tabstop=8:noexpandtab:filetype=help
diff --git a/.vim/doc/tags b/.vim/doc/tags
index 93b871e..8bc6648 100644
--- a/.vim/doc/tags
+++ b/.vim/doc/tags
@@ -1,6 +1,7 @@
'snippets' snipMate.txt /*'snippets'*
.snippet snipMate.txt /*.snippet*
.snippets snipMate.txt /*.snippets*
+:ToggleRaibowParenthesis rainbow_parenthsis.txt /*:ToggleRaibowParenthesis*
Align-copyright Align.txt /*Align-copyright*
ExtractSnips() snipMate.txt /*ExtractSnips()*
ExtractSnipsFile() snipMate.txt /*ExtractSnipsFile()*
@@ -90,12 +91,28 @@ alignmap-tt Align.txt /*alignmap-tt*
alignmap-t~ Align.txt /*alignmap-t~*
alignmaps Align.txt /*alignmaps*
alignusage Align.txt /*alignusage*
+cs surround.txt /*cs*
+ds surround.txt /*ds*
g:snippets_dir snipMate.txt /*g:snippets_dir*
g:snips_author snipMate.txt /*g:snips_author*
+i_CTRL-G_S surround.txt /*i_CTRL-G_S*
+i_CTRL-G_s surround.txt /*i_CTRL-G_s*
i_CTRL-R_<Tab> snipMate.txt /*i_CTRL-R_<Tab>*
list-snippets snipMate.txt /*list-snippets*
multi_snip snipMate.txt /*multi_snip*
otl2html vo_readme.txt /*otl2html*
+rainbow_parenthsis#Activate() rainbow_parenthsis.txt /*rainbow_parenthsis#Activate()*
+rainbow_parenthsis#Clear() rainbow_parenthsis.txt /*rainbow_parenthsis#Clear()*
+rainbow_parenthsis#LoadBraces() rainbow_parenthsis.txt /*rainbow_parenthsis#LoadBraces()*
+rainbow_parenthsis#LoadChevrons() rainbow_parenthsis.txt /*rainbow_parenthsis#LoadChevrons()*
+rainbow_parenthsis#LoadRound() rainbow_parenthsis.txt /*rainbow_parenthsis#LoadRound()*
+rainbow_parenthsis#LoadSquare() rainbow_parenthsis.txt /*rainbow_parenthsis#LoadSquare()*
+rainbow_parenthsis#Toggle() rainbow_parenthsis.txt /*rainbow_parenthsis#Toggle()*
+rainbow_parenthsis-about rainbow_parenthsis.txt /*rainbow_parenthsis-about*
+rainbow_parenthsis-commands rainbow_parenthsis.txt /*rainbow_parenthsis-commands*
+rainbow_parenthsis-configure rainbow_parenthsis.txt /*rainbow_parenthsis-configure*
+rainbow_parenthsis-functions rainbow_parenthsis.txt /*rainbow_parenthsis-functions*
+rainbow_parenthsis.txt rainbow_parenthsis.txt /*rainbow_parenthsis.txt*
snipMate snipMate.txt /*snipMate*
snipMate-$# snipMate.txt /*snipMate-$#*
snipMate-${#:} snipMate.txt /*snipMate-${#:}*
@@ -117,6 +134,16 @@ snipMate.txt snipMate.txt /*snipMate.txt*
snippet snipMate.txt /*snippet*
snippet-syntax snipMate.txt /*snippet-syntax*
snippets snipMate.txt /*snippets*
+surround surround.txt /*surround*
+surround-author surround.txt /*surround-author*
+surround-customizing surround.txt /*surround-customizing*
+surround-issues surround.txt /*surround-issues*
+surround-mappings surround.txt /*surround-mappings*
+surround-replacements surround.txt /*surround-replacements*
+surround-targets surround.txt /*surround-targets*
+surround.txt surround.txt /*surround.txt*
+vS surround.txt /*vS*
+vgS surround.txt /*vgS*
vimoutliner vo_readme.txt /*vimoutliner*
vo vo_readme.txt /*vo*
vo-activities vo_readme.txt /*vo-activities*
@@ -147,3 +174,8 @@ vo-troubleshooting vo_readme.txt /*vo-troubleshooting*
vo-updating vo_readme.txt /*vo-updating*
vo-version vo_readme.txt /*vo-version*
vo_readme.txt vo_readme.txt /*vo_readme.txt*
+vs surround.txt /*vs*
+yS surround.txt /*yS*
+ySS surround.txt /*ySS*
+ys surround.txt /*ys*
+yss surround.txt /*yss*
diff --git a/.vim/ftplugin/html/sparkup.py b/.vim/ftplugin/html/sparkup.py
new file mode 100755
index 0000000..f968d17
--- /dev/null
+++ b/.vim/ftplugin/html/sparkup.py
@@ -0,0 +1,1087 @@
+#!/usr/bin/python2
+# -*- coding: utf-8 -*-
+version = "0.1.3"
+
+import os
+import fileinput
+import getopt
+import sys
+import re
+
+# ===============================================================================
+
+class Dialect:
+ shortcuts = {}
+ synonyms = {}
+ required = {}
+ short_tags = ()
+
+class HtmlDialect(Dialect):
+ shortcuts = {
+ 'cc:ie': {
+ 'opening_tag': '<!--[if IE]>',
+ 'closing_tag': '<![endif]-->'},
+ 'cc:ie6': {
+ 'opening_tag': '<!--[if lte IE 6]>',
+ 'closing_tag': '<![endif]-->'},
+ 'cc:ie7': {
+ 'opening_tag': '<!--[if lte IE 7]>',
+ 'closing_tag': '<![endif]-->'},
+ 'cc:noie': {
+ 'opening_tag': '<!--[if !IE]><!-->',
+ 'closing_tag': '<!--<![endif]-->'},
+ 'html:4t': {
+ 'expand': True,
+ 'opening_tag':
+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n' +
+ '<html lang="en">\n' +
+ '<head>\n' +
+ ' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
+ ' ' + '<title></title>\n' +
+ '</head>\n' +
+ '<body>',
+ 'closing_tag':
+ '</body>\n' +
+ '</html>'},
+ 'html:4s': {
+ 'expand': True,
+ 'opening_tag':
+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n' +
+ '<html lang="en">\n' +
+ '<head>\n' +
+ ' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
+ ' ' + '<title></title>\n' +
+ '</head>\n' +
+ '<body>',
+ 'closing_tag':
+ '</body>\n' +
+ '</html>'},
+ 'html:xt': {
+ 'expand': True,
+ 'opening_tag':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' +
+ '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n' +
+ '<head>\n' +
+ ' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
+ ' ' + '<title></title>\n' +
+ '</head>\n' +
+ '<body>',
+ 'closing_tag':
+ '</body>\n' +
+ '</html>'},
+ 'html:xs': {
+ 'expand': True,
+ 'opening_tag':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n' +
+ '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n' +
+ '<head>\n' +
+ ' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
+ ' ' + '<title></title>\n' +
+ '</head>\n' +
+ '<body>',
+ 'closing_tag':
+ '</body>\n' +
+ '</html>'},
+ 'html:xxs': {
+ 'expand': True,
+ 'opening_tag':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n' +
+ '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n' +
+ '<head>\n' +
+ ' ' + '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />\n' +
+ ' ' + '<title></title>\n' +
+ '</head>\n' +
+ '<body>',
+ 'closing_tag':
+ '</body>\n' +
+ '</html>'},
+ 'html:5': {
+ 'expand': True,
+ 'opening_tag':
+ '<!DOCTYPE html>\n' +
+ '<html lang="en">\n' +
+ '<head>\n' +
+ ' ' + '<meta charset="UTF-8" />\n' +
+ ' ' + '<title></title>\n' +
+ '</head>\n' +
+ '<body>',
+ 'closing_tag':
+ '</body>\n' +
+ '</html>'},
+ 'input:button': {
+ 'name': 'input',
+ 'attributes': { 'class': 'button', 'type': 'button', 'name': '', 'value': '' }
+ },
+ 'input:password': {
+ 'name': 'input',
+ 'attributes': { 'class': 'text password', 'type': 'password', 'name': '', 'value': '' }
+ },
+ 'input:radio': {
+ 'name': 'input',
+ 'attributes': { 'class': 'radio', 'type': 'radio', 'name': '', 'value': '' }
+ },
+ 'input:checkbox': {
+ 'name': 'input',
+ 'attributes': { 'class': 'checkbox', 'type': 'checkbox', 'name': '', 'value': '' }
+ },
+ 'input:file': {
+ 'name': 'input',
+ 'attributes': { 'class': 'file', 'type': 'file', 'name': '', 'value': '' }
+ },
+ 'input:text': {
+ 'name': 'input',
+ 'attributes': { 'class': 'text', 'type': 'text', 'name': '', 'value': '' }
+ },
+ 'input:submit': {
+ 'name': 'input',
+ 'attributes': { 'class': 'submit', 'type': 'submit', 'value': '' }
+ },
+ 'input:hidden': {
+ 'name': 'input',
+ 'attributes': { 'type': 'hidden', 'name': '', 'value': '' }
+ },
+ 'script:src': {
+ 'name': 'script',
+ 'attributes': { 'src': '' }
+ },
+ 'script:jquery': {
+ 'name': 'script',
+ 'attributes': { 'src': 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' }
+ },
+ 'script:jsapi': {
+ 'name': 'script',
+ 'attributes': { 'src': 'http://www.google.com/jsapi' }
+ },
+ 'script:jsapix': {
+ 'name': 'script',
+ 'text': '\n google.load("jquery", "1.3.2");\n google.setOnLoadCallback(function() {\n \n });\n'
+ },
+ 'link:css': {
+ 'name': 'link',
+ 'attributes': { 'rel': 'stylesheet', 'type': 'text/css', 'href': '', 'media': 'all' },
+ },
+ 'link:print': {
+ 'name': 'link',
+ 'attributes': { 'rel': 'stylesheet', 'type': 'text/css', 'href': '', 'media': 'print' },
+ },
+ 'link:favicon': {
+ 'name': 'link',
+ 'attributes': { 'rel': 'shortcut icon', 'type': 'image/x-icon', 'href': '' },
+ },
+ 'link:touch': {
+ 'name': 'link',
+ 'attributes': { 'rel': 'apple-touch-icon', 'href': '' },
+ },
+ 'link:rss': {
+ 'name': 'link',
+ 'attributes': { 'rel': 'alternate', 'type': 'application/rss+xml', 'title': 'RSS', 'href': '' },
+ },
+ 'link:atom': {
+ 'name': 'link',
+ 'attributes': { 'rel': 'alternate', 'type': 'application/atom+xml', 'title': 'Atom', 'href': '' },
+ },
+ 'meta:ie7': {
+ 'name': 'meta',
+ 'attributes': { 'http-equiv': 'X-UA-Compatible', 'content': 'IE=7' },
+ },
+ 'meta:ie8': {
+ 'name': 'meta',
+ 'attributes': { 'http-equiv': 'X-UA-Compatible', 'content': 'IE=8' },
+ },
+ 'form:get': {
+ 'name': 'form',
+ 'attributes': { 'method': 'get' },
+ },
+ 'form:g': {
+ 'name': 'form',
+ 'attributes': { 'method': 'get' },
+ },
+ 'form:post': {
+ 'name': 'form',
+ 'attributes': { 'method': 'post' },
+ },
+ 'form:p': {
+ 'name': 'form',
+ 'attributes': { 'method': 'post' },
+ },
+ }
+ synonyms = {
+ 'checkbox': 'input:checkbox',
+ 'check': 'input:checkbox',
+ 'input:c': 'input:checkbox',
+ 'button': 'input:button',
+ 'input:b': 'input:button',
+ 'input:h': 'input:hidden',
+ 'hidden': 'input:hidden',
+ 'submit': 'input:submit',
+ 'input:s': 'input:submit',
+ 'radio': 'input:radio',
+ 'input:r': 'input:radio',
+ 'text': 'input:text',
+ 'passwd': 'input:password',
+ 'password': 'input:password',
+ 'pw': 'input:password',
+ 'input:t': 'input:text',
+ 'linkcss': 'link:css',
+ 'scriptsrc': 'script:src',
+ 'jquery': 'script:jquery',
+ 'jsapi': 'script:jsapi',
+ 'html5': 'html:5',
+ 'html4': 'html:4s',
+ 'html4s': 'html:4s',
+ 'html4t': 'html:4t',
+ 'xhtml': 'html:xxs',
+ 'xhtmlt': 'html:xt',
+ 'xhtmls': 'html:xs',
+ 'xhtml11': 'html:xxs',
+ 'opt': 'option',
+ 'st': 'strong',
+ 'css': 'style',
+ 'csss': 'link:css',
+ 'css:src': 'link:css',
+ 'csssrc': 'link:css',
+ 'js': 'script',
+ 'jss': 'script:src',
+ 'js:src': 'script:src',
+ 'jssrc': 'script:src',
+ }
+ short_tags = (
+ 'area', 'base', 'basefont', 'br', 'embed', 'hr', \
+ 'input', 'img', 'link', 'param', 'meta')
+ required = {
+ 'a': {'href':''},
+ 'base': {'href':''},
+ 'abbr': {'title': ''},
+ 'acronym':{'title': ''},
+ 'bdo': {'dir': ''},
+ 'link': {'rel': 'stylesheet', 'href': ''},
+ 'style': {'type': 'text/css'},
+ 'script': {'type': 'text/javascript'},
+ 'img': {'src':'', 'alt':''},
+ 'iframe': {'src': '', 'frameborder': '0'},
+ 'embed': {'src': '', 'type': ''},
+ 'object': {'data': '', 'type': ''},
+ 'param': {'name': '', 'value': ''},
+ 'form': {'action': '', 'method': 'post'},
+ 'table': {'cellspacing': '0'},
+ 'input': {'type': '', 'name': '', 'value': ''},
+ 'base': {'href': ''},
+ 'area': {'shape': '', 'coords': '', 'href': '', 'alt': ''},
+ 'select': {'name': ''},
+ 'option': {'value': ''},
+ 'textarea':{'name': ''},
+ 'meta': {'content': ''},
+ }
+
+class Parser:
+ """The parser.
+ """
+
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__(self, options=None, str='', dialect=HtmlDialect()):
+ """Constructor.
+ """
+
+ self.tokens = []
+ self.str = str
+ self.options = options
+ self.dialect = dialect
+ self.root = Element(parser=self)
+ self.caret = []
+ self.caret.append(self.root)
+ self._last = []
+
+ # Methods
+ # ---------------------------------------------------------------------------
+
+ def load_string(self, str):
+ """Loads a string to parse.
+ """
+
+ self.str = str
+ self._tokenize()
+ self._parse()
+
+ def render(self):
+ """Renders.
+ Called by [[Router]].
+ """
+
+ # Get the initial render of the root node
+ output = self.root.render()
+
+ # Indent by whatever the input is indented with
+ indent = re.findall("^[\r\n]*(\s*)", self.str)[0]
+ output = indent + output.replace("\n", "\n" + indent)
+
+ # Strip newline if not needed
+ if self.options.has("no-last-newline") \
+ or self.prefix or self.suffix:
+ output = re.sub(r'\n\s*$', '', output)
+
+ # TextMate mode
+ if self.options.has("textmate"):
+ output = self._textmatify(output)
+
+ return output
+
+ # Protected methods
+ # ---------------------------------------------------------------------------
+
+ def _textmatify(self, output):
+ """Returns a version of the output with TextMate placeholders in it.
+ """
+
+ matches = re.findall(r'(></)|("")|(\n\s+)\n|(.|\s)', output)
+ output = ''
+ n = 1
+ for i in matches:
+ if i[0]:
+ output += '>$%i</' % n
+ n += 1
+ elif i[1]:
+ output += '"$%i"' % n
+ n += 1
+ elif i[2]:
+ output += i[2] + '$%i\n' % n
+ n += 1
+ elif i[3]:
+ output += i[3]
+ output += "$0"
+ return output
+
+ def _tokenize(self):
+ """Tokenizes.
+ Initializes [[self.tokens]].
+ """
+
+ str = self.str.strip()
+
+ # Find prefix/suffix
+ while True:
+ match = re.match(r"^(\s*<[^>]+>\s*)", str)
+ if match is None: break
+ if self.prefix is None: self.prefix = ''
+ self.prefix += match.group(0)
+ str = str[len(match.group(0)):]
+
+ while True:
+ match = re.findall(r"(\s*<[^>]+>[\s\n\r]*)$", str)
+ if not match: break
+ if self.suffix is None: self.suffix = ''
+ self.suffix = match[0] + self.suffix
+ str = str[:-len(match[0])]
+
+ # Split by the element separators
+ for token in re.split('(<|>|\+(?!\\s*\+|$))', str):
+ if token.strip() != '':
+ self.tokens.append(Token(token, parser=self))
+
+ def _parse(self):
+ """Takes the tokens and does its thing.
+ Populates [[self.root]].
+ """
+
+ # Carry it over to the root node.
+ if self.prefix or self.suffix:
+ self.root.prefix = self.prefix
+ self.root.suffix = self.suffix
+ self.root.depth += 1
+
+ for token in self.tokens:
+ if token.type == Token.ELEMENT:
+ # Reset the "last elements added" list. We will
+ # repopulate this with the new elements added now.
+ self._last[:] = []
+
+ # Create [[Element]]s from a [[Token]].
+ # They will be created as many as the multiplier specifies,
+ # multiplied by how many carets we have
+ count = 0
+ for caret in self.caret:
+ local_count = 0
+ for i in range(token.multiplier):
+ count += 1
+ local_count += 1
+ new = Element(token, caret,
+ count = count,
+ local_count = local_count,
+ parser = self)
+ self._last.append(new)
+ caret.append(new)
+
+ # For >
+ elif token.type == Token.CHILD:
+ # The last children added.
+ self.caret[:] = self._last
+
+ # For <
+ elif token.type == Token.PARENT:
+ # If we're the root node, don't do anything
+ parent = self.caret[0].parent
+ if parent is not None:
+ self.caret[:] = [parent]
+ return
+
+ # Properties
+ # ---------------------------------------------------------------------------
+
+ # Property: dialect
+ # The dialect of XML
+ dialect = None
+
+ # Property: str
+ # The string
+ str = ''
+
+ # Property: tokens
+ # The list of tokens
+ tokens = []
+
+ # Property: options
+ # Reference to the [[Options]] instance
+ options = None
+
+ # Property: root
+ # The root [[Element]] node.
+ root = None
+
+ # Property: caret
+ # The current insertion point.
+ caret = None
+
+ # Property: _last
+ # List of the last appended stuff
+ _last = None
+
+ # Property: indent
+ # Yeah
+ indent = ''
+
+ # Property: prefix
+ # (String) The trailing tag in the beginning.
+ #
+ # Description:
+ # For instance, in `<div>ul>li</div>`, the `prefix` is `<div>`.
+ prefix = ''
+
+ # Property: suffix
+ # (string) The trailing tag at the end.
+ suffix = ''
+ pass
+
+# ===============================================================================
+
+class Element:
+ """An element.
+ """
+
+ def __init__(self, token=None, parent=None, count=None, local_count=None, \
+ parser=None, opening_tag=None, closing_tag=None, \
+ attributes=None, name=None, text=None):
+ """Constructor.
+
+ This is called by ???.
+
+ Description:
+ All parameters are optional.
+
+ token - (Token) The token (required)
+ parent - (Element) Parent element; `None` if root
+ count - (Int) The number to substitute for `&` (e.g., in `li.item-$`)
+ local_count - (Int) The number to substitute for `$` (e.g., in `li.item-&`)
+ parser - (Parser) The parser
+
+ attributes - ...
+ name - ...
+ text - ...
+ """
+
+ self.children = []
+ self.attributes = {}
+ self.parser = parser
+
+ if token is not None:
+ # Assumption is that token is of type [[Token]] and is
+ # a [[Token.ELEMENT]].
+ self.name = token.name
+ self.attributes = token.attributes.copy()
+ self.text = token.text
+ self.populate = token.populate
+ self.expand = token.expand
+ self.opening_tag = token.opening_tag
+ self.closing_tag = token.closing_tag
+
+ # `count` can be given. This will substitude & in classname and ID
+ if count is not None:
+ for key in self.attributes:
+ attrib = self.attributes[key]
+ attrib = attrib.replace('&', ("%i" % count))
+ if local_count is not None:
+ attrib = attrib.replace('$', ("%i" % local_count))
+ self.attributes[key] = attrib
+
+ # Copy over from parameters
+ if attributes: self.attributes = attribues
+ if name: self.name = name
+ if text: self.text = text
+
+ self._fill_attributes()
+
+ self.parent = parent
+ if parent is not None:
+ self.depth = parent.depth + 1
+
+ if self.populate: self._populate()
+
+ def render(self):
+ """Renders the element, along with it's subelements, into HTML code.
+
+ [Grouped under "Rendering methods"]
+ """
+
+ output = ""
+ try: spaces_count = int(self.parser.options.options['indent-spaces'])
+ except: spaces_count = 4
+ spaces = ' ' * spaces_count
+ indent = self.depth * spaces
+
+ prefix, suffix = ('', '')
+ if self.prefix: prefix = self.prefix + "\n"
+ if self.suffix: suffix = self.suffix
+
+ # Make the guide from the ID (/#header), or the class if there's no ID (/.item)
+ # This is for the start-guide, end-guide and post-tag-guides
+ guide_str = ''
+ if 'id' in self.attributes:
+ guide_str += "#%s" % self.attributes['id']
+ elif 'class' in self.attributes:
+ guide_str += ".%s" % self.attributes['class'].replace(' ', '.')
+
+ # Build the post-tag guide (e.g., </div><!-- /#header -->),
+ # the start guide, and the end guide.
+ guide = ''
+ start_guide = ''
+ end_guide = ''
+ if ((self.name == 'div') and \
+ (('id' in self.attributes) or ('class' in self.attributes))):
+
+ if (self.parser.options.has('post-tag-guides')):
+ guide = "<!-- /%s -->" % guide_str
+
+ if (self.parser.options.has('start-guide-format')):
+ format = self.parser.options.get('start-guide-format')
+ try: start_guide = format % guide_str
+ except: start_guide = (format + " " + guide_str).strip()
+ start_guide = "%s<!-- %s -->\n" % (indent, start_guide)
+
+ if (self.parser.options.has('end-guide-format')):
+ format = self.parser.options.get('end-guide-format')
+ try: end_guide = format % guide_str
+ except: end_guide = (format + " " + guide_str).strip()
+ end_guide = "\n%s<!-- %s -->" % (indent, end_guide)
+
+ # Short, self-closing tags (<br />)
+ short_tags = self.parser.dialect.short_tags
+
+ # When it should be expanded..
+ # (That is, <div>\n...\n</div> or similar -- wherein something must go
+ # inside the opening/closing tags)
+ if len(self.children) > 0 \
+ or self.expand \
+ or prefix or suffix \
+ or (self.parser.options.has('expand-divs') and self.name == 'div'):
+
+ for child in self.children:
+ output += child.render()
+
+ # For expand divs: if there are no children (that is, `output`
+ # is still blank despite above), fill it with a blank line.
+ if (output == ''): output = indent + spaces + "\n"
+
+ # If we're a root node and we have a prefix or suffix...
+ # (Only the root node can have a prefix or suffix.)
+ if prefix or suffix:
+ output = "%s%s%s%s%s\n" % \
+ (indent, prefix, output, suffix, guide)
+
+ # Uh..
+ elif self.name != '' or \
+ self.opening_tag is not None or \
+ self.closing_tag is not None:
+ output = start_guide + \
+ indent + self.get_opening_tag() + "\n" + \
+ output + \
+ indent + self.get_closing_tag() + \
+ guide + end_guide + "\n"
+
+
+ # Short, self-closing tags (<br />)
+ elif self.name in short_tags:
+ output = "%s<%s />\n" % (indent, self.get_default_tag())
+
+ # Tags with text, possibly
+ elif self.name != '' or \
+ self.opening_tag is not None or \
+ self.closing_tag is not None:
+ output = "%s%s%s%s%s%s%s%s" % \
+ (start_guide, indent, self.get_opening_tag(), \
+ self.text, \
+ self.get_closing_tag(), \
+ guide, end_guide, "\n")
+
+ # Else, it's an empty-named element (like the root). Pass.
+ else: pass
+
+
+ return output
+
+ def get_default_tag(self):
+ """Returns the opening tag (without brackets).
+
+ Usage:
+ element.get_default_tag()
+
+ [Grouped under "Rendering methods"]
+ """
+
+ output = '%s' % (self.name)
+ for key, value in self.attributes.iteritems():
+ output += ' %s="%s"' % (key, value)
+ return output
+
+ def get_opening_tag(self):
+ if self.opening_tag is None:
+ return "<%s>" % self.get_default_tag()
+ else:
+ return self.opening_tag
+
+ def get_closing_tag(self):
+ if self.closing_tag is None:
+ return "</%s>" % self.name
+ else:
+ return self.closing_tag
+
+ def append(self, object):
+ """Registers an element as a child of this element.
+
+ Usage:
+ element.append(child)
+
+ Description:
+ Adds a given element `child` to the children list of this element. It
+ will be rendered when [[render()]] is called on the element.
+
+ See also:
+ - [[get_last_child()]]
+
+ [Grouped under "Traversion methods"]
+ """
+
+ self.children.append(object)
+
+ def get_last_child(self):
+ """Returns the last child element which was [[append()]]ed to this element.
+
+ Usage:
+ element.get_last_child()
+
+ Description:
+ This is the same as using `element.children[-1]`.
+
+ [Grouped under "Traversion methods"]
+ """
+
+ return self.children[-1]
+
+ def _populate(self):
+ """Expands with default items.
+
+ This is called when the [[populate]] flag is turned on.
+ """
+
+ if self.name == 'ul':
+ elements = [Element(name='li', parent=self, parser=self.parser)]
+
+ elif self.name == 'dl':
+ elements = [
+ Element(name='dt', parent=self, parser=self.parser),
+ Element(name='dd', parent=self, parser=self.parser)]
+
+ elif self.name == 'table':
+ tr = Element(name='tr', parent=self, parser=self.parser)
+ td = Element(name='td', parent=tr, parser=self.parser)
+ tr.children.append(td)
+ elements = [tr]
+
+ else:
+ elements = []
+
+ for el in elements:
+ self.children.append(el)
+
+ def _fill_attributes(self):
+ """Fills default attributes for certain elements.
+
+ Description:
+ This is called by the constructor.
+
+ [Protected, grouped under "Protected methods"]
+ """
+
+ # Make sure <a>'s have a href, <img>'s have an src, etc.
+ required = self.parser.dialect.required
+
+ for element, attribs in required.iteritems():
+ if self.name == element:
+ for attrib in attribs:
+ if attrib not in self.attributes:
+ self.attributes[attrib] = attribs[attrib]
+
+ # ---------------------------------------------------------------------------
+
+ # Property: last_child
+ # [Read-only]
+ last_child = property(get_last_child)
+
+ # ---------------------------------------------------------------------------
+
+ # Property: parent
+ # (Element) The parent element.
+ parent = None
+
+ # Property: name
+ # (String) The name of the element (e.g., `div`)
+ name = ''
+
+ # Property: attributes
+ # (Dict) The dictionary of attributes (e.g., `{'src': 'image.jpg'}`)
+ attributes = None
+
+ # Property: children
+ # (List of Elements) The children
+ children = None
+
+ # Property: opening_tag
+ # (String or None) The opening tag. Optional; will use `name` and
+ # `attributes` if this is not given.
+ opening_tag = None
+
+ # Property: closing_tag
+ # (String or None) The closing tag
+ closing_tag = None
+
+ text = ''
+ depth = -1
+ expand = False
+ populate = False
+ parser = None
+
+ # Property: prefix
+ # Only the root note can have this.
+ prefix = None
+ suffix = None
+
+# ===============================================================================
+
+class Token:
+ def __init__(self, str, parser=None):
+ """Token.
+
+ Description:
+ str - The string to parse
+
+ In the string `div > ul`, there are 3 tokens. (`div`, `>`, and `ul`)
+
+ For `>`, it will be a `Token` with `type` set to `Token.CHILD`
+ """
+
+ self.str = str.strip()
+ self.attributes = {}
+ self.parser = parser
+
+ # Set the type.
+ if self.str == '<':
+ self.type = Token.PARENT
+ elif self.str == '>':
+ self.type = Token.CHILD
+ elif self.str == '+':
+ self.type = Token.SIBLING
+ else:
+ self.type = Token.ELEMENT
+ self._init_element()
+
+ def _init_element(self):
+ """Initializes. Only called if the token is an element token.
+ [Private]
+ """
+
+ # Get the tag name. Default to DIV if none given.
+ name = re.findall('^([\w\-:]*)', self.str)[0]
+ name = name.lower().replace('-', ':')
+
+ # Find synonyms through this thesaurus
+ synonyms = self.parser.dialect.synonyms
+ if name in synonyms.keys():
+ name = synonyms[name]
+
+ if ':' in name:
+ try: spaces_count = int(self.parser.options.get('indent-spaces'))
+ except: spaces_count = 4
+ indent = ' ' * spaces_count
+
+ shortcuts = self.parser.dialect.shortcuts
+ if name in shortcuts.keys():
+ for key, value in shortcuts[name].iteritems():
+ setattr(self, key, value)
+ if 'html' in name:
+ return
+ else:
+ self.name = name
+
+ elif (name == ''): self.name = 'div'
+ else: self.name = name
+
+ # Look for attributes
+ attribs = []
+ for attrib in re.findall('\[([^\]]*)\]', self.str):
+ attribs.append(attrib)
+ self.str = self.str.replace("[" + attrib + "]", "")
+ if len(attribs) > 0:
+ for attrib in attribs:
+ try: key, value = attrib.split('=', 1)
+ except: key, value = attrib, ''
+ self.attributes[key] = value
+
+ # Try looking for text
+ text = None
+ for text in re.findall('\{([^\}]*)\}', self.str):
+ self.str = self.str.replace("{" + text + "}", "")
+ if text is not None:
+ self.text = text
+
+ # Get the class names
+ classes = []
+ for classname in re.findall('\.([\$a-zA-Z0-9_\-\&]+)', self.str):
+ classes.append(classname)
+ if len(classes) > 0:
+ try: self.attributes['class']
+ except: self.attributes['class'] = ''
+ self.attributes['class'] += ' ' + ' '.join(classes)
+ self.attributes['class'] = self.attributes['class'].strip()
+
+ # Get the ID
+ id = None
+ for id in re.findall('#([\$a-zA-Z0-9_\-\&]+)', self.str): pass
+ if id is not None:
+ self.attributes['id'] = id
+
+ # See if there's a multiplier (e.g., "li*3")
+ multiplier = None
+ for multiplier in re.findall('\*\s*([0-9]+)', self.str): pass
+ if multiplier is not None:
+ self.multiplier = int(multiplier)
+
+ # Populate flag (e.g., ul+)
+ flags = None
+ for flags in re.findall('[\+\!]+$', self.str): pass
+ if flags is not None:
+ if '+' in flags: self.populate = True
+ if '!' in flags: self.expand = True
+
+ def __str__(self):
+ return self.str
+
+ str = ''
+ parser = None
+
+ # For elements
+ # See the properties of `Element` for description on these.
+ name = ''
+ attributes = None
+ multiplier = 1
+ expand = False
+ populate = False
+ text = ''
+ opening_tag = None
+ closing_tag = None
+
+ # Type
+ type = 0
+ ELEMENT = 2
+ CHILD = 4
+ PARENT = 8
+ SIBLING = 16
+
+# ===============================================================================
+
+class Router:
+ """The router.
+ """
+
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__(self):
+ pass
+
+ # Methods
+ # ---------------------------------------------------------------------------
+
+ def start(self, options=None, str=None, ret=None):
+ if (options):
+ self.options = Options(router=self, options=options, argv=None)
+ else:
+ self.options = Options(router=self, argv=sys.argv[1:], options=None)
+
+ if (self.options.has('help')):
+ return self.help()
+
+ elif (self.options.has('version')):
+ return self.version()
+
+ else:
+ return self.parse(str=str, ret=ret)
+
+ def help(self):
+ print "Usage: %s [OPTIONS]" % sys.argv[0]
+ print "Expands input into HTML."
+ print ""
+ for short, long, info in self.options.cmdline_keys:
+ if "Deprecated" in info: continue
+ if not short == '': short = '-%s,' % short
+ if not long == '': long = '--%s' % long.replace("=", "=XXX")
+
+ print "%6s %-25s %s" % (short, long, info)
+ print ""
+ print "\n".join(self.help_content)
+
+ def version(self):
+ print "Uhm, yeah."
+
+ def parse(self, str=None, ret=None):
+ self.parser = Parser(self.options)
+
+ try:
+ # Read the files
+ # for line in fileinput.input(): lines.append(line.rstrip(os.linesep))
+ if str is not None:
+ lines = str
+ else:
+ lines = [sys.stdin.read()]
+ lines = " ".join(lines)
+
+ except KeyboardInterrupt:
+ pass
+
+ except:
+ sys.stderr.write("Reading failed.\n")
+ return
+
+ try:
+ self.parser.load_string(lines)
+ output = self.parser.render()
+ if ret: return output
+ sys.stdout.write(output)
+
+ except:
+ sys.stderr.write("Parse error. Check your input.\n")
+ print sys.exc_info()[0]
+ print sys.exc_info()[1]
+
+ def exit(self):
+ sys.exit()
+
+ help_content = [
+ "Please refer to the manual for more information.",
+ ]
+
+# ===============================================================================
+
+class Options:
+ def __init__(self, router, argv, options=None):
+ # Init self
+ self.router = router
+
+ # `options` can be given as a dict of stuff to preload
+ if options:
+ for k, v in options.iteritems():
+ self.options[k] = v
+ return
+
+ # Prepare for getopt()
+ short_keys, long_keys = "", []
+ for short, long, info in self.cmdline_keys: # 'v', 'version'
+ short_keys += short
+ long_keys.append(long)
+
+ try:
+ getoptions, arguments = getopt.getopt(argv, short_keys, long_keys)
+
+ except getopt.GetoptError:
+ err = sys.exc_info()[1]
+ sys.stderr.write("Options error: %s\n" % err)
+ sys.stderr.write("Try --help for a list of arguments.\n")
+ return router.exit()
+
+ # Sort them out into options
+ options = {}
+ i = 0
+ for option in getoptions:
+ key, value = option # '--version', ''
+ if (value == ''): value = True
+
+ # If the key is long, write it
+ if key[0:2] == '--':
+ clean_key = key[2:]
+ options[clean_key] = value
+
+ # If the key is short, look for the long version of it
+ elif key[0:1] == '-':
+ for short, long, info in self.cmdline_keys:
+ if short == key[1:]:
+ print long
+ options[long] = True
+
+ # Done
+ for k, v in options.iteritems():
+ self.options[k] = v
+
+ def __getattr__(self, attr):
+ return self.get(attr)
+
+ def get(self, attr):
+ try: return self.options[attr]
+ except: return None
+
+ def has(self, attr):
+ try: return self.options.has_key(attr)
+ except: return False
+
+ options = {
+ 'indent-spaces': 4
+ }
+ cmdline_keys = [
+ ('h', 'help', 'Shows help'),
+ ('v', 'version', 'Shows the version'),
+ ('', 'no-guides', 'Deprecated'),
+ ('', 'post-tag-guides', 'Adds comments at the end of DIV tags'),
+ ('', 'textmate', 'Adds snippet info (textmate mode)'),
+ ('', 'indent-spaces=', 'Indent spaces'),
+ ('', 'expand-divs', 'Automatically expand divs'),
+ ('', 'no-last-newline', 'Skip the trailing newline'),
+ ('', 'start-guide-format=', 'To be documented'),
+ ('', 'end-guide-format=', 'To be documented'),
+ ]
+
+ # Property: router
+ # Router
+ router = 1
+
+# ===============================================================================
+
+if __name__ == "__main__":
+ z = Router()
+ z.start()
diff --git a/.vim/ftplugin/html/sparkup.vim b/.vim/ftplugin/html/sparkup.vim
new file mode 100644
index 0000000..ddf9a89
--- /dev/null
+++ b/.vim/ftplugin/html/sparkup.vim
@@ -0,0 +1,76 @@
+" Sparkup
+" Installation:
+" Copy the contents of vim/ftplugin/ to your ~/.vim/ftplugin directory.
+"
+" $ cp -R vim/ftplugin ~/.vim/ftplugin/
+"
+" Configuration:
+" g:sparkup (Default: 'sparkup') -
+" Location of the sparkup executable. You shouldn't need to change this
+" setting if you used the install option above.
+"
+" g:sparkupArgs (Default: '--no-last-newline') -
+" Additional args passed to sparkup.
+"
+" g:sparkupExecuteMapping (Default: '<c-e>') -
+" Mapping used to execute sparkup.
+"
+" g:sparkupNextMapping (Default: '<c-n>') -
+" Mapping used to jump to the next empty tag/attribute.
+
+set rtp+=~/.vim/ftplugin/html
+
+if !exists('g:sparkupExecuteMapping')
+ let g:sparkupExecuteMapping = '<c-e>'
+endif
+
+if !exists('g:sparkupNextMapping')
+ let g:sparkupNextMapping = '<c-n>'
+endif
+
+exec 'nmap <buffer> ' . g:sparkupExecuteMapping . ' :call <SID>Sparkup()<cr>'
+exec 'imap <buffer> ' . g:sparkupExecuteMapping . ' <c-g>u<Esc>:call <SID>Sparkup()<cr>'
+exec 'nmap <buffer> ' . g:sparkupNextMapping . ' :call <SID>SparkupNext()<cr>'
+exec 'imap <buffer> ' . g:sparkupNextMapping . ' <c-g>u<Esc>:call <SID>SparkupNext()<cr>'
+
+if exists('*s:Sparkup')
+ finish
+endif
+
+function! s:Sparkup()
+ if !exists('s:sparkup')
+ let s:sparkup = exists('g:sparkup') ? g:sparkup : 'sparkup'
+ let s:sparkupArgs = exists('g:sparkupArgs') ? g:sparkupArgs : '--no-last-newline'
+ " check the user's path first. if not found then search relative to
+ " sparkup.vim in the runtimepath.
+ if !executable(s:sparkup)
+ let paths = substitute(escape(&runtimepath, ' '), '\(,\|$\)', '/**\1', 'g')
+ let s:sparkup = findfile('sparkup.py', paths)
+
+ if !filereadable(s:sparkup)
+ echohl WarningMsg
+ echom 'Warning: could not find sparkup on your path or in your vim runtime path.'
+ echohl None
+ finish
+ endif
+ endif
+ let s:sparkup = '"' . s:sparkup . '"'
+ let s:sparkup .= printf(' %s --indent-spaces=%s', s:sparkupArgs, &shiftwidth)
+ if has('win32') || has('win64')
+ let s:sparkup = 'python ' . s:sparkup
+ endif
+ endif
+ exec '.!' . s:sparkup
+ call s:SparkupNext()
+endfunction
+
+function! s:SparkupNext()
+ " 1: empty tag, 2: empty attribute, 3: empty line
+ let n = search('><\/\|\(""\)\|^\s*$', 'Wp')
+ if n == 3
+ startinsert!
+ else
+ execute 'normal l'
+ startinsert
+ endif
+endfunction
diff --git a/.vim/plugin/NERD_commenter.vim b/.vim/plugin/NERD_commenter.vim
new file mode 100644
index 0000000..982b140
--- /dev/null
+++ b/.vim/plugin/NERD_commenter.vim
@@ -0,0 +1,2786 @@
+" ============================================================================
+" File: NERD_commenter.vim
+" Description: vim global plugin that provides easy code commenting
+" Maintainer: Martin Grenfell <martin_grenfell at msn dot com>
+" Version: 2.2.2
+" Last Change: 09th October, 2010
+" License: This program is free software. It comes without any warranty,
+" to the extent permitted by applicable law. You can redistribute
+" it and/or modify it under the terms of the Do What The Fuck You
+" Want To Public License, Version 2, as published by Sam Hocevar.
+" See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+" ============================================================================
+
+" Section: script init stuff {{{1
+if exists("loaded_nerd_comments")
+ finish
+endif
+if v:version < 700
+ echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!"
+ finish
+endif
+let loaded_nerd_comments = 1
+
+" Function: s:InitVariable() function {{{2
+" This function is used to initialise a given variable to a given value. The
+" variable is only initialised if it does not exist prior
+"
+" Args:
+" -var: the name of the var to be initialised
+" -value: the value to initialise var to
+"
+" Returns:
+" 1 if the var is set, 0 otherwise
+function s:InitVariable(var, value)
+ if !exists(a:var)
+ exec 'let ' . a:var . ' = ' . "'" . a:value . "'"
+ return 1
+ endif
+ return 0
+endfunction
+
+" Section: space string init{{{2
+" When putting spaces after the left delim and before the right we use
+" s:spaceStr for the space char. This way we can make it add anything after
+" the left and before the right by modifying this variable
+let s:spaceStr = ' '
+let s:lenSpaceStr = strlen(s:spaceStr)
+
+" Section: variable init calls {{{2
+call s:InitVariable("g:NERDAllowAnyVisualDelims", 1)
+call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0)
+call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0)
+call s:InitVariable("g:NERDCompactSexyComs", 0)
+call s:InitVariable("g:NERDCreateDefaultMappings", 1)
+call s:InitVariable("g:NERDDefaultNesting", 1)
+call s:InitVariable("g:NERDMenuMode", 3)
+call s:InitVariable("g:NERDLPlace", "[>")
+call s:InitVariable("g:NERDUsePlaceHolders", 1)
+call s:InitVariable("g:NERDRemoveAltComs", 1)
+call s:InitVariable("g:NERDRemoveExtraSpaces", 1)
+call s:InitVariable("g:NERDRPlace", "<]")
+call s:InitVariable("g:NERDSpaceDelims", 0)
+call s:InitVariable("g:NERDDelimiterRequests", 1)
+
+let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\"
+"vf ;;dA:hcs"'A {j^f(lyi(k$p0f{a A }0f{a 'left':jdd^
+
+let s:delimiterMap = {
+ \ 'aap': { 'left': '#' },
+ \ 'abc': { 'left': '%' },
+ \ 'acedb': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'actionscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'ada': { 'left': '--', 'leftAlt': '-- ' },
+ \ 'ahdl': { 'left': '--' },
+ \ 'ahk': { 'left': ';', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'amiga': { 'left': ';' },
+ \ 'aml': { 'left': '/*' },
+ \ 'ampl': { 'left': '#' },
+ \ 'apache': { 'left': '#' },
+ \ 'apachestyle': { 'left': '#' },
+ \ 'asciidoc': { 'left': '//' },
+ \ 'applescript': { 'left': '--', 'leftAlt': '(*', 'rightAlt': '*)' },
+ \ 'asm68k': { 'left': ';' },
+ \ 'asm': { 'left': ';', 'leftAlt': '#' },
+ \ 'asn': { 'left': '--' },
+ \ 'aspvbs': { 'left': '''' },
+ \ 'asterisk': { 'left': ';' },
+ \ 'asy': { 'left': '//' },
+ \ 'atlas': { 'left': 'C', 'right': '$' },
+ \ 'autohotkey': { 'left': ';' },
+ \ 'autoit': { 'left': ';' },
+ \ 'ave': { 'left': "'" },
+ \ 'awk': { 'left': '#' },
+ \ 'basic': { 'left': "'", 'leftAlt': 'REM ' },
+ \ 'bbx': { 'left': '%' },
+ \ 'bc': { 'left': '#' },
+ \ 'bib': { 'left': '%' },
+ \ 'bindzone': { 'left': ';' },
+ \ 'bst': { 'left': '%' },
+ \ 'btm': { 'left': '::' },
+ \ 'caos': { 'left': '*' },
+ \ 'calibre': { 'left': '//' },
+ \ 'catalog': { 'left': '--', 'right': '--' },
+ \ 'c': { 'left': '/*','right': '*/', 'leftAlt': '//' },
+ \ 'cfg': { 'left': '#' },
+ \ 'cg': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'ch': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'cl': { 'left': '#' },
+ \ 'clean': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'clipper': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'clojure': { 'left': ';' },
+ \ 'cmake': { 'left': '#' },
+ \ 'conkyrc': { 'left': '#' },
+ \ 'cpp': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'crontab': { 'left': '#' },
+ \ 'cs': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'csp': { 'left': '--' },
+ \ 'cterm': { 'left': '*' },
+ \ 'cucumber': { 'left': '#' },
+ \ 'cvs': { 'left': 'CVS:' },
+ \ 'd': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'dcl': { 'left': '$!' },
+ \ 'dakota': { 'left': '#' },
+ \ 'debcontrol': { 'left': '#' },
+ \ 'debsources': { 'left': '#' },
+ \ 'def': { 'left': ';' },
+ \ 'desktop': { 'left': '#' },
+ \ 'dhcpd': { 'left': '#' },
+ \ 'diff': { 'left': '#' },
+ \ 'django': { 'left': '<!--','right': '-->', 'leftAlt': '{#', 'rightAlt': '#}' },
+ \ 'docbk': { 'left': '<!--', 'right': '-->' },
+ \ 'dns': { 'left': ';' },
+ \ 'dosbatch': { 'left': 'REM ', 'leftAlt': '::' },
+ \ 'dosini': { 'left': ';' },
+ \ 'dot': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'dracula': { 'left': ';' },
+ \ 'dsl': { 'left': ';' },
+ \ 'dtml': { 'left': '<dtml-comment>', 'right': '</dtml-comment>' },
+ \ 'dylan': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'ebuild': { 'left': '#' },
+ \ 'ecd': { 'left': '#' },
+ \ 'eclass': { 'left': '#' },
+ \ 'eiffel': { 'left': '--' },
+ \ 'elf': { 'left': "'" },
+ \ 'elmfilt': { 'left': '#' },
+ \ 'erlang': { 'left': '%' },
+ \ 'eruby': { 'left': '<%#', 'right': '%>', 'leftAlt': '<!--', 'rightAlt': '-->' },
+ \ 'expect': { 'left': '#' },
+ \ 'exports': { 'left': '#' },
+ \ 'factor': { 'left': '! ', 'leftAlt': '!# ' },
+ \ 'fgl': { 'left': '#' },
+ \ 'focexec': { 'left': '-*' },
+ \ 'form': { 'left': '*' },
+ \ 'foxpro': { 'left': '*' },
+ \ 'fstab': { 'left': '#' },
+ \ 'fvwm': { 'left': '#' },
+ \ 'fx': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'gams': { 'left': '*' },
+ \ 'gdb': { 'left': '#' },
+ \ 'gdmo': { 'left': '--' },
+ \ 'geek': { 'left': 'GEEK_COMMENT:' },
+ \ 'genshi': { 'left': '<!--','right': '-->', 'leftAlt': '{#', 'rightAlt': '#}' },
+ \ 'gentoo-conf-d': { 'left': '#' },
+ \ 'gentoo-env-d': { 'left': '#' },
+ \ 'gentoo-init-d': { 'left': '#' },
+ \ 'gentoo-make-conf': { 'left': '#' },
+ \ 'gentoo-package-keywords': { 'left': '#' },
+ \ 'gentoo-package-mask': { 'left': '#' },
+ \ 'gentoo-package-use': { 'left': '#' },
+ \ 'gitcommit': { 'left': '#' },
+ \ 'gitconfig': { 'left': ';' },
+ \ 'gitrebase': { 'left': '#' },
+ \ 'gnuplot': { 'left': '#' },
+ \ 'groovy': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'gsp': { 'left': '<%--', 'right': '--%>' },
+ \ 'gtkrc': { 'left': '#' },
+ \ 'haskell': { 'left': '{-','right': '-}', 'leftAlt': '--' },
+ \ 'hb': { 'left': '#' },
+ \ 'h': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'haml': { 'left': '-#', 'leftAlt': '/' },
+ \ 'hercules': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'hog': { 'left': '#' },
+ \ 'hostsaccess': { 'left': '#' },
+ \ 'htmlcheetah': { 'left': '##' },
+ \ 'htmldjango': { 'left': '<!--','right': '-->', 'leftAlt': '{#', 'rightAlt': '#}' },
+ \ 'htmlos': { 'left': '#', 'right': '/#' },
+ \ 'ia64': { 'left': '#' },
+ \ 'icon': { 'left': '#' },
+ \ 'idlang': { 'left': ';' },
+ \ 'idl': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'inform': { 'left': '!' },
+ \ 'inittab': { 'left': '#' },
+ \ 'ishd': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'iss': { 'left': ';' },
+ \ 'ist': { 'left': '%' },
+ \ 'java': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'javacc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'javascript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'javascript.jquery': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'jess': { 'left': ';' },
+ \ 'jgraph': { 'left': '(*', 'right': '*)' },
+ \ 'jproperties': { 'left': '#' },
+ \ 'jsp': { 'left': '<%--', 'right': '--%>' },
+ \ 'kix': { 'left': ';' },
+ \ 'kscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'lace': { 'left': '--' },
+ \ 'ldif': { 'left': '#' },
+ \ 'lilo': { 'left': '#' },
+ \ 'lilypond': { 'left': '%' },
+ \ 'liquid': { 'left': '{%', 'right': '%}' },
+ \ 'lisp': { 'left': ';', 'leftAlt': '#|', 'rightAlt': '|#' },
+ \ 'llvm': { 'left': ';' },
+ \ 'lotos': { 'left': '(*', 'right': '*)' },
+ \ 'lout': { 'left': '#' },
+ \ 'lprolog': { 'left': '%' },
+ \ 'lscript': { 'left': "'" },
+ \ 'lss': { 'left': '#' },
+ \ 'lua': { 'left': '--', 'leftAlt': '--[[', 'rightAlt': ']]' },
+ \ 'lynx': { 'left': '#' },
+ \ 'lytex': { 'left': '%' },
+ \ 'mail': { 'left': '> ' },
+ \ 'mako': { 'left': '##' },
+ \ 'man': { 'left': '."' },
+ \ 'map': { 'left': '%' },
+ \ 'maple': { 'left': '#' },
+ \ 'markdown': { 'left': '<!--', 'right': '-->' },
+ \ 'masm': { 'left': ';' },
+ \ 'mason': { 'left': '<% #', 'right': '%>' },
+ \ 'master': { 'left': '$' },
+ \ 'matlab': { 'left': '%' },
+ \ 'mel': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'mib': { 'left': '--' },
+ \ 'mkd': { 'left': '>' },
+ \ 'mma': { 'left': '(*', 'right': '*)' },
+ \ 'model': { 'left': '$', 'right': '$' },
+ \ 'moduala.': { 'left': '(*', 'right': '*)' },
+ \ 'modula2': { 'left': '(*', 'right': '*)' },
+ \ 'modula3': { 'left': '(*', 'right': '*)' },
+ \ 'monk': { 'left': ';' },
+ \ 'mush': { 'left': '#' },
+ \ 'named': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'nasm': { 'left': ';' },
+ \ 'nastran': { 'left': '$' },
+ \ 'natural': { 'left': '/*' },
+ \ 'ncf': { 'left': ';' },
+ \ 'newlisp': { 'left': ';' },
+ \ 'nroff': { 'left': '\"' },
+ \ 'nsis': { 'left': '#' },
+ \ 'ntp': { 'left': '#' },
+ \ 'objc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'objcpp': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'objj': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'ocaml': { 'left': '(*', 'right': '*)' },
+ \ 'occam': { 'left': '--' },
+ \ 'omlet': { 'left': '(*', 'right': '*)' },
+ \ 'omnimark': { 'left': ';' },
+ \ 'openroad': { 'left': '//' },
+ \ 'opl': { 'left': "REM" },
+ \ 'ora': { 'left': '#' },
+ \ 'ox': { 'left': '//' },
+ \ 'pascal': { 'left': '{','right': '}', 'leftAlt': '(*', 'rightAlt': '*)' },
+ \ 'patran': { 'left': '$', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'pcap': { 'left': '#' },
+ \ 'pccts': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'pdf': { 'left': '%' },
+ \ 'pfmain': { 'left': '//' },
+ \ 'php': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'pic': { 'left': ';' },
+ \ 'pike': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'pilrc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'pine': { 'left': '#' },
+ \ 'plm': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'plsql': { 'left': '--', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'po': { 'left': '#' },
+ \ 'postscr': { 'left': '%' },
+ \ 'pov': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'povini': { 'left': ';' },
+ \ 'ppd': { 'left': '%' },
+ \ 'ppwiz': { 'left': ';;' },
+ \ 'processing': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'prolog': { 'left': '%', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'ps1': { 'left': '#' },
+ \ 'psf': { 'left': '#' },
+ \ 'ptcap': { 'left': '#' },
+ \ 'python': { 'left': '#' },
+ \ 'radiance': { 'left': '#' },
+ \ 'ratpoison': { 'left': '#' },
+ \ 'r': { 'left': '#' },
+ \ 'rc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'rebol': { 'left': ';' },
+ \ 'registry': { 'left': ';' },
+ \ 'remind': { 'left': '#' },
+ \ 'resolv': { 'left': '#' },
+ \ 'rgb': { 'left': '!' },
+ \ 'rib': { 'left': '#' },
+ \ 'robots': { 'left': '#' },
+ \ 'sa': { 'left': '--' },
+ \ 'samba': { 'left': ';', 'leftAlt': '#' },
+ \ 'sass': { 'left': '//', 'leftAlt': '/*' },
+ \ 'sather': { 'left': '--' },
+ \ 'scala': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'scilab': { 'left': '//' },
+ \ 'scsh': { 'left': ';' },
+ \ 'sed': { 'left': '#' },
+ \ 'sgmldecl': { 'left': '--', 'right': '--' },
+ \ 'sgmllnx': { 'left': '<!--', 'right': '-->' },
+ \ 'sicad': { 'left': '*' },
+ \ 'simula': { 'left': '%', 'leftAlt': '--' },
+ \ 'sinda': { 'left': '$' },
+ \ 'skill': { 'left': ';' },
+ \ 'slang': { 'left': '%' },
+ \ 'slice': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'slrnrc': { 'left': '%' },
+ \ 'sm': { 'left': '#' },
+ \ 'smarty': { 'left': '{*', 'right': '*}' },
+ \ 'smil': { 'left': '<!', 'right': '>' },
+ \ 'smith': { 'left': ';' },
+ \ 'sml': { 'left': '(*', 'right': '*)' },
+ \ 'snnsnet': { 'left': '#' },
+ \ 'snnspat': { 'left': '#' },
+ \ 'snnsres': { 'left': '#' },
+ \ 'snobol4': { 'left': '*' },
+ \ 'spec': { 'left': '#' },
+ \ 'specman': { 'left': '//' },
+ \ 'spectre': { 'left': '//', 'leftAlt': '*' },
+ \ 'spice': { 'left': '$' },
+ \ 'sql': { 'left': '--' },
+ \ 'sqlforms': { 'left': '--' },
+ \ 'sqlj': { 'left': '--' },
+ \ 'sqr': { 'left': '!' },
+ \ 'squid': { 'left': '#' },
+ \ 'st': { 'left': '"' },
+ \ 'stp': { 'left': '--' },
+ \ 'systemverilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'tads': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'tags': { 'left': ';' },
+ \ 'tak': { 'left': '$' },
+ \ 'tasm': { 'left': ';' },
+ \ 'tcl': { 'left': '#' },
+ \ 'texinfo': { 'left': "@c " },
+ \ 'texmf': { 'left': '%' },
+ \ 'tf': { 'left': ';' },
+ \ 'tidy': { 'left': '#' },
+ \ 'tli': { 'left': '#' },
+ \ 'tmux': { 'left': '#' },
+ \ 'trasys': { 'left': "$" },
+ \ 'tsalt': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'tsscl': { 'left': '#' },
+ \ 'tssgm': { 'left': "comment = '", 'right': "'" },
+ \ 'txt2tags': { 'left': '%' },
+ \ 'uc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'uil': { 'left': '!' },
+ \ 'vb': { 'left': "'" },
+ \ 'velocity': { 'left': "##", 'right': "", 'leftAlt': '#*', 'rightAlt': '*#' },
+ \ 'vera': { 'left': '/*','right': '*/', 'leftAlt': '//' },
+ \ 'verilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'verilog_systemverilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' },
+ \ 'vgrindefs': { 'left': '#' },
+ \ 'vhdl': { 'left': '--' },
+ \ 'vimperator': { 'left': '"' },
+ \ 'virata': { 'left': '%' },
+ \ 'vrml': { 'left': '#' },
+ \ 'vsejcl': { 'left': '/*' },
+ \ 'webmacro': { 'left': '##' },
+ \ 'wget': { 'left': '#' },
+ \ 'Wikipedia': { 'left': '<!--', 'right': '-->' },
+ \ 'winbatch': { 'left': ';' },
+ \ 'wml': { 'left': '#' },
+ \ 'wvdial': { 'left': ';' },
+ \ 'xdefaults': { 'left': '!' },
+ \ 'xkb': { 'left': '//' },
+ \ 'xmath': { 'left': '#' },
+ \ 'xpm2': { 'left': '!' },
+ \ 'xquery': { 'left': '(:', 'right': ':)' },
+ \ 'z8a': { 'left': ';' }
+ \ }
+
+" Section: Comment mapping functions, autocommands and commands {{{1
+" ============================================================================
+" Section: Comment enabler autocommands {{{2
+" ============================================================================
+
+augroup commentEnablers
+
+ "if the user enters a buffer or reads a buffer then we gotta set up
+ "the comment delimiters for that new filetype
+ autocmd BufEnter,BufRead * :call s:SetUpForNewFiletype(&filetype, 0)
+
+ "if the filetype of a buffer changes, force the script to reset the
+ "delims for the buffer
+ autocmd Filetype * :call s:SetUpForNewFiletype(&filetype, 1)
+augroup END
+
+
+" Function: s:SetUpForNewFiletype(filetype) function {{{2
+" This function is responsible for setting up buffer scoped variables for the
+" given filetype.
+"
+" Args:
+" -filetype: the filetype to set delimiters for
+" -forceReset: 1 if the delimiters should be reset if they have already be
+" set for this buffer.
+"
+function s:SetUpForNewFiletype(filetype, forceReset)
+ let b:NERDSexyComMarker = ''
+
+ if has_key(s:delimiterMap, a:filetype)
+ let b:NERDCommenterDelims = s:delimiterMap[a:filetype]
+ for i in ['left', 'leftAlt', 'right', 'rightAlt']
+ if !has_key(b:NERDCommenterDelims, i)
+ let b:NERDCommenterDelims[i] = ''
+ endif
+ endfor
+ else
+ let b:NERDCommenterDelims = s:CreateDelimMapFromCms()
+ endif
+
+endfunction
+
+function s:CreateDelimMapFromCms()
+ return {
+ \ 'left': substitute(&commentstring, '\([^ \t]*\)\s*%s.*', '\1', ''),
+ \ 'right': substitute(&commentstring, '.*%s\s*\(.*\)', '\1', 'g'),
+ \ 'leftAlt': '',
+ \ 'rightAlt': '' }
+endfunction
+
+" Function: s:SwitchToAlternativeDelimiters(printMsgs) function {{{2
+" This function is used to swap the delimiters that are being used to the
+" alternative delimiters for that filetype. For example, if a c++ file is
+" being edited and // comments are being used, after this function is called
+" /**/ comments will be used.
+"
+" Args:
+" -printMsgs: if this is 1 then a message is echoed to the user telling them
+" if this function changed the delimiters or not
+function s:SwitchToAlternativeDelimiters(printMsgs)
+ "if both of the alternative delimiters are empty then there is no
+ "alternative comment style so bail out
+ if b:NERDCommenterDelims['leftAlt'] == '' && b:NERDCommenterDelims['rightAlt'] == ''
+ if a:printMsgs
+ call s:NerdEcho("Cannot use alternative delimiters, none are specified", 0)
+ endif
+ return 0
+ endif
+
+ "save the current delimiters
+ let tempLeft = s:Left()
+ let tempRight = s:Right()
+
+ "swap current delimiters for alternative
+ let b:NERDCommenterDelims['left'] = b:NERDCommenterDelims['leftAlt']
+ let b:NERDCommenterDelims['right'] = b:NERDCommenterDelims['rightAlt']
+
+ "set the previously current delimiters to be the new alternative ones
+ let b:NERDCommenterDelims['leftAlt'] = tempLeft
+ let b:NERDCommenterDelims['rightAlt'] = tempRight
+
+ "tell the user what comment delimiters they are now using
+ if a:printMsgs
+ call s:NerdEcho("Now using " . s:Left() . " " . s:Right() . " to delimit comments", 1)
+ endif
+
+ return 1
+endfunction
+
+" Section: Comment delimiter add/removal functions {{{1
+" ============================================================================
+" Function: s:AppendCommentToLine(){{{2
+" This function appends comment delimiters at the EOL and places the cursor in
+" position to start typing the comment
+function s:AppendCommentToLine()
+ let left = s:Left({'space': 1})
+ let right = s:Right({'space': 1})
+
+ " get the len of the right delim
+ let lenRight = strlen(right)
+
+ let isLineEmpty = strlen(getline(".")) == 0
+ let insOrApp = (isLineEmpty==1 ? 'i' : 'A')
+
+ "stick the delimiters down at the end of the line. We have to format the
+ "comment with spaces as appropriate
+ execute ":normal! " . insOrApp . (isLineEmpty ? '' : ' ') . left . right . " "
+
+ " if there is a right delimiter then we gotta move the cursor left
+ " by the len of the right delimiter so we insert between the delimiters
+ if lenRight > 0
+ let leftMoveAmount = lenRight
+ execute ":normal! " . leftMoveAmount . "h"
+ endif
+ startinsert
+endfunction
+
+" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested ) {{{2
+" This function is used to comment out a region of code. This region is
+" specified as a bounding box by arguments to the function.
+"
+" Args:
+" -top: the line number for the top line of code in the region
+" -bottom: the line number for the bottom line of code in the region
+" -lSide: the column number for the left most column in the region
+" -rSide: the column number for the right most column in the region
+" -forceNested: a flag indicating whether comments should be nested
+function s:CommentBlock(top, bottom, lSide, rSide, forceNested )
+ " we need to create local copies of these arguments so we can modify them
+ let top = a:top
+ let bottom = a:bottom
+ let lSide = a:lSide
+ let rSide = a:rSide
+
+ "if the top or bottom line starts with tabs we have to adjust the left and
+ "right boundaries so that they are set as though the tabs were spaces
+ let topline = getline(top)
+ let bottomline = getline(bottom)
+ if s:HasLeadingTabs(topline, bottomline)
+
+ "find out how many tabs are in the top line and adjust the left
+ "boundary accordingly
+ let numTabs = s:NumberOfLeadingTabs(topline)
+ if lSide < numTabs
+ let lSide = &ts * lSide
+ else
+ let lSide = (lSide - numTabs) + (&ts * numTabs)
+ endif
+
+ "find out how many tabs are in the bottom line and adjust the right
+ "boundary accordingly
+ let numTabs = s:NumberOfLeadingTabs(bottomline)
+ let rSide = (rSide - numTabs) + (&ts * numTabs)
+ endif
+
+ "we must check that bottom IS actually below top, if it is not then we
+ "swap top and bottom. Similarly for left and right.
+ if bottom < top
+ let temp = top
+ let top = bottom
+ let bottom = top
+ endif
+ if rSide < lSide
+ let temp = lSide
+ let lSide = rSide
+ let rSide = temp
+ endif
+
+ "if the current delimiters arent multipart then we will switch to the
+ "alternative delims (if THEY are) as the comment will be better and more
+ "accurate with multipart delims
+ let switchedDelims = 0
+ if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart()
+ let switchedDelims = 1
+ call s:SwitchToAlternativeDelimiters(0)
+ endif
+
+ "start the commenting from the top and keep commenting till we reach the
+ "bottom
+ let currentLine=top
+ while currentLine <= bottom
+
+ "check if we are allowed to comment this line
+ if s:CanCommentLine(a:forceNested, currentLine)
+
+ "convert the leading tabs into spaces
+ let theLine = getline(currentLine)
+ let lineHasLeadTabs = s:HasLeadingTabs(theLine)
+ if lineHasLeadTabs
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ endif
+
+ "dont comment lines that begin after the right boundary of the
+ "block unless the user has specified to do so
+ if theLine !~ '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty
+
+ "attempt to place the cursor in on the left of the boundary box,
+ "then check if we were successful, if not then we cant comment this
+ "line
+ call setline(currentLine, theLine)
+ if s:CanPlaceCursor(currentLine, lSide)
+
+ let leftSpaced = s:Left({'space': 1})
+ let rightSpaced = s:Right({'space': 1})
+
+ "stick the left delimiter down
+ let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1)
+
+ if s:Multipart()
+ "stick the right delimiter down
+ let theLine = strpart(theLine, 0, rSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, rSide+strlen(leftSpaced))
+
+ let firstLeftDelim = s:FindDelimiterIndex(s:Left(), theLine)
+ let lastRightDelim = s:LastIndexOfDelim(s:Right(), theLine)
+
+ if firstLeftDelim != -1 && lastRightDelim != -1
+ let searchStr = strpart(theLine, 0, lastRightDelim)
+ let searchStr = strpart(searchStr, firstLeftDelim+strlen(s:Left()))
+
+ "replace the outter most delims in searchStr with
+ "place-holders
+ let theLineWithPlaceHolders = s:ReplaceDelims(s:Left(), s:Right(), g:NERDLPlace, g:NERDRPlace, searchStr)
+
+ "add the right delimiter onto the line
+ let theLine = strpart(theLine, 0, firstLeftDelim+strlen(s:Left())) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim)
+ endif
+ endif
+ endif
+ endif
+
+ "restore tabs if needed
+ if lineHasLeadTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+
+ call setline(currentLine, theLine)
+ endif
+
+ let currentLine = currentLine + 1
+ endwhile
+
+ "if we switched delims then we gotta go back to what they were before
+ if switchedDelims == 1
+ call s:SwitchToAlternativeDelimiters(0)
+ endif
+endfunction
+
+" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2
+" This function comments a range of lines.
+"
+" Args:
+" -forceNested: a flag indicating whether the called is requesting the comment
+" to be nested if need be
+" -align: should be "left" or "both" or "none"
+" -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLines(forceNested, align, firstLine, lastLine)
+ " we need to get the left and right indexes of the leftmost char in the
+ " block of of lines and the right most char so that we can do alignment of
+ " the delimiters if the user has specified
+ let leftAlignIndx = s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+ let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+
+ " gotta add the length of the left delimiter onto the rightAlignIndx cos
+ " we'll be adding a left delim to the line
+ let rightAlignIndx = rightAlignIndx + strlen(s:Left({'space': 1}))
+
+ " now we actually comment the lines. Do it line by line
+ let currentLine = a:firstLine
+ while currentLine <= a:lastLine
+
+ " get the next line, check commentability and convert spaces to tabs
+ let theLine = getline(currentLine)
+ let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ if s:CanCommentLine(a:forceNested, currentLine)
+ "if the user has specified forceNesting then we check to see if we
+ "need to switch delimiters for place-holders
+ if a:forceNested && g:NERDUsePlaceHolders
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ endif
+
+ " find out if the line is commented using normal delims and/or
+ " alternate ones
+ let isCommented = s:IsCommented(s:Left(), s:Right(), theLine) || s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine)
+
+ " check if we can comment this line
+ if !isCommented || g:NERDUsePlaceHolders || s:Multipart()
+ if a:align == "left" || a:align == "both"
+ let theLine = s:AddLeftDelimAligned(s:Left({'space': 1}), theLine, leftAlignIndx)
+ else
+ let theLine = s:AddLeftDelim(s:Left({'space': 1}), theLine)
+ endif
+ if a:align == "both"
+ let theLine = s:AddRightDelimAligned(s:Right({'space': 1}), theLine, rightAlignIndx)
+ else
+ let theLine = s:AddRightDelim(s:Right({'space': 1}), theLine)
+ endif
+ endif
+ endif
+
+ " restore leading tabs if appropriate
+ if lineHasLeadingTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+
+ " we are done with this line
+ call setline(currentLine, theLine)
+ let currentLine = currentLine + 1
+ endwhile
+
+endfunction
+
+" Function: s:CommentLinesMinimal(firstLine, lastLine) {{{2
+" This function comments a range of lines in a minimal style. I
+"
+" Args:
+" -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLinesMinimal(firstLine, lastLine)
+ "check that minimal comments can be done on this filetype
+ if !s:HasMultipartDelims()
+ throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters'
+ endif
+
+ "if we need to use place holders for the comment, make sure they are
+ "enabled for this filetype
+ if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine)
+ throw 'NERDCommenter.Settings exception: Place holders are required but disabled.'
+ endif
+
+ "get the left and right delims to smack on
+ let left = s:GetSexyComLeft(g:NERDSpaceDelims,0)
+ let right = s:GetSexyComRight(g:NERDSpaceDelims,0)
+
+ "make sure all multipart delims on the lines are replaced with
+ "placeholders to prevent illegal syntax
+ let currentLine = a:firstLine
+ while(currentLine <= a:lastLine)
+ let theLine = getline(currentLine)
+ let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine)
+ call setline(currentLine, theLine)
+ let currentLine = currentLine + 1
+ endwhile
+
+ "add the delim to the top line
+ let theLine = getline(a:firstLine)
+ let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ let theLine = s:AddLeftDelim(left, theLine)
+ if lineHasLeadingTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+ call setline(a:firstLine, theLine)
+
+ "add the delim to the bottom line
+ let theLine = getline(a:lastLine)
+ let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ let theLine = s:AddRightDelim(right, theLine)
+ if lineHasLeadingTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+ call setline(a:lastLine, theLine)
+endfunction
+
+" Function: s:CommentLinesSexy(topline, bottomline) function {{{2
+" This function is used to comment lines in the 'Sexy' style. eg in c:
+" /*
+" * This is a sexy comment
+" */
+" Args:
+" -topline: the line num of the top line in the sexy comment
+" -bottomline: the line num of the bottom line in the sexy comment
+function s:CommentLinesSexy(topline, bottomline)
+ let left = s:GetSexyComLeft(0, 0)
+ let right = s:GetSexyComRight(0, 0)
+
+ "check if we can do a sexy comment with the available delimiters
+ if left == -1 || right == -1
+ throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.'
+ endif
+
+ "make sure the lines arent already commented sexually
+ if !s:CanSexyCommentLines(a:topline, a:bottomline)
+ throw 'NERDCommenter.Nesting exception: cannot nest sexy comments'
+ endif
+
+
+ let sexyComMarker = s:GetSexyComMarker(0,0)
+ let sexyComMarkerSpaced = s:GetSexyComMarker(1,0)
+
+
+ " we jam the comment as far to the right as possible
+ let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline)
+
+ "check if we should use the compact style i.e that the left/right
+ "delimiters should appear on the first and last lines of the code and not
+ "on separate lines above/below the first/last lines of code
+ if g:NERDCompactSexyComs
+ let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '')
+
+ "comment the top line
+ let theLine = getline(a:topline)
+ let lineHasTabs = s:HasLeadingTabs(theLine)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ endif
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+ call setline(a:topline, theLine)
+
+ "comment the bottom line
+ if a:bottomline != a:topline
+ let theLine = getline(a:bottomline)
+ let lineHasTabs = s:HasLeadingTabs(theLine)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ endif
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ endif
+ let theLine = s:AddRightDelim(spaceString . right, theLine)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+ call setline(a:bottomline, theLine)
+ else
+
+ " add the left delimiter one line above the lines that are to be commented
+ call cursor(a:topline, 1)
+ execute 'normal! O'
+ let theLine = repeat(' ', leftAlignIndx) . left
+
+ " Make sure tabs are respected
+ if !&expandtab
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+ call setline(a:topline, theLine)
+
+ " add the right delimiter after bottom line (we have to add 1 cos we moved
+ " the lines down when we added the left delim
+ call cursor(a:bottomline+1, 1)
+ execute 'normal! o'
+ let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . right
+
+ " Make sure tabs are respected
+ if !&expandtab
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+ call setline(a:bottomline+2, theLine)
+
+ endif
+
+ " go thru each line adding the sexyComMarker marker to the start of each
+ " line in the appropriate place to align them with the comment delims
+ let currentLine = a:topline+1
+ while currentLine <= a:bottomline + !g:NERDCompactSexyComs
+ " get the line and convert the tabs to spaces
+ let theLine = getline(currentLine)
+ let lineHasTabs = s:HasLeadingTabs(theLine)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ endif
+
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+
+ " add the sexyComMarker
+ let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx)
+
+ if lineHasTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+
+
+ " set the line and move onto the next one
+ call setline(currentLine, theLine)
+ let currentLine = currentLine + 1
+ endwhile
+
+endfunction
+
+" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine) {{{2
+" Applies "toggle" commenting to the given range of lines
+"
+" Args:
+" -forceNested: a flag indicating whether the called is requesting the comment
+" to be nested if need be
+" -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLinesToggle(forceNested, firstLine, lastLine)
+ let currentLine = a:firstLine
+ while currentLine <= a:lastLine
+
+ " get the next line, check commentability and convert spaces to tabs
+ let theLine = getline(currentLine)
+ let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ if s:CanToggleCommentLine(a:forceNested, currentLine)
+
+ "if the user has specified forceNesting then we check to see if we
+ "need to switch delimiters for place-holders
+ if g:NERDUsePlaceHolders
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ endif
+
+ let theLine = s:AddLeftDelim(s:Left({'space': 1}), theLine)
+ let theLine = s:AddRightDelim(s:Right({'space': 1}), theLine)
+ endif
+
+ " restore leading tabs if appropriate
+ if lineHasLeadingTabs
+ let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+ endif
+
+ " we are done with this line
+ call setline(currentLine, theLine)
+ let currentLine = currentLine + 1
+ endwhile
+
+endfunction
+
+" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2
+" This function comments chunks of text selected in visual mode.
+" It will comment exactly the text that they have selected.
+" Args:
+" -topLine: the line num of the top line in the sexy comment
+" -topCol: top left col for this comment
+" -bottomline: the line num of the bottom line in the sexy comment
+" -bottomCol: the bottom right col for this comment
+" -forceNested: whether the caller wants comments to be nested if the
+" line(s) are already commented
+function s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested)
+
+ "switch delims (if we can) if the current set isnt multipart
+ let switchedDelims = 0
+ if !s:Multipart() && s:AltMultipart() && !g:NERDAllowAnyVisualDelims
+ let switchedDelims = 1
+ call s:SwitchToAlternativeDelimiters(0)
+ endif
+
+ "if there is only one line in the comment then just do it
+ if a:topLine == a:bottomLine
+ call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested)
+
+ "there are multiple lines in the comment
+ else
+ "comment the top line
+ call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested)
+
+ "comment out all the lines in the middle of the comment
+ let topOfRange = a:topLine+1
+ let bottomOfRange = a:bottomLine-1
+ if topOfRange <= bottomOfRange
+ call s:CommentLines(a:forceNested, "none", topOfRange, bottomOfRange)
+ endif
+
+ "comment the bottom line
+ let bottom = getline(a:bottomLine)
+ let numLeadingSpacesTabs = strlen(substitute(bottom, '^\([ \t]*\).*$', '\1', ''))
+ call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested)
+
+ endif
+
+ "stick the cursor back on the char it was on before the comment
+ call cursor(a:topLine, a:topCol + strlen(s:Left()) + g:NERDSpaceDelims)
+
+ "if we switched delims then we gotta go back to what they were before
+ if switchedDelims == 1
+ call s:SwitchToAlternativeDelimiters(0)
+ endif
+
+endfunction
+
+" Function: s:InvertComment(firstLine, lastLine) function {{{2
+" Inverts the comments on the lines between and including the given line
+" numbers i.e all commented lines are uncommented and vice versa
+" Args:
+" -firstLine: the top of the range of lines to be inverted
+" -lastLine: the bottom of the range of lines to be inverted
+function s:InvertComment(firstLine, lastLine)
+
+ " go thru all lines in the given range
+ let currentLine = a:firstLine
+ while currentLine <= a:lastLine
+ let theLine = getline(currentLine)
+
+ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine)
+
+ " if the line is commented normally, uncomment it
+ if s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)
+ call s:UncommentLines(currentLine, currentLine)
+ let currentLine = currentLine + 1
+
+ " check if the line is commented sexually
+ elseif !empty(sexyComBounds)
+ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf()
+ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1])
+
+ "move to the line after last line of the sexy comment
+ let numLinesAfterSexyComRemoved = s:NumLinesInBuf()
+ let currentLine = sexyComBounds[1] - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1
+
+ " the line isnt commented
+ else
+ call s:CommentLinesToggle(1, currentLine, currentLine)
+ let currentLine = currentLine + 1
+ endif
+
+ endwhile
+endfunction
+
+" Function: NERDComment(isVisual, type) function {{{2
+" This function is a Wrapper for the main commenting functions
+"
+" Args:
+" -isVisual: a flag indicating whether the comment is requested in visual
+" mode or not
+" -type: the type of commenting requested. Can be 'sexy', 'invert',
+" 'minimal', 'toggle', 'alignLeft', 'alignBoth', 'norm',
+" 'nested', 'toEOL', 'append', 'insert', 'uncomment', 'yank'
+function! NERDComment(isVisual, type) range
+ " we want case sensitivity when commenting
+ let oldIgnoreCase = &ignorecase
+ set noignorecase
+
+ if a:isVisual
+ let firstLine = line("'<")
+ let lastLine = line("'>")
+ let firstCol = col("'<")
+ let lastCol = col("'>") - (&selection == 'exclusive' ? 1 : 0)
+ else
+ let firstLine = a:firstline
+ let lastLine = a:lastline
+ endif
+
+ let countWasGiven = (a:isVisual == 0 && firstLine != lastLine)
+
+ let forceNested = (a:type == 'nested' || g:NERDDefaultNesting)
+
+ if a:type == 'norm' || a:type == 'nested'
+ if a:isVisual && visualmode() == ""
+ call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested)
+ elseif a:isVisual && visualmode() == "v" && (g:NERDCommentWholeLinesInVMode==0 || (g:NERDCommentWholeLinesInVMode==2 && s:HasMultipartDelims()))
+ call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested)
+ else
+ call s:CommentLines(forceNested, "none", firstLine, lastLine)
+ endif
+
+ elseif a:type == 'alignLeft' || a:type == 'alignBoth'
+ let align = "none"
+ if a:type == "alignLeft"
+ let align = "left"
+ elseif a:type == "alignBoth"
+ let align = "both"
+ endif
+ call s:CommentLines(forceNested, align, firstLine, lastLine)
+
+ elseif a:type == 'invert'
+ call s:InvertComment(firstLine, lastLine)
+
+ elseif a:type == 'sexy'
+ try
+ call s:CommentLinesSexy(firstLine, lastLine)
+ catch /NERDCommenter.Delimiters/
+ call s:CommentLines(forceNested, "none", firstLine, lastLine)
+ catch /NERDCommenter.Nesting/
+ call s:NerdEcho("Sexy comment aborted. Nested sexy cannot be nested", 0)
+ endtry
+
+ elseif a:type == 'toggle'
+ let theLine = getline(firstLine)
+
+ if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)
+ call s:UncommentLines(firstLine, lastLine)
+ else
+ call s:CommentLinesToggle(forceNested, firstLine, lastLine)
+ endif
+
+ elseif a:type == 'minimal'
+ try
+ call s:CommentLinesMinimal(firstLine, lastLine)
+ catch /NERDCommenter.Delimiters/
+ call s:NerdEcho("Minimal comments can only be used for filetypes that have multipart delimiters.", 0)
+ catch /NERDCommenter.Settings/
+ call s:NerdEcho("Place holders are required but disabled.", 0)
+ endtry
+
+ elseif a:type == 'toEOL'
+ call s:SaveScreenState()
+ call s:CommentBlock(firstLine, firstLine, col("."), col("$")-1, 1)
+ call s:RestoreScreenState()
+
+ elseif a:type == 'append'
+ call s:AppendCommentToLine()
+
+ elseif a:type == 'insert'
+ call s:PlaceDelimitersAndInsBetween()
+
+ elseif a:type == 'uncomment'
+ call s:UncommentLines(firstLine, lastLine)
+
+ elseif a:type == 'yank'
+ if a:isVisual
+ normal! gvy
+ elseif countWasGiven
+ execute firstLine .','. lastLine .'yank'
+ else
+ normal! yy
+ endif
+ execute firstLine .','. lastLine .'call NERDComment('. a:isVisual .', "norm")'
+ endif
+
+ let &ignorecase = oldIgnoreCase
+endfunction
+
+" Function: s:PlaceDelimitersAndInsBetween() function {{{2
+" This is function is called to place comment delimiters down and place the
+" cursor between them
+function s:PlaceDelimitersAndInsBetween()
+ " get the left and right delimiters without any escape chars in them
+ let left = s:Left({'space': 1})
+ let right = s:Right({'space': 1})
+
+ let theLine = getline(".")
+ let lineHasLeadTabs = s:HasLeadingTabs(theLine) || (theLine =~ '^ *$' && !&expandtab)
+
+ "convert tabs to spaces and adjust the cursors column to take this into
+ "account
+ let untabbedCol = s:UntabbedCol(theLine, col("."))
+ call setline(line("."), s:ConvertLeadingTabsToSpaces(theLine))
+ call cursor(line("."), untabbedCol)
+
+ " get the len of the right delim
+ let lenRight = strlen(right)
+
+ let isDelimOnEOL = col(".") >= strlen(getline("."))
+
+ " if the cursor is in the first col then we gotta insert rather than
+ " append the comment delimiters here
+ let insOrApp = (col(".")==1 ? 'i' : 'a')
+
+ " place the delimiters down. We do it differently depending on whether
+ " there is a left AND right delimiter
+ if lenRight > 0
+ execute ":normal! " . insOrApp . left . right
+ execute ":normal! " . lenRight . "h"
+ else
+ execute ":normal! " . insOrApp . left
+
+ " if we are tacking the delim on the EOL then we gotta add a space
+ " after it cos when we go out of insert mode the cursor will move back
+ " one and the user wont be in position to type the comment.
+ if isDelimOnEOL
+ execute 'normal! a '
+ endif
+ endif
+ normal! l
+
+ "if needed convert spaces back to tabs and adjust the cursors col
+ "accordingly
+ if lineHasLeadTabs
+ let tabbedCol = s:TabbedCol(getline("."), col("."))
+ call setline(line("."), s:ConvertLeadingSpacesToTabs(getline(".")))
+ call cursor(line("."), tabbedCol)
+ endif
+
+ startinsert
+endfunction
+
+" Function: s:RemoveDelimiters(left, right, line) {{{2
+" this function is called to remove the first left comment delimiter and the
+" last right delimiter of the given line.
+"
+" The args left and right must be strings. If there is no right delimiter (as
+" is the case for e.g vim file comments) them the arg right should be ""
+"
+" Args:
+" -left: the left comment delimiter
+" -right: the right comment delimiter
+" -line: the line to remove the delimiters from
+function s:RemoveDelimiters(left, right, line)
+
+ let l:left = a:left
+ let l:right = a:right
+ let lenLeft = strlen(left)
+ let lenRight = strlen(right)
+
+ let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces)
+
+ let line = a:line
+
+ "look for the left delimiter, if we find it, remove it.
+ let leftIndx = s:FindDelimiterIndex(a:left, line)
+ if leftIndx != -1
+ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft)
+
+ "if the user has specified that there is a space after the left delim
+ "then check for the space and remove it if it is there
+ if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) == s:spaceStr
+ let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr)
+ endif
+ endif
+
+ "look for the right delimiter, if we find it, remove it
+ let rightIndx = s:FindDelimiterIndex(a:right, line)
+ if rightIndx != -1
+ let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight)
+
+ "if the user has specified that there is a space before the right delim
+ "then check for the space and remove it if it is there
+ if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) == s:spaceStr && s:Multipart()
+ let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx)
+ endif
+ endif
+
+ return line
+endfunction
+
+" Function: s:UncommentLines(topLine, bottomLine) {{{2
+" This function uncomments the given lines
+"
+" Args:
+" topLine: the top line of the visual selection to uncomment
+" bottomLine: the bottom line of the visual selection to uncomment
+function s:UncommentLines(topLine, bottomLine)
+ "make local copies of a:firstline and a:lastline and, if need be, swap
+ "them around if the top line is below the bottom
+ let l:firstline = a:topLine
+ let l:lastline = a:bottomLine
+ if firstline > lastline
+ let firstline = lastline
+ let lastline = a:topLine
+ endif
+
+ "go thru each line uncommenting each line removing sexy comments
+ let currentLine = firstline
+ while currentLine <= lastline
+
+ "check the current line to see if it is part of a sexy comment
+ let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine)
+ if !empty(sexyComBounds)
+
+ "we need to store the num lines in the buf before the comment is
+ "removed so we know how many lines were removed when the sexy com
+ "was removed
+ let numLinesBeforeSexyComRemoved = s:NumLinesInBuf()
+
+ call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1])
+
+ "move to the line after last line of the sexy comment
+ let numLinesAfterSexyComRemoved = s:NumLinesInBuf()
+ let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved
+ let currentLine = sexyComBounds[1] - numLinesRemoved + 1
+ let lastline = lastline - numLinesRemoved
+
+ "no sexy com was detected so uncomment the line as normal
+ else
+ call s:UncommentLinesNormal(currentLine, currentLine)
+ let currentLine = currentLine + 1
+ endif
+ endwhile
+
+endfunction
+
+" Function: s:UncommentLinesSexy(topline, bottomline) {{{2
+" This function removes all the comment characters associated with the sexy
+" comment spanning the given lines
+" Args:
+" -topline/bottomline: the top/bottom lines of the sexy comment
+function s:UncommentLinesSexy(topline, bottomline)
+ let left = s:GetSexyComLeft(0,1)
+ let right = s:GetSexyComRight(0,1)
+
+
+ "check if it is even possible for sexy comments to exist with the
+ "available delimiters
+ if left == -1 || right == -1
+ throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.'
+ endif
+
+ let leftUnEsc = s:GetSexyComLeft(0,0)
+ let rightUnEsc = s:GetSexyComRight(0,0)
+
+ let sexyComMarker = s:GetSexyComMarker(0, 1)
+ let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0)
+
+ "the markerOffset is how far right we need to move the sexyComMarker to
+ "line it up with the end of the left delim
+ let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc)
+
+ " go thru the intermediate lines of the sexy comment and remove the
+ " sexy comment markers (eg the '*'s on the start of line in a c sexy
+ " comment)
+ let currentLine = a:topline+1
+ while currentLine < a:bottomline
+ let theLine = getline(currentLine)
+
+ " remove the sexy comment marker from the line. We also remove the
+ " space after it if there is one and if appropriate options are set
+ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc)
+ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims
+ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr)
+ else
+ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc))
+ endif
+
+ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine)
+
+ let theLine = s:ConvertLeadingWhiteSpace(theLine)
+
+ " move onto the next line
+ call setline(currentLine, theLine)
+ let currentLine = currentLine + 1
+ endwhile
+
+ " gotta make a copy of a:bottomline cos we modify the position of the
+ " last line it if we remove the topline
+ let bottomline = a:bottomline
+
+ " get the first line so we can remove the left delim from it
+ let theLine = getline(a:topline)
+
+ " if the first line contains only the left delim then just delete it
+ if theLine =~ '^[ \t]*' . left . '[ \t]*$' && !g:NERDCompactSexyComs
+ call cursor(a:topline, 1)
+ normal! dd
+ let bottomline = bottomline - 1
+
+ " topline contains more than just the left delim
+ else
+
+ " remove the delim. If there is a space after it
+ " then remove this too if appropriate
+ let delimIndx = stridx(theLine, leftUnEsc)
+ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims
+ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr)
+ else
+ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc))
+ endif
+ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine)
+ call setline(a:topline, theLine)
+ endif
+
+ " get the last line so we can remove the right delim
+ let theLine = getline(bottomline)
+
+ " if the bottomline contains only the right delim then just delete it
+ if theLine =~ '^[ \t]*' . right . '[ \t]*$'
+ call cursor(bottomline, 1)
+ normal! dd
+
+ " the last line contains more than the right delim
+ else
+ " remove the right delim. If there is a space after it and
+ " if the appropriate options are set then remove this too.
+ let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine)
+ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims
+ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr)
+ else
+ let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc))
+ endif
+
+ " if the last line also starts with a sexy comment marker then we
+ " remove this as well
+ if theLine =~ '^[ \t]*' . sexyComMarker
+
+ " remove the sexyComMarker. If there is a space after it then
+ " remove that too
+ let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc)
+ if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims
+ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr)
+ else
+ let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc))
+ endif
+ endif
+
+ let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine)
+ call setline(bottomline, theLine)
+ endif
+endfunction
+
+" Function: s:UncommentLineNormal(line) {{{2
+" uncomments the given line and returns the result
+" Args:
+" -line: the line to uncomment
+function s:UncommentLineNormal(line)
+ let line = a:line
+
+ "get the comment status on the line so we know how it is commented
+ let lineCommentStatus = s:IsCommentedOuttermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line)
+
+ "it is commented with s:Left() and s:Right() so remove these delims
+ if lineCommentStatus == 1
+ let line = s:RemoveDelimiters(s:Left(), s:Right(), line)
+
+ "it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delims
+ elseif lineCommentStatus == 2 && g:NERDRemoveAltComs
+ let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line)
+
+ "it is not properly commented with any delims so we check if it has
+ "any random left or right delims on it and remove the outtermost ones
+ else
+ "get the positions of all delim types on the line
+ let indxLeft = s:FindDelimiterIndex(s:Left(), line)
+ let indxLeftAlt = s:FindDelimiterIndex(s:Left({'alt': 1}), line)
+ let indxRight = s:FindDelimiterIndex(s:Right(), line)
+ let indxRightAlt = s:FindDelimiterIndex(s:Right({'alt': 1}), line)
+
+ "remove the outter most left comment delim
+ if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
+ let line = s:RemoveDelimiters(s:Left(), '', line)
+ elseif indxLeftAlt != -1
+ let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line)
+ endif
+
+ "remove the outter most right comment delim
+ if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
+ let line = s:RemoveDelimiters('', s:Right(), line)
+ elseif indxRightAlt != -1
+ let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line)
+ endif
+ endif
+
+
+ let indxLeft = s:FindDelimiterIndex(s:Left(), line)
+ let indxLeftAlt = s:FindDelimiterIndex(s:Left({'alt': 1}), line)
+ let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
+
+ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
+ let indxRightAlt = s:FindDelimiterIndex(s:Right({'alt': 1}), line)
+ let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
+
+ let right = s:Right()
+ let left = s:Left()
+ if !s:Multipart()
+ let right = s:Right({'alt': 1})
+ let left = s:Left({'alt': 1})
+ endif
+
+
+ "if there are place-holders on the line then we check to see if they are
+ "the outtermost delimiters on the line. If so then we replace them with
+ "real delimiters
+ if indxLeftPlace != -1
+ if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
+ endif
+ elseif indxRightPlace != -1
+ if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
+ endif
+
+ endif
+
+ let line = s:ConvertLeadingWhiteSpace(line)
+
+ return line
+endfunction
+
+" Function: s:UncommentLinesNormal(topline, bottomline) {{{2
+" This function is called to uncomment lines that arent a sexy comment
+" Args:
+" -topline/bottomline: the top/bottom line numbers of the comment
+function s:UncommentLinesNormal(topline, bottomline)
+ let currentLine = a:topline
+ while currentLine <= a:bottomline
+ let line = getline(currentLine)
+ call setline(currentLine, s:UncommentLineNormal(line))
+ let currentLine = currentLine + 1
+ endwhile
+endfunction
+
+
+" Section: Other helper functions {{{1
+" ============================================================================
+
+" Function: s:AddLeftDelim(delim, theLine) {{{2
+" Args:
+function s:AddLeftDelim(delim, theLine)
+ return substitute(a:theLine, '^\([ \t]*\)', '\1' . a:delim, '')
+endfunction
+
+" Function: s:AddLeftDelimAligned(delim, theLine) {{{2
+" Args:
+function s:AddLeftDelimAligned(delim, theLine, alignIndx)
+
+ "if the line is not long enough then bung some extra spaces on the front
+ "so we can align the delim properly
+ let theLine = a:theLine
+ if strlen(theLine) < a:alignIndx
+ let theLine = repeat(' ', a:alignIndx - strlen(theLine))
+ endif
+
+ return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx)
+endfunction
+
+" Function: s:AddRightDelim(delim, theLine) {{{2
+" Args:
+function s:AddRightDelim(delim, theLine)
+ if a:delim == ''
+ return a:theLine
+ else
+ return substitute(a:theLine, '$', a:delim, '')
+ endif
+endfunction
+
+" Function: s:AddRightDelimAligned(delim, theLine, alignIndx) {{{2
+" Args:
+function s:AddRightDelimAligned(delim, theLine, alignIndx)
+ if a:delim == ""
+ return a:theLine
+ else
+
+ " when we align the right delim we are just adding spaces
+ " so we get a string containing the needed spaces (it
+ " could be empty)
+ let extraSpaces = ''
+ let extraSpaces = repeat(' ', a:alignIndx-strlen(a:theLine))
+
+ " add the right delim
+ return substitute(a:theLine, '$', extraSpaces . a:delim, '')
+ endif
+endfunction
+
+" Function: s:AltMultipart() {{{2
+" returns 1 if the alternative delims are multipart
+function s:AltMultipart()
+ return b:NERDCommenterDelims['rightAlt'] != ''
+endfunction
+
+" Function: s:CanCommentLine(forceNested, line) {{{2
+"This function is used to determine whether the given line can be commented.
+"It returns 1 if it can be and 0 otherwise
+"
+" Args:
+" -forceNested: a flag indicating whether the caller wants comments to be nested
+" if the current line is already commented
+" -lineNum: the line num of the line to check for commentability
+function s:CanCommentLine(forceNested, lineNum)
+ let theLine = getline(a:lineNum)
+
+ " make sure we don't comment lines that are just spaces or tabs or empty.
+ if theLine =~ "^[ \t]*$"
+ return 0
+ endif
+
+ "if the line is part of a sexy comment then just flag it...
+ if s:IsInSexyComment(a:lineNum)
+ return 0
+ endif
+
+ let isCommented = s:IsCommentedNormOrSexy(a:lineNum)
+
+ "if the line isnt commented return true
+ if !isCommented
+ return 1
+ endif
+
+ "if the line is commented but nesting is allowed then return true
+ if a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders)
+ return 1
+ endif
+
+ return 0
+endfunction
+
+" Function: s:CanPlaceCursor(line, col) {{{2
+" returns 1 if the cursor can be placed exactly in the given position
+function s:CanPlaceCursor(line, col)
+ let c = col(".")
+ let l = line(".")
+ call cursor(a:line, a:col)
+ let success = (line(".") == a:line && col(".") == a:col)
+ call cursor(l,c)
+ return success
+endfunction
+
+" Function: s:CanSexyCommentLines(topline, bottomline) {{{2
+" Return: 1 if the given lines can be commented sexually, 0 otherwise
+function s:CanSexyCommentLines(topline, bottomline)
+ " see if the selected regions have any sexy comments
+ let currentLine = a:topline
+ while(currentLine <= a:bottomline)
+ if s:IsInSexyComment(currentLine)
+ return 0
+ endif
+ let currentLine = currentLine + 1
+ endwhile
+ return 1
+endfunction
+" Function: s:CanToggleCommentLine(forceNested, line) {{{2
+"This function is used to determine whether the given line can be toggle commented.
+"It returns 1 if it can be and 0 otherwise
+"
+" Args:
+" -lineNum: the line num of the line to check for commentability
+function s:CanToggleCommentLine(forceNested, lineNum)
+ let theLine = getline(a:lineNum)
+ if (s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)) && !a:forceNested
+ return 0
+ endif
+
+ " make sure we don't comment lines that are just spaces or tabs or empty.
+ if theLine =~ "^[ \t]*$"
+ return 0
+ endif
+
+ "if the line is part of a sexy comment then just flag it...
+ if s:IsInSexyComment(a:lineNum)
+ return 0
+ endif
+
+ return 1
+endfunction
+
+" Function: s:ConvertLeadingSpacesToTabs(line) {{{2
+" This function takes a line and converts all leading tabs on that line into
+" spaces
+"
+" Args:
+" -line: the line whose leading tabs will be converted
+function s:ConvertLeadingSpacesToTabs(line)
+ let toReturn = a:line
+ while toReturn =~ '^\t*' . s:TabSpace() . '\(.*\)$'
+ let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$' , '\1\t\2' , "")
+ endwhile
+
+ return toReturn
+endfunction
+
+
+" Function: s:ConvertLeadingTabsToSpaces(line) {{{2
+" This function takes a line and converts all leading spaces on that line into
+" tabs
+"
+" Args:
+" -line: the line whose leading spaces will be converted
+function s:ConvertLeadingTabsToSpaces(line)
+ let toReturn = a:line
+ while toReturn =~ '^\( *\)\t'
+ let toReturn = substitute(toReturn, '^\( *\)\t', '\1' . s:TabSpace() , "")
+ endwhile
+
+ return toReturn
+endfunction
+
+" Function: s:ConvertLeadingWhiteSpace(line) {{{2
+" Converts the leading white space to tabs/spaces depending on &ts
+"
+" Args:
+" -line: the line to convert
+function s:ConvertLeadingWhiteSpace(line)
+ let toReturn = a:line
+ while toReturn =~ '^ *\t'
+ let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), "g")
+ endwhile
+
+ if !&expandtab
+ let toReturn = s:ConvertLeadingSpacesToTabs(toReturn)
+ endif
+
+ return toReturn
+endfunction
+
+
+" Function: s:CountNonESCedOccurances(str, searchstr, escChar) {{{2
+" This function counts the number of substrings contained in another string.
+" These substrings are only counted if they are not escaped with escChar
+" Args:
+" -str: the string to look for searchstr in
+" -searchstr: the substring to search for in str
+" -escChar: the escape character which, when preceding an instance of
+" searchstr, will cause it not to be counted
+function s:CountNonESCedOccurances(str, searchstr, escChar)
+ "get the index of the first occurrence of searchstr
+ let indx = stridx(a:str, a:searchstr)
+
+ "if there is an instance of searchstr in str process it
+ if indx != -1
+ "get the remainder of str after this instance of searchstr is removed
+ let lensearchstr = strlen(a:searchstr)
+ let strLeft = strpart(a:str, indx+lensearchstr)
+
+ "if this instance of searchstr is not escaped, add one to the count
+ "and recurse. If it is escaped, just recurse
+ if !s:IsEscaped(a:str, indx, a:escChar)
+ return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar)
+ else
+ return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar)
+ endif
+ endif
+endfunction
+" Function: s:DoesBlockHaveDelim(delim, top, bottom) {{{2
+" Returns 1 if the given block of lines has a delimiter (a:delim) in it
+" Args:
+" -delim: the comment delimiter to check the block for
+" -top: the top line number of the block
+" -bottom: the bottom line number of the block
+function s:DoesBlockHaveDelim(delim, top, bottom)
+ let currentLine = a:top
+ while currentLine < a:bottom
+ let theline = getline(currentLine)
+ if s:FindDelimiterIndex(a:delim, theline) != -1
+ return 1
+ endif
+ let currentLine = currentLine + 1
+ endwhile
+ return 0
+endfunction
+
+" Function: s:DoesBlockHaveMultipartDelim(top, bottom) {{{2
+" Returns 1 if the given block has a >= 1 multipart delimiter in it
+" Args:
+" -top: the top line number of the block
+" -bottom: the bottom line number of the block
+function s:DoesBlockHaveMultipartDelim(top, bottom)
+ if s:HasMultipartDelims()
+ if s:Multipart()
+ return s:DoesBlockHaveDelim(s:Left(), a:top, a:bottom) || s:DoesBlockHaveDelim(s:Right(), a:top, a:bottom)
+ else
+ return s:DoesBlockHaveDelim(s:Left({'alt': 1}), a:top, a:bottom) || s:DoesBlockHaveDelim(s:Right({'alt': 1}), a:top, a:bottom)
+ endif
+ endif
+ return 0
+endfunction
+
+
+" Function: s:Esc(str) {{{2
+" Escapes all the tricky chars in the given string
+function s:Esc(str)
+ let charsToEsc = '*/\."&$+'
+ return escape(a:str, charsToEsc)
+endfunction
+
+" Function: s:FindDelimiterIndex(delimiter, line) {{{2
+" This function is used to get the string index of the input comment delimiter
+" on the input line. If no valid comment delimiter is found in the line then
+" -1 is returned
+" Args:
+" -delimiter: the delimiter we are looking to find the index of
+" -line: the line we are looking for delimiter on
+function s:FindDelimiterIndex(delimiter, line)
+
+ "make sure the delimiter isnt empty otherwise we go into an infinite loop.
+ if a:delimiter == ""
+ return -1
+ endif
+
+
+ let l:delimiter = a:delimiter
+ let lenDel = strlen(l:delimiter)
+
+ "get the index of the first occurrence of the delimiter
+ let delIndx = stridx(a:line, l:delimiter)
+
+ "keep looping thru the line till we either find a real comment delimiter
+ "or run off the EOL
+ while delIndx != -1
+
+ "if we are not off the EOL get the str before the possible delimiter
+ "in question and check if it really is a delimiter. If it is, return
+ "its position
+ if delIndx != -1
+ if s:IsDelimValid(l:delimiter, delIndx, a:line)
+ return delIndx
+ endif
+ endif
+
+ "we have not yet found a real comment delimiter so move past the
+ "current one we are lookin at
+ let restOfLine = strpart(a:line, delIndx + lenDel)
+ let distToNextDelim = stridx(restOfLine , l:delimiter)
+
+ "if distToNextDelim is -1 then there is no more potential delimiters
+ "on the line so set delIndx to -1. Otherwise, move along the line by
+ "distToNextDelim
+ if distToNextDelim == -1
+ let delIndx = -1
+ else
+ let delIndx = delIndx + lenDel + distToNextDelim
+ endif
+ endwhile
+
+ "there is no comment delimiter on this line
+ return -1
+endfunction
+
+" Function: s:FindBoundingLinesOfSexyCom(lineNum) {{{2
+" This function takes in a line number and tests whether this line number is
+" the top/bottom/middle line of a sexy comment. If it is then the top/bottom
+" lines of the sexy comment are returned
+" Args:
+" -lineNum: the line number that is to be tested whether it is the
+" top/bottom/middle line of a sexy com
+" Returns:
+" A string that has the top/bottom lines of the sexy comment encoded in it.
+" The format is 'topline,bottomline'. If a:lineNum turns out not to be the
+" top/bottom/middle of a sexy comment then -1 is returned
+function s:FindBoundingLinesOfSexyCom(lineNum)
+
+ "find which delimiters to look for as the start/end delims of the comment
+ let left = ''
+ let right = ''
+ if s:Multipart()
+ let left = s:Left({'esc': 1})
+ let right = s:Right({'esc': 1})
+ elseif s:AltMultipart()
+ let left = s:Left({'alt': 1, 'esc': 1})
+ let right = s:Right({'alt': 1, 'esc': 1})
+ else
+ return []
+ endif
+
+ let sexyComMarker = s:GetSexyComMarker(0, 1)
+
+ "initialise the top/bottom line numbers of the sexy comment to -1
+ let top = -1
+ let bottom = -1
+
+ let currentLine = a:lineNum
+ while top == -1 || bottom == -1
+ let theLine = getline(currentLine)
+
+ "check if the current line is the top of the sexy comment
+ if currentLine <= a:lineNum && theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right && currentLine < s:NumLinesInBuf()
+ let top = currentLine
+ let currentLine = a:lineNum
+
+ "check if the current line is the bottom of the sexy comment
+ elseif theLine =~ '^[ \t]*' . right && theLine !~ '.*' . left && currentLine > 1
+ let bottom = currentLine
+
+ "the right delimiter is on the same line as the last sexyComMarker
+ elseif theLine =~ '^[ \t]*' . sexyComMarker . '.*' . right
+ let bottom = currentLine
+
+ "we have not found the top or bottom line so we assume currentLine is an
+ "intermediate line and look to prove otherwise
+ else
+
+ "if the line doesnt start with a sexyComMarker then it is not a sexy
+ "comment
+ if theLine !~ '^[ \t]*' . sexyComMarker
+ return []
+ endif
+
+ endif
+
+ "if top is -1 then we havent found the top yet so keep looking up
+ if top == -1
+ let currentLine = currentLine - 1
+ "if we have found the top line then go down looking for the bottom
+ else
+ let currentLine = currentLine + 1
+ endif
+
+ endwhile
+
+ return [top, bottom]
+endfunction
+
+
+" Function: s:GetSexyComMarker() {{{2
+" Returns the sexy comment marker for the current filetype.
+"
+" C style sexy comments are assumed if possible. If not then the sexy comment
+" marker is the last char of the delimiter pair that has both left and right
+" delims and has the longest left delim
+"
+" Args:
+" -space: specifies whether the marker is to have a space string after it
+" (the space string will only be added if NERDSpaceDelims is set)
+" -esc: specifies whether the tricky chars in the marker are to be ESCed
+function s:GetSexyComMarker(space, esc)
+ let sexyComMarker = b:NERDSexyComMarker
+
+ "if there is no hardcoded marker then we find one
+ if sexyComMarker == ''
+
+ "if the filetype has c style comments then use standard c sexy
+ "comments
+ if s:HasCStyleComments()
+ let sexyComMarker = '*'
+ else
+ "find a comment marker by getting the longest available left delim
+ "(that has a corresponding right delim) and taking the last char
+ let lenLeft = strlen(s:Left())
+ let lenLeftAlt = strlen(s:Left({'alt': 1}))
+ let left = ''
+ let right = ''
+ if s:Multipart() && lenLeft >= lenLeftAlt
+ let left = s:Left()
+ elseif s:AltMultipart()
+ let left = s:Left({'alt': 1})
+ else
+ return -1
+ endif
+
+ "get the last char of left
+ let sexyComMarker = strpart(left, strlen(left)-1)
+ endif
+ endif
+
+ if a:space && g:NERDSpaceDelims
+ let sexyComMarker = sexyComMarker . s:spaceStr
+ endif
+
+ if a:esc
+ let sexyComMarker = s:Esc(sexyComMarker)
+ endif
+
+ return sexyComMarker
+endfunction
+
+" Function: s:GetSexyComLeft(space, esc) {{{2
+" Returns the left delimiter for sexy comments for this filetype or -1 if
+" there is none. C style sexy comments are used if possible
+" Args:
+" -space: specifies if the delim has a space string on the end
+" (the space string will only be added if NERDSpaceDelims is set)
+" -esc: specifies whether the tricky chars in the string are ESCed
+function s:GetSexyComLeft(space, esc)
+ let lenLeft = strlen(s:Left())
+ let lenLeftAlt = strlen(s:Left({'alt': 1}))
+ let left = ''
+
+ "assume c style sexy comments if possible
+ if s:HasCStyleComments()
+ let left = '/*'
+ else
+ "grab the longest left delim that has a right
+ if s:Multipart() && lenLeft >= lenLeftAlt
+ let left = s:Left()
+ elseif s:AltMultipart()
+ let left = s:Left({'alt': 1})
+ else
+ return -1
+ endif
+ endif
+
+ if a:space && g:NERDSpaceDelims
+ let left = left . s:spaceStr
+ endif
+
+ if a:esc
+ let left = s:Esc(left)
+ endif
+
+ return left
+endfunction
+
+" Function: s:GetSexyComRight(space, esc) {{{2
+" Returns the right delimiter for sexy comments for this filetype or -1 if
+" there is none. C style sexy comments are used if possible.
+" Args:
+" -space: specifies if the delim has a space string on the start
+" (the space string will only be added if NERDSpaceDelims
+" is specified for the current filetype)
+" -esc: specifies whether the tricky chars in the string are ESCed
+function s:GetSexyComRight(space, esc)
+ let lenLeft = strlen(s:Left())
+ let lenLeftAlt = strlen(s:Left({'alt': 1}))
+ let right = ''
+
+ "assume c style sexy comments if possible
+ if s:HasCStyleComments()
+ let right = '*/'
+ else
+ "grab the right delim that pairs with the longest left delim
+ if s:Multipart() && lenLeft >= lenLeftAlt
+ let right = s:Right()
+ elseif s:AltMultipart()
+ let right = s:Right({'alt': 1})
+ else
+ return -1
+ endif
+ endif
+
+ if a:space && g:NERDSpaceDelims
+ let right = s:spaceStr . right
+ endif
+
+ if a:esc
+ let right = s:Esc(right)
+ endif
+
+ return right
+endfunction
+
+" Function: s:HasMultipartDelims() {{{2
+" Returns 1 iff the current filetype has at least one set of multipart delims
+function s:HasMultipartDelims()
+ return s:Multipart() || s:AltMultipart()
+endfunction
+
+" Function: s:HasLeadingTabs(...) {{{2
+" Returns 1 if any of the given strings have leading tabs
+function s:HasLeadingTabs(...)
+ for s in a:000
+ if s =~ '^\t.*'
+ return 1
+ end
+ endfor
+ return 0
+endfunction
+" Function: s:HasCStyleComments() {{{2
+" Returns 1 iff the current filetype has c style comment delimiters
+function s:HasCStyleComments()
+ return (s:Left() == '/*' && s:Right() == '*/') || (s:Left({'alt': 1}) == '/*' && s:Right({'alt': 1}) == '*/')
+endfunction
+
+" Function: s:IsCommentedNormOrSexy(lineNum) {{{2
+"This function is used to determine whether the given line is commented with
+"either set of delimiters or if it is part of a sexy comment
+"
+" Args:
+" -lineNum: the line number of the line to check
+function s:IsCommentedNormOrSexy(lineNum)
+ let theLine = getline(a:lineNum)
+
+ "if the line is commented normally return 1
+ if s:IsCommented(s:Left(), s:Right(), theLine) || s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine)
+ return 1
+ endif
+
+ "if the line is part of a sexy comment return 1
+ if s:IsInSexyComment(a:lineNum)
+ return 1
+ endif
+ return 0
+endfunction
+
+" Function: s:IsCommented(left, right, line) {{{2
+"This function is used to determine whether the given line is commented with
+"the given delimiters
+"
+" Args:
+" -line: the line that to check if commented
+" -left/right: the left and right delimiters to check for
+function s:IsCommented(left, right, line)
+ "if the line isnt commented return true
+ if s:FindDelimiterIndex(a:left, a:line) != -1 && (s:FindDelimiterIndex(a:right, a:line) != -1 || !s:Multipart())
+ return 1
+ endif
+ return 0
+endfunction
+
+" Function: s:IsCommentedFromStartOfLine(left, line) {{{2
+"This function is used to determine whether the given line is commented with
+"the given delimiters at the start of the line i.e the left delimiter is the
+"first thing on the line (apart from spaces\tabs)
+"
+" Args:
+" -line: the line that to check if commented
+" -left: the left delimiter to check for
+function s:IsCommentedFromStartOfLine(left, line)
+ let theLine = s:ConvertLeadingTabsToSpaces(a:line)
+ let numSpaces = strlen(substitute(theLine, '^\( *\).*$', '\1', ''))
+ let delimIndx = s:FindDelimiterIndex(a:left, theLine)
+ return delimIndx == numSpaces
+endfunction
+
+" Function: s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) {{{2
+" Finds the type of the outtermost delims on the line
+"
+" Args:
+" -line: the line that to check if the outtermost comments on it are
+" left/right
+" -left/right: the left and right delimiters to check for
+" -leftAlt/rightAlt: the left and right alternative delimiters to check for
+"
+" Returns:
+" 0 if the line is not commented with either set of delims
+" 1 if the line is commented with the left/right delim set
+" 2 if the line is commented with the leftAlt/rightAlt delim set
+function s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line)
+ "get the first positions of the left delims and the last positions of the
+ "right delims
+ let indxLeft = s:FindDelimiterIndex(a:left, a:line)
+ let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line)
+ let indxRight = s:LastIndexOfDelim(a:right, a:line)
+ let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line)
+
+ "check if the line has a left delim before a leftAlt delim
+ if (indxLeft <= indxLeftAlt || indxLeftAlt == -1) && indxLeft != -1
+ "check if the line has a right delim after any rightAlt delim
+ if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart()
+ return 1
+ endif
+
+ "check if the line has a leftAlt delim before a left delim
+ elseif (indxLeftAlt <= indxLeft || indxLeft == -1) && indxLeftAlt != -1
+ "check if the line has a rightAlt delim after any right delim
+ if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart()
+ return 2
+ endif
+ else
+ return 0
+ endif
+
+ return 0
+
+endfunction
+
+
+" Function: s:IsDelimValid(delimiter, delIndx, line) {{{2
+" This function is responsible for determining whether a given instance of a
+" comment delimiter is a real delimiter or not. For example, in java the
+" // string is a comment delimiter but in the line:
+" System.out.println("//");
+" it does not count as a comment delimiter. This function is responsible for
+" distinguishing between such cases. It does so by applying a set of
+" heuristics that are not fool proof but should work most of the time.
+"
+" Args:
+" -delimiter: the delimiter we are validating
+" -delIndx: the position of delimiter in line
+" -line: the line that delimiter occurs in
+"
+" Returns:
+" 0 if the given delimiter is not a real delimiter (as far as we can tell) ,
+" 1 otherwise
+function s:IsDelimValid(delimiter, delIndx, line)
+ "get the delimiter without the escchars
+ let l:delimiter = a:delimiter
+
+ "get the strings before and after the delimiter
+ let preComStr = strpart(a:line, 0, a:delIndx)
+ let postComStr = strpart(a:line, a:delIndx+strlen(delimiter))
+
+ "to check if the delimiter is real, make sure it isnt preceded by
+ "an odd number of quotes and followed by the same (which would indicate
+ "that it is part of a string and therefore is not a comment)
+ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', "\\"))
+ return 0
+ endif
+ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", "\\"))
+ return 0
+ endif
+ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "`", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "`", "\\"))
+ return 0
+ endif
+
+
+ "if the comment delimiter is escaped, assume it isnt a real delimiter
+ if s:IsEscaped(a:line, a:delIndx, "\\")
+ return 0
+ endif
+
+ "vim comments are so fuckin stupid!! Why the hell do they have comment
+ "delimiters that are used elsewhere in the syntax?!?! We need to check
+ "some conditions especially for vim
+ if &filetype == "vim"
+ if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\"))
+ return 0
+ endif
+
+ "if the delimiter is on the very first char of the line or is the
+ "first non-tab/space char on the line then it is a valid comment delimiter
+ if a:delIndx == 0 || a:line =~ "^[ \t]\\{" . a:delIndx . "\\}\".*$"
+ return 1
+ endif
+
+ let numLeftParen =s:CountNonESCedOccurances(preComStr, "(", "\\")
+ let numRightParen =s:CountNonESCedOccurances(preComStr, ")", "\\")
+
+ "if the quote is inside brackets then assume it isnt a comment
+ if numLeftParen > numRightParen
+ return 0
+ endif
+
+ "if the line has an even num of unescaped "'s then we can assume that
+ "any given " is not a comment delimiter
+ if s:IsNumEven(s:CountNonESCedOccurances(a:line, "\"", "\\"))
+ return 0
+ endif
+ endif
+
+ return 1
+
+endfunction
+
+" Function: s:IsNumEven(num) {{{2
+" A small function the returns 1 if the input number is even and 0 otherwise
+" Args:
+" -num: the number to check
+function s:IsNumEven(num)
+ return (a:num % 2) == 0
+endfunction
+
+" Function: s:IsEscaped(str, indx, escChar) {{{2
+" This function takes a string, an index into that string and an esc char and
+" returns 1 if the char at the index is escaped (i.e if it is preceded by an
+" odd number of esc chars)
+" Args:
+" -str: the string to check
+" -indx: the index into str that we want to check
+" -escChar: the escape char the char at indx may be ESCed with
+function s:IsEscaped(str, indx, escChar)
+ "initialise numEscChars to 0 and look at the char before indx
+ let numEscChars = 0
+ let curIndx = a:indx-1
+
+ "keep going back thru str until we either reach the start of the str or
+ "run out of esc chars
+ while curIndx >= 0 && strpart(a:str, curIndx, 1) == a:escChar
+
+ "we have found another esc char so add one to the count and move left
+ "one char
+ let numEscChars = numEscChars + 1
+ let curIndx = curIndx - 1
+
+ endwhile
+
+ "if there is an odd num of esc chars directly before the char at indx then
+ "the char at indx is escaped
+ return !s:IsNumEven(numEscChars)
+endfunction
+
+" Function: s:IsInSexyComment(line) {{{2
+" returns 1 if the given line number is part of a sexy comment
+function s:IsInSexyComment(line)
+ return !empty(s:FindBoundingLinesOfSexyCom(a:line))
+endfunction
+
+" Function: s:IsSexyComment(topline, bottomline) {{{2
+" This function takes in 2 line numbers and returns 1 if the lines between and
+" including the given line numbers are a sexy comment. It returns 0 otherwise.
+" Args:
+" -topline: the line that the possible sexy comment starts on
+" -bottomline: the line that the possible sexy comment stops on
+function s:IsSexyComment(topline, bottomline)
+
+ "get the delim set that would be used for a sexy comment
+ let left = ''
+ let right = ''
+ if s:Multipart()
+ let left = s:Left()
+ let right = s:Right()
+ elseif s:AltMultipart()
+ let left = s:Left({'alt': 1})
+ let right = s:Right({'alt': 1})
+ else
+ return 0
+ endif
+
+ "swap the top and bottom line numbers around if need be
+ let topline = a:topline
+ let bottomline = a:bottomline
+ if bottomline < topline
+ topline = bottomline
+ bottomline = a:topline
+ endif
+
+ "if there is < 2 lines in the comment it cannot be sexy
+ if (bottomline - topline) <= 0
+ return 0
+ endif
+
+ "if the top line doesnt begin with a left delim then the comment isnt sexy
+ if getline(a:topline) !~ '^[ \t]*' . left
+ return 0
+ endif
+
+ "if there is a right delim on the top line then this isnt a sexy comment
+ if s:FindDelimiterIndex(right, getline(a:topline)) != -1
+ return 0
+ endif
+
+ "if there is a left delim on the bottom line then this isnt a sexy comment
+ if s:FindDelimiterIndex(left, getline(a:bottomline)) != -1
+ return 0
+ endif
+
+ "if the bottom line doesnt begin with a right delim then the comment isnt
+ "sexy
+ if getline(a:bottomline) !~ '^.*' . right . '$'
+ return 0
+ endif
+
+ let sexyComMarker = s:GetSexyComMarker(0, 1)
+
+ "check each of the intermediate lines to make sure they start with a
+ "sexyComMarker
+ let currentLine = a:topline+1
+ while currentLine < a:bottomline
+ let theLine = getline(currentLine)
+
+ if theLine !~ '^[ \t]*' . sexyComMarker
+ return 0
+ endif
+
+ "if there is a right delim in an intermediate line then the block isnt
+ "a sexy comment
+ if s:FindDelimiterIndex(right, theLine) != -1
+ return 0
+ endif
+
+ let currentLine = currentLine + 1
+ endwhile
+
+ "we have not found anything to suggest that this isnt a sexy comment so
+ return 1
+
+endfunction
+
+" Function: s:LastIndexOfDelim(delim, str) {{{2
+" This function takes a string and a delimiter and returns the last index of
+" that delimiter in string
+" Args:
+" -delim: the delimiter to look for
+" -str: the string to look for delim in
+function s:LastIndexOfDelim(delim, str)
+ let delim = a:delim
+ let lenDelim = strlen(delim)
+
+ "set index to the first occurrence of delim. If there is no occurrence then
+ "bail
+ let indx = s:FindDelimiterIndex(delim, a:str)
+ if indx == -1
+ return -1
+ endif
+
+ "keep moving to the next instance of delim in str till there is none left
+ while 1
+
+ "search for the next delim after the previous one
+ let searchStr = strpart(a:str, indx+lenDelim)
+ let indx2 = s:FindDelimiterIndex(delim, searchStr)
+
+ "if we find a delim update indx to record the position of it, if we
+ "dont find another delim then indx is the last one so break out of
+ "this loop
+ if indx2 != -1
+ let indx = indx + indx2 + lenDelim
+ else
+ break
+ endif
+ endwhile
+
+ return indx
+
+endfunction
+
+" Function: s:Left(...) {{{2
+" returns left delimiter data
+function s:Left(...)
+ let params = a:0 ? a:1 : {}
+
+ let delim = has_key(params, 'alt') ? b:NERDCommenterDelims['leftAlt'] : b:NERDCommenterDelims['left']
+
+ if delim == ''
+ return ''
+ endif
+
+ if has_key(params, 'space') && g:NERDSpaceDelims
+ let delim = delim . s:spaceStr
+ endif
+
+ if has_key(params, 'esc')
+ let delim = s:Esc(delim)
+ endif
+
+ return delim
+endfunction
+
+" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2
+" This function takes in 2 line numbers and returns the index of the left most
+" char (that is not a space or a tab) on all of these lines.
+" Args:
+" -countCommentedLines: 1 if lines that are commented are to be checked as
+" well. 0 otherwise
+" -countEmptyLines: 1 if empty lines are to be counted in the search
+" -topline: the top line to be checked
+" -bottomline: the bottom line to be checked
+function s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline)
+
+ " declare the left most index as an extreme value
+ let leftMostIndx = 1000
+
+ " go thru the block line by line updating leftMostIndx
+ let currentLine = a:topline
+ while currentLine <= a:bottomline
+
+ " get the next line and if it is allowed to be commented, or is not
+ " commented, check it
+ let theLine = getline(currentLine)
+ if a:countEmptyLines || theLine !~ '^[ \t]*$'
+ if a:countCommentedLines || (!s:IsCommented(s:Left(), s:Right(), theLine) && !s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine))
+ " convert spaces to tabs and get the number of leading spaces for
+ " this line and update leftMostIndx if need be
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ let leadSpaceOfLine = strlen( substitute(theLine, '\(^[ \t]*\).*$','\1','') )
+ if leadSpaceOfLine < leftMostIndx
+ let leftMostIndx = leadSpaceOfLine
+ endif
+ endif
+ endif
+
+ " move on to the next line
+ let currentLine = currentLine + 1
+ endwhile
+
+ if leftMostIndx == 1000
+ return 0
+ else
+ return leftMostIndx
+ endif
+endfunction
+
+" Function: s:Multipart() {{{2
+" returns 1 if the current delims are multipart
+function s:Multipart()
+ return s:Right() != ''
+endfunction
+
+" Function: s:NerdEcho(msg, typeOfMsg) {{{2
+" Args:
+" -msg: the message to echo
+" -typeOfMsg: 0 = warning message
+" 1 = normal message
+function s:NerdEcho(msg, typeOfMsg)
+ if a:typeOfMsg == 0
+ echohl WarningMsg
+ echo 'NERDCommenter:' . a:msg
+ echohl None
+ elseif a:typeOfMsg == 1
+ echo 'NERDCommenter:' . a:msg
+ endif
+endfunction
+
+" Function: s:NumberOfLeadingTabs(s) {{{2
+" returns the number of leading tabs in the given string
+function s:NumberOfLeadingTabs(s)
+ return strlen(substitute(a:s, '^\(\t*\).*$', '\1', ""))
+endfunction
+
+" Function: s:NumLinesInBuf() {{{2
+" Returns the number of lines in the current buffer
+function s:NumLinesInBuf()
+ return line('$')
+endfunction
+
+" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) {{{2
+" This function takes in a string, 2 delimiters in that string and 2 strings
+" to replace these delimiters with.
+"
+" Args:
+" -toReplace1: the first delimiter to replace
+" -toReplace2: the second delimiter to replace
+" -replacor1: the string to replace toReplace1 with
+" -replacor2: the string to replace toReplace2 with
+" -str: the string that the delimiters to be replaced are in
+function s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str)
+ let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str)
+ let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line)
+ return line
+endfunction
+
+" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str) {{{2
+" This function takes a string and a delimiter and replaces the left most
+" occurrence of this delimiter in the string with a given string
+"
+" Args:
+" -toReplace: the delimiter in str that is to be replaced
+" -replacor: the string to replace toReplace with
+" -str: the string that contains toReplace
+function s:ReplaceLeftMostDelim(toReplace, replacor, str)
+ let toReplace = a:toReplace
+ let replacor = a:replacor
+ "get the left most occurrence of toReplace
+ let indxToReplace = s:FindDelimiterIndex(toReplace, a:str)
+
+ "if there IS an occurrence of toReplace in str then replace it and return
+ "the resulting string
+ if indxToReplace != -1
+ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace))
+ return line
+ endif
+
+ return a:str
+endfunction
+
+" Function: s:ReplaceRightMostDelim(toReplace, replacor, str) {{{2
+" This function takes a string and a delimiter and replaces the right most
+" occurrence of this delimiter in the string with a given string
+"
+" Args:
+" -toReplace: the delimiter in str that is to be replaced
+" -replacor: the string to replace toReplace with
+" -str: the string that contains toReplace
+"
+function s:ReplaceRightMostDelim(toReplace, replacor, str)
+ let toReplace = a:toReplace
+ let replacor = a:replacor
+ let lenToReplace = strlen(toReplace)
+
+ "get the index of the last delim in str
+ let indxToReplace = s:LastIndexOfDelim(toReplace, a:str)
+
+ "if there IS a delimiter in str, replace it and return the result
+ let line = a:str
+ if indxToReplace != -1
+ let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace))
+ endif
+ return line
+endfunction
+
+"FUNCTION: s:RestoreScreenState() {{{2
+"
+"Sets the screen state back to what it was when s:SaveScreenState was last
+"called.
+"
+function s:RestoreScreenState()
+ if !exists("t:NERDComOldTopLine") || !exists("t:NERDComOldPos")
+ throw 'NERDCommenter exception: cannot restore screen'
+ endif
+
+ call cursor(t:NERDComOldTopLine, 0)
+ normal! zt
+ call setpos(".", t:NERDComOldPos)
+endfunction
+
+" Function: s:Right(...) {{{2
+" returns right delimiter data
+function s:Right(...)
+ let params = a:0 ? a:1 : {}
+
+ let delim = has_key(params, 'alt') ? b:NERDCommenterDelims['rightAlt'] : b:NERDCommenterDelims['right']
+
+ if delim == ''
+ return ''
+ endif
+
+ if has_key(params, 'space') && g:NERDSpaceDelims
+ let delim = s:spaceStr . delim
+ endif
+
+ if has_key(params, 'esc')
+ let delim = s:Esc(delim)
+ endif
+
+ return delim
+endfunction
+
+" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2
+" This function takes in 2 line numbers and returns the index of the right most
+" char on all of these lines.
+" Args:
+" -countCommentedLines: 1 if lines that are commented are to be checked as
+" well. 0 otherwise
+" -countEmptyLines: 1 if empty lines are to be counted in the search
+" -topline: the top line to be checked
+" -bottomline: the bottom line to be checked
+function s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline)
+ let rightMostIndx = -1
+
+ " go thru the block line by line updating rightMostIndx
+ let currentLine = a:topline
+ while currentLine <= a:bottomline
+
+ " get the next line and see if it is commentable, otherwise it doesnt
+ " count
+ let theLine = getline(currentLine)
+ if a:countEmptyLines || theLine !~ '^[ \t]*$'
+
+ if a:countCommentedLines || (!s:IsCommented(s:Left(), s:Right(), theLine) && !s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine))
+
+ " update rightMostIndx if need be
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ let lineLen = strlen(theLine)
+ if lineLen > rightMostIndx
+ let rightMostIndx = lineLen
+ endif
+ endif
+ endif
+
+ " move on to the next line
+ let currentLine = currentLine + 1
+ endwhile
+
+ return rightMostIndx
+endfunction
+
+"FUNCTION: s:SaveScreenState() {{{2
+"Saves the current cursor position in the current buffer and the window
+"scroll position
+function s:SaveScreenState()
+ let t:NERDComOldPos = getpos(".")
+ let t:NERDComOldTopLine = line("w0")
+endfunction
+
+" Function: s:SwapOutterMultiPartDelimsForPlaceHolders(line) {{{2
+" This function takes a line and swaps the outter most multi-part delims for
+" place holders
+" Args:
+" -line: the line to swap the delims in
+"
+function s:SwapOutterMultiPartDelimsForPlaceHolders(line)
+ " find out if the line is commented using normal delims and/or
+ " alternate ones
+ let isCommented = s:IsCommented(s:Left(), s:Right(), a:line)
+ let isCommentedAlt = s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), a:line)
+
+ let line2 = a:line
+
+ "if the line is commented and there is a right delimiter, replace
+ "the delims with place-holders
+ if isCommented && s:Multipart()
+ let line2 = s:ReplaceDelims(s:Left(), s:Right(), g:NERDLPlace, g:NERDRPlace, a:line)
+
+ "similarly if the line is commented with the alternative
+ "delimiters
+ elseif isCommentedAlt && s:AltMultipart()
+ let line2 = s:ReplaceDelims(s:Left({'alt': 1}), s:Right({'alt': 1}), g:NERDLPlace, g:NERDRPlace, a:line)
+ endif
+
+ return line2
+endfunction
+
+" Function: s:SwapOutterPlaceHoldersForMultiPartDelims(line) {{{2
+" This function takes a line and swaps the outtermost place holders for
+" multi-part delims
+" Args:
+" -line: the line to swap the delims in
+"
+function s:SwapOutterPlaceHoldersForMultiPartDelims(line)
+ let left = ''
+ let right = ''
+ if s:Multipart()
+ let left = s:Left()
+ let right = s:Right()
+ elseif s:AltMultipart()
+ let left = s:Left({'alt': 1})
+ let right = s:Right({'alt': 1})
+ endif
+
+ let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line)
+ return line
+endfunction
+" Function: s:TabbedCol(line, col) {{{2
+" Gets the col number for given line and existing col number. The new col
+" number is the col number when all leading spaces are converted to tabs
+" Args:
+" -line:the line to get the rel col for
+" -col: the abs col
+function s:TabbedCol(line, col)
+ let lineTruncated = strpart(a:line, 0, a:col)
+ let lineSpacesToTabs = substitute(lineTruncated, s:TabSpace(), '\t', 'g')
+ return strlen(lineSpacesToTabs)
+endfunction
+"FUNCTION: s:TabSpace() {{{2
+"returns a string of spaces equal in length to &tabstop
+function s:TabSpace()
+ let tabSpace = ""
+ let spacesPerTab = &tabstop
+ while spacesPerTab > 0
+ let tabSpace = tabSpace . " "
+ let spacesPerTab = spacesPerTab - 1
+ endwhile
+ return tabSpace
+endfunction
+
+" Function: s:UnEsc(str, escChar) {{{2
+" This function removes all the escape chars from a string
+" Args:
+" -str: the string to remove esc chars from
+" -escChar: the escape char to be removed
+function s:UnEsc(str, escChar)
+ return substitute(a:str, a:escChar, "", "g")
+endfunction
+
+" Function: s:UntabbedCol(line, col) {{{2
+" Takes a line and a col and returns the absolute column of col taking into
+" account that a tab is worth 3 or 4 (or whatever) spaces.
+" Args:
+" -line:the line to get the abs col for
+" -col: the col that doesnt take into account tabs
+function s:UntabbedCol(line, col)
+ let lineTruncated = strpart(a:line, 0, a:col)
+ let lineTabsToSpaces = substitute(lineTruncated, '\t', s:TabSpace(), 'g')
+ return strlen(lineTabsToSpaces)
+endfunction
+" Section: Comment mapping setup {{{1
+" ===========================================================================
+
+" switch to/from alternative delimiters
+nnoremap <plug>NERDCommenterAltDelims :call <SID>SwitchToAlternativeDelimiters(1)<cr>
+
+" comment out lines
+nnoremap <silent> <plug>NERDCommenterComment :call NERDComment(0, "norm")<cr>
+vnoremap <silent> <plug>NERDCommenterComment <ESC>:call NERDComment(1, "norm")<cr>
+
+" toggle comments
+nnoremap <silent> <plug>NERDCommenterToggle :call NERDComment(0, "toggle")<cr>
+vnoremap <silent> <plug>NERDCommenterToggle <ESC>:call NERDComment(1, "toggle")<cr>
+
+" minimal comments
+nnoremap <silent> <plug>NERDCommenterMinimal :call NERDComment(0, "minimal")<cr>
+vnoremap <silent> <plug>NERDCommenterMinimal <ESC>:call NERDComment(1, "minimal")<cr>
+
+" sexy comments
+nnoremap <silent> <plug>NERDCommenterSexy :call NERDComment(0, "sexy")<CR>
+vnoremap <silent> <plug>NERDCommenterSexy <ESC>:call NERDComment(1, "sexy")<CR>
+
+" invert comments
+nnoremap <silent> <plug>NERDCommenterInvert :call NERDComment(0, "invert")<CR>
+vnoremap <silent> <plug>NERDCommenterInvert <ESC>:call NERDComment(1, "invert")<CR>
+
+" yank then comment
+nmap <silent> <plug>NERDCommenterYank :call NERDComment(0, "yank")<CR>
+vmap <silent> <plug>NERDCommenterYank <ESC>:call NERDComment(1, "yank")<CR>
+
+" left aligned comments
+nnoremap <silent> <plug>NERDCommenterAlignLeft :call NERDComment(0, "alignLeft")<cr>
+vnoremap <silent> <plug>NERDCommenterAlignLeft <ESC>:call NERDComment(1, "alignLeft")<cr>
+
+" left and right aligned comments
+nnoremap <silent> <plug>NERDCommenterAlignBoth :call NERDComment(0, "alignBoth")<cr>
+vnoremap <silent> <plug>NERDCommenterAlignBoth <ESC>:call NERDComment(1, "alignBoth")<cr>
+
+" nested comments
+nnoremap <silent> <plug>NERDCommenterNest :call NERDComment(0, "nested")<cr>
+vnoremap <silent> <plug>NERDCommenterNest <ESC>:call NERDComment(1, "nested")<cr>
+
+" uncomment
+nnoremap <silent> <plug>NERDCommenterUncomment :call NERDComment(0, "uncomment")<cr>
+vnoremap <silent> <plug>NERDCommenterUncomment :call NERDComment(1, "uncomment")<cr>
+
+" comment till the end of the line
+nnoremap <silent> <plug>NERDCommenterToEOL :call NERDComment(0, "toEOL")<cr>
+
+" append comments
+nmap <silent> <plug>NERDCommenterAppend :call NERDComment(0, "append")<cr>
+
+" insert comments
+inoremap <silent> <plug>NERDCommenterInInsert <SPACE><BS><ESC>:call NERDComment(0, "insert")<CR>
+
+
+function! s:CreateMaps(target, combo)
+ if !hasmapto(a:target, 'n')
+ exec 'nmap ' . a:combo . ' ' . a:target
+ endif
+
+ if !hasmapto(a:target, 'v')
+ exec 'vmap ' . a:combo . ' ' . a:target
+ endif
+endfunction
+
+if g:NERDCreateDefaultMappings
+ call s:CreateMaps('<plug>NERDCommenterComment', '<leader>cc')
+ call s:CreateMaps('<plug>NERDCommenterToggle', '<leader>c<space>')
+ call s:CreateMaps('<plug>NERDCommenterMinimal', '<leader>cm')
+ call s:CreateMaps('<plug>NERDCommenterSexy', '<leader>cs')
+ call s:CreateMaps('<plug>NERDCommenterInvert', '<leader>ci')
+ call s:CreateMaps('<plug>NERDCommenterYank', '<leader>cy')
+ call s:CreateMaps('<plug>NERDCommenterAlignLeft', '<leader>cl')
+ call s:CreateMaps('<plug>NERDCommenterAlignBoth', '<leader>cb')
+ call s:CreateMaps('<plug>NERDCommenterNest', '<leader>cn')
+ call s:CreateMaps('<plug>NERDCommenterUncomment', '<leader>cu')
+ call s:CreateMaps('<plug>NERDCommenterToEOL', '<leader>c$')
+ call s:CreateMaps('<plug>NERDCommenterAppend', '<leader>cA')
+
+ if !hasmapto('<plug>NERDCommenterAltDelims', 'n')
+ nmap <leader>ca <plug>NERDCommenterAltDelims
+ endif
+endif
+
+
+
+" Section: Menu item setup {{{1
+" ===========================================================================
+"check if the user wants the menu to be displayed
+if g:NERDMenuMode != 0
+
+ let menuRoot = ""
+ if g:NERDMenuMode == 1
+ let menuRoot = 'comment'
+ elseif g:NERDMenuMode == 2
+ let menuRoot = '&comment'
+ elseif g:NERDMenuMode == 3
+ let menuRoot = '&Plugin.&comment'
+ endif
+
+ function! s:CreateMenuItems(target, desc, root)
+ exec 'nmenu <silent> ' . a:root . '.' . a:desc . ' ' . a:target
+ exec 'vmenu <silent> ' . a:root . '.' . a:desc . ' ' . a:target
+ endfunction
+ call s:CreateMenuItems("<plug>NERDCommenterComment", 'Comment', menuRoot)
+ call s:CreateMenuItems("<plug>NERDCommenterToggle", 'Toggle', menuRoot)
+ call s:CreateMenuItems('<plug>NERDCommenterMinimal', 'Minimal', menuRoot)
+ call s:CreateMenuItems('<plug>NERDCommenterNest', 'Nested', menuRoot)
+ exec 'nmenu <silent> '. menuRoot .'.To\ EOL <plug>NERDCommenterToEOL'
+ call s:CreateMenuItems('<plug>NERDCommenterInvert', 'Invert', menuRoot)
+ call s:CreateMenuItems('<plug>NERDCommenterSexy', 'Sexy', menuRoot)
+ call s:CreateMenuItems('<plug>NERDCommenterYank', 'Yank\ then\ comment', menuRoot)
+ exec 'nmenu <silent> '. menuRoot .'.Append <plug>NERDCommenterAppend'
+ exec 'menu <silent> '. menuRoot .'.-Sep- :'
+ call s:CreateMenuItems('<plug>NERDCommenterAlignLeft', 'Left\ aligned', menuRoot)
+ call s:CreateMenuItems('<plug>NERDCommenterAlignBoth', 'Left\ and\ right\ aligned', menuRoot)
+ exec 'menu <silent> '. menuRoot .'.-Sep2- :'
+ call s:CreateMenuItems('<plug>NERDCommenterUncomment', 'Uncomment', menuRoot)
+ exec 'nmenu <silent> '. menuRoot .'.Switch\ Delimiters <plug>NERDCommenterAltDelims'
+ exec 'imenu <silent> '. menuRoot .'.Insert\ Comment\ Here <plug>NERDCommenterInInsert'
+ exec 'menu <silent> '. menuRoot .'.-Sep3- :'
+ exec 'menu <silent>'. menuRoot .'.Help :help NERDCommenterContents<CR>'
+endif
+" vim: set foldmethod=marker :
diff --git a/.vim/plugin/rainbow_parenthsis.vim b/.vim/plugin/rainbow_parenthsis.vim
new file mode 100644
index 0000000..e5e3806
--- /dev/null
+++ b/.vim/plugin/rainbow_parenthsis.vim
@@ -0,0 +1,40 @@
+"------------------------------------------------------------------------------
+" Description: Rainbow colors for parenthsis
+" $Id: rainbow_parenthsis.vim 29 2007-09-24 11:40:36Z krischik@users.sourceforge.net $
+" Copyright: Copyright (C) 2006 Martin Krischik
+" Maintainer: Martin Krischik
+" John Gilmore
+" $Author: krischik@users.sourceforge.net $
+" $Date: 2007-09-24 13:40:36 +0200 (Mo, 24 Sep 2007) $
+" Version: 4.0
+" $Revision: 29 $
+" $HeadURL: https://vim-scripts.googlecode.com/svn/trunk/1561%20Rainbow%20Parenthsis%20Bundle/plugin/rainbow_parenthsis.vim $
+" History: 24.05.2006 MK Unified Headers
+" 15.10.2006 MK Bram's suggestion for runtime integration
+" 06.09.2007 LH Buffer friendly (can be used in different buffers),
+" can be toggled
+" 09.09.2007 MK Use on LH's suggestion but use autoload to
+" impove memory consumtion and startup performance
+" 09.10.2007 MK Now with round, square brackets, curly and angle
+" brackets.
+" Usage: copy to plugin directory.
+"------------------------------------------------------------------------------
+" This is a simple script. It extends the syntax highlighting to
+" highlight each matching set of parens in different colors, to make
+" it visually obvious what matches which.
+"
+" Obviously, most useful when working with lisp or Ada. But it's also nice other
+" times.
+"------------------------------------------------------------------------------
+
+command! -nargs=0 ToggleRaibowParenthesis call rainbow_parenthsis#Toggle()
+
+finish
+
+"------------------------------------------------------------------------------
+" Copyright (C) 2006 Martin Krischik
+"
+" Vim is Charityware - see ":help license" or uganda.txt for licence details.
+"------------------------------------------------------------------------------
+" vim: textwidth=78 wrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab
+" vim: filetype=vim foldmethod=marker
diff --git a/.vim/rainbow_parenthsis_options.vim b/.vim/rainbow_parenthsis_options.vim
new file mode 100644
index 0000000..a36a9ad
--- /dev/null
+++ b/.vim/rainbow_parenthsis_options.vim
@@ -0,0 +1,55 @@
+"------------------------------------------------------------------------------
+" Description: Options setable by the rainbow_parenthsis plugin
+" $Id: rainbow_parenthsis_options.vim 29 2007-09-24 11:40:36Z krischik@users.sourceforge.net $
+" Copyright: Copyright (C) 2006 Martin Krischik
+" Maintainer: Martin Krischik (krischik@users.sourceforge.net)
+" $Author: krischik@users.sourceforge.net $
+" $Date: 2007-09-24 13:40:36 +0200 (Mo, 24 Sep 2007) $
+" Version: 4.0
+" $Revision: 29 $
+" $HeadURL: https://vim-scripts.googlecode.com/svn/trunk/1561%20Rainbow%20Parenthsis%20Bundle/rainbow_parenthsis_options.vim $
+" History: 17.11.2006 MK rainbow_parenthsis_Options
+" 01.01.2007 MK Bug fixing
+" 09.10.2007 MK Now with round, square brackets, curly and angle
+" brackets.
+" Usage: copy content into your .vimrc and change options to your
+" likeing.
+" Help Page: rainbow_parenthsis.txt
+"------------------------------------------------------------------------------
+
+echoerr 'It is suggested to copy the content of ada_options into .vimrc!'
+finish " 1}}}
+
+" Section: rainbow_parenthsis options {{{1
+
+" }}}1
+
+" Section: Vimball options {{{1
+:set noexpandtab fileformat=unix encoding=utf-8
+:31,34 MkVimball rainbow_parenthsis-4.0.vba
+
+autoload/rainbow_parenthsis.vim
+doc/rainbow_parenthsis.txt
+plugin/rainbow_parenthsis.vim
+rainbow_parenthsis_options.vim
+
+" }}}1
+
+" Section: Tar options {{{1
+
+tar --create --bzip2 \
+ --file="rainbow_parenthsis-4.0.tar.bz2" \
+ rainbow_parenthsis_options.vim \
+ doc/rainbow_parenthsis.txt \
+ autoload/rainbow_parenthsis.vim \
+ plugin/rainbow_parenthsis.vim ;
+
+" }}}1
+
+"------------------------------------------------------------------------------
+" Copyright (C) 2006 Martin Krischik
+"
+" Vim is Charityware - see ":help license" or uganda.txt for licence derainbow_parenthsiss.
+"------------------------------------------------------------------------------
+" vim: textwidth=0 nowrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab
+" vim: foldmethod=marker