r746 - in /trunk/packages/vim-scripts/vim-scripts-7:
CHANGES.CVSCommand.txt
debian/TODO.Debian debian/copyright debian/vim-scripts.status
plugin/NERD_comments.vim
zack at users.alioth.debian.org
zack at users.alioth.debian.org
Tue Aug 22 18:51:04 UTC 2006
Author: zack
Date: Tue Aug 22 18:51:02 2006
New Revision: 746
URL: http://svn.debian.org/wsvn/pkg-vim/?sc=1&rev=746
Log:
added nerd commenter plugin
Added:
trunk/packages/vim-scripts/vim-scripts-7/CHANGES.CVSCommand.txt
trunk/packages/vim-scripts/vim-scripts-7/plugin/NERD_comments.vim
Modified:
trunk/packages/vim-scripts/vim-scripts-7/debian/TODO.Debian
trunk/packages/vim-scripts/vim-scripts-7/debian/copyright
trunk/packages/vim-scripts/vim-scripts-7/debian/vim-scripts.status
Added: trunk/packages/vim-scripts/vim-scripts-7/CHANGES.CVSCommand.txt
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/vim-scripts-7/CHANGES.CVSCommand.txt?rev=746&op=file
==============================================================================
--- trunk/packages/vim-scripts/vim-scripts-7/CHANGES.CVSCommand.txt (added)
+++ trunk/packages/vim-scripts/vim-scripts-7/CHANGES.CVSCommand.txt Tue Aug 22 18:51:02 2006
@@ -1,0 +1,38 @@
+vim600: set foldmethod=marker:tw=78:formatoptions=aw2tq
+
+1. Require Vim 7 in order to leverage several convenient features; also
+because I wanted to play with Vim 7.
+
+2. Renamed commands to start with 'VCS' instead of 'CVS'. The exceptions are
+the 'CVSEdit' and 'CVSWatch' family of commands, which are specific to CVS.
+
+3. Renamed options, events to start with 'VCSCommand'.
+
+4. Removed option to jump to the parent version of the current line in an
+annotated buffer, as opposed to the version on the current line. This made
+little sense in the branching scheme used by subversion, where jumping to a
+parent branch required finding a different location in the repository. It
+didn't work consistently in CVS anyway.
+
+5. Removed option to have nameless scratch buffers.
+
+6. Changed default behavior of scratch buffers to split the window instead of
+displaying in the current window. This may still be overridden using the
+'VCSCommandEdit' option.
+
+7. Split plugin into multiple plugins.
+
+8. Added 'VCSLock' and 'VCSUnlock' commands. These are implemented for
+subversion but not for CVS. These were not kept specific to subversion as they
+seemed more general in nature and more likely to be supported by any future VCS
+supported by this plugin.
+
+9. Changed name of buffer variables set by commands.
+
+'b:cvsOrigBuffNR' became 'b:VCSCommandOriginalBuffer'
+'b:cvscmd' became 'b:VCSCommandCommand'
+
+10. Added new automatic variables to command result buffers.
+
+'b:VCSCommandSourceFile'
+'b:VCSCommandVCSType'
Modified: trunk/packages/vim-scripts/vim-scripts-7/debian/TODO.Debian
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/vim-scripts-7/debian/TODO.Debian?rev=746&op=diff
==============================================================================
--- trunk/packages/vim-scripts/vim-scripts-7/debian/TODO.Debian (original)
+++ trunk/packages/vim-scripts/vim-scripts-7/debian/TODO.Debian Tue Aug 22 18:51:02 2006
@@ -10,10 +10,3 @@
-- Stefano Zacchiroli <zack at debian.org> Sat, 16 Apr 2005 23:05:50 +0200
-- add NERD_commenter
-
- -- Stefano Zacchiroli <zack at debian.org> Tue, 11 Apr 2006 14:11:03 -0400
-
-- review/remove scripts no longer working with vim 7
-
- -- Stefano Zacchiroli <zack at debian.org> Fri, 16 Jun 2006 10:02:49 +0200
Modified: trunk/packages/vim-scripts/vim-scripts-7/debian/copyright
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/vim-scripts-7/debian/copyright?rev=746&op=diff
==============================================================================
--- trunk/packages/vim-scripts/vim-scripts-7/debian/copyright (original)
+++ trunk/packages/vim-scripts/vim-scripts-7/debian/copyright Tue Aug 22 18:51:02 2006
@@ -122,6 +122,11 @@
url: http://vim.sourceforge.net/scripts/script.php?script_id=13
license: no license
+script: plugin/NERD_comments.vim;
+author: Marty Grenfell < mrg39 at student.canterbury.ac.nz >
+url: http://www.vim.org/scripts/script.php?script_id=1218
+license: no license
+
--
Licenses referenced above
Modified: trunk/packages/vim-scripts/vim-scripts-7/debian/vim-scripts.status
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/vim-scripts-7/debian/vim-scripts.status?rev=746&op=diff
==============================================================================
--- trunk/packages/vim-scripts/vim-scripts-7/debian/vim-scripts.status (original)
+++ trunk/packages/vim-scripts/vim-scripts-7/debian/vim-scripts.status Tue Aug 22 18:51:02 2006
@@ -20,7 +20,7 @@
author_url: http://www.vim.org/account/profile.php?user_id=49
email: feline at irendi.com
license: license [1], see below
-version: 2.12
+version: 2.14
script_name: plugin/whatdomain.vim
script_url: http://www.vim.org/scripts/script.php?script_id=62
@@ -36,7 +36,7 @@
author_url: http://www.vim.org/account/profile.php?user_id=97
email: delux256-vim at yahoo dot com
license: license [2], see below
-version: 7.0.6
+version: 7.0.11
extras: doc/bufexplorer.txt
script_name: plugin/minibufexpl.vim
@@ -61,7 +61,7 @@
author_url: http://www.vim.org/account/profile.php?user_id=244
email: yegappan at yahoo.com
license: no license
-version: 4.0b2
+version: 4.0b4
extras: doc/taglist.txt
script_name: plugin/calendar.vim
@@ -70,7 +70,7 @@
author_url: http://www.vim.org/account/profile.php?user_id=103
email: mattn_jp at mail.goo.ne.jp
license: no license
-version: 1.4
+version: 1.4a
script_name: plugin/winmanager.vim
script_url: http://www.vim.org/scripts/script.php?script_id=95
@@ -87,7 +87,7 @@
author_url: http://www.vim.org/account/profile.php?user_id=96
email: drchip at campbellfamily.biz
license: GNU GPL, see /usr/share/common-licenses/GPL-2
-version: 28/33
+version: 29/34
extras: doc/Align.txt, plugin/AlignMaps.vim, plugin/cecutil.vim, autoload/Align.vim
script_name: plugin/cvsmenu.vim
@@ -96,7 +96,7 @@
author_url: http://www.vim.org/account/profile.php?user_id=6184
email: adah at sh163.net
license: GNU LGPL, see /usr/share/common-licenses/LGPL-2
-version: 1.121
+version: 1.124
script_name: plugin/vcscommand.vim
script_url: http://www.vim.org/scripts/script.php?script_id=90
@@ -198,6 +198,14 @@
license: no license
version: 0.9.1
+script_name: plugin/NERD_comments.vim
+script_url: http://www.vim.org/scripts/script.php?script_id=1218
+author: Marty Grenfell
+author_url: http://www.vim.org/account/profile.php?user_id=7006
+email: mrg39 at student.canterbury.ac.nz
+license: no license
+version: 1.68
+
--
Licenses referenced above
Added: trunk/packages/vim-scripts/vim-scripts-7/plugin/NERD_comments.vim
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/vim-scripts-7/plugin/NERD_comments.vim?rev=746&op=file
==============================================================================
--- trunk/packages/vim-scripts/vim-scripts-7/plugin/NERD_comments.vim (added)
+++ trunk/packages/vim-scripts/vim-scripts-7/plugin/NERD_comments.vim Tue Aug 22 18:51:02 2006
@@ -1,0 +1,4596 @@
+" vim global plugin that provides easy code commenting for various file types
+" Last Change: 13 Aug 2006
+" Maintainer: Martin Grenfell <mrg39 at student.canterbury.ac.nz>
+let s:NERD_comments_version = 1.68
+
+
+" For help documentation type :help NERD_comments. If this fails, Restart vim
+" and try again. If it sill doesnt work... the help page is at the bottom
+" of this file.
+
+" Section: script init stuff {{{1
+if exists("loaded_nerd_comments")
+ finish
+endif
+let loaded_nerd_comments = 1
+
+" Section: tabSpace init {{{2
+" here we get a string that is the same length as a tabstop but with spaces
+" instead of a tab. Also, we store the number of spaces in a tab
+let s:tabSpace = ""
+let s:spacesPerTab = &tabstop
+while s:spacesPerTab > 0
+ let s:tabSpace = s:tabSpace . " "
+ let s:spacesPerTab = s:spacesPerTab - 1
+endwhile
+let s:spacesPerTab = &tabstop
+
+" Section: spaces init {{{2
+" Occasionally we need to grab a string of spaces so just make one here
+let s:spaces = ""
+while strlen(s:spaces) < 100
+ let s:spaces = s:spaces . " "
+endwhile
+
+" 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:NERD_use_ada_with_spaces", 0)
+call s:InitVariable("g:NERD_use_c_style_acedb_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_ch_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_clean_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_clipper_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_cpp_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_cs_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_dot_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_dylan_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_h_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_hercules_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_idl_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_ishd_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_java_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_javascript_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_kscript_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_mel_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_named_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_pccts_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_pike_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_pilrc_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_plm_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_pov_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_prolog_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_rc_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_tads_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_tsalt_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_uc_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_verilog_comments", 0)
+call s:InitVariable("g:NERD_use_dash_dash_simula_comments", 0)
+call s:InitVariable("g:NERD_use_dnl_style_automake_comments", 0)
+call s:InitVariable("g:NERD_use_hash_samba_comments", 0)
+call s:InitVariable("g:NERD_use_c_style_php_comments", 0)
+call s:InitVariable("g:NERD_use_long_haskell_comments", 0)
+call s:InitVariable("g:NERD_use_long_lisp_comments", 0)
+call s:InitVariable("g:NERD_use_long_lua_comments", 0)
+call s:InitVariable("g:NERD_use_nested_comments_default", 0)
+call s:InitVariable("g:NERD_use_paren_star_pascal_comments", 0)
+call s:InitVariable("g:NERD_use_REM_basic_comments", 0)
+call s:InitVariable("g:NERD_use_single_part_c_comments", 0)
+
+call s:InitVariable("g:NERD_allow_any_visual_delims_regexp", ".*")
+call s:InitVariable("g:NERD_block_com_after_right", 0)
+call s:InitVariable("g:NERD_comment_whole_lines_in_v_mode", 0)
+call s:InitVariable("g:NERD_create_h_filetype", 0)
+call s:InitVariable("g:NERD_menu_mode", 2)
+call s:InitVariable("g:NERD_dont_remove_alt_coms", 0)
+call s:InitVariable("g:NERD_dont_remove_spaces_regexp", "^python$")
+call s:InitVariable("g:NERD_left_align_regexp", "^$")
+call s:InitVariable("g:NERD_lPlace", "[>")
+call s:InitVariable("g:NERD_place_holder_regexp", ".*")
+call s:InitVariable("g:NERD_right_align_regexp", "^$")
+call s:InitVariable("g:NERD_rPlace", "<]")
+call s:InitVariable("g:NERD_shut_up", '0')
+call s:InitVariable("g:NERD_space_delim_filetype_regexp", "^$")
+call s:InitVariable("g:NERD_use_compact_sexy_com_regexp", "^$")
+
+call s:InitVariable("g:mapleader", '\')
+call s:InitVariable("g:NERD_mapleader", g:mapleader . 'c')
+
+call s:InitVariable("g:NERD_alt_com_map", g:NERD_mapleader . 'a')
+call s:InitVariable("g:NERD_append_com_map", g:NERD_mapleader . 'A')
+call s:InitVariable("g:NERD_com_align_both_map", g:NERD_mapleader . 'b')
+call s:InitVariable("g:NERD_com_align_left_map", g:NERD_mapleader . 'l')
+call s:InitVariable("g:NERD_com_align_right_map", g:NERD_mapleader . 'r')
+call s:InitVariable("g:NERD_com_in_insert_map", '<C-c>')
+call s:InitVariable("g:NERD_com_line_invert_map", g:NERD_mapleader . 'i')
+call s:InitVariable("g:NERD_com_line_map", g:NERD_mapleader . 'c')
+call s:InitVariable("g:NERD_com_line_nest_map", g:NERD_mapleader . 'n')
+call s:InitVariable("g:NERD_com_line_sexy_map", g:NERD_mapleader . 's')
+call s:InitVariable("g:NERD_com_line_toggle_map", g:NERD_mapleader . '<space>')
+call s:InitVariable("g:NERD_com_line_minimal_map", g:NERD_mapleader . 'm')
+call s:InitVariable("g:NERD_com_line_yank_map", g:NERD_mapleader . 'y')
+call s:InitVariable("g:NERD_com_to_end_of_line_map", g:NERD_mapleader . '$')
+call s:InitVariable("g:NERD_prepend_com_map", g:NERD_mapleader . 'I')
+call s:InitVariable("g:NERD_uncom_line_map", g:NERD_mapleader . 'u')
+
+" Section: Comment mapping functions and autocommands {{{1
+" ============================================================================
+" Section: Comment enabler autocommands {{{2
+" ============================================================================
+
+if !exists("nerd_autocmds_loaded")
+ let nerd_autocmds_loaded=1
+
+ augroup commentEnablers
+
+ if g:NERD_create_h_filetype == 1
+ " some versions of vim dont have an h filetype... so we set it
+ " ourselves, we also set syntax highlighting to c++ style
+ autocmd BufEnter *.h :setfiletype h | :set syntax=cpp
+ endif
+
+ "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)
+ augroup END
+
+endif
+
+" Function: s:SetUpForNewFiletype(filetype) function {{{2
+" This function is responsible for setting up buffer scoped variables for the
+" given filetype.
+"
+" These variables include the comment delimiters for the given filetype and calls
+" MapDelimiters or MapDelimitersWithAlternative passing in these delimiters.
+"
+" Args:
+" -filetype: the filetype to set delimiters for
+"
+function s:SetUpForNewFiletype(filetype)
+ "if we have already set the delimiters for this buffer then dont go thru
+ "it again
+ if exists("b:left") && b:left != ''
+ return
+ endif
+
+ let b:sexyComMarker = ''
+
+ "check the filetype against all known filetypes to see if we have
+ "hardcoded the comment delimiters to use
+ if a:filetype == "abaqus"
+ call s:MapDelimiters('**', '')
+ elseif a:filetype == "abc"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "acedb"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_acedb_comments )
+ elseif a:filetype == "ada"
+ call s:MapDelimitersWithAlternative('--','', '-- ', '', g:NERD_use_ada_with_spaces)
+ elseif a:filetype == "ahdl"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "amiga"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "aml"
+ call s:MapDelimiters('/*', '')
+ elseif a:filetype == "ampl"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "ant"
+ call s:MapDelimiters('<!--','-->')
+ elseif a:filetype == "apache"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "apachestyle"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "asm68k"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "asm"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "asm"
+ call s:MapDelimiters('!','')
+ elseif a:filetype == "asn"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "aspvbs"
+ call s:MapDelimiters('''', '')
+ elseif a:filetype == "atlas"
+ call s:MapDelimiters('C','$')
+ elseif a:filetype == "automake"
+ call s:MapDelimitersWithAlternative('#','', 'dnl ', '', g:NERD_use_dnl_style_automake_comments)
+ elseif a:filetype == "ave"
+ call s:MapDelimiters(''','')
+ elseif a:filetype == "awk"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "basic"
+ call s:MapDelimitersWithAlternative(''','', 'REM ', '', g:NERD_use_REM_basic_comments)
+ elseif a:filetype == "b"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "bc"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "bdf"
+ call s:MapDelimiters('COMMENT ', '')
+ elseif a:filetype == "bib"
+ call s:MapDelimiters('','')
+ elseif a:filetype == "bindzone"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "btm"
+ call s:MapDelimiters('::', '')
+ elseif a:filetype == "caos"
+ call s:MapDelimiters('*', '')
+ elseif a:filetype == "catalog"
+ call s:MapDelimiters('--','--')
+ elseif a:filetype == "c"
+ call s:MapDelimitersWithAlternative('/*','*/', '//', '', g:NERD_use_single_part_c_comments)
+ elseif a:filetype == "cfg"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "cg"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', 0)
+ elseif a:filetype == "ch"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_ch_comments )
+ elseif a:filetype == "cl"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "clean"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_clean_comments )
+ elseif a:filetype == "clipper"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_clipper_comments )
+ elseif a:filetype == "conf"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "config"
+ call s:MapDelimiters('dnl ', '')
+ elseif a:filetype == "context"
+ call s:MapDelimiters('%','')
+ elseif a:filetype == "cpp"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_cpp_comments)
+ elseif a:filetype == "crontab"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "cs"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_cs_comments)
+ elseif a:filetype == "csc"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "csp"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "css"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "cterm"
+ call s:MapDelimiters('*', '')
+ elseif a:filetype == "cupl"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "cvs"
+ call s:MapDelimiters('CVS:','')
+ elseif a:filetype == "dcl"
+ call s:MapDelimiters('$!', '')
+ elseif a:filetype == "def"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "diff"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "dns"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "dosbatch"
+ call s:MapDelimiters('REM ','')
+ elseif a:filetype == "dosini"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "dot"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_dot_comments )
+ elseif a:filetype == "dracula"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "dsl"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "dtd"
+ call s:MapDelimiters('<!--','-->')
+ elseif a:filetype == "dtml"
+ call s:MapDelimiters('<dtml-comment>','</dtml-comment>')
+ elseif a:filetype == "dylan"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_dylan_comments )
+ elseif a:filetype == "ecd"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "eiffel"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "elf"
+ call s:MapDelimiters(''', '')
+ elseif a:filetype == "elmfilt"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "erlang"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "eterm"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "expect"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "exports"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "fgl"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "focexec"
+ call s:MapDelimiters('-*', '')
+ elseif a:filetype == "form"
+ call s:MapDelimiters('*', '')
+ elseif a:filetype == "fortran"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "foxpro"
+ call s:MapDelimiters('*', '')
+ elseif a:filetype == "fvwm"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "fx"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', 0)
+ elseif a:filetype == "gdb"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "gdmo"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "geek"
+ call s:MapDelimiters('GEEK_COMMENT:', '')
+ elseif a:filetype == "gnuplot"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "gtkrc"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "haskell"
+ call s:MapDelimitersWithAlternative('--','', '{-', '-}', g:NERD_use_long_haskell_comments)
+ elseif a:filetype == "hb"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "h"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_h_comments )
+ elseif a:filetype == "help"
+ call s:MapDelimiters('"','')
+ elseif a:filetype == "hercules"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_hercules_comments )
+ elseif a:filetype == "hog"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "html"
+ call s:MapDelimitersWithAlternative('<!--','-->', '//', '', 0)
+ elseif a:filetype == "htmlos"
+ call s:MapDelimiters('#','/#')
+ elseif a:filetype == "ia64"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "icon"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "idlang"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "idl"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_idl_comments )
+ elseif a:filetype == "indent"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "inform"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "inittab"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "ishd"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_ishd_comments )
+ elseif a:filetype == "iss"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "ist"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "jam"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "java"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_java_comments)
+ elseif a:filetype == "javascript"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_javascript_comments)
+ elseif a:filetype == "jess"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "jgraph"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "jproperties"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "jproperties"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "jsp"
+ call s:MapDelimiters('<%--', '--%>')
+ elseif a:filetype == "kix"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "kscript"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_kscript_comments )
+ elseif a:filetype == "lace"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "lex"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "lftp"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "lifelines"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "lilo"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "lisp"
+ call s:MapDelimitersWithAlternative(';','', '#|', '|#', g:NERD_use_long_lisp_comments)
+ elseif a:filetype == "lite"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "lotos"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "lout"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "lprolog"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "lscript"
+ call s:MapDelimiters("'", '')
+ elseif a:filetype == "lss"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "lua"
+ call s:MapDelimitersWithAlternative('--','', '--[[', ']]', g:NERD_use_long_lua_comments)
+ elseif a:filetype == "lynx"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "m4"
+ call s:MapDelimiters('dnl ', '')
+ elseif a:filetype == "mail"
+ call s:MapDelimiters('> ','')
+ elseif a:filetype == "make"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "maple"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "masm"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "master"
+ call s:MapDelimiters('$', '')
+ elseif a:filetype == "matlab"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "mel"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_mel_comments )
+ elseif a:filetype == "mf"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "mib"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "mma"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "model"
+ call s:MapDelimiters('$','$')
+ elseif a:filetype =~ "moduala."
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "modula2"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "modula3"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "monk"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "mush"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "muttrc"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "named"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_named_comments )
+ elseif a:filetype == "nasm"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "nastran"
+ call s:MapDelimiters('$', '')
+ elseif a:filetype == "natural"
+ call s:MapDelimiters('/*', '')
+ elseif a:filetype == "ncf"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "nqc"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "nsis"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "ocaml"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "omnimark"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "openroad"
+ call s:MapDelimiters('//', '')
+ elseif a:filetype == "opl"
+ call <sid>mapdelimiters("REM", "")
+ elseif a:filetype == "ora"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "ox"
+ call s:MapDelimiters('//', '')
+ elseif a:filetype == "pascal"
+ call s:MapDelimitersWithAlternative('{','}', '(*', '*)', g:NERD_use_paren_star_pascal_comments)
+ elseif a:filetype == "pcap"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "pccts"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_pccts_comments )
+ elseif a:filetype == "perl"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "pfmain"
+ call s:MapDelimiters('//', '')
+ elseif a:filetype == "php"
+ call s:MapDelimitersWithAlternative('//','','/*', '*/', g:NERD_use_c_style_php_comments)
+ elseif a:filetype == "phtml"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "pic"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "pike"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_pike_comments )
+ elseif a:filetype == "pilrc"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_pilrc_comments )
+ elseif a:filetype == "pine"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "plaintex"
+ call s:MapDelimiters('%','')
+ elseif a:filetype == "plm"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_plm_comments )
+ elseif a:filetype == "plsql"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "po"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "postscr"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "pov"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_pov_comments )
+ elseif a:filetype == "povini"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "ppd"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "ppwiz"
+ call s:MapDelimiters(';;', '')
+ elseif a:filetype == "procmail"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "progress"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "prolog"
+ call s:MapDelimitersWithAlternative('%','','/*','*/', g:NERD_use_c_style_prolog_comments)
+ elseif a:filetype == "psf"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "ptcap"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "python"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "python"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "radiance"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "ratpoison"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "r"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "rc"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_rc_comments )
+ elseif a:filetype == "readline"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "rebol"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "registry"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "remind"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "rexx"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "robots"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "rpl"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "ruby"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "sa"
+ call s:MapDelimiters('--','')
+ elseif a:filetype == "samba"
+ call s:MapDelimitersWithAlternative(';','', '#', '', g:NERD_use_hash_samba_comments)
+ elseif a:filetype == "sas"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "sather"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "scheme"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "scilab"
+ call s:MapDelimiters('//', '')
+ elseif a:filetype == "screen"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "scsh"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "sdl"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "sed"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "sgml"
+ call s:MapDelimiters('<!','>')
+ elseif a:filetype == "sgmldecl"
+ call s:MapDelimiters('--','--')
+ elseif a:filetype == "sgmllnx"
+ call s:MapDelimiters('<!--','-->')
+ elseif a:filetype == "sicad"
+ call s:MapDelimiters('*', '')
+ elseif a:filetype == "simula"
+ call s:MapDelimitersWithAlternative('%', '', '--', '', g:NERD_use_dash_dash_simula_comments)
+ elseif a:filetype == "sinda"
+ call s:MapDelimiters('$', '')
+ elseif a:filetype == "skill"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "slang"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "sl"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "slrnrc"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "sm"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "smil"
+ call s:MapDelimiters('<!','>')
+ elseif a:filetype == "smith"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "sml"
+ call s:MapDelimiters('(*','*)')
+ elseif a:filetype == "snnsnet"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "snnspat"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "snnsres"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "snobol4"
+ call s:MapDelimiters('*', '')
+ elseif a:filetype == "spec"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "specman"
+ call s:MapDelimiters('//', '')
+ elseif a:filetype == "spice"
+ call s:MapDelimiters('$', '')
+ elseif a:filetype == "sql"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "sqlforms"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "sqlj"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "sqr"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "squid"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "st"
+ call s:MapDelimiters('"",''')
+ elseif a:filetype == "stp"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "strace"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "tads"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_tads_comments )
+ elseif a:filetype == "tags"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "tak"
+ call s:MapDelimiters('$', '')
+ elseif a:filetype == "tasm"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "tcl"
+ call s:MapDelimiters('#','')
+ elseif a:filetype == "terminfo"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "tex"
+ call s:MapDelimiters('%','')
+ elseif a:filetype == "plaintex"
+ call s:MapDelimiters('%','')
+ elseif a:filetype == "texinfo"
+ call <sid>mapdelimiters("@c ", "")
+ elseif a:filetype == "texmf"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "tf"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "tidy"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "tli"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "trasys"
+ call <sid>mapdelimiters("$", "")
+ elseif a:filetype == "tsalt"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_tsalt_comments )
+ elseif a:filetype == "tsscl"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "tssgm"
+ call s:MapDelimiters('comment = '',''')
+ elseif a:filetype == "uc"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_uc_comments )
+ elseif a:filetype == "uil"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "vb"
+ call s:MapDelimiters(''','')
+ elseif a:filetype == "verilog"
+ call s:MapDelimitersWithAlternative('//','', '/*','*/', g:NERD_use_c_style_verilog_comments)
+ elseif a:filetype == "vgrindefs"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "vhdl"
+ call s:MapDelimiters('--', '')
+ elseif a:filetype == "vim"
+ call s:MapDelimiters('"','')
+ elseif a:filetype == "virata"
+ call s:MapDelimiters('%', '')
+ elseif a:filetype == "vrml"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "vsejcl"
+ call s:MapDelimiters('/*', '')
+ elseif a:filetype == "webmacro"
+ call s:MapDelimiters('##', '')
+ elseif a:filetype == "wget"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "winbatch"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "wml"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype =~ "[^w]*sh"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "wvdial"
+ call s:MapDelimiters(';', '')
+ elseif a:filetype == "xdefaults"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "xf86conf"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "xkb"
+ call s:MapDelimiters('//', '')
+ elseif a:filetype == "xmath"
+ call s:MapDelimiters('#', '')
+ elseif a:filetype == "xml"
+ call s:MapDelimiters('<!--','-->')
+ elseif a:filetype == "xmodmap"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "xpm2"
+ call s:MapDelimiters('!', '')
+ elseif a:filetype == "xpm"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "xslt"
+ call s:MapDelimiters('<!--','-->')
+ elseif a:filetype == "yacc"
+ call s:MapDelimiters('/*','*/')
+ elseif a:filetype == "z8a"
+ call s:MapDelimiters(';', '')
+
+ elseif a:filetype == ""
+ call s:MapDelimitersWithAlternative("","", "", "", 0)
+
+ "we have not hardcoded the comment delimiters to use for this filetype so
+ "get them from &commentstring.
+ else
+ "print a disclaimer to the user :)
+ call s:NerdEcho("NERD_comments:Unknown filetype, setting delimiters by &commentstring", 0)
+
+ "extract the delims from &commentstring
+ let left= substitute(&commentstring, '\(.*\)%s.*', '\1', '')
+ let right= substitute(&commentstring, '.*%s\(.*\)', '\1', 'g')
+
+ call s:MapDelimiters(left,right)
+ endif
+endfunction
+
+" Function: s:MapDelimiters(left, right) function {{{2
+" This function is a wrapper for s:MapDelimiters(left, right, leftAlt, rightAlt, useAlt) and is called when there
+" is no alternative comment delimiters for the current filetype
+"
+" Args:
+" -left: the left comment delimiter
+" -right: the right comment delimiter
+function s:MapDelimiters(left, right)
+ call s:MapDelimitersWithAlternative(a:left, a:right, "", "", 0)
+endfunction
+
+" Function: s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt, useAlt) function {{{2
+" this function sets up the comment delimiter buffer variables
+"
+" Args:
+" -left: the string defining the comment start delimiter
+" -right: the string defining the comment end delimiter
+" -leftAlt: the string for the alternative comment style defining the comment start delimiter
+" -rightAlt: the string for the alternative comment style defining the comment end delimiter
+" -useAlt: a flag specifying whether to use the alternative comment style 0 is
+" false
+function s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt, useAlt)
+
+ " if the useAlt flag is not set then we use a:left and a:right
+ " as the left and right comment delimiters
+ if a:useAlt == 0
+ let b:left = a:left
+ let b:right = a:right
+ let b:leftAlt = a:leftAlt
+ let b:rightAlt = a:rightAlt
+ else
+ let b:left = a:leftAlt
+ let b:right = a:rightAlt
+ let b:leftAlt = a:left
+ let b:rightAlt = a:right
+ endif
+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:leftAlt=="" && b:rightAlt=="")
+ if a:printMsgs
+ call s:NerdEcho("NERD_comments:Cannot use alternative delimiters, none are specified", 0)
+ endif
+ return 0
+ endif
+
+ "save the current delimiters
+ let tempLeft = b:left
+ let tempRight = b:right
+
+ "swap current delimiters for alternative
+ let b:left = b:leftAlt
+ let b:right = b:rightAlt
+
+ "set the previously current delimiters to be the new alternative ones
+ let b:leftAlt = tempLeft
+ let b:rightAlt = tempRight
+
+ "tell the user what comment delimiters they are now using
+ if a:printMsgs
+ let leftNoEsc = b:left
+ let rightNoEsc = b:right
+ call s:NerdEcho("NERD_comments:Now using " . leftNoEsc . " " . rightNoEsc . " 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:GetLeft(0,1,0)
+ let right = s:GetRight(0,1,0)
+
+ " 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 ) range {{{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. Note that the
+" range keyword is specified for this function. This is because this function
+" cannot be applied implicitly to every line specified in visual mode
+"
+" 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 ) range
+ " 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 topline =~ '^\t\t*' || bottomline =~ '^\t\t*'
+ "find out how many tabs are in the top line and adjust the left
+ "boundary accordingly
+ let numTabs = strlen(substitute(topline, '^\(\t*\).*$', '\1', ""))
+ if lSide < numTabs
+ let lSide = s:spacesPerTab * lSide
+ else
+ let lSide = (lSide - numTabs) + (s:spacesPerTab * numTabs)
+ endif
+
+ "find out how many tabs are in the bottom line and adjust the right
+ "boundary accordingly
+ let numTabs = strlen(substitute(bottomline, '^\(\t*\).*$', '\1', ""))
+ let rSide = (rSide - numTabs) + (s:spacesPerTab * 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 didSwitchDelims = -1
+
+ "if the right delim isnt empty then we can use it for this comment
+ if b:right != '' || &filetype !~ g:NERD_allow_any_visual_delims_regexp
+ let didSwitchDelims = 0
+ "if the alternative comment right delimiter isnt null then we can use the
+ "alternative right delims
+ elseif b:rightAlt != ''
+ let didSwitchDelims = 1
+ call <sid>SwitchToAlternativeDelimiters(0)
+ endif
+
+
+ "get versions of left/right without the escape chars
+ let leftNoEsc = b:left
+ let rightNoEsc = b:right
+
+ "we need the len of leftNoEsc soon
+ let lenLeftNoEsc = strlen(leftNoEsc)
+
+ "we need the len of rightNoEsc soon
+ let lenRightNoEsc = strlen(rightNoEsc)
+
+ "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:GetCanCommentLine(a:forceNested, currentLine)
+
+ "convert the leading tabs into spaces
+ let theLine = getline(currentLine)
+ let lineHasLeadTabs = s:HasLeadingTab(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:NERD_block_com_after_right==1
+
+ "lineLSide and lineRSide are used as indexes into theLine. They
+ "are used to point to index where the left and right
+ "delimiters will be placed on the current line. The position
+ "of the delimiters may be altered if the current left position
+ "is in the middle of a delimiter.
+ let lineLSide = lSide
+ let lineRSide = rSide
+
+ "If the left or right boundaries are inside an existing
+ "delimiter then adjust lineLSide and lineRSide appropriately so
+ "that they are just after/before these delimiters
+ let offset = s:GetIndxInSubstr(lSide-1, leftNoEsc, theLine)
+ if offset > 0
+ let lineLSide = lSide + lenLeftNoEsc - offset
+ endif
+ let offset = s:GetIndxInSubstr(lSide-1, rightNoEsc, theLine)
+ if offset > 0
+ let lineLSide = lSide - offset
+ endif
+
+ let offset = s:GetIndxInSubstr(rSide, rightNoEsc, theLine)
+ if offset > 0
+ let lineRSide = rSide + lenRightNoEsc - offset
+ endif
+ let offset = s:GetIndxInSubstr(rSide, leftNoEsc, theLine)
+ if offset > 0
+ let lineRSide = rSide + lenLeftNoEsc - offset
+ endif
+
+ let offset = s:GetIndxInSubstr(lSide-1, g:NERD_lPlace, theLine)
+ if offset > 0
+ let lineLSide = lSide + strlen(g:NERD_lPlace) - offset
+ endif
+ let offset = s:GetIndxInSubstr(lSide-1, g:NERD_rPlace, theLine)
+ if offset > 0
+ let lineLSide = lSide - offset
+ endif
+
+ let offset = s:GetIndxInSubstr(rSide, g:NERD_rPlace, theLine)
+ if offset > 0
+ let lineRSide = rSide + strlen(g:NERD_rPlace) - offset
+ endif
+ let offset = s:GetIndxInSubstr(rSide, g:NERD_lPlace, theLine)
+ if offset > 0
+ let lineRSide = rSide + strlen(g:NERD_lPlace) - offset
+ endif
+
+ if b:leftAlt != ""
+ let leftANoEsc = b:leftAlt
+ let rightANoEsc = b:rightAlt
+ let lenRightANoEsc = strlen(rightANoEsc)
+ let lenLeftANoEsc = strlen(leftANoEsc)
+
+ let offset = s:GetIndxInSubstr(lSide-1, leftANoEsc, theLine)
+ if offset > 0
+ let lineLSide = lSide + lenLeftANoEsc - offset
+ endif
+ let offset = s:GetIndxInSubstr(lSide-1, rightANoEsc, theLine)
+ if offset > 0
+ let lineLSide = lSide - offset
+ endif
+
+ let offset = s:GetIndxInSubstr(rSide, rightANoEsc, theLine)
+ if offset > 0
+ let lineRSide = rSide + lenRightNoEsc - offset
+ endif
+ let offset = s:GetIndxInSubstr(rSide, leftANoEsc, theLine)
+ if offset > 0
+ let lineRSide = rSide + lenLeftANoEsc - offset
+ endif
+ endif
+
+ "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)
+ call cursor(currentLine, lineLSide)
+ if col(".") == lineLSide && line(".") == currentLine
+
+ let leftSpaced = s:GetLeft(0,1,0)
+ let rightSpaced = s:GetRight(0,1,0)
+
+ "stick the left delimiter down
+ let theLine = strpart(theLine, 0, lineLSide-1) . leftSpaced . strpart(theLine, lineLSide-1)
+
+ "attempt to go the right boundary to place the right
+ "delimiter, if we cant go to the right boundary then the
+ "comment delimiter will be placed on the EOL.
+ if rightNoEsc != ''
+ call cursor(currentLine, lineRSide+strlen(leftSpaced))
+
+ "stick the right delimiter down
+ let theLine = strpart(theLine, 0, lineRSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, lineRSide+strlen(rightSpaced))
+
+ "get the first/last indexes of the delimiters and get
+ "the string between them and call it searchStr
+ let firstLeftDelim = s:FindDelimiterIndex(leftNoEsc, theLine)
+ let lastRightDelim = s:GetLastIndexOfDelim(rightNoEsc, theLine)
+
+ "if the user has placed somewhere so that
+ "NERD_comments doesnt recognise it as a comment
+ "delimiter then dont try to use place-holders as we'd
+ "probably just screw it up more
+ if firstLeftDelim != -1 && lastRightDelim != -1
+ let searchStr = strpart(theLine, 0, lastRightDelim)
+ let searchStr = strpart(searchStr, firstLeftDelim+strlen(leftNoEsc))
+
+ "replace the outter most delims in searchStr with
+ "place-holders
+ let theLineWithPlaceHolders = s:ReplaceDelims(leftNoEsc, rightNoEsc, g:NERD_lPlace, g:NERD_rPlace, searchStr)
+
+ "add the right delimiter onto the line
+ let theLine = strpart(theLine, 0, firstLeftDelim+strlen(leftNoEsc)) . 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
+
+
+ "move onto the next line
+ let currentLine = currentLine + 1
+ endwhile
+
+ "if we switched delims then we gotta go back to what they were before
+ if didSwitchDelims == 1
+ call s:SwitchToAlternativeDelimiters(0)
+ endif
+endfunction
+
+" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) range {{{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
+" -alignRight/alignLeft: 0/1 if the comments delimiters should/shouldnt be
+" aligned left/right
+" -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) range
+ " 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:GetLeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+ let rightAlignIndx = s:GetRightMostIndx(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:GetLeft(0,1,0))
+
+ " 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:HasLeadingTab(theLine)
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ if s:GetCanCommentLine(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 && &filetype =~ g:NERD_place_holder_regexp
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ endif
+
+ " find out if the line is commented using normal delims and/or
+ " alternate ones
+ let isCommented = s:IsCommented(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine)
+
+ " check if we can comment this line
+ if !isCommented || &filetype =~ g:NERD_place_holder_regexp || b:right==""
+ if a:alignLeft
+ let theLine = s:AddLeftDelimAligned(b:left, theLine, leftAlignIndx)
+ else
+ let theLine = s:AddLeftDelim(s:GetLeft(0,1,0), theLine)
+ endif
+ if a:alignRight
+ let theLine = s:AddRightDelimAligned(b:right, theLine, rightAlignIndx)
+ else
+ let theLine = s:AddRightDelim(s:GetRight(0,1,0), 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) range {{{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) range
+ "if we need to use place holders for the comment, make sure they are
+ "enabled for this filetype
+ if &filetype !~ g:NERD_place_holder_regexp && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine)
+ call s:NerdEcho("NERD_comments: comment aborted. Place holders are required but disabled.",1)
+ return
+ endif
+
+ "get the left and right delims to smack on
+ let useSpaceStr = &filetype =~ g:NERD_space_delim_filetype_regexp
+ let left = s:GetSexyComLeft(useSpaceStr,0)
+ let right = s:GetSexyComRight(useSpaceStr,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:NERD_lPlace, g:NERD_rPlace, 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:HasLeadingTab(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:HasLeadingTab(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) range
+
+ 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
+ return -1
+ 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:GetLeftMostIndx(1, 1, a:topline, a:bottomline)
+
+ "check whether the user has specified that this filetype use compact sexy
+ "delimiters: 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 &filetype =~ g:NERD_use_compact_sexy_com_regexp
+ let spaceString = (&filetype =~ g:NERD_space_delim_filetype_regexp ? s:spaceStr : '')
+
+ "comment the top line
+ let theLine = getline(a:topline)
+ let lineHasTabs = s:HasLeadingTab(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
+ let theLine = getline(a:bottomline)
+ let lineHasTabs = s:HasLeadingTab(theLine)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ endif
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ 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'
+ call setline(a:topline, strpart(s:spaces, 0, leftAlignIndx) . left )
+
+ " 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'
+ call setline(a:bottomline+2, strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, strlen(left)-strlen(sexyComMarker)) . right )
+
+ 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 + (&filetype !~ g:NERD_use_compact_sexy_com_regexp)
+ " get the line and convert the tabs to spaces
+ let theLine = getline(currentLine)
+ let lineHasTabs = s:HasLeadingTab(theLine)
+ if lineHasTabs
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ endif
+
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+
+ " add the sexyComMarker
+ let theLine = strpart(s:spaces, 0, leftAlignIndx) . strpart(s:spaces, 0, 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, alignLeft, alignRight, firstLine, lastLine) range {{{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
+" -alignRight/alignLeft: 0/1 if the comments delimiters should/shouldnt be
+" aligned left/right
+" -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLinesToggle(forceNested, alignLeft, alignRight, firstLine, lastLine) range
+ " 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:GetLeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+ let rightAlignIndx = s:GetRightMostIndx(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:GetLeft(0, 1, 0))
+
+ " 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:HasLeadingTab(theLine)
+ let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+ if s:GetCanToggleCommentLine(a:forceNested, currentLine)
+
+ "if the user has specified forceNesting then we check to see if we
+ "need to switch delimiters for place-holders
+ if &filetype =~ g:NERD_place_holder_regexp
+ let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+ endif
+
+ if a:alignLeft
+ " let theLine = s:AddLeftDelimAligned(b:left, theLine, leftAlignIndx)
+ let theLine = s:AddLeftDelimAligned(s:GetLeft(0,1,0), theLine, leftAlignIndx)
+ else
+ let theLine = s:AddLeftDelim(s:GetLeft(0, 1, 0), theLine)
+ endif
+ if a:alignRight
+ let theLine = s:AddRightDelimAligned(s:GetRight(0, 1, 0), theLine, rightAlignIndx)
+ else
+ let theLine = s:AddRightDelim(s:GetRight(0, 1, 0), theLine)
+ endif
+
+ "re-align the delims existing if needed
+ elseif (a:alignLeft || a:alignRight) && !a:forceNested && (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine))
+ "get the delims the line is commented with
+ if s:IsCommentedFromStartOfLine(b:left, theLine)
+ let l:left = s:GetLeft(0, 1, 0)
+ let l:right = s:GetRight(0, 1, 0)
+ else
+ let l:left = s:GetLeft(1, 1, 0)
+ let l:right = s:GetRight(1, 1, 0)
+ endif
+ let theLine = s:UncommentLineNormal(theLine)
+
+ if a:alignLeft
+ let theLine = s:AddLeftDelimAligned(l:left, theLine, leftAlignIndx)
+ else
+ let theLine = s:AddLeftDelim(l:left, theLine)
+ endif
+ if a:alignRight
+ let theLine = s:AddRightDelimAligned(l:right, theLine, rightAlignIndx)
+ else
+ let theLine = s:AddRightDelim(l:right, theLine)
+ 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:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2
+" This function is designed to comment 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) range
+ "we may need to switch to the alt delims if the current ones arent
+ "multi-part.
+ let didSwitchDelims = -1
+
+ "if the right delim isnt empty then we can use it for this comment
+ if b:right != '' || &filetype !~ g:NERD_allow_any_visual_delims_regexp
+ let didSwitchDelims = 0
+ "if the alternative comment right delimiter isnt null then we can use the
+ "alternative right delims
+ elseif b:rightAlt != ''
+ let didSwitchDelims = 1
+ call <sid>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, 0, 0, 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(b:left) + &filetype =~ g:NERD_space_delim_filetype_regexp)
+
+ "if we switched delims then we gotta go back to what they were before
+ if didSwitchDelims == 1
+ call s:SwitchToAlternativeDelimiters(0)
+ endif
+
+
+endfunction
+
+
+" Function: s:DoComment(forceNested, isVisual, alignLeft, alignRight, type) function {{{2
+" This function is a Wrapper for the main commenting functions
+"
+" Args:
+" -forceNested: a flag indicating whether comments should be nested
+" -isVisual: a flag indicating whether the comment is requested in visual
+" mode or not
+" -alignLeft/alignRight: flags indicating whether the comment delimiters should be
+" aligned left/right
+" -type: the type of commenting requested. Can be "sexy", "invert",
+" "minimal", "toggle" or "norm"
+function s:DoComment(forceNested, isVisual, alignLeft, alignRight, type) range
+ " we want case sensitivity when commenting
+ let prevIgnoreCase = &ignorecase
+ set noignorecase
+
+ " remember where the cursor was initially so we can move it back
+ if a:isVisual
+ normal! gv
+ endif
+ call s:SaveCursorPosition()
+
+ if a:type == 'norm'
+ if a:isVisual && visualmode() == ""
+ call s:CommentBlock(line("'<"), line("'>"), col("'<"), col("'>"), a:forceNested)
+ elseif a:isVisual && visualmode() == "v" && (g:NERD_comment_whole_lines_in_v_mode==0 || (g:NERD_comment_whole_lines_in_v_mode==2 && s:HasMultipartDelims()))
+ call s:CommentRegion(line("'<"), col("'<"), line("'>"), col("'>"), a:forceNested)
+ else
+ call s:CommentLines(a:forceNested, a:alignLeft, a:alignRight, a:firstline, a:lastline)
+ endif
+ elseif a:type == 'invert'
+ call s:InvertComment(a:firstline, a:lastline)
+ elseif a:type == 'sexy'
+ " see if the selected regions have any sexy comments
+ let currentLine = a:firstline
+ let foundSexyCom=0
+ while(currentLine <= a:lastline)
+ if(s:FindBoundingLinesOfSexyCom(currentLine) != -1)
+ let foundSexyCom=1
+ break
+ endif
+ let currentLine = currentLine + 1
+ endwhile
+
+ " we dont allow nested comments yet..
+ if foundSexyCom
+ call s:NerdEcho("NERD_comments: Sexy comment aborted. Nested sexy commenting not supported yet..", 0)
+ else
+ call s:CommentLinesSexy(a:firstline, a:lastline)
+ endif
+
+ " check if the user requested a toggle comment
+ elseif a:type == 'toggle'
+ let theLine = getline(a:firstline)
+ if s:FindBoundingLinesOfSexyCom(a:firstline)!=-1 || s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)
+ execute ':' . a:firstline . ',' . a:lastline .'call s:UncommentLines(1)'
+ else
+ call s:CommentLinesToggle(a:forceNested, a:alignLeft, a:alignRight, a:firstline, a:lastline)
+ endif
+ elseif a:type == 'minimal'
+ "check that minimal comments can be done on this filetype
+ if b:right == '' && b:rightAlt == ''
+ call s:NerdEcho('Minimal comments can only be used for filetypes that have multipart delimiters', 0)
+ return
+ endif
+ call s:CommentLinesMinimal(a:firstline, a:lastline)
+ endif
+
+ let &ignorecase = prevIgnoreCase
+
+ " move the cursor back to where it was
+ call s:RestoreCursorPostion()
+
+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) range
+
+ " 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(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine)
+ execute ':' currentLine . ',' . currentLine . 'call s:UncommentLines(1)'
+ let currentLine = currentLine + 1
+
+ " check if the line is commented sexually
+ elseif sexyComBounds != -1
+ let topBound = substitute(sexyComBounds, '\(.*\),.*', '\1', '')
+ let bottomBound = substitute(sexyComBounds, '.*,\(.*\)', '\1', '')
+ let numLinesBeforeSexyComRemoved = s:GetNumLinesInBuf()
+ call s:UncommentLinesSexy(topBound, bottomBound)
+
+ "move to the line after last line of the sexy comment
+ let numLinesAfterSexyComRemoved = s:GetNumLinesInBuf()
+ let currentLine = bottomBound - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1
+
+ " the line isnt commented
+ else
+ call s:CommentLinesToggle(1, 0, 0, currentLine, currentLine)
+ let currentLine = currentLine + 1
+ endif
+
+ endwhile
+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:GetLeft(0, 1, 0)
+ let right = s:GetRight(0, 1, 0)
+
+ let theLine = getline(".")
+ let lineHasLeadTabs = s:HasLeadingTab(theLine) || (theLine =~ '^ *$' && !&expandtab)
+
+ "convert tabs to spaces and adjust the cursors column to take this into
+ "account
+ let untabbedCol = s:GetUntabbedCol(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:GetTabbedCol(getline("."), col("."))
+ call setline(line("."), s:ConvertLeadingSpacesToTabs(getline(".")))
+ call cursor(line("."), tabbedCol)
+ endif
+
+ startinsert
+endfunction
+
+" Function: s:PrependCommentToLine(){{{2
+" This function prepends comment delimiters to the start of line and places
+" the cursor in position to start typing the comment
+function s:PrependCommentToLine()
+ " get the left and right delimiters without any escape chars in them
+ let left = s:GetLeft(0, 1, 0)
+ let right = s:GetRight(0, 1, 0)
+
+ " get the len of the right delim
+ let lenRight = strlen(right)
+
+
+ "if the line is empty then we need to know about this later on
+ let isLineEmpty = strlen(getline(".")) == 0
+
+ "stick the delimiters down at the start of the line. We have to format the
+ "comment with spaces as appropriate
+ if lenRight > 0
+ execute ":normal I" . left . right
+ else
+ execute ":normal I" . left
+ endif
+
+ " 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
+ normal l
+
+ "if the line was empty then we gotta add an extra space on the end because
+ "the cursor will move back one more at the end of the last "execute"
+ "command
+ if isLineEmpty && lenRight == 0
+ execute ":normal a "
+ 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)
+
+ "get the left and right delimiters without the esc chars. Also, get their
+ "lengths
+ let l:left = a:left
+ let l:right = a:right
+ let lenLeft = strlen(left)
+ let lenRight = strlen(right)
+
+ let delimsSpaced = (&filetype =~ g:NERD_space_delim_filetype_regexp || &filetype !~ g:NERD_dont_remove_spaces_regexp)
+
+ 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 && right != ''
+ let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx)
+ endif
+ endif
+
+ return line
+endfunction
+
+" Function: s:UncommentLines(onlyWholeLineComs) {{{2
+" Args:
+" This function uncomments the given lines
+function s:UncommentLines(onlyWholeLineComs) range
+ "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:firstline
+ let l:lastline = a:lastline
+ if firstline > lastline
+ let firstline = lastline
+ let lastline = a:firstline
+ 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 sexyComBounds != -1
+
+ "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:GetNumLinesInBuf()
+
+ "extract the top/bottom lines of the sexy comment and call the
+ "appropriate function to remove the comment
+ let topBound = substitute(sexyComBounds, '\(.*\),.*', '\1', '')
+ let bottomBound = substitute(sexyComBounds, '.*,\(.*\)', '\1', '')
+ call s:UncommentLinesSexy(topBound, bottomBound)
+
+ "move to the line after last line of the sexy comment
+ let numLinesAfterSexyComRemoved = s:GetNumLinesInBuf()
+ let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved
+ let currentLine = bottomBound - numLinesRemoved + 1
+ let lastline = lastline - numLinesRemoved
+
+ "no sexy com was detected so uncomment the line as normal
+ else
+ let theLine = getline(currentLine)
+ if a:onlyWholeLineComs && (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, theLine))
+ call s:UncommentLinesNormal(currentLine, currentLine)
+ elseif !a:onlyWholeLineComs
+ call s:UncommentLinesNormal(currentLine, currentLine)
+ endif
+ 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
+ return -1
+ 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)
+
+ let removeSpace = (&filetype =~ g:NERD_space_delim_filetype_regexp || &filetype !~ g:NERD_dont_remove_spaces_regexp)
+
+ "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 && removeSpace
+ 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)
+
+ " 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]*$' && &filetype !~ g:NERD_use_compact_sexy_com_regexp
+ 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 && removeSpace
+ 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:GetLastIndexOfDelim(rightUnEsc, theLine)
+ if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && removeSpace
+ 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 && removeSpace
+ 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(b:leftAlt, b:rightAlt, b:left, b:right, line)
+
+ "it is commented with b:left and b:right so remove these delims
+ if lineCommentStatus == 1
+ let line = s:RemoveDelimiters(b:leftAlt, b:rightAlt, line)
+
+ "it is commented with b:leftAlt and b:rightAlt so remove these delims
+ elseif lineCommentStatus == 2 && g:NERD_dont_remove_alt_coms==0
+ let line = s:RemoveDelimiters(b:left, b:right, 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(b:left, line)
+ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line)
+ let indxRight = s:FindDelimiterIndex(b:right, line)
+ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line)
+
+ "remove the outter most left comment delim
+ if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
+ let line = s:ReplaceLeftMostDelim(b:left, '', line)
+ elseif indxLeftAlt != -1
+ let line = s:ReplaceLeftMostDelim(b:leftAlt, '', line)
+ endif
+
+ "remove the outter most right comment delim
+ if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
+ let line = s:ReplaceRightMostDelim(b:right, '', line)
+ elseif indxRightAlt != -1
+ let line = s:ReplaceRightMostDelim(b:rightAlt, '', line)
+ endif
+ endif
+
+
+ let indxLeft = s:FindDelimiterIndex(b:left, line)
+ let indxLeftAlt = s:FindDelimiterIndex(b:leftAlt, line)
+ let indxLeftPlace = s:FindDelimiterIndex(g:NERD_lPlace, line)
+
+ let indxRightPlace = s:FindDelimiterIndex(g:NERD_rPlace, line)
+ let indxRightAlt = s:FindDelimiterIndex(b:rightAlt, line)
+ let indxRightPlace = s:FindDelimiterIndex(g:NERD_rPlace, line)
+
+ let right = b:right
+ let left = b:left
+ if b:right == ""
+ let right = b:rightAlt
+ let left = b:leftAlt
+ 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:NERD_lPlace, g:NERD_rPlace, left, right, line)
+ endif
+ elseif indxRightPlace != -1
+ if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+ let line = s:ReplaceDelims(g:NERD_lPlace, g:NERD_rPlace, left, right, line)
+ endif
+
+ endif
+
+
+ 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 = strpart(s:spaces, 0, 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 = strpart(s:spaces, 0, a:alignIndx-strlen(a:theLine))
+
+ " add the right delim
+ return substitute(a:theLine, '$', extraSpaces . a:delim, '')
+ endif
+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: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 b:right != ''
+ return s:DoesBlockHaveDelim(b:left, a:top, a:bottom) || s:DoesBlockHaveDelim(b:right, a:top, a:bottom)
+ else
+ return s:DoesBlockHaveDelim(b:leftAlt, a:top, a:bottom) || s:DoesBlockHaveDelim(b:rightAlt, 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
+
+ "get the delimiter without esc chars and its length
+ 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 b:right != ''
+ let left = s:GetLeft(0,0,1)
+ let right = s:GetRight(0,0,1)
+ elseif b:rightAlt != ''
+ let left = s:GetLeft(1,0,1)
+ let right = s:GetRight(1,0,1)
+ else
+ return -1
+ 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 theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right
+ 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
+ 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 -1
+ 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
+
+ "encode the answer in a string and return it
+ return top . ',' . bottom
+endfunction
+
+
+" Function: s:GetCanCommentLine(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:GetCanCommentLine(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:FindBoundingLinesOfSexyCom(a:lineNum) != -1
+ return 0
+ endif
+
+ let isCommented = s:IsCommentedNormOrSexy(a:lineNum)
+ let canUsePlaceHolders = (&filetype =~ g:NERD_place_holder_regexp)
+
+ "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 && (b:right=='' || canUsePlaceHolders)
+ return 1
+ endif
+
+ return 0
+endfunction
+
+" Function: s:GetCanToggleCommentLine(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:GetCanToggleCommentLine(forceNested, lineNum)
+ let theLine = getline(a:lineNum)
+ if (s:IsCommentedFromStartOfLine(b:left, theLine) || s:IsCommentedFromStartOfLine(b:leftAlt, 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:FindBoundingLinesOfSexyCom(a:lineNum) != -1
+ return 0
+ endif
+
+ return 1
+endfunction
+
+" Function: s:GetIndxInSubstr(indx, substr, str) {{{2
+" This function look for an occurrence of substr that is pointed to by indx. An
+" int is returned indicating how many chars into substr indx occurs. For
+" example if str is "abcfoobar" and substr is "foobar" and indx is 5 then 2 is
+" returned cos indx points 2 chars into substr
+"
+" Args:
+" -indx: the indx to look for the occurrence of substr at
+" -substr: the substring that we will get the relative index of indx to
+" -str: the string to look in
+function s:GetIndxInSubstr(indx, substr, str)
+ "validate params
+ if a:substr=="" || a:str=="" || a:indx<0
+ return -1
+ endif
+
+ let lenSubstr = strlen(a:substr)
+
+ "i is used to measure the relative dist from the last occurrence of substr
+ "to the next one. i2 is the absolute indx of the current instance of
+ "substsr
+ let i = 0
+ let i2 = 0
+
+ "keep looping till there are no more instances of substr left
+ while i != -1
+
+ "get the indx of the next occurrence of substr
+ let i = stridx(strpart(a:str, i2), a:substr)
+ let i2 = i2 + i
+
+ "if indx lies inside this instance of substr return its relative
+ "position inside the substr
+ if i != -1 && a:indx < i2+lenSubstr && a:indx >= i2
+ return a:indx - i2
+ endif
+
+ "move past this instance of substr
+ let i2 = i2 + lenSubstr
+
+ endwhile
+
+ return -1
+endfunction
+
+
+
+
+" Function: s:GetLastIndexOfDelim(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:GetLastIndexOfDelim(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:GetLeftMostIndx(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:GetLeftMostIndx(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(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, 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:GetLeft(alt, space, esc) {{{2
+" returns the left/left-alternative delimiter
+" Args:
+" -alt: specifies whether to get left or left-alternative delim
+" -space: specifies whether the delim should be spaced or not
+" (the space string will only be added if NERD_space_delim_filetype_regexp
+" is specified for the current filetype)
+" -esc: specifies whether the tricky chars in the delim should be ESCed
+function s:GetLeft(alt, space, esc)
+ let delim = b:left
+
+ if a:alt
+ if b:leftAlt == ''
+ return ''
+ else
+ let delim = b:leftAlt
+ endif
+ endif
+ if delim == ''
+ return ''
+ endif
+
+ if a:space && &filetype =~ g:NERD_space_delim_filetype_regexp
+ let delim = delim . s:spaceStr
+ endif
+
+ if a:esc
+ let delim = s:Esc(delim)
+ endif
+
+ return delim
+endfunction
+
+" Function: s:GetRight(alt, space, esc) {{{2
+" returns the right/right-alternative delimiter
+" Args:
+" -alt: specifies whether to get right or right-alternative delim
+" -space: specifies whether the delim should be spaced or not
+" (the space string will only be added if NERD_space_delim_filetype_regexp
+" is specified for the current filetype)
+" -esc: specifies whether the tricky chars in the delim should be ESCed
+function s:GetRight(alt, space, esc)
+ let delim = b:right
+
+ if a:alt
+ if b:rightAlt == ''
+ return ''
+ else
+ let delim = b:rightAlt
+ endif
+ endif
+ if delim == ''
+ return ''
+ endif
+
+ if a:space && &filetype =~ g:NERD_space_delim_filetype_regexp
+ let delim = s:spaceStr . delim
+ endif
+
+ if a:esc
+ let delim = s:Esc(delim)
+ endif
+
+ return delim
+endfunction
+
+
+" Function: s:GetRightMostIndx(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:GetRightMostIndx(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(b:left, b:right, theLine) && !s:IsCommented(b:leftAlt, b:rightAlt, 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:GetNumLinesInBuf() {{{2
+" Returns the number of lines in the current buffer
+function s:GetNumLinesInBuf()
+ return line('$')
+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 NERD_space_delim_filetype_regexp
+" is specified for the current filetype)
+" -esc: specifies whether the tricky chars in the marker are to be ESCed
+function s:GetSexyComMarker(space, esc)
+ let sexyComMarker = b:sexyComMarker
+
+
+ "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(b:left)
+ let lenLeftAlt = strlen(b:leftAlt)
+ let left = ''
+ let right = ''
+ if b:right != '' && lenLeft >= lenLeftAlt
+ let left = b:left
+ elseif b:rightAlt != ''
+ let left = b:leftAlt
+ else
+ return -1
+ endif
+
+ "get the last char of left
+ let sexyComMarker = strpart(left, strlen(left)-1)
+ endif
+ endif
+
+ if a:space && &filetype =~ g:NERD_space_delim_filetype_regexp
+ 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 NERD_space_delim_filetype_regexp
+" is specified for the current filetype)
+" -esc: specifies whether the tricky chars in the string are ESCed
+function s:GetSexyComLeft(space, esc)
+ let lenLeft = strlen(b:left)
+ let lenLeftAlt = strlen(b:leftAlt)
+ 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 b:right != '' && lenLeft >= lenLeftAlt
+ let left = b:left
+ elseif b:rightAlt != ''
+ let left = b:leftAlt
+ else
+ return -1
+ endif
+ endif
+
+ if a:space
+ 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 NERD_space_delim_filetype_regexp
+" 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(b:left)
+ let lenLeftAlt = strlen(b:leftAlt)
+ 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 b:right != '' && lenLeft >= lenLeftAlt
+ let right = b:right
+ elseif b:rightAlt != ''
+ let right = b:rightAlt
+ else
+ return -1
+ endif
+ endif
+
+ if a:space
+ let right = s:spaceStr . right
+ endif
+
+ if a:esc
+ let right = s:Esc(right)
+ endif
+
+ return right
+endfunction
+
+" Function: s:GetTabbedCol(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:GetTabbedCol(line, col)
+ let lineTruncated = strpart(a:line, 0, a:col)
+ let lineSpacesToTabs = substitute(lineTruncated, s:tabSpace, '\t', 'g')
+ return strlen(lineSpacesToTabs)
+endfunction
+" Function: s:GetUntabbedCol(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:GetUntabbedCol(line, col)
+ let lineTruncated = strpart(a:line, 0, a:col)
+ let lineTabsToSpaces = substitute(lineTruncated, '\t', s:tabSpace, 'g')
+ return strlen(lineTabsToSpaces)
+endfunction
+" Function: s:HasMultipartDelims() {{{2
+" Returns 1 iff the current filetype has at least one set of multipart delims
+function s:HasMultipartDelims()
+ return (b:left != '' && b:right != '') || (b:leftAlt != '' && b:rightAlt != '')
+endfunction
+
+" Function: s:HasLeadingTab(str) {{{2
+" Returns 1 iff the input has >= 1 leading tab
+function s:HasLeadingTab(str)
+ return a:str =~ '^\t.*'
+endfunction
+" Function: s:HasCStyleComments() {{{2
+" Returns 1 iff the current filetype has c style comment delimiters
+function s:HasCStyleComments()
+ return (b:left == '/*' && b:right == '*/') || (b:leftAlt == '/*' && b:rightAlt == '*/')
+endfunction
+
+" Function: s:InstallDocumentation(full_name, revision) {{{2
+" Install help documentation.
+" Arguments:
+" full_name: Full name of this vim plugin script, including path name.
+" revision: Revision of the vim script. #version# mark in the document file
+" will be replaced with this string with 'v' prefix.
+" Return:
+" 1 if new document installed, 0 otherwise.
+" Note: Cleaned and generalized by guo-peng Wen.
+"
+" Note about authorship: this function was taken from the vimspell plugin
+" which can be found at http://www.vim.org/scripts/script.php?script_id=465
+"
+function s:InstallDocumentation(full_name, revision)
+ " Name of the document path based on the system we use:
+ if has("vms")
+ " No chance that this script will work with
+ " VMS - to much pathname juggling here.
+ return 1
+ elseif (has("unix"))
+ " On UNIX like system, using forward slash:
+ let l:slash_char = '/'
+ let l:mkdir_cmd = ':silent !mkdir -p '
+ else
+ " On M$ system, use backslash. Also mkdir syntax is different.
+ " This should only work on W2K and up.
+ let l:slash_char = '\'
+ let l:mkdir_cmd = ':silent !mkdir '
+ endif
+
+ let l:doc_path = l:slash_char . 'doc'
+ let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc'
+
+ " Figure out document path based on full name of this script:
+ let l:vim_plugin_path = fnamemodify(a:full_name, ':h')
+ let l:vim_doc_path = fnamemodify(a:full_name, ':h:h') . l:doc_path
+ if (!(filewritable(l:vim_doc_path) == 2))
+ "Doc path: " . l:vim_doc_path
+ call s:NerdEcho("Doc path: " . l:vim_doc_path, 0)
+ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"'
+ if (!(filewritable(l:vim_doc_path) == 2))
+ " Try a default configuration in user home:
+ let l:vim_doc_path = expand("~") . l:doc_home
+ if (!(filewritable(l:vim_doc_path) == 2))
+ execute l:mkdir_cmd . '"' . l:vim_doc_path . '"'
+ if (!(filewritable(l:vim_doc_path) == 2))
+ " Put a warning:
+ call s:NerdEcho("Unable to open documentation directory", 0)
+ call s:NerdEcho(" type :help add-local-help for more informations.", 0)
+ echo l:vim_doc_path
+ return 0
+ endif
+ endif
+ endif
+ endif
+
+ " Exit if we have problem to access the document directory:
+ if (!isdirectory(l:vim_plugin_path) || !isdirectory(l:vim_doc_path) || filewritable(l:vim_doc_path) != 2)
+ return 0
+ endif
+
+ " Full name of script and documentation file:
+ let l:script_name = fnamemodify(a:full_name, ':t')
+ let l:doc_name = fnamemodify(a:full_name, ':t:r') . '.txt'
+ let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name
+ let l:doc_file = l:vim_doc_path . l:slash_char . l:doc_name
+
+ " Bail out if document file is still up to date:
+ if (filereadable(l:doc_file) && getftime(l:plugin_file) < getftime(l:doc_file))
+ return 0
+ endif
+
+ " Prepare window position restoring command:
+ if (strlen(@%))
+ let l:go_back = 'b ' . bufnr("%")
+ else
+ let l:go_back = 'enew!'
+ endif
+
+ " Create a new buffer & read in the plugin file (me):
+ setl nomodeline
+ exe 'enew!'
+ exe 'r ' . l:plugin_file
+
+ setl modeline
+ let l:buf = bufnr("%")
+ setl noswapfile modifiable
+
+ norm zR
+ norm gg
+
+ " Delete from first line to a line starts with
+ " === START_DOC
+ 1,/^=\{3,}\s\+START_DOC\C/ d
+
+ " Delete from a line starts with
+ " === END_DOC
+ " to the end of the documents:
+ /^=\{3,}\s\+END_DOC\C/,$ d
+
+ " Remove fold marks:
+ norm :%s/{\{3}[1-9]/ /
+
+ " Add modeline for help doc: the modeline string is mangled intentionally
+ " to avoid it be recognized by VIM:
+ call append(line('$'), '')
+ call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:')
+
+ " Replace revision:
+ "exe "normal :1s/#version#/ v" . a:revision . "/\<CR>"
+ exe "normal :%s/#version#/ v" . a:revision . "/\<CR>"
+
+ " Save the help document:
+ exe 'w! ' . l:doc_file
+ exe l:go_back
+ exe 'bw ' . l:buf
+
+ " Build help tags:
+ exe 'helptags ' . l:vim_doc_path
+
+ return 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(b:left, b:right, theLine) || s:IsCommented(b:leftAlt, b:rightAlt, theLine)
+ return 1
+ endif
+
+ "if the line is part of a sexy comment return 1
+ if s:FindBoundingLinesOfSexyCom(a:lineNum) != -1
+ 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 || a:right == "")
+ 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:GetLastIndexOfDelim(a:right, a:line)
+ let indxRightAlt = s:GetLastIndexOfDelim(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) || a:right == ''
+ 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) || a:rightAlt == ''
+ 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: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 b:right != ''
+ let left = b:left
+ let right = b:right
+ elseif b:rightAlt != ''
+ let left = b:leftAlt
+ let right = b:rightAlt
+ 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
+ return 1
+
+endfunction
+
+" Function: s:NerdEcho(msg, typeOfMsg) {{{2
+" Echos the given message in the given style iff the NERD_shut_up option is
+" not set
+" Args:
+" -msg: the message to echo
+" -typeOfMsg: 0 = warning message
+" 1 = normal message
+function s:NerdEcho(msg, typeOfMsg)
+ if g:NERD_shut_up
+ return
+ endif
+
+ if a:typeOfMsg == 0
+ echohl WarningMsg
+ echo a:msg
+ echohl None
+ elseif a:typeOfMsg == 1
+ echo a:msg
+ endif
+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:GetLastIndexOfDelim(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:SaveCursorPosition() {{{2
+" Saves where the cursor is using the s and t registers. See also
+" RestoreCursorPostion()
+function s:SaveCursorPosition()
+ " see :h restore-position for details of how this works
+ let b:old_s_reg=@s
+ let b:old_t_reg=@t
+ normal! ms
+ normal! H
+ normal! mt
+ normal! ``
+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(b:left, b:right, a:line)
+ let isCommentedAlt = s:IsCommented(b:leftAlt, b:rightAlt, 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 && b:right != ""
+ let line2 = s:ReplaceDelims(b:left, b:right, g:NERD_lPlace, g:NERD_rPlace, a:line)
+
+ "similarly if the line is commented with the alternative
+ "delimiters
+ elseif isCommentedAlt && b:rightAlt != ""
+ let line2 = s:ReplaceDelims(b:leftAlt, b:rightAlt, g:NERD_lPlace, g:NERD_rPlace, 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 b:right != ''
+ let left = b:left
+ let right = b:right
+ elseif b:rightAlt != ''
+ let left = b:leftAlt
+ let right = b:rightAlt
+ endif
+
+ let line = s:ReplaceDelims(g:NERD_lPlace, g:NERD_rPlace, left, right, a:line)
+ return line
+endfunction
+
+" Function: s:RestoreCursorPosition() {{{2
+" Restores where the cursor is using the s and t registers. See also
+" RestoreCursorPostion(). Sets the s and t registers back to their original
+" values before SaveCursorPosition was called
+function s:RestoreCursorPostion()
+ " see :h restore-position for details of how this works
+ let @s=b:old_s_reg
+ let @t=b:old_t_reg
+ normal! `t
+ normal! zt
+ normal! `s
+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
+
+" Section: Comment mapping setup {{{1
+" ===========================================================================
+" This is where the mappings calls are made that set up the commenting key
+" mappings.
+
+" set up the mapping to switch to/from alternative delimiters
+execute 'nnoremap <silent>' . g:NERD_alt_com_map . ' :call <SID>SwitchToAlternativeDelimiters(1)<cr>'
+
+" set up the mappings to comment out lines
+execute 'nnoremap <silent>' . g:NERD_com_line_map . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 0, 0, 0, "norm")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_line_map . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "norm")<cr><ESC>'
+
+" set up the mappings to do toggle comments
+execute 'nnoremap <silent>' . g:NERD_com_line_toggle_map . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 0, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "toggle")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_line_toggle_map . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "toggle")<cr><ESC>'
+
+" set up the mapp to do minimal comments
+execute 'nnoremap <silent>' . g:NERD_com_line_minimal_map . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 0, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "minimal")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_line_minimal_map . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "minimal")<cr><ESC>'
+
+" set up the mappings to comment out lines sexily
+execute 'nnoremap <silent>' . g:NERD_com_line_sexy_map . ' :call <SID>DoComment(0, 0, 0, 0, "sexy")<CR>'
+execute 'vnoremap <silent>' . g:NERD_com_line_sexy_map . ' :call <SID>DoComment(0, 1, 0, 0, "sexy")<CR>'
+
+" set up the mappings to do invert comments
+execute 'nnoremap <silent>' . g:NERD_com_line_invert_map . ' :call <SID>DoComment(0, 0, 0, 0, "invert")<CR>'
+execute 'vnoremap <silent>' . g:NERD_com_line_invert_map . ' :call <SID>DoComment(0, 1, 0, 0, "invert")<CR>'
+
+" set up the mappings to yank then comment out lines
+execute 'nmap <silent>' . g:NERD_com_line_yank_map . ' "0Y' . g:NERD_com_line_map
+execute 'vmap <silent>' . g:NERD_com_line_yank_map . ' "0ygv' . g:NERD_com_line_map
+
+" set up the mappings for left aligned comments
+execute 'nnoremap <silent>' . g:NERD_com_align_left_map . ' :call <SID>DoComment(1, 0, 1, 0, "norm")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_align_left_map . ' :call <SID>DoComment(1, 1, 1, 0, "norm")<cr><ESC>'
+
+" set up the mappings for right aligned comments
+execute 'nnoremap <silent>' . g:NERD_com_align_right_map . ' :call <SID>DoComment(1, 0, 0, 1, "norm")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_align_right_map . ' :call <SID>DoComment(1, 1, 0, 1, "norm")<cr><ESC>'
+
+" set up the mappings for left and right aligned comments
+execute 'nnoremap <silent>' . g:NERD_com_align_both_map . ' :call <SID>DoComment(1, 0, 1, 1, "norm")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_align_both_map . ' :call <SID>DoComment(1, 1, 1, 1, "norm")<cr><ESC>'
+
+" set up the mappings to do nested comments
+execute 'nnoremap <silent>' . g:NERD_com_line_nest_map . ' :call <SID>DoComment(1, 0, 0, 0, "norm")<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_com_line_nest_map . ' :call <SID>DoComment(1, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "norm")<cr><ESC>'
+
+" set up the mapping to uncomment a line
+execute 'nnoremap <silent>' . g:NERD_uncom_line_map . ' :call <SID>UncommentLines(0)<cr><ESC>'
+execute 'vnoremap <silent>' . g:NERD_uncom_line_map . ' :call <SID>UncommentLines(0)<cr> gv'
+
+" set up the mapping to comment out to the end of the line
+execute 'nnoremap <silent>' . g:NERD_com_to_end_of_line_map . ' :call <SID>SaveCursorPosition()<cr>:call <SID>CommentBlock(line("."), line("."), col("."), col("$")-1, 1)<cr>:call <SID>RestoreCursorPostion()<cr><ESC>'
+
+" set up the mappings to append comments to the line
+execute 'nmap <silent>' . g:NERD_append_com_map . ' :call <SID>AppendCommentToLine()<cr>'
+
+" set up the mappings to append comments to the line
+execute 'nmap <silent>' . g:NERD_prepend_com_map . ' :call <SID>PrependCommentToLine()<cr>'
+
+" set up the mapping to insert comment delims at the cursor position in insert
+" mode
+execute 'inoremap <silent>' . g:NERD_com_in_insert_map . ' ' . '<SPACE><BS><ESC>:call <SID>PlaceDelimitersAndInsBetween()<CR>'
+
+" Section: Menu item setup {{{1
+" ===========================================================================
+
+
+"check if the user wants the menu to be displayed
+if g:NERD_menu_mode != 0
+
+ "determine whether the user wants the menu to have a keyboard shortcut and
+ "set the menu root accordingly.
+ let s:menuRoot = g:NERD_menu_mode == 1 ? "comment" : "&comment"
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment<TAB>' . escape(g:NERD_com_line_map, '\') . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 0, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "norm")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment<TAB>' . escape(g:NERD_com_line_map, '\') . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "norm")<CR><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Toggle<TAB>' . escape(g:NERD_com_line_toggle_map, '\') . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 0, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "toggle")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Toggle<TAB>' . escape(g:NERD_com_line_toggle_map, '\') . ' :call <SID>DoComment(g:NERD_use_nested_comments_default, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "toggle")<CR><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Minimal<TAB>' . escape(g:NERD_com_line_minimal_map, '\') . ' :call <SID>DoComment(0, 0, 0, 0, "minimal")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Minimal<TAB>' . escape(g:NERD_com_line_minimal_map, '\') . ' :call <SID>DoComment(0, 1, 0, 0, "minimal")<CR><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Nested<TAB>' . escape(g:NERD_com_line_nest_map, '\') . ' :call <SID>DoComment(1, 0, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "norm")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Nested<TAB>' . escape(g:NERD_com_line_nest_map, '\') . ' :call <SID>DoComment(1, 1, &filetype =~ g:NERD_left_align_regexp, &filetype =~ g:NERD_right_align_regexp, "norm")<CR><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ To\ EOL<TAB>' . escape(g:NERD_com_to_end_of_line_map, '\') . ' :call <SID>SaveCursorPosition()<cr>:call <SID>CommentBlock(line("."), line("."), col("."), col("$")-1, 1)<cr>:call <SID>RestoreCursorPostion()<cr><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Invert<TAB>' . escape(g:NERD_com_line_invert_map, '\') . ' :call <SID>DoComment(0,0,0,0,"invert")<CR>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Invert<TAB>' . escape(g:NERD_com_line_invert_map, '\') . ' :call <SID>DoComment(0,1,0,0,"invert")<CR>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Sexily<TAB>' . escape(g:NERD_com_line_sexy_map, '\') . ' :call <SID>DoComment(0,0,0,0,"sexy")<CR>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Sexily<TAB>' . escape(g:NERD_com_line_sexy_map, '\') . ' :call <SID>DoComment(0,1,0,0,"sexy")<CR>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Yank\ line(s)\ then\ comment<TAB>' . escape(g:NERD_com_line_yank_map, '\') . ' "0Y' . g:NERD_com_line_map
+ execute 'vmenu <silent> '. s:menuRoot .'.Yank\ line(s)\ then\ comment<TAB>' . escape(g:NERD_com_line_yank_map, '\') . ' "0ygv' . g:NERD_com_line_map
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Append\ Comment\ to\ Line<TAB>' . escape(g:NERD_append_com_map, '\') . ' :call <SID>AppendCommentToLine()<cr>'
+ execute 'nmenu <silent> '. s:menuRoot .'.Prepend\ Comment\ to\ Line<TAB>' . escape(g:NERD_prepend_com_map, '\') . ' :call <SID>PrependCommentToLine()<cr>'
+
+ execute 'menu <silent> '. s:menuRoot .'.-Sep- :'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Align\ Left\ (nested)<TAB>' . escape(g:NERD_com_align_left_map, '\') . ' :call <SID>DoComment(1, 0, 1, 0, "norm")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Align\ Left\ (nested)<TAB>' . escape(g:NERD_com_align_left_map, '\') . ' :call <SID>DoComment(1, 1, 1, 0, "norm")<CR><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Align\ Right\ (nested)<TAB>' . escape(g:NERD_com_align_right_map, '\') . ' :call <SID>DoComment(1, 0, 0, 1, "norm")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Align\ Right\ (nested)<TAB>' . escape(g:NERD_com_align_right_map, '\') . ' :call <SID>DoComment(1, 1, 0, 1, "norm")<CR><ESC>'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Comment\ Align\ Both\ (nested)<TAB>' . escape(g:NERD_com_align_both_map, '\') . ' :call <SID>DoComment(1, 0, 1, 1, "norm")<CR><ESC>'
+ execute 'vmenu <silent> '. s:menuRoot .'.Comment\ Align\ Both\ (nested)<TAB>' . escape(g:NERD_com_align_both_map, '\') . ' :call <SID>DoComment(1, 1, 1, 1, "norm")<CR><ESC>'
+
+ execute 'menu <silent> '. s:menuRoot .'.-Sep2- :'
+
+ execute 'menu <silent> '. s:menuRoot .'.Uncomment<TAB>' . escape(g:NERD_uncom_line_map, '\') . ' :call <SID>UncommentLines(0)<CR>gv'
+
+ execute 'menu <silent> '. s:menuRoot .'.-Sep3- :'
+
+ execute 'nmenu <silent> '. s:menuRoot .'.Use\ Alternative\ Delimiters<TAB>' . escape(g:NERD_alt_com_map, '\') . ' :call <SID>SwitchToAlternativeDelimiters(1)<CR>'
+
+
+ execute 'imenu <silent> '. s:menuRoot .'.Insert\ Delims<TAB>' . escape(g:NERD_com_in_insert_map, '\') . ' <SPACE><BS><ESC>:call <SID>PlaceDelimitersAndInsBetween()<CR>'
+
+ execute 'menu '. s:menuRoot .'.-Sep4- :'
+
+ execute 'menu <silent>'. s:menuRoot .'.Help<TAB>:help\ NERD_comments-contents :help NERD_comments-contents<CR>'
+endif
+
+" Section: Doc installation call {{{1
+silent call s:InstallDocumentation(expand('<sfile>:p'), s:NERD_comments_version)
+
+finish
+"=============================================================================
+" Section: The help file {{{1
+" Title {{{2
+" ============================================================================
+=== START_DOC
+*NERD_comments.txt* Plugin for commenting code #version#
+
+
+ NERD_COMMENTS REFERENCE MANUAL~
+
+
+
+
+
+==============================================================================
+CONTENTS {{{2 *NERD_comments-contents*
+
+ 1.Intro...................................|NERD_comments|
+ 2.Functionality provided..................|NERD_com-functionality|
+ 2.1 Functionality Summary.............|NERD_com-functionality-summary|
+ 2.2 Functionality Details.............|NERD_com-functionality-details|
+ 2.2.1 Comment map.................|NERD_com-comment|
+ 2.2.2 Nested comment map..........|NERD_com-nested-comment|
+ 2.2.3 Toggle comment map..........|NERD_com-toggle-comment|
+ 2.2.4 Minimal comment map.........|NERD_com-minimal-comment|
+ 2.2.5 Invert comment map..........|NERD_com-invert-comment|
+ 2.2.6 Sexy comment map............|NERD_com-sexy-comment|
+ 2.2.7 Yank comment map............|NERD_com-yank-comment|
+ 2.2.8 Comment to EOL map..........|NERD_com-EOL-comment|
+ 2.2.9 Append com to line map......|NERD_com-append-comment|
+ 2.2.10 Prepend com to line map.....|NERD_com-prepend-comment|
+ 2.2.11 Insert comment map.........|NERD_com-insert-comment|
+ 2.2.12 Use alternate delims map...|NERD_com-alt-delim|
+ 2.2.13 Comment aligned maps.......|NERD_com-aligned-comment|
+ 2.2.14 Uncomment line map.........|NERD_com-uncomment-line|
+ 2.3 Supported filetypes...............|NERD_com-filetypes|
+ 2.4 Sexy Comments.....................|NERD_com_sexy_comments|
+ 3.Customisation...........................|NERD_com-customisation|
+ 3.1 Customisation summary.............|NERD_com-cust-summary|
+ 3.2 Customisation details.............|NERD_com-cust-details|
+ 3.3 Default delimiter customisation...|NERD_com-cust-delims|
+ 3.4 Key mapping customisation.........|NERD_com-cust-keys|
+ 3.5 Sample regular expressions........|NERD_com-reg-exps|
+ 4.Issues with the script..................|NERD_com-issues|
+ 4.1 Delimiter detection heuristics....|NERD_com-heuristics|
+ 4.2 Nesting issues....................|NERD_com-nesting|
+ 5.TODO list...............................|NERD_com-todo|
+ 6.Credits.................................|NERD_com-credits|
+
+==============================================================================
+1. Intro {{{2 *NERD_comments*
+
+NERD_comments provides a set of handy key mappings for commenting code. These
+mappings are consistent across all supported filetypes.
+
+When writing NERD_comments I have tried to give it as many features/options as
+possible while keeping it so that the plugin can still be used with little or
+no knowledge of these. The average user need only know about a few key
+mappings to use NERD_comments while there are plenty of other features for the
+l33t nerd take advantage of.
+
+Enjoy :D
+
+==============================================================================
+2. Functionality provided {{{2 *NERD_com-functionality*
+
+------------------------------------------------------------------------------
+2.1 Functionality summary {{{3 *NERD_com-functionality-summary*
+
+The following key mappings are provided by default (there is also a menu
+provided that contains menu items corresponding to all the below mappings):
+
+Note: <leader> is a user defined key that is used to start keymappings and
+defaults to \. Check out |<leader>| for details.
+
+Most of the following mappings are for normal/visual mode only. The
+|NERD_com-insert-comment| mapping is for insert mode only.
+
+<leader>cc |NERD_com-comment-map|
+Comments out the current line or text selected in visual mode.
+
+
+<leader>cn |NERD_com-nested-comment|
+Same as |NERD_com-comment-map| but enforces nesting.
+
+
+<leader>c<space> |NERD_com-toggle-comment|
+Toggles the comment state of the selected line(s). If the topmost selected
+line is commented, all selected lines are uncommented and vice versa.
+
+
+<leader>cm |NERD_com-minimal-comment|
+Comments the given lines using only one set of multipart delimiters if
+possible.
+
+
+<leader>ci |NERD_com-invert-comment|
+Toggles the comment state of the selected line(s) individually. Each selected
+line that is commented is uncommented and vice versa.
+
+
+<leader>cs |NERD_com-sexy-comment|
+Comments out the selected lines ``sexually''
+
+
+<leader>cy |NERD_com-yank-comment|
+Same as |NERD_com-comment-map| except that the commented line(s) are yanked
+before commenting.
+
+
+<leader>c$ |NERD_com-EOL-comment|
+Comments the current line from the cursor to the end of line.
+
+
+<leader>cA |NERD_com-append-comment|
+Adds comment delimiters to the end of line and goes into insert mode between
+them.
+
+
+<leader>cI |NERD_com-prepend-comment|
+Adds comment delimiters to the start of line and goes into insert mode between
+them.
+
+
+<C-c> |NERD_com-insert-comment|
+Adds comment delimiters at the current cursor position and inserts between.
+
+
+<leader>ca |NERD_com-alt-delim|
+Switches to the alternative set of delimiters.
+
+
+<leader>cl OR <leader>cr OR <leader>cb |NERD_com-aligned-comment|
+Same as |NERD_com-comment| except that the delimiters are aligned down the
+left side (<leader>cl), the right side (<leader>cr) or both sides
+(<leader>cb).
+
+
+<leader>cu |NERD_com-uncomment-line|
+Uncomments the selected line(s).
+
+------------------------------------------------------------------------------
+2.2 Functionality details {{{3 *NERD_com-functionality-details*
+
+------------------------------------------------------------------------------
+2.2.1 Comment map *NERD_com-comment*
+<leader>cc
+Comments out the current line. If multiple lines are selected in visual-line
+mode, they are all commented out. If some text is selected in visual or
+visual-block mode then NERD_comments will try to comment out the exact text
+that is selected using multi-part delimiters if they are available.
+
+Works in normal, visual, visual-line and visual-block mode.
+
+Change the mapping with: |NERD_com_line_map|.
+
+Relevant options:
+|NERD_allow_any_visual_delims_regexp|
+|NERD_comment_whole_lines_in_v_mode|
+|NERD_block_com_after_right|
+|NERD_left_align_regexp|
+|NERD_place_holder_regexp|
+|NERD_right_align_regexp|
+|NERD_space_delim_filetype_regexp|
+|NERD_use_nested_comments_default|
+
+------------------------------------------------------------------------------
+2.2.2 Nested comment map *NERD_com-nested-comment*
+<leader>cn
+Performs nested commenting. Works the same as <leader>cc except that if a
+line is already commented then it will be commented again.
+
+If the filetype is covered by the |NERD_place_holder_regexp| option
+then the previous comment delimiters will be replaced by place-holder
+delimiters if needed. Otherwise the nested comment will only be added if the
+current commenting delimiters have no right delimiter (to avoid compiler
+errors)
+
+Works in normal, visual, visual-line, visual-block modes.
+
+Change the mapping with: |NERD_com_line_nest_map|.
+
+Relevant options:
+|NERD_allow_any_visual_delims_regexp|
+|NERD_comment_whole_lines_in_v_mode|
+|NERD_block_com_after_right|
+|NERD_left_align_regexp|
+|NERD_place_holder_regexp|
+|NERD_right_align_regexp|
+|NERD_space_delim_filetype_regexp|
+|NERD_use_nested_comments_default|
+
+
+------------------------------------------------------------------------------
+2.2.3 Toggle comment map *NERD_com-toggle-comment*
+<leader>c<space>
+Toggles commenting of the lines selected. The behaviour of this mapping
+depends on whether the first line selected is commented or not. If so, all
+selected lines are uncommented and vice versa.
+
+With this mapping, lines are only considered to be commented if a left comment
+delimiter is the first non-space/tab char on the line.
+
+Works in normal, visual-line, modes.
+Using this mapping in visual or visual-block modes will cause it to work like
+|NERD_com-comment|
+
+Change the mapping with: |NERD_com_line_toggle_map|.
+
+Relevant options:
+|NERD_left_align_regexp|
+|NERD_right_align_regexp|
+|NERD_space_delim_filetype_regexp|
+|NERD_use_nested_comments_default|
+
+------------------------------------------------------------------------------
+2.2.4 Minimal comment map *NERD_com-minimal-comment*
+<leader>cm
+Comments the selected lines using one set of multipart delimiters if possible.
+
+For example: if you are programming in c and you select 5 lines and press
+<leader>cm then a '/*' will be placed at the start of the top line and a '*/'
+will be placed at the end of the last line.
+
+Sets of multipart comment delimiters that are between the top and bottom
+selected lines are replaced with place holders (see |NERD_lPlace|) if
+NERD_place_holder_regexp is set for the current filetype. If it is not, then
+the comment will be aborted if place holders are required to prevent illegal
+syntax.
+
+------------------------------------------------------------------------------
+2.2.5 Invert comment map *NERD_com-invert-comment*
+<leader>ci
+Inverts the commented state of each selected line. If the a selected line is
+commented then it is uncommented and vice versa. Each line is examined and
+commented/uncommented individually.
+
+With this mapping, lines are only considered to be commented if a left comment
+delimiter is the first non-space/tab char on the line.
+
+Works in normal, visual-line, modes.
+
+Change the mapping with: |NERD_com_line_invert_map|.
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.6 Sexy comment map *NERD_com-sexy-comment*
+<leader>cs
+Comments the selected line(s) ``sexily''... see |NERD_com_sexy_commenting| for
+a description of what sexy comments are. Can only be done on filetypes for
+which there is at least one set of multipart comment delimiters specified.
+
+Sexy comments cannot be nested and lines inside a sexy comment cannot be
+commented again.
+
+Works in normal, visual-line.
+
+Change the mapping with: |NERD_com_line_sexy_map|
+
+Relevant options:
+|NERD_use_compact_sexy_com_regexp|
+
+------------------------------------------------------------------------------
+2.2.7 Yank comment map *NERD_com-yank-comment*
+<leader>cy
+Same as <leader>cc except that it yanks the line(s) that are commented first.
+
+Works in normal, visual, visual-line, visual-block modes.
+
+Change the mapping with: |NERD_com_line_yank_map|
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.8 Comment to EOL map *NERD_com-EOL-comment*
+<leader>c$
+Comments the current line from the current cursor position up to the end of
+the line.
+
+Works in normal mode.
+
+Change the mapping with: |NERD_com_to_end_of_line_map|
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.9 Append com to line map *NERD_com-append-comment*
+<leader>cA
+Appends comment delimiters to the end of the current line and goes
+to insert mode between the new delimiters.
+
+Works in normal mode.
+
+Change the mapping with: |NERD_append_com_map|.
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.10 Prepend com to line map *NERD_com-prepend-comment*
+<leader>cI
+Prepends comment delimiters to the start of the current line and goes to
+insert mode between the new delimiters.
+
+Works in normal mode.
+
+Change the mapping with: |NERD_prepend_com_map|.
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.11 Insert comment map *NERD_com-insert-comment*
+<C-c>
+Adds comment delimiters at the current cursor position and inserts
+between them.
+
+Works in insert mode.
+
+Change the mapping with: |NERD_com_in_insert_map|.
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.12 Use alternate delims map *NERD_com-alt-delim*
+<leader>ca
+Changes to the alternative commenting style if one is available. For example,
+if the user is editing a c++ file using // comments and they hit <leader>ca
+then they will be switched over to /**/ comments.
+keys for this mappings can be overridden with the
+
+Works in normal mode.
+
+Change the mapping with: |NERD_alt_com_map|
+
+Relevant options:
+
+
+------------------------------------------------------------------------------
+2.2.13 Comment aligned maps *NERD_com-aligned-comment*
+<leader>cl <leader>cr <leader>cb
+Same as <leader>cc except that the comment delimiters are aligned on the left
+side, right side or both sides respectively. These comments are always nested
+if the line(s) are already commented.
+
+Works in normal, visual-line.
+
+Change the mappings with: |NERD_com_align_left_map|, |NERD_com_align_right_map|
+and |NERD_com_align_both_map|.
+
+Relevant options:
+|NERD_left_align_regexp|
+|NERD_right_align_regexp|
+
+
+------------------------------------------------------------------------------
+2.2.14 Uncomment line map *NERD_com-uncomment-line*
+<leader>cu
+Uncomments the current line. If multiple lines are selected in
+visual mode then they are all uncommented.
+
+When uncommenting, if the line contains multiple sets of delimiters then the
+``outtermost'' pair of delimiters will be removed.
+
+The script uses a set of heurisics to distinguish ``real'' delimiters from
+``fake'' ones when uncommenting. See |NERD_com-issues| for details.
+
+Works in normal, visual, visual-line, visual-block.
+
+Change the mapping with: |NERD_uncom_line_map|.
+
+Relevant options:
+|NERD_dont_remove_alt_coms|
+|NERD_dont_remove_spaces_regexp|
+
+
+------------------------------------------------------------------------------
+2.3 Supported filetypes *NERD_com-filetypes*
+
+Files that can be commented by this plugin:
+abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asm
+asn aspvbs atlas automake ave awk basic b bc bdf bib bindzone btm caos catalog
+c cfg cg ch cl clean clipper conf config cpp crontab cs csc csp css cterm cupl
+cvs dcl def diff dns dosbatch dosini dot dracula dsl dtd dtml dylan ecd eiffel
+elf elmfilt erlang eterm expect exports fgl focexec form fortran foxpro fvwm
+fx gdb gdmo gnuplot gtkrc haskell hb h help hercules hog html htmlos ia64 icon
+idlang idl indent inform inittab ishd iss ist jam java javascript jess jgraph
+jproperties jproperties jsp kix kscript lace lex lftp lifelines lilo lisp lite
+lotos lout lprolog lscript lss lua lynx m4 make maple masm master matlab mel
+mf mib mma model moduala. modula2 modula3 monk mush muttrc named nasm nastran
+natural ncf nqc nsis ocaml omnimark openroad opl ora ox pascal pcap pccts perl
+pfmain php phtml pic pike pilrc pine plm plsql po postscr pov povini ppd ppwiz
+procmail progress prolog psf ptcap python python radiance ratpoison r rc
+readline rebol registry remind rexx robots rpl ruby sa samba sas sather scheme
+scilab screen scsh sdl sed sgml sgmldecl sgmllnx sicad simula sinda skill
+slang sl slrnrc sm smil smith sml snnsnet snnspat snnsres snobol4 spec specman
+spice sql sqlforms sqlj sqr squid st stp strace tads tags tak tasm tcl
+terminfo tex texinfo texmf tf tidy tli trasys tsalt tsscl tssgm uc uil vb
+verilog vgrindefs vhdl vim virata vrml vsejcl webmacro wget winbatch wml sh
+wvdial xdefaults xf86conf xkb xmath xml xmodmap xpm2 xpm xslt yacc z8a
+
+If a language is not in the list of hardcoded supported filetypes then the
+&commentstring vim option is used.
+
+
+------------------------------------------------------------------------------
+2.4 Sexy Comments *NERD_com_sexy_comments*
+These are comments that use one set of multipart comment delimiters as well as
+one other marker symbol. For example: >
+ /*
+ * This is a c style sexy comment
+ * So there!
+ */
+
+ /* This is a c style sexy comment
+ * So there!
+ * But this one is ``compact'' style */
+<
+Here the multipart delimiters are /* and */ and the marker is *. NERD_comments
+is capable of adding and removing comments of this type.
+
+
+==============================================================================
+3. Customisation {{{2 *NERD_com-customisation*
+
+------------------------------------------------------------------------------
+3.1 Customisation summary *NERD_com-cust-summary*
+
+|loaded_nerd_comments| Turns off the script.
+|NERD_allow_any_visual_delims_regexp| Allows multipart alternative delims to
+ be used when commenting in
+ visual/visual-block mode.
+|NERD_block_com_after_right| Forces right delims to be placed when
+ doing visual-block comments.
+|NERD_comment_whole_lines_in_v_mode| Changes behaviour of visual comments.
+|NERD_menu_mode| Determines if a NERD comment menu will
+ be made and whether the menu will have a
+ keyboard shortcut.
+|NERD_dont_remove_alt_coms| Causes alternative comments not to be
+ removed when uncommenting.
+|NERD_dont_remove_spaces_regexp| Causes spaces not to be removed when
+ uncommenting if the filetype doesnt
+ match |NERD_space_delim_filetype_regexp|
+|NERD_create_h_filetype| Creates a new filetype for .h files.
+|NERD_lPlace| Specifies what to use as the left
+ delimiter placeholder when nesting
+ comments.
+|NERD_left_align_regexp| Specifies which filetypes to align left
+ delimiters for.
+|NERD_mapleader| Specifies what all the commenting key
+ mappings will begin with.
+|NERD_place_holder_regexp| Specifies which filetypes may use
+ placeholders when nesting comments.
+|NERD_right_align_regexp| Specifies which filetypes to align right
+ delimiters for.
+|NERD_rPlace| Specifies what to use as the right
+ delimiter placeholder when nesting
+ comments.
+|NERD_shut_up| Stops all output from the script.
+|NERD_space_delim_filetype_regexp| Specifies which filetypes to add spaces
+ around the delimiters for.
+|NERD_use_compact_sexy_com_regexp| Specifies which filetypes to use compact
+ sexy comments for.
+|NERD_use_nested_comments_default| Tells the script to use nested comments
+ by default.
+
+-----------------------------------------------------------------------------
+3.3 Customisation details *NERD_com-cust-details*
+
+To enable any of the below options you should put the given line in your
+~/.vimrc
+
+ *loaded_nerd_comments*
+If this script is driving you insane you can turn it off by setting this
+option >
+ let loaded_nerd_comments=1
+<
+
+-----------------------------------------------------------------------------
+ *NERD_allow_any_visual_delims_regexp*
+This option is set to a regular expression that is used to specify which
+filetypes this option should be turned on for. If this covers the current
+filetype then, when NERD_comments is doing a visual or visual-block comment
+(but not a visual-line comment) it will choose the right delimiters to use for
+the comment. This normally means using the current delimiters if they are
+multipart or using the alternative delimiters if THEY are multipart and the
+current delims are not. For example if we are editing the following java
+code: >
+ float foo = 1221;
+ float bar = 324;
+ System.out.println(foo * bar);
+<
+If we are using // comments and select the "foo" and "bar" in visual-block
+mode, as shown left below (where '|'s are used to represent the visual-block
+boundary), and comment it then it will use the alternative delims as shown on
+the right: >
+ float |foo| = 1221; float /*foo*/ = 1221;
+ float |bar| = 324; float /*bar*/ = 324;
+ System.out.println(foo * bar); System.out.println(foo * bar);
+<
+By default this option is set to '.*' i.e is turned on for all filetypes.
+
+-----------------------------------------------------------------------------
+ *NERD_block_com_after_right*
+This option affects commenting when it is done in visual-block mode. If this
+option is turned on, lines that begin outside the right boundary of the
+selection block will be commented. Enable this option with: >
+ let NERD_block_com_after_right=1
+<
+For example, if you are commenting this chunk of c code in visual-block mode
+(where the '|'s are used to represent the visual-block boundary) >
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stdio.h>
+ |int| main(){
+ | | printf("SUCK THIS\n");
+ | | while(1){
+ | | fork();
+ | | }
+ |} |
+<
+If NERD_block_com_after_right=1 then this code will become: >
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stdio.h>
+ /*int*/ main(){
+ /* */ printf("SUCK THIS\n");
+ /* */ while(1){
+ /* */ fork();
+ /* */ }
+ /*} */
+<
+Otherwise, the code block would become: >
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stdio.h>
+ /*int*/ main(){
+ printf("SUCK THIS\n");
+ while(1){
+ fork();
+ }
+ /*} */
+<
+
+-----------------------------------------------------------------------------
+ *NERD_comment_whole_lines_in_v_mode*
+This option can take 2 values. By default NERD_comments tries to comment out
+exactly what is selected in visual mode (v). For example if you select and
+comment the following c code (using | to represent the visual boundary): >
+ in|t foo = 3;
+ int bar =| 9;
+ int baz = foo + bar;
+<
+This will result in: >
+ in/*t foo = 3;*/
+ /*int bar =*/ 9;
+ int baz = foo + bar;
+<
+But some people prefer it if the whole lines are commented like: >
+ /*int foo = 3;*/
+ /*int bar = 9;*/
+ int baz = foo + bar;
+<
+If you prefer the second option then stick this line in your .vimrc: >
+ let NERD_comment_whole_lines_in_v_mode=1
+<
+
+If the filetype you are editing only has no multipart delimiters (for example
+a shell script) and you hadnt set this option then the above would become >
+ in#t foo = 3;
+ #int bar = 9;
+<
+(where # is the comment delimiter) as this is the closest NERD_comments can
+come to commenting out exactly what was selected. If you prefer for whole
+lines to be commented out when there is no multipart delimiters but the EXACT
+text that was selected to be commented out if there IS multipart delimiters
+then stick the following line in your .vimrc: >
+ let NERD_comment_whole_lines_in_v_mode=2
+<
+
+Note that this option does not affect the behaviour of visual-block mode ().
+
+-----------------------------------------------------------------------------
+ *NERD_dont_remove_alt_coms*
+When uncommenting a line when there is an alternative commenting style for the
+current filetype, this option tells the script not to look for, and remove,
+comments delimiters of the alternative style. >
+ let NERD_dont_remove_alt_coms=1
+<
+For example, if you are editing a c++ file using // style comments and you go
+<leader>cu on this line: >
+ /* This is a c++ comment baby! */
+<
+It will not be uncommented if the NERD_dont_remove_alt_coms is set to 1.
+
+-----------------------------------------------------------------------------
+ *NERD_dont_remove_spaces_regexp*
+By default, the NERD commenter will remove spaces around comment delimiters if
+either:
+1. The current filetype matches the |NERD_space_delim_filetype_regexp| option
+ (which is a regular expression).
+2. The current filtype doesnt match NERD_dont_remove_spaces_regexp option
+ (which is also a reg exp)
+
+This means that if we have the following lines in a c code file: >
+ /* int foo = 5; */
+ /* int bar = 10; */
+ int baz = foo + bar
+<
+If either of the above conditions hold then if these lines are uncommented
+they will become: >
+ int foo = 5;
+ int bar = 10;
+ int baz = foo + bar
+<
+Otherwise they would become: >
+ int foo = 5;
+ int bar = 10;
+ int baz = foo + bar
+<
+If you want the spaces to be removed only if the current filetype matches
+|NERD_space_delim_filetype_regexp| then set the
+NERD_dont_remove_spaces_regexp option in your vimrc so that it matches the
+desired filetypes.
+
+See |NERD_com-reg-exps| for example reg exps.
+
+Defaults to "^python$"
+
+-----------------------------------------------------------------------------
+ *NERD_create_h_filetype*
+If this option is set then NERD_comments will create a seperate filetype for h
+files. This could be needed because some versions of vim treat h files as cpp
+files which can be dodgy for commenting because if you are using // to comment
+cpp files then this is invalid when you are commenting h files for a c
+project (unless you arent adhering to the ANSI standard... naughty naughty).
+To enable this option, stick the following line in your .vimrc: >
+ let NERD_create_h_filetype = 1
+<
+
+-----------------------------------------------------------------------------
+ *NERD_lPlace*
+ *NERD_rPlace*
+These options are used to control the strings used as place-holder delimiters.
+Place holder delimiters are used when performing nested commenting when the
+filetype supports commenting styles with both left and right delimiters.
+To set these options use lines like: >
+ let NERD_lPlace="FOO"
+ let NERD_rPlace="BAR"
+<
+Following the above example, if we have line of c code: >
+ /* int horse */
+<
+and we comment it with <leader>cn it will be changed to: >
+ /*FOO int horse BAR*/
+<
+When we uncomment this line it will go back to what it was.
+NERD_lPlace defaults to '[>', NERD_rPlace defaults to '<]'.
+
+-----------------------------------------------------------------------------
+ *NERD_left_align_regexp*
+This option is a regular expression which is used to specify which filetypes
+should have their left delimiters aligned when commenting multiple lines.
+
+For example, consider this chunk of c code: >
+ 1 int foo = 3;
+ 2 int bar = 5;
+ 3 while(foo < 50){
+ 4 foo = foo + bar;
+ 5 printf("i am just making up this code\n");
+ 6 printf("i have no idea what im writing\n");
+ 7 }
+<
+If the NERD_left_align_regexp regexp covers c files then if we select lines
+3-7 in visual mode and hit <leader>cc the code will become: >
+ 1 int foo = 3;
+ 2 int bar = 5;
+ 3 /*while(foo < 50){*/
+ 4 /* foo = foo + bar;*/
+ 5 /* printf("i am just making up this code\n");*/
+ 6 /* printf("i have no idea what im writing\n");*/
+ 7 /*}*/
+<
+If NERD_left_align_regexp doesnt cover c files then the code will become: >
+ 1 int foo = 3;
+ 2 int bar = 5;
+ 3 /* while(foo < 50){ */
+ 4 /* foo = foo + bar; */
+ 5 /* printf("i am just making up this code\n"); */
+ 6 /* printf("i have no idea what im writing\n"); */
+ 7 /* } */
+<
+NERD_left_align_regexp defaults to '^$' meaning no filetypes have their left
+delims aligned.
+
+See |NERD_com-reg-exps| for example reg exps.
+
+-----------------------------------------------------------------------------
+ *NERD_mapleader*
+NERD_mapleader is used to specify what all the NERD commenter key mappings
+begin with.
+
+Assuming that <leader> == '\', the default key mappings will look like this: >
+ \cc
+ \cu
+ \ca
+ \ci
+ \cs
+ ...
+<
+However, if this line: >
+ let NERD_mapleader = ',x'
+<
+were present in your vimrc then the default mappings would look like this: >
+ ,xc
+ ,xu
+ ,xa
+ ,xi
+ ,xs
+ ...
+<
+This option only affects the mappings that have not been explicitly set
+manually (see |NERD_com-cust-keys|).
+
+Default is <leader>c.
+
+-----------------------------------------------------------------------------
+ *NERD_menu_mode*
+This option can take 3 values:
+ "0": Turns the NERD commenter menu off completely.
+ "1": Turns the NERD commenter menu on with no menu shortcut.
+ "2": Turns the NERD commenter menu on with <alt>-c as the menu shortcut.
+
+Default is "2".
+
+-----------------------------------------------------------------------------
+ *NERD_place_holder_regexp*
+This option is a regular expression which is used to specify which filetypes
+place-holder delimiters should be used for when adding nested comments.
+
+See |NERD_com-reg-exps| for example reg exps.
+
+-----------------------------------------------------------------------------
+ *NERD_right_align_regexp*
+This option is a regular expression which is used to specify which filetypes
+should have their right delimiters aligned when commenting multiple lines.
+
+For example, consider this chunk of c code: >
+ 1 int foo = 3;
+ 2 int bar = 5;
+ 3 while(foo < 50){
+ 4 foo = foo + bar;
+ 5 printf("i am just making up this code\n");
+ 6 printf("i have no idea what im writing\n");
+ 7 }
+<
+If the NERD_right_align_regexp regexp covers c files then if we select lines
+3-7 in visual mode and hit <leader>cc the code will become: >
+ 1 int foo = 3;
+ 2 int bar = 5;
+ 3 /*while(foo < 50){ */
+ 4 /*foo = foo + bar; */
+ 5 /*printf("i am just making up this code\n"); */
+ 6 /*printf("i have no idea what im writing\n");*/
+ 7 /*} */
+<
+If NERD_right_align_regexp doesnt cover c files then the code will become: >
+ 1 int foo = 3;
+ 2 int bar = 5;
+ 3 /* while(foo < 50){ */
+ 4 /* foo = foo + bar; */
+ 5 /* printf("i am just making up this code\n"); */
+ 6 /* printf("i have no idea what im writing\n"); */
+ 7 /* } */
+<
+NERD_right_align_regexp defaults to '^$' meaning no filetypes have their right
+delims aligned.
+
+See |NERD_com-reg-exps| for example reg exps.
+
+-----------------------------------------------------------------------------
+ *NERD_shut_up*
+This option is used to prevent NERD_comments from echoing anything.
+Stick this line in your .vimrc: >
+ let NERD_shut_up=1
+<
+
+-----------------------------------------------------------------------------
+ *NERD_space_delim_filetype_regexp*
+Some people prefer a space after the left delimiter and before the right
+delimiter like this: >
+ /* int foo=2; */
+<
+as opposed to this: >
+ /*int foo=2;*/
+<
+This option is a regular expression that is used to specify which filetypes
+NERD_comments should use spaces for (as in the first eg above).
+NERD_space_delim_filetype_regexp defaults to '^$'.
+
+See also |NERD_dont_remove_spaces_regexp|.
+See |NERD_com-reg-exps| for example reg exps.
+
+-----------------------------------------------------------------------------
+ *NERD_use_compact_sexy_com_regexp*
+Some people may want their sexy comments to be like this: >
+ /* Hi There!
+ * This is a sexy comment
+ * in c */
+<
+As opposed to like this: >
+ /*
+ * Hi There!
+ * This is a sexy comment
+ * in c
+ */
+<
+The option NERD_use_compact_sexy_com_regexp is a regular expression. If the
+filetype that the user is commenting matches this regular expression then when
+they do sexy comments they will look like the first comment above.
+
+-----------------------------------------------------------------------------
+ *NERD_use_nested_comments_default*
+When this option is turned on comments are nested automatically. That is, if
+you hit <leader>cc on a line that is already commented, or contains comments,
+it will be commented again. >
+ let NERD_use_nested_comments_default=1
+<
+
+-----------------------------------------------------------------------------
+3.3 Default delimiter customisation *NERD_com-cust-delims*
+These options are used to tell NERD_comments which delimiters to use for a
+given filetype when it first loads up. To set one of these options just stick
+the corresponding line in your .vimrc. For example: if i want to use /* */ to
+delimit comments in java files instead of // (which is the default) then I
+would stick this line in my .vimrc: >
+ let NERD_use_c_style_java_comments=1
+<
+
+Note that if filetype has two commenting styles, which are both supported, you
+can switch between them with <leader>ca. See |NERD_com-alt-delim|. These
+options only change which style is used when the script is initialsed.
+
+NERD_use_ada_with_spaces: use --<space> instead of -- for ada files.
+NERD_use_c_style_acedb_comments: use /**/ instead of // for acedb files.
+NERD_use_c_style_ch_comments: use /**/ instead of // for ch files.
+NERD_use_c_style_clean_comments: use /**/ instead of // for clean files.
+NERD_use_c_style_clipper_comments: use /**/ instead of // for clipper files.
+NERD_use_c_style_cpp_comments: use /**/ instead of // for c++ files.
+NERD_use_c_style_cs_comments: use /**/ instead of // for c# files.
+NERD_use_c_style_dot_comments: use /**/ instead of // for dot files.
+NERD_use_c_style_dylan_comments: use /**/ instead of // for dylan files.
+NERD_use_c_style_h_comments: use /**/ instead of // for h files.
+NERD_use_c_style_hercules_comments: use /**/ instead of // for hercules files.
+NERD_use_c_style_idl_comments: use /**/ instead of // for idl files.
+NERD_use_c_style_ishd_comments: use /**/ instead of // for ishd files.
+NERD_use_c_style_java_comments: use /**/ instead of // for java files.
+NERD_use_c_style_javascript_comments: use /**/ instead of // for javascript files.
+NERD_use_c_style_kscript_comments: use /**/ instead of // for kscript files.
+NERD_use_c_style_mel_comments: use /**/ instead of // for mel files.
+NERD_use_c_style_named_comments: use /**/ instead of // for named files.
+NERD_use_c_style_pccts_comments: use /**/ instead of // for pccts files.
+NERD_use_c_style_php_comments: use /* */ instead of // for php files.
+NERD_use_c_style_pike_comments: use /**/ instead of // for pike files.
+NERD_use_c_style_pilrc_comments: use /**/ instead of // for pilrc files.
+NERD_use_c_style_plm_comments: use /**/ instead of // for plm files.
+NERD_use_c_style_pov_comments: use /**/ instead of // for pov files.
+NERD_use_c_style_prolog_comments: use /**/ instead of % for prolog files.
+NERD_use_c_style_rc_comments: use /**/ instead of // for rc files.
+NERD_use_c_style_tads_comments: use /**/ instead of // for tads files.
+NERD_use_c_style_tsalt_comments: use /**/ instead of // for tsalt files.
+NERD_use_c_style_uc_comments: use /**/ instead of // for uc files.
+NERD_use_c_style_verilog_comments: use /**/ instead of // for verilog files.
+NERD_use_dash_dash_simula_comments: use -- instead of % for simula files.
+NERD_use_dnl_style_automake_comments: use dnl instead of # for automake files.
+NERD_use_hash_samba_comments: use # instead of ; for samba files.
+NERD_use_long_haskell_comments: use {--} instead of -- for haskell files.
+NERD_use_long_lisp_comments: use #||# instead of ; for lisp files.
+NERD_use_long_lua_comments: use --[[]] instead of -- for lua files.
+NERD_use_paren_star_pascal_comments: use (**) instead of {} for pascal files.
+NERD_use_REM_basic_comments: use REM instead of ' for basic files.
+NERD_use_single_part_c_comments: use // instead of /* */ for c files.
+
+
+-----------------------------------------------------------------------------
+3.4 Key mapping customisation *NERD_com-cust-keys*
+
+These options are used to override the default keys that are used for the
+commenting mappings. Their values must be set to strings. As an example: if
+you wanted to use the mapping <leader>foo to uncomment lines of code then
+you would place this line in your vimrc >
+ let NERD_uncom_line_map="<leader>foo"
+<
+
+Check out |NERD_com-functionality| for details about what the following
+mappings do.
+
+ *NERD_alt_com_map*
+To override the <leader>ca mapping, set this option >
+ let NERD_alt_com_map="<new mapping>"
+<
+ *NERD_append_com_map*
+To override the <leader>ce mapping, set this option >
+ let NERD_append_com_map="<new mapping>"
+<
+ *NERD_com_align_left_map*
+To override the <leader>cl mapping, set this option >
+ let NERD_com_align_left_map="<new mapping>"
+<
+ *NERD_com_align_both_map*
+To override the <leader>cb mapping, set this option >
+ let NERD_com_align_both_map="<new mapping>"
+<
+ *NERD_com_align_right_map*
+To override the <leader>cr mapping, set this option >
+ let NERD_com_align_right_map="<new mapping>"
+<
+ *NERD_com_in_insert_map*
+To override the <C-c> mapping, set this option >
+ let NERD_com_in_insert_map="<new mapping>"
+<
+ *NERD_com_line_invert_map*
+To override the <leader>ci mapping, set this option >
+ let NERD_com_line_invert_map="<new mapping>"
+<
+ *NERD_com_line_map*
+To override the <leader>cc mapping, set this option >
+ let NERD_com_line_map="<new mapping>"
+<
+ *NERD_com_line_nest_map*
+To override the <leader>cn mapping, set this option >
+ let NERD_com_line_nest_map="<new mapping>"
+<
+ *NERD_com_line_sexy_map*
+To override the <leader>cs mapping, set this option >
+ let NERD_com_line_sexy_map="<new mapping>"
+<
+ *NERD_com_line_toggle_map*
+To override the <leader>c<space> mapping, set this option >
+ let NERD_com_line_toggle_map="<new mapping>"
+<
+ *NERD_com_line_minimal_map*
+To override the <leader>cm mapping, set this option >
+ let NERD_com_line_minimal_map="<new mapping>"
+<
+ *NERD_com_to_end_of_line_map*
+To override the <leader>c$ mapping, set this option >
+ let NERD_com_to_end_of_line_map="<new mapping>"
+<
+ *NERD_com_line_yank_map*
+To override the <leader>cy mapping, set this option >
+ let NERD_com_line_yank_map="<new mapping>"
+<
+ *NERD_uncom_line_map*
+To override the <leader>cu mapping, set this option >
+ let NERD_uncom_line_map="<new mapping>"
+<
+
+------------------------------------------------------------------------------
+3.5 Sample regular expressions *NERD_com-reg-exps*
+
+Many of the options in the NERD commenter must be set to regular
+expressions... regular expressions can be a bit confusing so i have provided
+some template ones here that you can start from:
+
+Regexp1: '.*'
+Matches any filetype. This is useful for turning an option on for all files.
+
+Regexp2: '^$'
+Matches no filetypes. This is useful for turning an option off for all files.
+
+Regexp3: '^\(java\)$'
+Matches only the java filetype.
+
+Regexp4: '^\(c\|vim\)$'
+Matches only c and vim filetypes.
+
+Regexp5: '^\(c.*\|vim\)$'
+Matches filetypes beginning with c (eg c, cpp, cs, etc) as well
+as vim files.
+
+Regexp6: '^\(c.*\|java\|tex\)$'
+Matches filetypes beginning with c (eg c, cpp, cs, etc) as well as java and
+tex filetypes.
+
+Regexp7: '^\(python\)\@!'
+Matches anything other than 'python'.
+
+Regexp8: '^c\(s\)\@!'
+Matches 'c' followed by anything accept an 's'.
+
+Regexp9: '^\(foo$\|bar$\|baz$\)\@!'
+Matches any strings except 'foo', 'bar' and 'baz'.
+
+==============================================================================
+4. Issues with the script{{{2 *NERD_com-issues*
+
+
+------------------------------------------------------------------------------
+4.1 Delimiter detection heuristics *NERD_com-heuristics*
+
+Heuristics are used to distinguish the real comment delimiters
+
+Because we have comment mappings that place delimiters in the middle of lines,
+removing comment delimiters is a bit tricky. This is because if comment
+delimiters appear in a line doesnt mean they really ARE delimiters. For
+example, Java uses // comments but the line >
+ System.out.println("//");
+<
+clearly contains no real comment delimiters.
+
+To distinguish between ``real'' comment delimiters and ``fake'' ones we use a
+set of heuristics. For example, one such heuristic states that any comment
+delimiter that has an odd number of non-escaped " characters both preceding
+and following it on the line is not a comment because it is probably part of a
+string. These heuristics, while usually pretty accurate, will not work for all
+cases.
+
+------------------------------------------------------------------------------
+4.2 Nesting issues *NERD_com-nesting*
+
+If we have some line of code like this: >
+ /*int foo */ = /*5 + 9;*/
+<
+This will not be uncommented legally. The NERD commenter will remove the
+"outter most" delimiters so the line will become: >
+ int foo */ = /*5 + 9;
+<
+which almost certainly will not be what you want. Nested sets of comments will
+uncomment fine though. Eg: >
+ /*int/* foo =*/ 5 + 9;*/
+<
+will become: >
+ int/* foo =*/ 5 + 9;
+<
+(Note that in the above examples I have deliberately not used place holders
+for simplicity)
+
+==============================================================================
+5. TODO list {{{2 *NERD_com-todo*
+
+Uncommenting of minimal comments needs to be more robust. Currently it is easy
+to get illegal syntax when uncommenting them.
+
+
+
+==============================================================================
+6. Credits {{{2 *NERD_com-credits*
+
+Thanks and respect to the following people:
+
+Thanks to Nick Brettell for his many ideas and criticisms. A bloody good
+bastard.
+:normal :.-2s/good//
+
+Thanks to Matthew Hawkins for his awesome refactoring!
+
+Thanks to the authors of the vimspell whose documentation
+installation function I stole :)
+
+Thanks to Greg Searle for the idea of using place-holders for nested comments.
+
+Thanks to Nguyen for the suggestions and pointing the h file highlighting bug!
+Also, thanks for the idea of doing sexy comments as well as his suggestions
+relating to it :P
+Thanks again to Nguyen for complaining about the NERD_comments menu mapping
+(<Alt>-c) interfering with another mapping of his... and thus the
+NERD_dont_create_menu_shortcut option was born :P
+(it was then replaced with NERD_menu_mode in version 1.67 :)
+
+Thanks to Sam R for pointing out some filetypes that NERD_comments could support!
+
+Cheers to Litchi for the idea of having a mapping that appends a comment to
+the current line :)
+
+Thanks to jorge scandaliaris and Shufeng Zheng for telling me about some
+problems with commenting in visual mode. Thanks again to Jorge for his
+continued suggestions on this matter :)
+
+Thanks to Martin Stubenschrott for pointing out a bug with the <C-c> mapping
+:) Ive gotta stop breaking this mapping!
+
+Thanks to Markus Erlmann for pointing out a conflict that this script was
+having with the taglist plugin.
+
+Thanks to Brent Rice for alerting me about, and helping me track down, a bug
+in the script when the "ignorecase" option in vim was set.
+
+Thanks to Richard Willis for telling me about how line continuation was
+causing problems on cygwin. Also, thanks pointing out a bug in the help file
+and for suggesting // comments for c (its about time SOMEONE did :P). May ANSI
+have mercy on your soul :)
+
+Thanks to Igor Prischepoff for suggesting that i implement "toggle comments".
+Also, thanks for his suggested improvements about toggle comments after i
+implemented them.
+
+Thanks to harry for telling me that i broke the <leader>cn mapping in 1.53 :),
+and thanks again for telling me about a bug that occurred when editing a file
+in a new tab.
+
+Thanks to Martin (Krischikim?) for his patch that fixed a bug with the doc
+install function and added support for ada comments with spaces as well as
+making a couple of other small changes.
+
+Thanks to David Bourgeois for pointing out a bug with when commenting c files
+:)... [a few days later] ok i completely misunderstood what David was talking
+about and ended up fixing a completely different bug to what he was talking
+about :P
+
+Thanks to David Bourgeois for pointing out a bug when changing buffers.
+
+Cheers to Eike Von Seggern for sending me a patch to fix a bug in 1.60 that
+was causing spaces to be added to the end of lines with single-part
+delimiters. It's nice when people do my work for me :D
+
+Thanks to Torsten Blix for telling me about a couple of bugs when uncommenting
+sexy comments. Sexy comments dont look so sexy when they are only half removed
+:P
+
+Thanks to Alexander "boesi" Bosecke for pointing out a bug that was stopping
+the NERD_space_delim_filetype_regexp option from working with left aligned
+toggle comments.
+
+Thanks to Stefano Zacchiroli for suggesting the idea of "Minimal comments".
+And for suggested improvements to minimal comments.
+
+Thanks to Norick Chen for emailing in a patch that fixed the asp delimiters.
+In 1.65
+
+Thanks to Jonathan Derque for alerting me to some filetypes that could be
+supported (Namely: context, plaintext and mail).
+
+Thanks to Joseph Barker for the sugesting that the menu be an optional
+feature.
+
+Thanks to Gary Church and Tim Carey-Smith for complaining about the
+keymappings and causing me to introduce the NERD_mapleader option :)
+
+
+Cheers to myself for being the best looking man on Earth!
+
+=== END_DOC
+
+" vim: set foldmethod=marker :
More information about the pkg-vim-maintainers
mailing list