From fc7dc3f34a917767e424713b1e208a68976b4783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Wo=C5=BAniak?= Date: Mon, 16 Nov 2020 12:54:24 +0100 Subject: [PATCH] Added bash-support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Woźniak --- .config/nvim/plugged/bash-support.vim | 1 - .config/nvim/plugged/bash-support.vim/README | 49 + .../autoload/mmtemplates/core.vim | 3883 +++++++++++++++++ .../bash-support/README.bashsupport | 193 + .../bash-support/codesnippets/_trap_DEBUG | 21 + .../bash-support/codesnippets/_trap_ERR | 15 + .../bash-support/codesnippets/_trap_EXIT | 14 + .../bash-support/codesnippets/_trap_RETURN | 17 + .../codesnippets/basename+pathname | 5 + .../codesnippets/check-for-signed-integer | 3 + .../codesnippets/check-for-unsigned-integer | 3 + .../check-number-of-command-line-arguments | 5 + .../bash-support/codesnippets/create-tempfile | 3 + .../create-tempfile-in-secure-manner | 17 + .../codesnippets/create-tempfile-with-trap | 19 + .../codesnippets/debugging/_debug_PS4 | 22 + .../codesnippets/debugging/_debug_assert | 16 + .../debugging/_debug_function.noindent | 15 + .../debugging/_debug_print_pos_param | 3 + .../debugging/_debug_timestamp.noindent | 16 + .../codesnippets/free-software-comment | 8 + .../bash-support/codesnippets/timestamp | 3 + .../usage-and-command-line-arguments.noindent | 39 + .../codesnippets/use-file-descriptor-read | 15 + .../codesnippets/use-file-descriptor-write | 13 + .../codesnippets/well-behaved-script | 29 + .../bash-support/rc/customization.bashrc | 9 + .../bash-support/rc/customization.gvimrc | 63 + .../bash-support/rc/customization.vimrc | 210 + .../bash-support/rc/sample_template_file | 16 + .../bash-support.vim/bash-support/rc/sh.vim | 35 + .../bash-support/scripts/wrapper.sh | 34 + .../bash-support/templates/Templates | 42 + .../bash-support/templates/builtins.templates | 70 + .../bash-support/templates/comments.templates | 142 + .../templates/environment.templates | 100 + .../templates/io-redirection.templates | 32 + .../bash-support/templates/paramsub.templates | 33 + .../templates/patternmatching.templates | 51 + .../bash-support/templates/regexp.templates | 51 + .../bash-support/templates/set.templates | 36 + .../templates/shelloptions.templates | 54 + .../templates/specialparams.templates | 21 + .../templates/statements.templates | 79 + .../bash-support/templates/tests.templates | 86 + .../bash-support/wordlists/bash-keywords.list | 264 ++ .../plugged/bash-support.vim/doc/ChangeLog | 437 ++ .../bash-support.vim/doc/bash-hotkeys.pdf | Bin 0 -> 27562 bytes .../bash-support.vim/doc/bash-hotkeys.tex | 268 ++ .../bash-support.vim/doc/bashsupport.txt | 1298 ++++++ .../nvim/plugged/bash-support.vim/doc/tags | 136 + .../nvim/plugged/bash-support.vim/doc/tags-te | 0 .../bash-support.vim/doc/templatesupport.txt | 2368 ++++++++++ .../plugged/bash-support.vim/ftplugin/sh.vim | 43 + .../bash-support.vim/plugin/bash-support.vim | 1879 ++++++++ .../bash-support.vim/syntax/template.vim | 94 + 56 files changed, 12377 insertions(+), 1 deletion(-) delete mode 160000 .config/nvim/plugged/bash-support.vim create mode 100644 .config/nvim/plugged/bash-support.vim/README create mode 100644 .config/nvim/plugged/bash-support.vim/autoload/mmtemplates/core.vim create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/README.bashsupport create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_DEBUG create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_ERR create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_EXIT create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_RETURN create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/basename+pathname create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-signed-integer create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-unsigned-integer create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-number-of-command-line-arguments create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-in-secure-manner create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-with-trap create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_PS4 create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_assert create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_function.noindent create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_print_pos_param create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_timestamp.noindent create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/free-software-comment create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/timestamp create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/usage-and-command-line-arguments.noindent create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-read create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-write create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/codesnippets/well-behaved-script create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/rc/customization.bashrc create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/rc/customization.gvimrc create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/rc/customization.vimrc create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/rc/sample_template_file create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/rc/sh.vim create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/scripts/wrapper.sh create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/Templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/builtins.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/comments.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/environment.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/io-redirection.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/paramsub.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/patternmatching.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/regexp.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/set.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/shelloptions.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/specialparams.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/statements.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/templates/tests.templates create mode 100644 .config/nvim/plugged/bash-support.vim/bash-support/wordlists/bash-keywords.list create mode 100644 .config/nvim/plugged/bash-support.vim/doc/ChangeLog create mode 100644 .config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.pdf create mode 100644 .config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.tex create mode 100644 .config/nvim/plugged/bash-support.vim/doc/bashsupport.txt create mode 100644 .config/nvim/plugged/bash-support.vim/doc/tags create mode 100644 .config/nvim/plugged/bash-support.vim/doc/tags-te create mode 100644 .config/nvim/plugged/bash-support.vim/doc/templatesupport.txt create mode 100644 .config/nvim/plugged/bash-support.vim/ftplugin/sh.vim create mode 100644 .config/nvim/plugged/bash-support.vim/plugin/bash-support.vim create mode 100644 .config/nvim/plugged/bash-support.vim/syntax/template.vim diff --git a/.config/nvim/plugged/bash-support.vim b/.config/nvim/plugged/bash-support.vim deleted file mode 160000 index 309d6fe..0000000 --- a/.config/nvim/plugged/bash-support.vim +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 309d6fe45859f2d30d0e8fe8016ca69f03b9f7d6 diff --git a/.config/nvim/plugged/bash-support.vim/README b/.config/nvim/plugged/bash-support.vim/README new file mode 100644 index 0000000..83ccee9 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/README @@ -0,0 +1,49 @@ +This is a mirror of http://www.vim.org/scripts/script.php?script_id=365 + +Write BASH-scripts by inserting comments, statements, tests, variables, builtins, etc.. +Speed up writing new scripts considerably. +Write code und comments with a professional appearance from the beginning. + +Here are some screen shots : http://lug.fh-swf.de/vim/vim-bash/screenshots-en.html + +The help file online : http://lug.fh-swf.de/vim/vim-bash/bashsupport.html + +The key mappings of this plugin (PDF) : http://lug.fh-swf.de/vim/vim-bash/bash-hotkeys.pdf + +DOCUMENTATION +-------------------------------------------------------- +This plugin comes with a help file (bashsupport.txt). +Read it with + + :h bashsupport + +** PLEASE READ THE DOCUMENTATION ** + +Editing actions differ for different modes! +There are a lot of features which can be configured or customized to match your needs. + +The installation explained: http://www.thegeekstuff.com article +"Make Vim as Your Bash-IDE Using bash-support Plugin" +(http://www.thegeekstuff.com/2009/02/make-vim-as-your-bash-ide-using-bash-support-plugin) + +Plugin featured in the linux.com article 'Turn Vim into a bash IDE' : http://www.linux.com/articles/114359 + +GitHub +-------------------------------------------------------- +Bash Support is on GitHub: + + https://github.com/WolfgangMehner/vim-plugins + +(Please help us keep track of all the issues and name your report/request "Bash-Support: ") + +MAILING LIST +-------------------------------------------------------- +You can subscribe to the vim-plugins-list mailing list to post your questions or +suggestions for improvement or to report bugs. The list will also be used to +announce new releases ( c.vim / bash-support / perl-support / doxygen-support ). +Visit the following page for subscribing to the mailing list: + + http://lug.fh-swf.de/cgi-bin/mailman/listinfo/vim-plugins-list + +The vim-plugins-list list is very low on traffic. + diff --git a/.config/nvim/plugged/bash-support.vim/autoload/mmtemplates/core.vim b/.config/nvim/plugged/bash-support.vim/autoload/mmtemplates/core.vim new file mode 100644 index 0000000..249228a --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/autoload/mmtemplates/core.vim @@ -0,0 +1,3883 @@ +"=============================================================================== +" +" File: mmtemplates#core.vim +" +" Description: Template engine: Core. +" +" Maps & Menus - Template Engine +" +" VIM Version: 7.0+ +" Author: Wolfgang Mehner, wolfgang-mehner@web.de +" Organization: +" Version: see variable g:Templates_Version below +" Created: 30.08.2011 +" Revision: 28.03.2014 +" License: Copyright (c) 2012-2013, Wolfgang Mehner +" This program is free software; you can redistribute it and/or +" modify it under the terms of the GNU General Public License as +" published by the Free Software Foundation, version 2 of the +" License. +" This program is distributed in the hope that it will be +" useful, but WITHOUT ANY WARRANTY; without even the implied +" warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +" PURPOSE. +" See the GNU General Public License version 2 for more details. +"=============================================================================== +" +"------------------------------------------------------------------------------- +" === Basic Checks === {{{1 +"------------------------------------------------------------------------------- +" +" need at least 7.0 +if v:version < 700 + echohl WarningMsg + echo 'The plugin templates.vim needs Vim version >= 7.' + echohl None + finish +endif +" +" prevent duplicate loading +" need compatible +if &cp || ( exists('g:Templates_Version') && g:Templates_Version != 'searching' && ! exists('g:Templates_DevelopmentOverwrite') ) + finish +endif +" +let s:Templates_Version = '0.9.3' " version number of this script; do not change +" +"---------------------------------------------------------------------- +" --- Find Newest Version --- {{{2 +"---------------------------------------------------------------------- +" +if exists('g:Templates_DevelopmentOverwrite') + " skip ahead +elseif exists('g:Templates_VersionUse') + " + " not the newest one: abort + if s:Templates_Version != g:Templates_VersionUse + finish + endif + " + " otherwise: skip ahead + " +elseif exists('g:Templates_VersionSearch') + " + " add own version number to the list + call add ( g:Templates_VersionSearch, s:Templates_Version ) + " + finish + " +else + " + "------------------------------------------------------------------------------- + " s:VersionComp : Compare two version numbers. {{{3 + " + " Parameters: + " op1 - first version number (string) + " op2 - second version number (string) + " Returns: + " result - -1, 0 or 1, to the specifications of sort() (integer) + "------------------------------------------------------------------------------- + function! s:VersionComp ( op1, op2 ) + " + let l1 = split ( a:op1, '[.-]' ) + let l2 = split ( a:op2, '[.-]' ) + " + for i in range( 0, max( [ len( l1 ), len( l2 ) ] ) - 1 ) + " until now, all fields where equal + if len ( l2 ) <= i + return -1 " op1 has more fields -> sorts first + elseif len( l1 ) <= i + return 1 " op2 has more fields -> sorts first + elseif str2nr ( l1[i] ) > str2nr ( l2[i] ) + return -1 " op1 is larger here -> sorts first + elseif str2nr ( l2[i] ) > str2nr ( l1[i] ) + return 1 " op2 is larger here -> sorts first + endif + endfor + " + return 0 " same amount of fields, all equal + endfunction " ---------- end of function s:VersionComp ---------- + " }}}3 + "------------------------------------------------------------------------------- + " + try + " + " collect all available version + let g:Templates_Version = 'searching' + let g:Templates_VersionSearch = [] + " + runtime! autoload/mmtemplates/core.vim + " + " select the newest one + call sort ( g:Templates_VersionSearch, 's:VersionComp' ) + " + let g:Templates_VersionUse = g:Templates_VersionSearch[ 0 ] + " + " run all scripts again, the newest one will be used + runtime! autoload/mmtemplates/core.vim + " + unlet g:Templates_VersionSearch + unlet g:Templates_VersionUse + " + finish + " + catch /.*/ + " + " an error occurred, skip ahead + echohl WarningMsg + echomsg 'Search for the newest version number failed.' + echomsg 'Using this version ('.s:Templates_Version.').' + echohl None + endtry + " +endif +" }}}2 +"------------------------------------------------------------------------------- +" +let g:Templates_Version = s:Templates_Version " version number of this script; do not change +" +"---------------------------------------------------------------------- +" === Modul Setup === {{{1 +"---------------------------------------------------------------------- +" +let s:DebugGlobalOverwrite = 0 +let s:DebugLevel = s:DebugGlobalOverwrite +" +if ! exists ( 'g:Templates_MapInUseWarn' ) + let g:Templates_MapInUseWarn = 1 +endif +" +let s:StateStackStyleTop = -2 +let s:StateStackFile = -1 +" +let s:StateStackLength = 2 +" +let s:Flagactions = { + \ ':i' : '', + \ ':l' : ' (-> lowercase)', + \ ':u' : ' (-> uppercase)', + \ ':c' : ' (-> capitalize)', + \ ':L' : ' (-> legalize name)', + \ } +" +let s:StandardPriority = 500 +" +let g:CheckedFiletypes = {} +" +"---------------------------------------------------------------------- +" s:StandardMacros : The standard macros. {{{2 +"---------------------------------------------------------------------- +" +let s:StandardMacros = { + \ 'BASENAME' : '', + \ 'DATE' : '%x', + \ 'FILENAME' : '', + \ 'PATH' : '', + \ 'SUFFIX' : '', + \ 'TIME' : '%X', + \ 'YEAR' : '%Y', + \ } +" +"---------------------------------------------------------------------- +" s:StandardProperties : The standard properties. {{{2 +"---------------------------------------------------------------------- +" +let s:StandardProperties = { + \ 'Templates::EditTemplates::Map' : 're', + \ 'Templates::RereadTemplates::Map' : 'rr', + \ 'Templates::ChooseStyle::Map' : 'rs', + \ + \ 'Templates::EditTemplates::Shortcut' : 'e', + \ 'Templates::RereadTemplates::Shortcut' : 'r', + \ 'Templates::ChooseStyle::Shortcut' : 's', + \ + \ 'Templates::Mapleader' : '\', + \ } +" +"---------------------------------------------------------------------- +" s:TypeNames : Name of types as characters. {{{2 +"---------------------------------------------------------------------- +" +let s:TypeNames = [ ' ', ' ', ' ', ' ', ' ', ' ' ] +" +let s:TypeNames[ type(0) ] = 'i' " integer +let s:TypeNames[ type("") ] = 's' " string +let s:TypeNames[ type([]) ] = 'l' " list +let s:TypeNames[ type({}) ] = 'd' " dict +"let s:TypeNames[ type(0.0) ] = 'n' " number +" TODO: why does float not work in some cases? +" not important right now. +" +"---------------------------------------------------------------------- +" === Syntax: Regular Expressions === {{{1 +"---------------------------------------------------------------------- +" +let s:RegexSettings = { + \ 'MacroName' : '[a-zA-Z_][a-zA-Z0-9_]*', + \ 'MacroList' : '\%([a-zA-Z_]\|[a-zA-Z_][a-zA-Z0-9_ \t,]*[a-zA-Z0-9_]\)', + \ 'TemplateName' : '[a-zA-Z_][a-zA-Z0-9_+\-\., ]*[a-zA-Z0-9_+\-\.,]', + \ 'TextOpt' : '[a-zA-Z_][a-zA-Z0-9_+\-: \t,]*[a-zA-Z0-9_+\-]', + \ 'Mapping' : '[a-zA-Z0-9+\-]\+', + \ + \ 'CommentStart' : '\$', + \ 'BlockDelimiter' : '==', + \ + \ 'CommentHint' : '$', + \ 'CommandHint' : '[A-Z]', + \ 'DelimHint' : '=', + \ 'MacroHint' : '|', + \ + \ 'MacroStart' : '|', + \ 'MacroEnd' : '|', + \ 'EditTagStart' : '<', + \ 'EditTagEnd' : '>', + \ 'JumpTag1Start' : '{', + \ 'JumpTag1End' : '}', + \ 'JumpTag2Start' : '<', + \ 'JumpTag2End' : '>', + \ } +" +"---------------------------------------------------------------------- +" s:UpdateFileReadRegex : Update the regular expressions. {{{2 +"---------------------------------------------------------------------- +" +function! s:UpdateFileReadRegex ( regex, settings ) + " + let quote = '\(["'']\?\)' + " + " Basics + let a:regex.MacroName = a:settings.MacroName + let a:regex.MacroNameC = '\('.a:settings.MacroName.'\)' + let a:regex.TemplateNameC = '\('.a:settings.TemplateName.'\)' + let a:regex.Mapping = a:settings.Mapping + let a:regex.AbsolutePath = '^[\~/]' " TODO: Is that right and/or complete? + " + " Syntax Categories + let a:regex.EmptyLine = '^\s*$' + let a:regex.CommentLine = '^'.a:settings.CommentStart + let a:regex.FunctionCall = '^\s*'.a:regex.MacroNameC.'\s*(\(.*\))\s*$' + let a:regex.MacroAssign = '^\s*'.a:settings.MacroStart.a:regex.MacroNameC.a:settings.MacroEnd + \ .'\s*=\s*'.quote.'\(.\{-}\)'.'\2'.'\s*$' " deprecated + " + " Blocks + let delim = a:settings.BlockDelimiter + let a:regex.Styles1Start = '^'.delim.'\s*IF\s\+|STYLE|\s\+IS\s\+'.a:regex.MacroNameC.'\s*'.delim + let a:regex.Styles1End = '^'.delim.'\s*ENDIF\s*'.delim + + let a:regex.Styles2Start = '^'.delim.'\s*USE\s\+STYLES\s*:' + \ .'\s*\('.a:settings.MacroList.'\)'.'\s*'.delim + let a:regex.Styles2End = '^'.delim.'\s*ENDSTYLES\s*'.delim + " + " Texts + let a:regex.TemplateStart = '^'.delim.'\s*\%(TEMPLATE:\)\?\s*'.a:regex.TemplateNameC.'\s*'.delim + \ .'\s*\%(\('.a:settings.TextOpt.'\)\s*'.delim.'\)\?' + let a:regex.TemplateEnd = '^'.delim.'\s*ENDTEMPLATE\s*'.delim + " + let a:regex.HelpStart = '^'.delim.'\s*HELP:\s*'.a:regex.TemplateNameC.'\s*'.delim + \ .'\s*\%(\('.a:settings.TextOpt.'\)\s*'.delim.'\)\?' + "let a:regex.HelpEnd = '^'.delim.'\s*ENDHELP\s*'.delim + " + let a:regex.MenuSep = '^'.delim.'\s*SEP:\s*'.a:regex.TemplateNameC.'\s*'.delim + " + let a:regex.ListStart = '^'.delim.'\s*LIST:\s*'.a:regex.MacroNameC.'\s*'.delim + \ .'\s*\%(\('.a:settings.TextOpt.'\)\s*'.delim.'\)\?' + let a:regex.ListEnd = '^'.delim.'\s*ENDLIST\s*'.delim + " + " Special Hints + let a:regex.CommentHint = a:settings.CommentHint + let a:regex.CommandHint = a:settings.CommandHint + let a:regex.DelimHint = a:settings.DelimHint + let a:regex.MacroHint = a:settings.MacroHint + " +endfunction " ---------- end of function s:UpdateFileReadRegex ---------- +" +"---------------------------------------------------------------------- +" s:UpdateTemplateRegex : Update the regular expressions. {{{2 +"---------------------------------------------------------------------- +" +function! s:UpdateTemplateRegex ( regex, settings ) + " + let quote = '["'']' + " + " Function Arguments + let a:regex.RemoveQuote = '^\s*'.quote.'\zs.*\ze'.quote.'\s*$' + " + " Basics + let a:regex.MacroStart = a:settings.MacroStart + let a:regex.MacroEnd = a:settings.MacroEnd + let a:regex.MacroName = a:settings.MacroName + let a:regex.MacroNameC = '\('.a:settings.MacroName.'\)' + let a:regex.MacroMatch = '^'.a:settings.MacroStart.a:settings.MacroName.a:settings.MacroEnd.'$' + " + " Syntax Categories + let a:regex.FunctionLine = '^'.a:settings.MacroStart.'\('.a:regex.MacroNameC.'(\(.*\))\)'.a:settings.MacroEnd.'\s*\n' + let a:regex.FunctionChecked = '^'.a:regex.MacroNameC.'(\(.*\))$' + let a:regex.FunctionList = '^LIST(\(.\{-}\))$' + let a:regex.FunctionComment = a:settings.MacroStart.'\(C\|Comment\)'.'(\(.\{-}\))'.a:settings.MacroEnd + let a:regex.FunctionInsert = a:settings.MacroStart.'\(Insert\|InsertLine\)'.'(\(.\{-}\))'.a:settings.MacroEnd + let a:regex.MacroRequest = a:settings.MacroStart.'?'.a:regex.MacroNameC.'\%(:\(\a\)\)\?'.a:settings.MacroEnd + let a:regex.MacroInsert = a:settings.MacroStart.''.a:regex.MacroNameC.'\%(:\(\a\)\)\?'.a:settings.MacroEnd + let a:regex.MacroNoCapture = a:settings.MacroStart.a:settings.MacroName.'\%(:\a\)\?'.a:settings.MacroEnd + let a:regex.ListItem = a:settings.MacroStart.''.a:regex.MacroNameC.':ENTRY_*'.a:settings.MacroEnd + " + let a:regex.TextBlockFunctions = '^\%(C\|Comment\|Insert\|InsertLine\)$' + " + " Jump Tags + let a:regex.JumpTagBoth = '<-\w*->\|{-\w*-}\|<+\w*+>\|{+\w*+}' + let a:regex.JumpTagType2 = '<-\w*->\|{-\w*-}' + " +endfunction " ---------- end of function s:UpdateTemplateRegex ---------- +" }}}2 +" +"---------------------------------------------------------------------- +" === Script: Auxiliary Functions === {{{1 +"---------------------------------------------------------------------- +" +"---------------------------------------------------------------------- +" s:ParameterTypes : Get the types of the arguments. {{{2 +" +" Returns a string with one character per argument, denoting the type. +" Uses the codebook 's:TypeNames'. +" +" Examples: +" - s:ParameterTypes ( 1, "string", [] ) -> "isl" +" - s:ParameterTypes ( 1, 'string', {} ) -> "isd" +" - s:ParameterTypes ( 1, 1.0 ) -> "in" +"---------------------------------------------------------------------- +" +function! s:ParameterTypes ( ... ) + return join( map( copy( a:000 ), 's:TypeNames[ type ( v:val ) ]' ), '' ) +endfunction " ---------- end of function s:ParameterTypes ---------- +" +"---------------------------------------------------------------------- +" s:FunctionCheck : Check the syntax, name and parameter types. {{{2 +" +" Throw a 'Template:Check:*' exception whenever: +" - The syntax of the call "name( params )" is wrong. +" - The function name 'name' is not a key in 'namespace'. +" - The parameter string (as produced by s:ParameterTypes) does not match +" the regular expression found in "namespace[name]". +"---------------------------------------------------------------------- +" +function! s:FunctionCheck ( name, param, namespace ) + " + " check the syntax and get the parameter string + try + exe 'let param_s = s:ParameterTypes( '.a:param.' )' + catch /^Vim(let):E\d\+:/ + throw 'Template:Check:function call "'.a:name.'('.a:param.')": '.matchstr ( v:exception, '^Vim(let):E\d\+:\zs.*' ) + endtry + " + " check the function and the parameters + if ! has_key ( a:namespace, a:name ) + throw 'Template:Check:unknown function: "'.a:name.'"' + elseif param_s !~ '^'.a:namespace[ a:name ].'$' + throw 'Template:Check:wrong parameter types: "'.a:name.'"' + endif + " +endfunction " ---------- end of function s:FunctionCheck ---------- +" +"---------------------------------------------------------------------- +" s:LiteralReplacement : Substitute without using regular expressions. {{{2 +"---------------------------------------------------------------------- +" +function! s:LiteralReplacement ( text, remove, insert, flag ) + return substitute( a:text, + \ '\V'.escape( a:remove, '\' ), + \ escape( a:insert, '\&~' ), a:flag ) +" \ '\='.string( a:insert ), a:flag ) +endfunction " ---------- end of function s:LiteralReplacement ---------- +" +"---------------------------------------------------------------------- +" s:ConcatNormalizedFilename : Concatenate and normalize a filename. {{{2 +"---------------------------------------------------------------------- +" +function! s:ConcatNormalizedFilename ( ... ) + if a:0 == 1 + let filename = ( a:1 ) + elseif a:0 == 2 + let filename = ( a:1 ).'/'.( a:2 ) + endif + return fnamemodify( filename, ':p' ) +endfunction " ---------- end of function s:ConcatNormalizedFilename ---------- +" +"---------------------------------------------------------------------- +" s:GetNormalizedPath : Split and normalize a path. {{{2 +"---------------------------------------------------------------------- +" +function! s:GetNormalizedPath ( filename ) + return fnamemodify( a:filename, ':p:h' ) +endfunction " ---------- end of function s:GetNormalizedPath ---------- +" +""---------------------------------------------------------------------- +" s:UserInput : Input after a highlighted prompt. {{{2 +" +" 3. argument : optional completion +" 4. argument : optional list, if the 3. argument is 'customlist' +" +" Throws an exception 'Template:UserInputAborted' if the obtained input is empty, +" so use it like this: +" try +" let style = s:UserInput( 'prompt', '', ... ) +" catch /Template:UserInputAborted/ +" return +" endtry +"---------------------------------------------------------------------- +" +function! s:UserInput ( prompt, text, ... ) + " + echohl Search " highlight prompt + call inputsave() " preserve typeahead + if a:0 == 0 || a:1 == '' + let retval = input( a:prompt, a:text ) + elseif a:1 == 'customlist' + let s:UserInputList = a:2 + let retval = input( a:prompt, a:text, 'customlist,mmtemplates#core#UserInputEx' ) + let s:UserInputList = [] + else + let retval = input( a:prompt, a:text, a:1 ) + endif + call inputrestore() " restore typeahead + echohl None " reset highlighting + " + if empty( retval ) + throw 'Template:UserInputAborted' + endif + " + let retval = substitute( retval, '^\s\+', "", "" ) " remove leading whitespaces + let retval = substitute( retval, '\s\+$', "", "" ) " remove trailing whitespaces + " + return retval + " +endfunction " ---------- end of function s:UserInput ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#UserInputEx : ex-command for s:UserInput. {{{3 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#UserInputEx ( ArgLead, CmdLine, CursorPos ) + if empty( a:ArgLead ) + return copy( s:UserInputList ) + endif + return filter( copy( s:UserInputList ), 'v:val =~ ''\V\<'.escape(a:ArgLead,'\').'\w\*''' ) +endfunction " ---------- end of function mmtemplates#core#UserInputEx ---------- +" }}}3 +" +let s:UserInputList = [] +" +"---------------------------------------------------------------------- +" s:ErrorMsg : Print an error message. {{{2 +"---------------------------------------------------------------------- +" +function! s:ErrorMsg ( ... ) + echohl WarningMsg + for line in a:000 + echomsg line + endfor + echohl None +endfunction " ---------- end of function s:ErrorMsg ---------- +" +"---------------------------------------------------------------------- +" s:DebugMsg : Print debug information. {{{2 +"---------------------------------------------------------------------- +" +function! s:DebugMsg ( msg, ... ) + if s:DebugLevel + if a:0 == 0 || ( a:1 <= s:DebugLevel ) + echo a:msg + endif + endif +endfunction " ---------- end of function s:DebugMsg ---------- +" +"---------------------------------------------------------------------- +" s:OpenFold : Open fold and go to the first or last line of this fold. {{{2 +"---------------------------------------------------------------------- +" +function! s:OpenFold ( mode ) + if foldclosed(".") < 0 + return + endif + " we are on a closed fold: + " get end position, open fold, + " jump to the last line of the previously closed fold + let foldstart = foldclosed(".") + let foldend = foldclosedend(".") + normal! zv + if a:mode == 'below' + exe ":".foldend + elseif a:mode == 'start' + exe ":".foldstart + endif +endfunction " ---------- end of function s:OpenFold ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#NewLibrary : Create a new template library. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#NewLibrary ( ... ) + " + " ================================================== + " options + " ================================================== + " + let i = 1 + while i <= a:0 + " + if a:[i] == 'debug' && i+1 <= a:0 && ! s:DebugGlobalOverwrite + let s:DebugLevel = a:[i+1] + let i += 2 + else + if type ( a:[i] ) == type ( '' ) | call s:ErrorMsg ( 'Unknown option: "'.a:[i].'"' ) + else | call s:ErrorMsg ( 'Unknown option at position '.i.'.' ) | endif + let i += 1 + endif + " + endwhile + " + " ================================================== + " data + " ================================================== + " + " library + let library = { + \ 'macros' : {}, + \ 'properties' : {}, + \ 'resources' : {}, + \ 'templates' : {}, + \ + \ 'menu_order' : [], + \ + \ 'styles' : [ 'default' ], + \ 'current_style' : 'default', + \ + \ 'menu_shortcuts' : {}, + \ 'menu_existing' : { 'base' : 0 }, + \ + \ 'regex_settings' : ( copy ( s:RegexSettings ) ), + \ 'regex_file' : {}, + \ 'regex_template' : {}, + \ + \ 'library_files' : [], + \ } + " entry used by maps: 'map_commands' + " + call extend ( library.macros, s:StandardMacros, 'keep' ) + call extend ( library.properties, s:StandardProperties, 'keep' ) + " + call s:UpdateFileReadRegex ( library.regex_file, library.regex_settings ) + call s:UpdateTemplateRegex ( library.regex_template, library.regex_settings ) + " + " ================================================== + " wrap up + " ================================================== + " + let s:DebugLevel = s:DebugGlobalOverwrite " reset debug + " + return library " return the new library + " +endfunction " ---------- end of function mmtemplates#core#NewLibrary ---------- +" +"---------------------------------------------------------------------- +" === Read Templates: Auxiliary Functions === {{{1 +"---------------------------------------------------------------------- +" +"---------------------------------------------------------------------- +" s:TemplateTypeNames : Readable type names for templates. {{{2 +"---------------------------------------------------------------------- +" +let s:TemplateTypeNames = { + \ 'help' : 'help', + \ 'sep' : 'separator', + \ 't' : 'template', + \ } +" +"---------------------------------------------------------------------- +" s:AddText : Add a text. {{{2 +"---------------------------------------------------------------------- +" +function! s:AddText ( type, name, settings, lines ) + " + if a:type == 'help' + call s:AddTemplate ( 'help', a:name, a:settings, a:lines ) + elseif a:type == 'list' + call s:AddList ( 'list', a:name, a:settings, a:lines ) + elseif a:type == 'template' + call s:AddTemplate ( 't', a:name, a:settings, a:lines ) + endif + " +endfunction " ---------- end of function s:AddText ---------- +" +"---------------------------------------------------------------------- +" s:AddList : Add a list. {{{2 +"---------------------------------------------------------------------- +" +function! s:AddList ( type, name, settings, lines ) + " + " ================================================== + " checks + " ================================================== + " + " Error: empty name + if empty ( a:name ) + call s:ErrorMsg ( 'List name can not be empty.' ) + return + endif + " + " Warning: empty list + if empty ( a:lines ) + call s:ErrorMsg ( 'Warning: Empty list: "'.a:name.'"' ) + endif + " + " Warning: already existing + if s:t_runtime.overwrite_warning && has_key ( s:library.resources, 'list!'.a:name ) + call s:ErrorMsg ( 'Warning: Overwriting list "'.a:name.'"' ) + endif + " + " ================================================== + " settings + " ================================================== + " + let type = 'list' + let bare = 0 + " + for s in a:settings + " + if s == 'list' + let type = 'list' + elseif s == 'hash' || s == 'dict' || s == 'dictionary' + let type = 'dict' + elseif s == 'bare' + let bare = 1 + else + call s:ErrorMsg ( 'Warning: Unknown setting in list "'.a:name.'": "'.s.'"' ) + endif + " + endfor + " + if type == 'list' + if bare + let lines = escape( a:lines, '"' ) + let lines = substitute( lines, '^\s*', '"', '' ) + let lines = substitute( lines, '\s*\n$', '"', '' ) + let lines = substitute( lines, '\s*\n\s*', '", "', 'g' ) + exe 'let list = [ '.lines.' ]' + else + exe 'let list = [ '.substitute( a:lines, '\n', ' ', 'g' ).' ]' + end + call sort ( list ) + elseif type == 'dict' + if bare + s:ErrorMsg ( 'bare hash: to be implemented' ) + else + exe 'let list = { '.substitute( a:lines, '\n', ' ', 'g' ).' }' + end + endif + " + let s:library.resources[ 'list!'.a:name ] = list + " +endfunction " ---------- end of function s:AddList ---------- +" +"---------------------------------------------------------------------- +" s:AddTemplate : Add a template. {{{2 +"---------------------------------------------------------------------- +" +function! s:AddTemplate ( type, name, settings, lines ) + " + let name = a:name + " + " ================================================== + " checks + " ================================================== + " + " Error: empty name + if empty ( name ) + call s:ErrorMsg ( 'Template name can not be empty.' ) + return + endif + " + " Warning: empty template + if empty ( a:lines ) + call s:ErrorMsg ( 'Warning: Empty template: "'.name.'"' ) + endif + " + " ================================================== + " new template + " ================================================== + " + if has_key ( s:library.templates, name.'!!type' ) + let my_type = a:type + let other_type = split ( s:library.templates[ name.'!!type' ], ',' )[0] + " + if my_type != other_type + if my_type == 't' + call s:ErrorMsg ( 'Template "'.name.'" can not overwrite an object of the same name of type "'.s:TemplateTypeNames[other_type].'".' ) + elseif my_type == 'help' + call s:ErrorMsg ( 'Help template "'.name.'" can not overwrite an object of the same name of type "'.s:TemplateTypeNames[other_type].'".' ) + endif + return + endif + else + " + " -------------------------------------------------- + " new template + " -------------------------------------------------- + let type = a:type + let placement = 'below' + let indentation = '1' + " + let visual = -1 != stridx ( a:lines, '<SPLIT>' ) + let mp = '' + let entry = 1 + let sc = '' + " + " -------------------------------------------------- + " settings + " -------------------------------------------------- + for s in a:settings + " + if s == 'start' || s == 'above' || s == 'below' || s == 'append' || s == 'insert' + let placement = s + + " indentation + elseif s == 'indent' + let indentation = '1' + elseif s == 'noindent' + let indentation = '0' + + " special insertion in visual mode: + elseif s == 'visual' + let visual = 1 + elseif s == 'novisual' + let visual = 0 + + " map: + elseif s =~ '^map\s*:' + let mp = matchstr ( s, '^map\s*:\s*\zs'.s:library.regex_file.Mapping ) + + " entry and shortcut: + elseif s == 'nomenu' + let entry = 0 + elseif s == 'expandmenu' + let entry = 2 + elseif s =~ '^sc\s*:' || s =~ '^shortcut\s*:' + let sc = matchstr ( s, '^\w\+\s*:\s*\zs'.s:library.regex_file.Mapping ) + + else + call s:ErrorMsg ( 'Warning: Unknown setting in template "'.name.'": "'.s.'"' ) + endif + " + endfor + " + " TODO: review this + if a:type == 'help' + let placement = 'help' + endif + " + " -------------------------------------------------- + " new template + " -------------------------------------------------- + let s:library.templates[ name.'!!type' ] = type.','.placement.','.indentation + let s:library.templates[ name.'!!menu' ] = visual.",".string(mp).",".entry.",'',".string(sc) + " + call add ( s:library.menu_order, name ) + " + endif + " + " ================================================== + " text + " ================================================== + " + " the styles + if a:type == 'help' + " Warning: overwriting a style + if s:t_runtime.overwrite_warning && has_key ( s:library.templates, name.'!default' ) + call s:ErrorMsg ( 'Warning: Overwriting a help template: "'.name.'"' ) + endif + let s:library.templates[ name.'!default' ] = a:lines + return + elseif empty ( s:t_runtime.use_styles ) + let styles = [ 'default' ] + else + let styles = s:t_runtime.use_styles + endif + " + " save the lines + for s in styles + " + " Warning: overwriting a style + if s:t_runtime.overwrite_warning && has_key ( s:library.templates, name.'!'.s ) + call s:ErrorMsg ( 'Warning: Overwriting style in template "'.name.'": "'.s.'"' ) + endif + " + let s:library.templates[ name.'!'.s ] = a:lines + " + endfor + " +endfunction " ---------- end of function s:AddTemplate ---------- +" +"---------------------------------------------------------------------- +" s:AddSeparator : Add a menu separator. {{{2 +"---------------------------------------------------------------------- +" +function! s:AddSeparator ( type, name, settings ) + " + let name = a:name + " + " ================================================== + " checks + " ================================================== + " + " Error: empty name + if empty ( name ) + call s:ErrorMsg ( 'Separator name can not be empty.' ) + return + endif + " + " ================================================== + " new separator + " ================================================== + " + if has_key ( s:library.templates, name.'!!type' ) + " + let my_type = a:type + let other_type = split ( s:library.templates[ name.'!!type' ], ',' )[0] + " + if my_type != other_type + call s:ErrorMsg ( 'Separator "'.name.'" can not overwrite an object of the same name of type "'.s:TemplateTypeNames[other_type].'".' ) + return + endif + else + " + let s:library.templates[ name.'!!type' ] = 'sep,,0' + let s:library.templates[ name.'!!menu' ] = "0,'',11,'',''" + " + call add ( s:library.menu_order, name ) + " + endif + " +endfunction " ---------- end of function s:AddSeparator ---------- +" +"---------------------------------------------------------------------- +" s:AddStyles : Add styles to the list. {{{2 +"---------------------------------------------------------------------- +" +function! s:AddStyles ( styles ) + " + " TODO: check for valid name + " add the styles to the list + for s in a:styles + if -1 == index ( s:library.styles, s ) + call add ( s:library.styles, s ) + endif + endfor + " +endfunction " ---------- end of function s:AddStyles ---------- +" +"---------------------------------------------------------------------- +" s:UseStyles : Set the styles. {{{2 +"---------------------------------------------------------------------- +" +function! s:UseStyles ( styles ) + " + " 'use_styles' empty? -> we may have new styles + " otherwise -> must be a subset, so no new styles + if empty ( s:t_runtime.use_styles ) + " add the styles to the list + call s:AddStyles ( a:styles ) + else + " are the styles a sub-set of the currently used styles? + for s in a:styles + if -1 == index ( s:t_runtime.use_styles, s ) + call s:ErrorMsg ( 'Style "'.s.'" currently not in use.' ) + return + endif + endfor + endif + " + " push the new style and use it as the current style + call add ( s:t_runtime.styles_stack, a:styles ) + let s:t_runtime.use_styles = a:styles + " +endfunction " ---------- end of function s:UseStyles ---------- +" +"---------------------------------------------------------------------- +" s:RevertStyles : Revert the styles. {{{2 +"---------------------------------------------------------------------- +" +function! s:RevertStyles ( times ) + " + " get the current top, and check whether any more styles can be removed + let state_lim = s:t_runtime.state_stack[ s:StateStackStyleTop ] + let state_top = len( s:t_runtime.styles_stack ) + " + if state_lim > ( state_top - a:times ) + call s:ErrorMsg ( 'Can not close any more style sections.' ) + return + endif + " + " remove the top + call remove ( s:t_runtime.styles_stack, -1 * a:times, -1 ) + " + " reset the current style + if state_top > a:times + let s:t_runtime.use_styles = s:t_runtime.styles_stack[ -1 ] + else + let s:t_runtime.use_styles = [] + endif + " +endfunction " ---------- end of function s:RevertStyles ---------- +" +"---------------------------------------------------------------------- +" === Read Templates: Template File Namespace === {{{1 +"---------------------------------------------------------------------- +" +"---------------------------------------------------------------------- +" s:FileReadNameSpace : The set of functions a template file can call. {{{2 +"---------------------------------------------------------------------- +" +let s:FileReadNameSpace = { + \ 'IncludeFile' : 'ss\?', + \ 'SetFormat' : 'ss', + \ 'SetMacro' : 'ss', + \ 'SetPath' : 'ss', + \ 'SetProperty' : 'ss', + \ 'SetStyle' : 's', + \ + \ 'MenuShortcut' : 'ss', + \ } +" \ 'SetMap' : 'ss', +" \ 'SetShortcut' : 'ss', +" +"---------------------------------------------------------------------- +" s:SetFormat : Set the format of |DATE|, ... (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:SetFormat ( name, replacement ) + " + " check for valid name + if a:name !~ 'TIME\|DATE\|YEAR' + call s:ErrorMsg ( 'Can not set the format of: '.a:name ) + return + endif + " + let s:library.macros[ a:name ] = a:replacement + " +endfunction " ---------- end of function s:SetFormat ---------- +" +"---------------------------------------------------------------------- +" s:SetMacro : Set a replacement (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:SetMacro ( name, replacement ) + " + " check for valid name + if a:name !~ s:library.regex_file.MacroName + call s:ErrorMsg ( 'Macro name must be a valid identifier: '.a:name ) + return + elseif has_key ( s:StandardMacros, a:name ) + call s:ErrorMsg ( 'The special macro "'.a:name.'" can not be replaced via SetMacro.' ) + return + endif + " + let s:library.macros[ a:name ] = a:replacement + " +endfunction " ---------- end of function s:SetMacro ---------- +" +"---------------------------------------------------------------------- +" s:SetStyle : Set the current style (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:SetStyle ( name ) + " + " check for valid name + if a:name !~ s:library.regex_file.MacroName + call s:ErrorMsg ( 'Style name must be a valid identifier: '.a:name ) + return + endif + " + let s:library.current_style = a:name + " +endfunction " ---------- end of function s:SetStyle ---------- +" +"---------------------------------------------------------------------- +" s:SetPath : Set a path-resource (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:SetPath ( name, value ) + " + " check for valid name + if a:name !~ s:library.regex_file.MacroName + call s:ErrorMsg ( 'Path name must be a valid identifier: '.a:name ) + return + endif + " + let s:library.resources[ 'path!'.a:name ] = a:value + " +endfunction " ---------- end of function s:SetPath ---------- +" +"---------------------------------------------------------------------- +" s:MenuShortcut : Set a shortcut for a sub-menu (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:MenuShortcut ( name, shortcut ) + " + " check for valid shortcut + if len ( a:shortcut ) > 1 + call s:ErrorMsg ( 'The shortcut for "'.a:name.'" must be a single character.' ) + return + endif + " + let name = substitute( a:name, '\.$', '', '' ) + " + let s:library.menu_shortcuts[ name ] = a:shortcut + " +endfunction " ---------- end of function s:MenuShortcut ---------- +" +"---------------------------------------------------------------------- +" s:SetMap : TODO (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:SetMap ( name, map ) + " + echo 'SetMap: TO BE IMPLEMENTED' + " +endfunction " ---------- end of function s:SetMap ---------- +" +"---------------------------------------------------------------------- +" s:SetProperty : Set an existing property. {{{2 +"---------------------------------------------------------------------- +" +function! s:SetProperty ( name, value ) + " + let [ _, err ] = mmtemplates#core#Resource ( s:library, 'set', 'property', a:name , a:value ) + " + if err != '' + return s:ErrorMsg ( 'Can not set the property "'.a:name.'".' ) + endif + " +endfunction " ---------- end of function s:SetProperty ---------- +" +"---------------------------------------------------------------------- +" s:SetShortcut : TODO (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:SetShortcut ( name, shortcut ) + " + " check for valid shortcut + if len ( a:shortcut ) > 1 + call s:ErrorMsg ( 'The shortcut for "'.a:name.'" must be a single character.' ) + return + endif + " + echo 'SetShortcut: TO BE IMPLEMENTED' + " +endfunction " ---------- end of function s:SetShortcut ---------- +" +"---------------------------------------------------------------------- +" s:IncludeFile : Read a template file (template function). {{{2 +"---------------------------------------------------------------------- +" +function! s:IncludeFile ( templatefile, ... ) + " + let regex = s:library.regex_file + " + let read_abs = 0 + if a:0 >= 1 && a:1 == 'abs' + let read_abs = 1 + endif + " + " ================================================== + " checks + " ================================================== + " + " Expand ~, $HOME, ... and check for absolute path + let templatefile = expand( a:templatefile ) + " +" if templatefile =~ regex.AbsolutePath +" let templatefile = s:ConcatNormalizedFilename ( templatefile ) +" else +" let templatefile = s:ConcatNormalizedFilename ( s:t_runtime.state_stack[ s:StateStackFile ], templatefile ) +" endif + if read_abs + let templatefile = s:ConcatNormalizedFilename ( templatefile ) + else + let templatefile = s:ConcatNormalizedFilename ( s:t_runtime.state_stack[ s:StateStackFile ], templatefile ) + endif + " + " file does not exists or was already visited? + if !filereadable( templatefile ) + throw 'Template:Check:file "'.templatefile.'" does not exist or is not readable' + elseif has_key ( s:t_runtime.files_visited, templatefile ) + throw 'Template:Check:file "'.templatefile.'" already read' + endif + " + " ================================================== + " setup + " ================================================== + " + " add to the state stack + call add ( s:t_runtime.state_stack, len( s:t_runtime.styles_stack ) ) " length of styles_stack + call add ( s:t_runtime.state_stack, s:GetNormalizedPath ( templatefile ) ) " current path + " + " mark file as read + let s:t_runtime.files_visited[templatefile] = 1 + " + " debug: + call s:DebugMsg ( 'Reading '.templatefile.' ...', 2 ) + " + let state = 'command' + let t_start = 0 + let last_styles = '' + " + " ================================================== + " go trough the file + " ================================================== + " + let filelines = readfile( templatefile ) + " + for line in filelines + " + let firstchar = line[0] + " + " which state + if state == 'command' + " ================================================== + " state: command + " ================================================== + " + " empty line? + if empty ( line ) + continue + endif + " + " comment? + if firstchar == regex.CommentHint + if line =~ regex.CommentLine + continue + endif + endif + " + " macro line? --- |MACRO| = something + if firstchar == regex.MacroHint + " + let mlist = matchlist ( line, regex.MacroAssign ) + if ! empty ( mlist ) + " STYLE, includefile or general macro + if mlist[1] == 'STYLE' + call s:SetStyle ( mlist[3] ) + elseif mlist[1] == 'includefile' + try + call s:IncludeFile ( mlist[3], 'old' ) + catch /Template:Check:.*/ + let msg = v:exception[ len( 'Template:Check:') : -1 ] + call s:ErrorMsg ( 'While loading "'.templatefile.'":', msg ) + endtry + else + call s:SetMacro ( mlist[1], mlist[3] ) + endif + continue + endif + " + endif + " + " function call? --- Function( param_list ) + if firstchar =~ regex.CommandHint + " + let mlist = matchlist ( line, regex.FunctionCall ) + if ! empty ( mlist ) + let [ name, param ] = mlist[ 1 : 2 ] + " + try + " check the call + call s:FunctionCheck ( name, param, s:FileReadNameSpace ) + " try to call + exe 'call s:'.name.' ( '.param.' ) ' + catch /Template:Check:.*/ + let msg = v:exception[ len( 'Template:Check:') : -1 ] + call s:ErrorMsg ( 'While loading "'.templatefile.'":', msg ) + catch // + call s:ErrorMsg ( 'While calling "'.name.'" in "'.templatefile.'":', v:exception ) + endtry + " + continue + endif + " + endif + " + " section or text? + if firstchar == regex.DelimHint + " + " switch styles? + let mlist = matchlist ( line, regex.Styles1Start ) + if ! empty ( mlist ) + call s:UseStyles ( [ mlist[1] ] ) + let last_styles = mlist[0] + continue + endif + " + " switch styles? + if line =~ regex.Styles1End + call s:RevertStyles ( 1 ) + continue + endif + " + " switch styles? + let mlist = matchlist ( line, regex.Styles2Start ) + if ! empty ( mlist ) + call s:UseStyles ( split( mlist[1], '\s*,\s*' ) ) + let last_styles = mlist[0] + continue + endif + " + " switch styles? + if line =~ regex.Styles2End + call s:RevertStyles ( 1 ) + continue + endif + " + " separator? + let mlist = matchlist ( line, regex.MenuSep ) + if ! empty ( mlist ) + call s:AddSeparator ( 'sep', mlist[1], '' ) + continue + endif + " + " start of text? + let mlist_template = matchlist ( line, regex.TemplateStart ) + let mlist_help = matchlist ( line, regex.HelpStart ) + let mlist_list = matchlist ( line, regex.ListStart ) + if ! empty ( mlist_template ) + let state = 'text' + let t_type = 'template' + let t_start = 1 + elseif ! empty ( mlist_help ) + let state = 'text' + let t_type = 'help' + let t_start = 1 + elseif ! empty ( mlist_list ) + let state = 'text' + let t_type = 'list' + let t_start = 1 + endif + " + endif + " + " empty line? + if line =~ regex.EmptyLine + continue + endif + " + elseif state == 'text' + " ================================================== + " state: text + " ================================================== + " + if firstchar == regex.CommentHint || firstchar == regex.DelimHint + " + " comment or end of template? + if line =~ regex.CommentLine + \ || line =~ regex.TemplateEnd + \ || line =~ regex.ListEnd + let state = 'command' + call s:AddText ( t_type, t_name, t_settings, t_lines ) + continue + endif + " + " start of new text? + let mlist_template = matchlist ( line, regex.TemplateStart ) + let mlist_help = matchlist ( line, regex.HelpStart ) + let mlist_list = matchlist ( line, regex.ListStart ) + if ! empty ( mlist_template ) + call s:AddText ( t_type, t_name, t_settings, t_lines ) + let t_type = 'template' + let t_start = 1 + elseif ! empty ( mlist_help ) + call s:AddText ( t_type, t_name, t_settings, t_lines ) + let t_type = 'help' + let t_start = 1 + elseif ! empty ( mlist_list ) + call s:AddText ( t_type, t_name, t_settings, t_lines ) + let t_type = 'list' + let t_start = 1 + else + let t_lines .= line."\n" " read the line + continue + endif + " + else + let t_lines .= line."\n" " read the line + continue + endif + " + endif + " + " start of template? + if t_start + if t_type == 'template' + let t_name = mlist_template[1] + let t_settings = split( mlist_template[2], '\s*,\s*' ) + elseif t_type == 'list' + let t_name = mlist_list[1] + let t_settings = split( mlist_list[2], '\s*,\s*' ) + elseif t_type == 'help' + let t_name = mlist_help[1] + let t_settings = split( mlist_help[2], '\s*,\s*' ) + endif + let t_lines = '' + let t_start = 0 + continue + endif + " + call s:ErrorMsg ( 'Failed to read line: '.line ) + " + endfor + " + " ================================================== + " wrap up + " ================================================== + " + if state == 'text' + call s:AddText ( t_type, t_name, t_settings, t_lines ) + endif + " + " all style sections closed? + let state_lim = s:t_runtime.state_stack[ s:StateStackStyleTop ] + let state_top = len( s:t_runtime.styles_stack ) + if state_lim < state_top + call s:RevertStyles ( state_top - state_lim ) + call s:ErrorMsg ( 'Styles section has not been closed: '.last_styles ) + endif + " + " debug: + call s:DebugMsg ( '... '.templatefile.' done.', 2 ) + " + " restore the previous state + call remove ( s:t_runtime.state_stack, -1 * s:StateStackLength, -1 ) + " +endfunction " ---------- end of function s:IncludeFile ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#ReadTemplates : Read a template file. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#ReadTemplates ( library, ... ) + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + return s:ErrorMsg ( 'Argument "library" must be given as a dict or string.' ) + endif + " + " ================================================== + " setup + " ================================================== + " + " library and runtime information + let s:library = t_lib + let s:t_runtime = { + \ 'state_stack' : [], + \ 'use_styles' : [], + \ 'styles_stack' : [], + \ 'files_visited' : {}, + \ + \ 'overwrite_warning' : 0, + \ } + " + let mode = '' + let file = '' + " + " ================================================== + " options + " ================================================== + " + let i = 1 + while i <= a:0 + " + if a:[i] == 'load' && i+1 <= a:0 + let mode = 'load' + let file = a:[i+1] + let i += 2 + elseif a:[i] == 'reload' && i+1 <= a:0 + let mode = 'reload' + let file = a:[i+1] + let i += 2 + elseif a:[i] == 'overwrite_warning' + let s:t_runtime.overwrite_warning = 1 + let i += 1 + elseif a:[i] == 'debug' && i+1 <= a:0 && ! s:DebugGlobalOverwrite + let s:DebugLevel = a:[i+1] + let i += 2 + else + if type ( a:[i] ) == type ( '' ) | call s:ErrorMsg ( 'Unknown option: "'.a:[i].'"' ) + else | call s:ErrorMsg ( 'Unknown option at position '.i.'.' ) | endif + let i += 1 + endif + " + endwhile + " + " ================================================== + " files + " ================================================== + " + let templatefiles = [] + " + if mode == 'load' + " + " check the type + if type( file ) != type( '' ) + return s:ErrorMsg ( 'Argument "filename" must be given as a string.' ) + endif + " + " expand ~, $HOME, ... and normalize + let file = expand ( file ) + call add ( templatefiles, s:ConcatNormalizedFilename ( file ) ) + " + " add to library + call add ( t_lib.library_files, s:ConcatNormalizedFilename ( file ) ) + " + elseif mode == 'reload' + " + if type( file ) == type( 0 ) + call add ( templatefiles, t_lib.library_files[ file ] ) + elseif type( file ) == type( '' ) + " load all or a specific file + if file == 'all' + call extend ( templatefiles, t_lib.library_files ) + else + " + " check and add the file + let file = expand ( file ) + let file = s:ConcatNormalizedFilename ( file ) + " + if ! filereadable ( file ) + return s:ErrorMsg ( 'The file "'.file.'" does not exist.' ) + elseif index ( t_lib.library_files, file ) == -1 + return s:ErrorMsg ( 'The file "'.file.'" is not part of the template library.' ) + endif + " + call add ( templatefiles, file ) + " + endif + else + return s:ErrorMsg ( 'Argument "fileid" must be given as an integer or string.' ) + endif + " + " remove old maps + if has_key ( t_lib, 'map_commands' ) + call remove ( t_lib, 'map_commands' ) + endif + " + endif + " + " ================================================== + " read the library + " ================================================== + " + " debug: + if s:DebugLevel > 0 + let time_start = reltime() + endif + " + for f in templatefiles + " + " file exists? + if !filereadable ( f ) + call s:ErrorMsg ( 'Template library "'.f.'" does not exist or is not readable.' ) + continue + endif + " + " runtime information: + " - set up the state stack: length of styles_stack + current path + " - reset the current styles + let s:t_runtime.state_stack = [ 0, s:GetNormalizedPath ( f ) ] + let s:t_runtime.use_styles = [] + let s:t_runtime.styles_stack = [] + " + " read the top-level file + call s:IncludeFile ( f, 'abs' ) + " + endfor + " + call sort ( s:library.styles ) " sort the styles + " + " debug: + if s:DebugLevel > 0 + echo 'Loading library: '.reltimestr( reltime( time_start ) ) + endif + " + if mode == 'reload' + echo 'Reloaded the template library.' + endif + " + " ================================================== + " wrap up + " ================================================== + " + unlet s:library " remove script variables + unlet s:t_runtime " ... + " + let s:DebugLevel = s:DebugGlobalOverwrite " reset debug + " +endfunction " ---------- end of function mmtemplates#core#ReadTemplates ---------- +" +"---------------------------------------------------------------------- +" === Templates === {{{1 +"---------------------------------------------------------------------- +" +"---------------------------------------------------------------------- +" s:ApplyFlag : Modify a text according to 'flag'. {{{2 +"---------------------------------------------------------------------- +" +function! s:ApplyFlag ( text, flag ) + " + if a:flag == '' || a:flag == 'i' " i : identity + return a:text + elseif a:flag == 'l' " l : lowercase + return tolower(a:text) + elseif a:flag == 'u' " u : uppercase + return toupper(a:text) + elseif a:flag == 'c' " c : capitalize + return toupper(a:text[0]).a:text[1:] + elseif a:flag == 'L' " L : legalized name + let text = substitute( a:text, '\s\+', '_', 'g' ) " multiple whitespaces + let text = substitute( text, '\W\+', '_', 'g' ) " multiple non-word characters + let text = substitute( text, '_\+', '_', 'g' ) " multiple underscores + return text + else " flag not valid + return a:text + endif + " +endfunction " ---------- end of function s:ApplyFlag ---------- +" +"---------------------------------------------------------------------- +" s:ReplaceMacros : Replace all the macros in a text. {{{2 +"---------------------------------------------------------------------- +" +function! s:ReplaceMacros ( text, m_local ) + " + let text1 = '' + let text2 = a:text + " + let regex = '\(\_.\{-}\)'.s:library.regex_template.MacroInsert.'\(\_.*\)' + " + while 1 + " + let mlist = matchlist ( text2, regex ) + " + " no more macros? + if empty ( mlist ) + break + endif + " + " check for recursion + if -1 != index ( s:t_runtime.macro_stack, mlist[2] ) + let m_text = '' + call add ( s:t_runtime.macro_stack, mlist[2] ) + throw 'Template:MacroRecursion' + elseif has_key ( a:m_local, mlist[2] ) + let m_text = get ( a:m_local, mlist[2] ) + else + let m_text = get ( s:library.macros, mlist[2], '' ) + end + " + if m_text =~ s:library.regex_template.MacroNoCapture + " + call add ( s:t_runtime.macro_stack, mlist[2] ) + " + let m_text = s:ReplaceMacros ( m_text, a:m_local ) + " + call remove ( s:t_runtime.macro_stack, -1 ) + " + endif + " + " apply flag? + if ! empty ( mlist[3] ) + let m_text = s:ApplyFlag ( m_text, mlist[3] ) + endif + " + let text1 .= mlist[1].m_text + let text2 = mlist[4] + " + endwhile + " + return text1.text2 + " +endfunction " ---------- end of function s:ReplaceMacros ---------- +" +"---------------------------------------------------------------------- +" s:CheckHelp : Check a template (help). {{{2 +"---------------------------------------------------------------------- +" +let s:NamespaceHelp = { + \ 'Word' : 's', + \ 'Pattern' : 's', 'Default' : 's', + \ 'Substitute' : 'sss', 'LiteralSub' : 'sss', + \ 'System' : 's', 'Vim' : 's', + \ } +" +function! s:CheckHelp ( cmds, text, calls ) + return [ a:cmds, a:text ] +endfunction " ---------- end of function s:CheckHelp ---------- +" +" "---------------------------------------------------------------------- +" s:CheckStdTempl : Check a template (standard). {{{2 +"---------------------------------------------------------------------- +" +let s:NamespaceStdTempl = { + \ 'DefaultMacro' : 's[sl]', + \ 'PickFile' : 'ss', + \ 'PickList' : 's[sld]', + \ 'Prompt' : 'ss', + \ 'SurroundWith' : 's[sl]*', + \ } +let s:NamespaceStdTemplInsert = { + \ 'Comment' : 's\?', + \ 'Insert' : 's[sl]*', + \ 'InsertLine' : 's[sl]*', + \ } +" +function! s:CheckStdTempl ( cmds, text, calls ) + " + let regex = s:library.regex_template + let ms = regex.MacroStart + let me = regex.MacroEnd + " + let cmds = a:cmds + let text = a:text + " + let prompted = {} + " + " -------------------------------------------------- + " replacements + " -------------------------------------------------- + while 1 + " + let mlist = matchlist ( text, regex.MacroRequest ) + " + " no more macros? + if empty ( mlist ) + break + endif + " + let m_name = mlist[1] + let m_flag = mlist[2] + " + " not a special macro and not already done? + if has_key ( s:StandardMacros, m_name ) + call s:ErrorMsg ( 'The special macro "'.m_name.'" can not be replaced via |?'.m_name.'|.' ) + elseif ! has_key ( prompted, m_name ) + let cmds .= "Prompt(".string(m_name).",".string(m_flag).")\n" + let prompted[ m_name ] = 1 + endif + " + if ! empty ( m_flag ) | let m_flag = ':'.m_flag | endif + " + " insert a normal macro + let text = s:LiteralReplacement ( text, + \ mlist[0], ms.m_name.m_flag.me, 'g' ) + " + endwhile + " + " -------------------------------------------------- + " lists + " -------------------------------------------------- + let list_items = [ 'EMPTY', 'SINGLE', 'FIRST', 'LAST' ] " + 'ENTRY' + " + while 1 + " + let mlist = matchlist ( text, regex.ListItem ) + " + " no more macros? + if empty ( mlist ) + break + endif + " + let l_name = mlist[1] + " + let mlist = matchlist ( text, + \ '\([^'."\n".']*\)'.ms.l_name.':ENTRY_*'.me.'\([^'."\n".']*\)\n' ) + " + let cmds .= "LIST(".string(l_name)."," + \ .string(mlist[1]).",".string(mlist[2]).")\n" + let text = s:LiteralReplacement ( text, + \ mlist[0], ms.l_name.':LIST'.me."\n", '' ) + " + for item in list_items + " + let mlist = matchlist ( text, + \ '\([^'."\n".']*\)'.ms.l_name.':'.item.'_*'.me.'\([^'."\n".']*\)\n' ) + " + if empty ( mlist ) + let cmds .= "\n" + continue + endif + " + let cmds .= "[".string(mlist[1]).",".string(mlist[2])."]\n" + let text = s:LiteralReplacement ( text, mlist[0], '', '' ) + endfor + " + endwhile + " + " -------------------------------------------------- + " comments + " -------------------------------------------------- + while 1 + " + let mlist = matchlist ( text, regex.FunctionComment ) + " + " no more comments? + if empty ( mlist ) + break + endif + " + let [ f_name, f_param ] = mlist[ 1 : 2 ] + " + " check the call + call s:FunctionCheck ( 'Comment', f_param, s:NamespaceStdTemplInsert ) + " + exe 'let flist = ['.f_param.']' + " + if empty ( flist ) | let flag = 'eol' + else | let flag = flist[0] | endif + " + let mlist = matchlist ( text, regex.FunctionComment.'\s*\([^'."\n".']*\)' ) + " + let text = s:LiteralReplacement ( text, mlist[0], + \ ms.'InsertLine("Comments.end-of-line","|CONTENT|",'.string( mlist[3] ).')'.me, '' ) + " + endwhile + " + return [ cmds, text ] + " +endfunction " ---------- end of function s:CheckStdTempl ---------- +" +"---------------------------------------------------------------------- +" s:CheckTemplate : Check a template. {{{2 +" +" Get the command and text block. +"---------------------------------------------------------------------- +" +function! s:CheckTemplate ( template, type ) + " + let regex = s:library.regex_template + " + let cmds = '' + let text = '' + let calls = [] + " + " the known functions + if a:type == 't' + let namespace = s:NamespaceStdTempl +" " TODO: remove this code: +" elseif a:type == 'pick-file' +" let namespace = s:NamespacePickFile +" elseif a:type == 'pick-list' +" let namespace = s:NamespacePickList + elseif a:type == 'help' + let namespace = s:NamespaceHelp + endif + " + " go trough the lines + let idx = 0 + while idx < len ( a:template ) + " + let idx_n = stridx ( a:template, "\n", idx ) + let mlist = matchlist ( a:template[ idx : idx_n ], regex.FunctionLine ) + " + " no match or 'Comment' or 'Insert' function? + if empty ( mlist ) || mlist[ 2 ] =~ regex.TextBlockFunctions + break + endif + " + let [ f_name, f_param ] = mlist[ 2 : 3 ] + " + " check the call + call s:FunctionCheck ( f_name, f_param, namespace ) + " + call add ( calls, [ f_name, f_param ] ) + " + let cmds .= mlist[1]."\n" + let idx += len ( mlist[0] ) + " + endwhile + " + let text = a:template[ idx : -1 ] + " + " checks depending on the type + if a:type == 't' + return s:CheckStdTempl( cmds, text, calls ) +" " TODO: remove this code: +" elseif a:type == 'pick-file' +" return s:CheckPickFile( cmds, text, calls ) +" elseif a:type == 'pick-list' +" return s:CheckPickList( cmds, text, calls ) + elseif a:type == 'help' + return s:CheckHelp( cmds, text, calls ) + endif + " +endfunction " ---------- end of function s:CheckTemplate ---------- +" +"---------------------------------------------------------------------- +" s:GetTemplate : Get a template. {{{2 +"---------------------------------------------------------------------- +" +function! s:GetTemplate ( name, style ) + " + let name = a:name + let style = a:style + " + " check the template + if has_key ( s:library.templates, name.'!!type' ) + let info = s:library.templates[ a:name.'!!type' ] + let [ type, placement, indentation ] = split ( info, ',' ) + else + throw 'Template:Prepare:template does not exist' + endif + " + if style == '!any' + for s in s:library.styles + if has_key ( s:library.templates, name.'!'.s ) + let template = get ( s:library.templates, name.'!'.s ) + let style = s + endif + endfor + else + " check the style + if has_key ( s:library.templates, name.'!'.style ) + let template = get ( s:library.templates, name.'!'.style ) + elseif has_key ( s:library.templates, name.'!default' ) + let template = get ( s:library.templates, name.'!default' ) + let style = 'default' + elseif style == 'default' + throw 'Template:Prepare:template does not have the default style' + else + throw 'Template:Prepare:template has neither the style "'.style.'" nor the default style' + endif + endif + " + " check the text + let head = template[ 0 : 5 ] + " + if head == "|P()|\n" " plain text + " TODO: special type for plain + let cmds = '' + let text = template[ 6 : -1 ] + elseif head == "|T()|\n" " only text (contains only macros without '?') + let cmds = '' + let text = template[ 6 : -1 ] + elseif head == "|C()|\n" " command and text block + let splt = stridx ( template, "|T()|\n" ) - 1 + let cmds = template[ 6 : splt ] + let text = template[ splt+7 : -1 ] + else + " + " do checks + let [ cmds, text ] = s:CheckTemplate ( template, type ) + " + " save the result + if empty ( cmds ) + let template = "|T()|\n".text + else + let template = "|C()|\n".cmds."|T()|\n".text + end + let s:library.templates[ a:name.'!'.style ] = template + " + end + " + return [ cmds, text, type, placement, indentation ] +endfunction " ---------- end of function s:GetTemplate ---------- +" +"---------------------------------------------------------------------- +" s:GetPickList : Get the list used in a template. {{{2 +"---------------------------------------------------------------------- +" +function! s:GetPickList ( name ) + " + let regex = s:library.regex_template + " + " get the template + let [ cmds, text, type, placement, indentation ] = s:GetTemplate ( a:name, '!any' ) + " + if type == 't' + " + for line in split( cmds, "\n" ) + " the line will match and it will be a valid function + let [ f_name, f_param ] = matchlist ( line, regex.FunctionChecked )[ 1 : 2 ] + " + if f_name == 'PickList' + " + exe 'let [ _, listarg ] = [ '.f_param.' ]' + " + let entry = '' + " + if type ( listarg ) == type ( '' ) + if ! has_key ( s:library.resources, 'list!'.listarg ) + call s:ErrorMsg ( 'List "'.listarg.'" does not exist.' ) + return [] + endif + let list = s:library.resources[ 'list!'.listarg ] + else + let list = listarg + endif + " + endif + endfor + " +" " TODO: remove this code: +" elseif type == 'pick-list' +" " +" for line in split( cmds, "\n" ) +" " the line will match and it will be a valid function +" let [ f_name, f_param ] = matchlist ( line, regex.FunctionChecked )[ 1 : 2 ] +" " +" if f_name == 'List' +" exe 'let list = '.f_param +" elseif f_name == 'GetList' +" " +" let listname = matchstr ( f_param, regex.RemoveQuote ) +" if ! has_key ( s:library.resources, 'list!'.listname ) +" call s:ErrorMsg ( 'List "'.listname.'" does not exist.' ) +" return [] +" endif +" let list = s:library.resources[ 'list!'.listname ] +" " +" endif +" endfor +" " + else + call s:ErrorMsg ( 'Template "'.a:name.'" is not a list picker.' ) + return [] + endif + " + if type ( list ) == type ( [] ) + return list + else + return sort ( keys ( list ) ) + endif + " +endfunction " ---------- end of function s:GetPickList ---------- +" +"---------------------------------------------------------------------- +" s:PrepareHelp : Prepare a template (help). {{{2 +"---------------------------------------------------------------------- +" +function! s:PrepareHelp ( cmds, text ) + " + let regex = s:library.regex_template + " + let pick = '' + let default = '' + let method = '' + let call = '' + " + let buf_line = getline('.') + let buf_pos = col('.') - 1 + " + " ================================================== + " command block + " ================================================== + " + for line in split( a:cmds, "\n" ) + " + " the line will match and it will be a valid function + let [ f_name, f_param ] = matchlist ( line, regex.FunctionChecked )[ 1 : 2 ] + " + if f_name == 'C' + " ignore + elseif f_name == 'Word' + exe 'let switch = '.f_param | " TODO: works differently than 'Pattern': picks up word behind the cursor, too + if switch == 'W' | let pick = expand('<cWORD>') + else | let pick = expand('<cword>') | endif + elseif f_name == 'Pattern' + exe 'let pattern = '.f_param + let cnt = 1 + while 1 + let m_end = matchend ( buf_line, pattern, 0, cnt ) - 1 + if m_end < 0 + let pick = '' + break + elseif m_end >= buf_pos + let m_start = match ( buf_line, pattern, 0, cnt ) + if m_start <= buf_pos | let pick = buf_line[ m_start : m_end ] + else | let pick = '' | endif + break + endif + let cnt += 1 + endwhile + elseif f_name == 'Default' + exe 'let default = '.f_param + elseif f_name == 'LiteralSub' + exe 'let [ p, r, f ] = ['.f_param.']' + let pick = s:LiteralReplacement ( pick, p, r, f ) + elseif f_name == 'Substitute' + exe 'let [ p, r, f ] = ['.f_param.']' + let pick = substitute ( pick, p, r, f ) + elseif f_name == 'System' || f_name == 'Vim' + let method = f_name + exe 'let call = '.f_param + endif + " + endfor + " + " ================================================== + " call for help + " ================================================== + " + if empty ( pick ) && empty ( default ) + \ || empty ( method ) + return '' + endif + " + let m_local = copy ( s:t_runtime.macros ) + " + if ! empty ( pick ) + let m_local.PICK = pick + let call = s:ReplaceMacros ( call, m_local ) + else + let call = s:ReplaceMacros ( default, m_local ) + endif + " + if method == 'System' + echo 'call system ( '.string ( call ).' )' | " debug + exe 'call system ( '.string ( call ).' )' + elseif method == 'Vim' + echo call | " debug + exe call + endif + " + return '' + " +endfunction " ---------- end of function s:PrepareHelp ---------- +" +" "---------------------------------------------------------------------- +" s:PrepareStdTempl : Prepare a template (standard). {{{2 +"---------------------------------------------------------------------- +" +function! s:PrepareStdTempl ( cmds, text ) + " + " TODO: revert must work like a stack, first set, last reverted + " TODO: revert in case of PickList and PickFile + " + let regex = s:library.regex_template + let ms = regex.MacroStart + let me = regex.MacroEnd + " + let m_local = s:t_runtime.macros + let m_global = s:library.macros + let prompted = s:t_runtime.prompted + " + let text = a:text + let surround = '' + let revert = '' + " + " + " ================================================== + " command block + " ================================================== + " + let cmds = split( a:cmds, "\n" ) + let i_cmds = 0 + let n_cmds = len( cmds ) + " + while i_cmds < n_cmds + " + " the line will match and it will be a valid function + let [ f_name, f_param ] = matchlist ( cmds[ i_cmds ], regex.FunctionChecked )[ 1 : 2 ] + " + if f_name == 'C' + " ignore + elseif f_name == 'SurroundWith' + let surround = f_param + elseif f_name == 'DefaultMacro' + " + let [ m_name, m_text ] = eval ( '[ '.f_param.' ]' ) + " + if ! has_key ( m_local, m_name ) + let revert = 'call remove ( m_local, "'.m_name.'" ) | '.revert + let m_local[ m_name ] = m_text + endif + " + elseif f_name == 'PickFile' + " + let [ p_prompt, p_path ] = eval ( '[ '.f_param.' ]' ) + " + if p_path =~ regex.MacroName + if ! has_key ( s:library.resources, 'path!'.p_path ) + throw 'Template:Prepare:the resources "'.p_path.'" does not exist' + endif + let p_path = s:library.resources[ 'path!'.p_path ] + endif + " + let p_path = expand ( p_path ) + let file = s:UserInput ( p_prompt.' : ', p_path, 'file' ) + " + let m_local.PICK_COMPL = file + let m_local.PATH_COMPL = fnamemodify ( file, ':h' ) + " + let file = substitute ( file, '\V\^'.p_path, '', '' ) + " + let m_local.PICK = file + let m_local.PATH = fnamemodify ( file, ':h' ) + let m_local.FILENAME = fnamemodify ( file, ':t' ) + let m_local.BASENAME = fnamemodify ( file, ':t:r' ) + let m_local.SUFFIX = fnamemodify ( file, ':e' ) + " + elseif f_name == 'PickEntry' + " + let [ p_which, p_entry ] = eval ( '[ '.f_param.' ]' ) + " + let l:pick_entry = p_entry + " + elseif f_name == 'PickList' + " + let [ p_prompt, p_list ] = eval ( '[ '.f_param.' ]' ) + " + if type ( p_list ) == type ( '' ) + if ! has_key ( s:library.resources, 'list!'.p_list ) + throw 'Template:Prepare:the resources "'.p_list.'" does not exist' + endif + let list = s:library.resources[ 'list!'.p_list ] + else + let list = p_list + end + " + if type ( list ) == type ( [] ) + let type = 'list' + let input_list = list + else + let type = 'dict' + let input_list = sort ( keys ( list ) ) + endif + " + if exists ( 'l:pick_entry' ) + let entry = l:pick_entry + else + let entry = s:UserInput ( p_prompt.' : ', '', 'customlist', input_list ) + endif + " + let m_local.KEY = entry + " + if type == 'dict' + if ! has_key ( list, entry ) + throw 'Template:Prepare:the entry "'.entry.'" does not exist' + endif + let entry = list[ entry ] + endif + " + let m_local.VALUE = entry + let m_local.PICK = entry + " + elseif f_name == 'Prompt' + " + let [ m_name, m_flag ] = eval ( '[ '.f_param.' ]' ) + " + " not already done and not a local macro? + if ! has_key ( prompted, m_name ) + \ && ! has_key ( m_local, m_name ) + let m_text = get ( m_global, m_name, '' ) + " + " prompt user for replacement + let flagaction = get ( s:Flagactions, m_flag, '' ) " notify flag action, if any + let m_text = s:UserInput ( m_name.flagaction.' : ', m_text ) + let m_text = s:ApplyFlag ( m_text, m_flag ) + " + " save the result + let m_global[ m_name ] = m_text + let prompted[ m_name ] = 1 + endif + else + break + endif + " + let i_cmds += 1 + endwhile + " + " -------------------------------------------------- + " lists + " -------------------------------------------------- + " + while i_cmds < n_cmds + " + let mlist = matchlist ( cmds[ i_cmds ], regex.FunctionList ) + " + if empty ( mlist ) + break + endif + " + exe 'let [ l_name, head_def, tail_def ] = ['.mlist[1].']' + let l_text = '' + if ! has_key ( m_local, l_name ) + let l_len = 0 + elseif type ( m_local[ l_name ] ) == type ( '' ) + let l_list = [ m_local[ l_name ] ] + let l_len = 1 + else + let l_list = m_local[ l_name ] + let l_len = len ( l_list ) + endif + " + if l_len == 0 + if ! empty ( cmds[ i_cmds+1 ] ) + exe 'let [ head, tail ] = '.cmds[ i_cmds+1 ] + let l_text = head.tail."\n" + endif + elseif l_len == 1 + if ! empty ( cmds[ i_cmds+2 ] ) + exe 'let [ head, tail ] = '.cmds[ i_cmds+2 ] + let l_text = head.l_list[0].tail."\n" + elseif ! empty ( cmds[ i_cmds+3 ] ) + exe 'let [ head, tail ] = '.cmds[ i_cmds+3 ] + let l_text = head.l_list[0].tail."\n" + else + let l_text = head_def.l_list[0].tail_def."\n" + end + else " l_len >= 2 + " + if ! empty ( cmds[ i_cmds+3 ] ) + exe 'let [ head, tail ] = '.cmds[ i_cmds+3 ] + let l_text .= head.l_list[0].tail."\n" + else + let l_text .= head_def.l_list[0].tail_def."\n" + endif + " + for idx in range ( 1, l_len-2 ) + let l_text .= head_def.l_list[idx].tail_def."\n" + endfor + " + if ! empty ( cmds[ i_cmds+4 ] ) + exe 'let [ head, tail ] = '.cmds[ i_cmds+4 ] + let l_text .= head.l_list[-1].tail."\n" + else + let l_text .= head_def.l_list[-1].tail_def."\n" + endif + endif + " + let text = s:LiteralReplacement ( text, ms.l_name.':LIST'.me."\n", l_text, '' ) + " + let i_cmds += 5 + endwhile + " + " ================================================== + " text block: macros and templates + " ================================================== + " + " insert other templates + while 1 + " + let mlist = matchlist ( text, regex.FunctionInsert ) + " + " no more inserts? + if empty ( mlist ) + break + endif + " + let [ f_name, f_param ] = mlist[ 1 : 2 ] + " + " check the call + call s:FunctionCheck ( f_name, f_param, s:NamespaceStdTemplInsert ) + " + if f_name == 'InsertLine' + " get the replacement + exe 'let m_text = s:PrepareTemplate ( '.f_param.' )[0]' + let m_text = m_text[ 0 : -2 ] + " check + if m_text =~ "\n" + throw 'Template:Prepare:inserts more than a single line: "'.mlist[0].'"' + endif + elseif f_name == 'Insert' + " get the replacement + exe 'let m_text = s:PrepareTemplate ( '.f_param.' )[0]' + let m_text = m_text[ 0 : -2 ] + " prepare + let mlist = matchlist ( text, '\([^'."\n".']*\)'.regex.FunctionInsert.'\([^'."\n".']*\)' ) + let head = mlist[1] + let tail = mlist[4] + let m_text = head.substitute( m_text, "\n", tail."\n".head, 'g' ).tail + else + throw 'Template:Check:the function "'.f_name.'" does not exist' + endif + " + " insert + let text = s:LiteralReplacement ( text, mlist[0], m_text, '' ) + " + endwhile + " + " insert the replacements + let text = s:ReplaceMacros ( text, m_local ) + " + " ================================================== + " surround the template + " ================================================== + " + if ! empty ( surround ) + " get the replacement + exe 'let [ s_text, s_place ] = s:PrepareTemplate ( '.surround.', "do_surround" )' + " + if s_place == 'CONTENT' + if -1 == match( s_text, '<CONTENT>' ) + throw 'Template:Prepare:surround template: <CONTENT> missing' + endif + " + let mcontext = matchlist ( s_text, '\([^'."\n".']*\)'.'<CONTENT>'.'\([^'."\n".']*\)' ) + let head = mcontext[1] + let tail = mcontext[2] + " insert + let text = text[ 0: -2 ] " remove trailing '\n' + let text = head.substitute( text, "\n", tail."\n".head, 'g' ).tail + let text = s:LiteralReplacement ( s_text, mcontext[0], text, '' ) + elseif s_place == 'SPLIT' + if -1 == match( s_text, '<SPLIT>' ) + throw 'Template:Prepare:surround template: <SPLIT> missing' + endif + " + if match( s_text, '<SPLIT>\s*\n' ) >= 0 + let part = split ( s_text, '\s*<SPLIT>\s*\n', 1 ) + else + let part = split ( s_text, '<SPLIT>', 1 ) + endif + let text = part[0].text.part[1] + endif + endif + " + exe revert + " + return text + " +endfunction " ---------- end of function s:PrepareStdTempl ---------- +" +"---------------------------------------------------------------------- +" s:PrepareTemplate : Prepare a template for insertion. {{{2 +"---------------------------------------------------------------------- +" +function! s:PrepareTemplate ( name, ... ) + " + let regex = s:library.regex_template + " + " ================================================== + " setup and checks + " ================================================== + " + " check for recursion + if -1 != index ( s:t_runtime.obj_stack, a:name ) + call add ( s:t_runtime.obj_stack, a:name ) + throw 'Template:Recursion' + endif + " + call add ( s:t_runtime.obj_stack, a:name ) + " + " current style + let style = s:library.current_style + " + " get the template + let [ cmds, text, type, placement, indentation ] = s:GetTemplate ( a:name, style ) + " + " current macros + let m_local = s:t_runtime.macros + let prompted = s:t_runtime.prompted + " + let remove_cursor = 1 + let remove_split = 1 + let use_surround = 0 + let use_split = 0 + " + let revert = '' + " + " ================================================== + " parameters + " ================================================== + " + let i = 1 + while i <= a:0 + " + if a:[i] =~ regex.MacroMatch && i+1 <= a:0 + let m_name = matchlist ( a:[i], regex.MacroNameC )[1] + if has_key ( m_local, m_name ) + let revert = 'let m_local["'.m_name.'"] = '.string( m_local[ m_name ] ).' | '.revert + else + let revert = 'call remove ( m_local, "'.m_name.'" ) | '.revert + endif + let m_local[ m_name ] = a:[i+1] + let i += 2 + elseif a:[i] == '<CURSOR>' + let remove_cursor = 0 + let i += 1 + elseif a:[i] == '<SPLIT>' + let remove_split = 0 + let i += 1 + elseif a:[i] == 'do_surround' + let use_surround = 1 + let i += 1 + elseif a:[i] == 'use_split' + let use_split = 1 + let remove_split = 0 + let i += 1 + elseif a:[i] == 'pick' && i+1 <= a:0 + let cmds = "PickEntry( '', ".string(a:[i+1])." )\n".cmds + let i += 2 + else + if type ( a:[i] ) == type ( '' ) | call s:ErrorMsg ( 'Unknown option: "'.a:[i].'"' ) + else | call s:ErrorMsg ( 'Unknown option at position '.i.'.' ) | endif + let i += 1 + endif + " + endwhile + " + " ================================================== + " prepare + " ================================================== + " + if type == 't' + let text = s:PrepareStdTempl( cmds, text ) +" " TODO: remove this code: +" elseif type == 'pick-file' +" let text = s:PreparePickFile( cmds, text ) +" elseif type == 'pick-list' +" let text = s:PreparePickList( cmds, text ) + elseif type == 'help' + let text = s:PrepareHelp( cmds, text ) + endif + " + if remove_cursor + let text = s:LiteralReplacement( text, '<CURSOR>', '', 'g' ) + endif + if remove_split + let text = s:LiteralReplacement( text, '<SPLIT>', '', 'g' ) + endif + if ! use_surround || use_split + let text = s:LiteralReplacement( text, '<CONTENT>', '', 'g' ) + endif + " + " ================================================== + " wrap up + " ================================================== + " + exe revert + " + call remove ( s:t_runtime.obj_stack, -1 ) + " + if use_split + return [ text, 'SPLIT' ] + elseif use_surround + return [ text, 'CONTENT' ] + else + return [ text, placement, indentation ] + endif + " +endfunction " ---------- end of function s:PrepareTemplate ---------- +" +"---------------------------------------------------------------------- +" === Insert Templates: Auxiliary Functions === {{{1 +"---------------------------------------------------------------------- +" +"---------------------------------------------------------------------- +" s:InsertIntoBuffer : Insert a text into the buffer. {{{2 +" (thanks to Fritz Mehner) +"---------------------------------------------------------------------- +" +function! s:InsertIntoBuffer ( text, placement, indentation, flag_mode ) + " + " TODO: syntax + let regex = s:library.regex_template + " + let placement = a:placement + let indentation = a:indentation == '1' + " + if a:flag_mode != 'v' + " -------------------------------------------------- + " command and insert mode + " -------------------------------------------------- + " + " remove the split point + let text = substitute( a:text, '\V'.'<SPLIT>', '', 'g' ) + " + if placement == 'below' + " + exe ':'.s:t_runtime.range[1] + call s:OpenFold('below') + let pos1 = line(".")+1 + silent put = text + let pos2 = line(".") + " + elseif placement == 'above' + " + exe ':'.s:t_runtime.range[0] + let pos1 = line(".") + silent put! = text + let pos2 = line(".") + " + elseif placement == 'start' + " + exe ':1' + call s:OpenFold('start') + let pos1 = 1 + silent put! = text + let pos2 = line(".") + " + elseif placement == 'append' || placement == 'insert' + " + if &foldenable && foldclosed(".") >= 0 + throw 'Template:Insert:insertion not available for a closed fold' + elseif placement == 'append' + let pos1 = line(".") + silent put = text + let pos2 = line(".")-1 + exe ":".pos1 + :join! + let indentation = 0 + elseif placement == 'insert' + let text = text[ 0: -2 ] " remove trailing '\n' + let currentline = getline( "." ) + let pos1 = line(".") + let pos2 = pos1 + count( split(text,'\zs'), "\n" ) + if a:flag_mode == 'i' + exe 'normal! gi'.text + else + exe 'normal! a'.text + endif + " reformat only multi-line inserts and previously empty lines + if pos1 == pos2 && currentline != '' + let indentation = 0 + endif + endif + " + else + throw 'Template:Insert:unknown placement "'.placement.'"' + endif + " + elseif a:flag_mode == 'v' + " -------------------------------------------------- + " visual mode + " -------------------------------------------------- + " + " remove the jump targets (2nd type) + let text = substitute( a:text, regex.JumpTagType2, '', 'g' ) + " + " TODO: Is the behaviour well-defined? + " Suggestion: The line might include a cursor and a split and nothing else. + if match( text, '<SPLIT>' ) >= 0 + if match( text, '<SPLIT>\s*\n' ) >= 0 + let part = split ( text, '\s*<SPLIT>\s*\n', 1 ) + else + let part = split ( text, '<SPLIT>', 1 ) + endif + let part[1] = part[1][ 0: -2 ] " remove trailing '\n' + else + let part = [ "", text[ 0: -2 ] ] " remove trailing '\n' + echomsg 'tag <SPLIT> missing in template.' + endif + " + " 'visual' and placement 'insert': + " <part0><marked area><part1> + " part0 and part1 can consist of several lines + " + " 'visual' and placement 'below': + " <part0> + " <marked area> + " <part1> + " part0 and part1 can consist of several lines + " + if placement == 'insert' + " windows: register @* does not work + " solution: recover area of the visual mode and yank, + " puts the selected area into the buffer @" + let pos1 = line("'<") + let pos2 = line("'>") + len(split( text, '\n' )) - 1 + normal! gvy + let repl = escape ( part[0].@".part[1], '\&~' ) + " substitute the selected area (using the '< and '> marks) + exe ':s/\%''<.*\%''>./'.repl.'/' + let indentation = 0 + elseif placement == 'below' + silent '<put! = part[0] + silent '>put = part[1] + let pos1 = line("'<") - len(split( part[0], '\n' )) + let pos2 = line("'>") + len(split( part[1], '\n' )) + elseif placement =~ '^\%(start\|above\|append\)$' + throw 'Template:Insert:usage in split mode not allowed for placement "'.placement.'"' + else + throw 'Template:Insert:unknown placement "'.placement.'"' + endif + " + endif + " + " proper indenting + if indentation + silent exe ":".pos1 + silent exe "normal! ".( pos2-pos1+1 )."==" + endif + " + return [ pos1, pos2 ] + " +endfunction " ---------- end of function s:InsertIntoBuffer ---------- +" +"---------------------------------------------------------------------- +" s:PositionCursor : Position the cursor. {{{2 +" (thanks to Fritz Mehner) +"---------------------------------------------------------------------- +" +function! s:PositionCursor ( placement, flag_mode, pos1, pos2 ) + " + " :TODO:12.08.2013 11:03:WM: changeable syntax? + " :TODO:12.08.2013 12:00:WM: change behavior? + " + call setpos ( '.', [ bufnr('%'), a:pos1, 1, 0 ] ) + let mtch = search( '\m<CURSOR>\|{CURSOR}', 'c', a:pos2 ) + if mtch != 0 + " tag found (and cursor moved, we are now at the position of the match) + let line = getline(mtch) + if line =~ '<CURSOR>$\|{CURSOR}$' + " the tag is at the end of the line + call setline( mtch, substitute( line, '<CURSOR>\|{CURSOR}', '', '' ) ) + if a:flag_mode == 'v' && getline('.') =~ '^\s*$' + "if a:flag_mode == 'v' && getline('.') =~ '^\s*\%(<CURSOR>\|{CURSOR}\)\s*$' + " the line contains nothing but the tag: remove and join without + " changing the second line + normal! J + "call setline( mtch, '' ) + "normal! gJ + else + " the line contains other characters: remove the tag and start appending + "call setline( mtch, substitute( line, '<CURSOR>\|{CURSOR}', '', '' ) ) + startinsert! + endif + else + " the line contains other characters: remove the tag and start inserting + call setline( mtch, substitute( line, '<CURSOR>\|{CURSOR}', '', '' ) ) + startinsert + endif + else + " no tag found (and cursor not moved) + if a:placement == 'below' + " to the end of the block, needed for repeated inserts + exe ":".a:pos2 + endif + endif + " +endfunction " ---------- end of function s:PositionCursor ---------- +" +"---------------------------------------------------------------------- +" s:HighlightJumpTargets : Highlight the jump targets. {{{2 +"---------------------------------------------------------------------- +" +function! s:HighlightJumpTargets ( regex ) + exe 'match Search /'.a:regex.'/' +endfunction " ---------- end of function s:HighlightJumpTargets ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#InsertTemplate : Insert a template. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#InsertTemplate ( library, t_name, ... ) range + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + return s:ErrorMsg ( 'Argument "library" must be given as a dict or string.' ) + endif + " + if type( a:t_name ) != type( '' ) + return s:ErrorMsg ( 'Argument "template_name" must be given as a string.' ) + endif + " + " ================================================== + " setup + " ================================================== + " + " library and runtime information + let s:library = t_lib + let s:t_runtime = { + \ 'obj_stack' : [], + \ 'macro_stack' : [], + \ 'macros' : {}, + \ 'prompted' : {}, + \ + \ 'placement' : '', + \ 'range' : [ a:firstline, a:lastline ], + \ } + let regex = s:library.regex_template + " + " renew the predefined macros + let s:t_runtime.macros[ 'BASENAME' ] = expand( '%:t:r' ) + let s:t_runtime.macros[ 'FILENAME' ] = expand( '%:t' ) + let s:t_runtime.macros[ 'PATH' ] = expand( '%:p:h' ) + let s:t_runtime.macros[ 'SUFFIX' ] = expand( '%:e' ) + " + let s:t_runtime.macros[ 'DATE' ] = strftime( s:library.macros[ 'DATE' ] ) + let s:t_runtime.macros[ 'TIME' ] = strftime( s:library.macros[ 'TIME' ] ) + let s:t_runtime.macros[ 'YEAR' ] = strftime( s:library.macros[ 'YEAR' ] ) + " + " handle folds internally (and save the state) + if &foldenable + let foldmethod_save = &foldmethod + set foldmethod=manual + endif + " use internal formatting to avoid conflicts when using == below + " (and save the state) + let equalprg_save = &equalprg + set equalprg= + " + let flag_mode = 'n' + let options = [] + " + " ================================================== + " options + " ================================================== + " + let i = 1 + while i <= a:0 + " + if a:[i] == 'i' || a:[i] == 'insert' + let flag_mode = 'i' + let i += 1 + elseif a:[i] == 'v' || a:[i] == 'visual' + let flag_mode = 'v' + let i += 1 + elseif a:[i] == 'placement' && i+1 <= a:0 + let s:t_runtime.placement = a:[i+1] + let i += 2 + elseif a:[i] == 'range' && i+2 <= a:0 + let s:t_runtime.range[0] = a:[i+1] + let s:t_runtime.range[1] = a:[i+2] + let i += 3 + elseif a:[i] =~ regex.MacroMatch && i+1 <= a:0 + let name = matchlist ( a:[i], regex.MacroNameC )[1] + let s:t_runtime.macros[ name ] = a:[i+1] + let i += 2 + elseif a:[i] == 'pick' && i+1 <= a:0 + call add ( options, 'pick' ) + call add ( options, a:[i+1] ) + let i += 2 + elseif a:[i] == 'debug' && i+1 <= a:0 && ! s:DebugGlobalOverwrite + let s:DebugLevel = a:[i+1] + let i += 2 + else + if type ( a:[i] ) == type ( '' ) | call s:ErrorMsg ( 'Unknown option: "'.a:[i].'"' ) + else | call s:ErrorMsg ( 'Unknown option at position '.i.'.' ) | endif + let i += 1 + endif + " + endwhile + " + " ================================================== + " do the job + " ================================================== + " + try + " + " prepare the template for insertion + if empty ( options ) + let [ text, placement, indentation ] = s:PrepareTemplate ( a:t_name, '<CURSOR>', '<SPLIT>' ) + else + let [ text, placement, indentation ] = call ( 's:PrepareTemplate', [ a:t_name, '<CURSOR>', '<SPLIT>' ] + options ) + endif + " + if placement == 'help' + " job already done, TODO: review this + else + " + if ! empty ( s:t_runtime.placement ) + let placement = s:t_runtime.placement + endif + " + " insert the text into the buffer + let [ pos1, pos2 ] = s:InsertIntoBuffer ( text, placement, indentation, flag_mode ) + " + " position the cursor + call s:PositionCursor ( placement, flag_mode, pos1, pos2 ) + " + " highlight jump targets + call s:HighlightJumpTargets ( regex.JumpTagBoth ) + endif + " + catch /Template:UserInputAborted/ + " noop + catch /Template:Check:.*/ + " + let templ = s:t_runtime.obj_stack[ -1 ] + let msg = v:exception[ len( 'Template:Check:') : -1 ] + call s:ErrorMsg ( 'Checking "'.templ.'":', msg ) + " + catch /Template:Prepare:.*/ + " + let templ = s:t_runtime.obj_stack[ -1 ] + let incld = len ( s:t_runtime.obj_stack ) == 1 ? '' : '(included by: "'.s:t_runtime.obj_stack[ -2 ].'")' + let msg = v:exception[ len( 'Template:Prepare:') : -1 ] + call s:ErrorMsg ( 'Preparing "'.templ.'":', incld, msg ) + " + catch /Template:Recursion/ + " + let templ = s:t_runtime.obj_stack[ -1 ] + let idx1 = index ( s:t_runtime.obj_stack, templ ) + let cont = idx1 == 0 ? [] : [ '...' ] + call call ( 's:ErrorMsg', [ 'Recursion detected while including the template/s:' ] + cont + + \ s:t_runtime.obj_stack[ idx1 : -1 ] ) + " + catch /Template:MacroRecursion/ + " + let macro = s:t_runtime.macro_stack[ -1 ] + let idx1 = index ( s:t_runtime.macro_stack, macro ) + let cont = idx1 == 0 ? [] : [ '...' ] + call call ( 's:ErrorMsg', [ 'Recursion detected while replacing the macro/s:' ] + cont + + \ s:t_runtime.macro_stack[ idx1 : -1 ] ) + " + catch /Template:Insert:.*/ + " + let msg = v:exception[ len( 'Template:Insert:') : -1 ] + call s:ErrorMsg ( 'Inserting "'.a:t_name.'":', msg ) + " + catch /Template:.*/ + " + let msg = v:exception[ len( 'Template:') : -1 ] + call s:ErrorMsg ( msg ) + " + finally + " + " ================================================== + " wrap up + " ================================================== + " + " restore the state: folding and formatter program + if &foldenable + exe "set foldmethod=".foldmethod_save + normal! zv + endif + let &equalprg = equalprg_save + " + unlet s:library " remove script variables + unlet s:t_runtime " ... + " + let s:DebugLevel = s:DebugGlobalOverwrite " reset debug + " + endtry + " +endfunction " ---------- end of function mmtemplates#core#InsertTemplate ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#CreateMaps : Create maps for a template library. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#CreateMaps ( library, localleader, ... ) + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + else + return s:ErrorMsg ( 'Argument "library" must be given as a string.' ) + endif + " + if type( a:localleader ) != type( '' ) + call s:ErrorMsg ( 'Argument "localleader" must be given as a string.' ) + return + elseif ! empty ( a:localleader ) + if exists ( 'g:maplocalleader' ) + let ll_save = g:maplocalleader + endif + let g:maplocalleader = a:localleader + endif + " + " ================================================== + " reuse previous commands + " ================================================== + " + if has_key ( t_lib, 'map_commands' ) + "let TimeStart = reltime() + exe t_lib.map_commands + if ! empty ( a:localleader ) + if exists ( 'll_save' ) + let g:maplocalleader = ll_save + else + unlet g:maplocalleader + endif + endif + "echo 'Executing maps: '.reltimestr( reltime( TimeStart ) ) + return + endif + " + " ================================================== + " setup + " ================================================== + " + " options + let options = '<buffer> <silent>' + let leader = '<LocalLeader>' + let sep = "\n" + " + let do_jump_map = 0 + let do_special_maps = 0 + " + let cmd = '' + " + " ================================================== + " options + " ================================================== + " + let i = 1 + while i <= a:0 + " + if a:[i] == 'do_jump_map' + let do_jump_map = 1 + let i += 1 + elseif a:[i] == 'do_special_maps' + let do_special_maps = 1 + let i += 1 + else + if type ( a:[i] ) == type ( '' ) | call s:ErrorMsg ( 'Unknown option: "'.a:[i].'"' ) + else | call s:ErrorMsg ( 'Unknown option at position '.i.'.' ) | endif + let i += 1 + endif + " + endwhile + " + "let TimeStart = reltime() + " + " ================================================== + " generate new commands + " ================================================== + " + if has_key ( g:CheckedFiletypes, &filetype ) + let echo_warning = 0 + else + let g:CheckedFiletypes[ &filetype ] = 1 + let echo_warning = g:Templates_MapInUseWarn != 0 + endif + " + " go through all the templates + for t_name in t_lib.menu_order + " + exe 'let [ visual, mp ] = ['.t_lib.templates[ t_name.'!!menu' ].'][0:1]' + " + " no map? + " separators have an empty string "map", so they are skipped here + if empty ( mp ) + continue + endif + " + for mode in [ 'n', 'v', 'i' ] + " + " map already existing? + if ! empty ( maparg( leader.mp, mode ) ) + if echo_warning + call s:ErrorMsg ( 'Mapping already in use: "'.leader.mp.'", mode "'.mode.'"' ) + endif + continue + endif + " + " insert and visual mode: insert '<Esc>' + if mode == 'n' | let esc = '' + else | let esc = '<Esc>' | endif + " + " insert mode, flag 'i': + " change behavior of templates with placement 'insert' + " visual mode, flag 'v': + " template contains a split tag, or the mode is forced + if mode == 'i' | let flag = ',"i"' + elseif mode == 'v' && visual == 1 | let flag = ',"v"' + else | let flag = '' | endif + " + " assemble the command to create the maps + let cmd .= mode.'noremap '.options.' '.leader.mp.' '.esc.':call mmtemplates#core#InsertTemplate('.a:library.',"'.t_name.'"'.flag.')<CR>'.sep + endfor + " + endfor + " + " jump map + if do_jump_map + let jump_key = '<C-j>' " TODO: configurable + if ! empty ( maparg( jump_key ) ) + if echo_warning + call s:ErrorMsg ( 'Mapping already in use: "'.jump_key.'"' ) + endif + else + let jump_regex = string ( escape ( t_lib.regex_template.JumpTagBoth, '|' ) ) + let cmd .= 'nnoremap '.options.' '.jump_key.' i<C-R>=mmtemplates#core#JumpToTag('.jump_regex.')<CR>'.sep + let cmd .= 'inoremap '.options.' '.jump_key.' <C-R>=mmtemplates#core#JumpToTag('.jump_regex.')<CR>'.sep + endif + endif + " + " special maps + " TODO: configuration of maps + " TODO: edit template + if do_special_maps + let special_maps = { + \ t_lib.properties[ 'Templates::EditTemplates::Map' ] : ':call mmtemplates#core#EditTemplateFiles('.a:library.',-1)<CR>', + \ t_lib.properties[ 'Templates::RereadTemplates::Map' ] : ':call mmtemplates#core#ReadTemplates('.a:library.',"reload","all")<CR>', + \ t_lib.properties[ 'Templates::ChooseStyle::Map' ] : ':call mmtemplates#core#ChooseStyle('.a:library.',"!pick")<CR>', + \ } + " + for [ mp, action ] in items ( special_maps ) + if ! empty ( maparg( leader.mp ) ) + if echo_warning + call s:ErrorMsg ( 'Mapping already in use: "'.leader.mp.'"' ) + endif + else + let cmd .= ' noremap '.options.' '.leader.mp.' '.action.sep + let cmd .= 'inoremap '.options.' '.leader.mp.' <Esc>'.action.sep + endif + endfor + endif + " + let t_lib.map_commands = cmd + exe cmd + " + " ================================================== + " wrap up + " ================================================== + " + if ! empty ( a:localleader ) + if exists ( 'll_save' ) + let g:maplocalleader = ll_save + else + unlet g:maplocalleader + endif + endif + " + "echo 'Generating maps: '.reltimestr( reltime( TimeStart ) ) + " +endfunction " ---------- end of function mmtemplates#core#CreateMaps ---------- +" +"---------------------------------------------------------------------- +" === Create Menus: Auxiliary Functions === {{{1 +"---------------------------------------------------------------------- +" +"---------------------------------------------------------------------- +" s:InsertShortcut : Insert a shortcut into a menu entry. {{{2 +" +" Inserts the shortcut by prefixing the appropriate character with '&', +" or by appending " (<shortcut>)". If escaped is true, the appended string is +" correctly escaped. +"---------------------------------------------------------------------- +" +function! s:InsertShortcut ( entry, shortcut, escaped ) + if empty ( a:shortcut ) + return a:entry + else + let entry = a:entry + let sc = a:shortcut + if stridx ( tolower( entry ), tolower( sc ) ) == -1 + if a:escaped | return entry.'\ (&'.sc.')' + else | return entry.' (&'.sc.')' + endif + else + return substitute( entry, '\V\c'.sc, '\&&', '' ) + endif + endif +endfunction " ---------- end of function s:InsertShortcut ---------- +" +"---------------------------------------------------------------------- +" s:CreateSubmenu : Create sub-menus, given they do not already exists. {{{2 +" +" The menu 'menu' can contain '&' and a trailing '.'. Both are ignored. +"---------------------------------------------------------------------- +" +function! s:CreateSubmenu ( t_lib, root_menu, global_name, menu, priority ) + " + " split point: + " a point, preceded by an even number of backslashes + " in turn, the backslashes must be preceded by a different character, or the + " beginning of the string + let level = len( split( a:root_menu, '\%(\_^\|[^\\]\)\%(\\\\\)*\zs\.' ) ) + let parts = split( a:menu, '\%(\_^\|[^\\]\)\%(\\\\\)*\zs\.' ) + let n_parts = len( parts ) + let level += n_parts + " + let priority_str = '' + " + " go through the menu, clean up and check for new menus + let submenu = '' + for i in range( 1, len( parts ) ) + " + let part = parts[ i-1 ] + " + if i == n_parts + let priority_str = repeat( '.', level-1 ).a:priority.'. ' + endif + " + let clean = substitute( part, '&', '', 'g' ) + if ! has_key ( a:t_lib.menu_existing, submenu.clean ) + " a new menu! + let a:t_lib.menu_existing[ submenu.clean ] = 0 + " + " shortcut and menu entry + if has_key ( a:t_lib.menu_shortcuts, submenu.clean ) + let shortcut = a:t_lib.menu_shortcuts[ submenu.clean ] + if stridx ( tolower( clean ), tolower( shortcut ) ) == -1 + let assemble = submenu.clean.' (&'.shortcut.')' + else + let assemble = submenu.substitute( clean, '\c'.shortcut, '\&&', '' ) + endif + else + let assemble = submenu.part + endif + " + let assemble .= '.' + " + if -1 != stridx ( clean, '<TAB>' ) + exe 'anoremenu '.priority_str.a:root_menu.escape( assemble.clean, ' ' ).' :echo "This is a menu header."<CR>' + else + exe 'anoremenu '.priority_str.a:root_menu.escape( assemble.clean, ' ' ).'<TAB>'.escape( a:global_name, ' .' ).' :echo "This is a menu header."<CR>' + endif + exe 'anoremenu '.a:root_menu.escape( assemble, ' ' ).'-TSep00- <Nop>' + endif + let submenu .= clean.'.' + endfor + " +endfunction " ---------- end of function s:CreateSubmenu ---------- +" +"---------------------------------------------------------------------- +" s:CreateTemplateMenus : Create menus for the templates. {{{2 +"---------------------------------------------------------------------- +" +function! s:CreateTemplateMenus ( t_lib, root_menu, global_name, t_lib_name ) + " + let map_ldr = mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::Mapleader' ], 'right' ) + " + " go through all the templates + for t_name in a:t_lib.menu_order + " + exe 'let [ visual, mp, entry, _, shortcut ] = ['.a:t_lib.templates[ t_name.'!!menu' ].']' + " + " no menu entry? + if entry == 0 + continue + endif + " + " get the sub-menu and the entry + let [ t_menu, t_last ] = matchlist ( t_name, '^\(.*\.\)\?\([^\.]\+\)$' )[1:2] + " + " menu does not exist? + if ! empty ( t_menu ) && ! has_key ( a:t_lib.menu_existing, t_menu[ 0 : -2 ] ) + call s:CreateSubmenu ( a:t_lib, a:root_menu, a:global_name, t_menu[ 0 : -2 ], s:StandardPriority ) + endif + " + if entry == 11 + let m_key = t_menu[ 0 : -2 ] + if empty ( m_key ) + let m_key = '!base' + endif + " + let sep_nr = a:t_lib.menu_existing[ m_key ] + 1 + let a:t_lib.menu_existing[ m_key ] = sep_nr + " + exe 'anoremenu '.a:root_menu.escape( t_menu, ' ' ).'-TSep'.sep_nr.'- :' + " + continue + endif + " + " shortcut and menu entry + if ! empty ( shortcut ) + if stridx ( tolower( t_last ), tolower( shortcut ) ) == -1 + let t_last .= ' (&'.shortcut.')' + else + let t_last = substitute( t_last, '\c'.shortcut, '\&&', '' ) + endif + endif + " + " assemble the entry, including the map, TODO: escape the map + let compl_entry = escape( t_menu.t_last, ' ' ) + if empty ( mp ) + let map_entry = '' + else + let map_entry = '<TAB>'.map_ldr.mp + end + " + if entry == 1 + " <Esc><Esc> prevents problems in insert mode + exe 'anoremenu <silent> '.a:root_menu.compl_entry.map_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'")<CR>' + exe 'inoremenu <silent> '.a:root_menu.compl_entry.map_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'","i")<CR>' + if visual == 1 + exe 'vnoremenu <silent> '.a:root_menu.compl_entry.map_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'","v")<CR>' + endif + elseif entry == 2 + call s:CreateSubmenu ( a:t_lib, a:root_menu, a:global_name, t_menu.t_last.map_entry, s:StandardPriority ) + " + for item in s:GetPickList ( t_name ) + let item_entry = compl_entry.'.'.substitute ( substitute ( escape ( item, ' .' ), '&', '\&\&', 'g' ), '\w', '\&&', '' ) + exe 'anoremenu <silent> '.a:root_menu.item_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'","pick",'.string(item).')<CR>' + exe 'inoremenu <silent> '.a:root_menu.item_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'","i","pick",'.string(item).')<CR>' + if visual == 1 + exe 'vnoremenu <silent> '.a:root_menu.item_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'","v","pick",'.string(item).')<CR>' + endif + endfor + " +" exe 'anoremenu '.a:root_menu.compl_entry.'.-\ choose\ -'.map_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'")<CR>' +" if visual == 1 +" exe 'vnoremenu '.a:root_menu.compl_entry.'.-\ choose\ -'.map_entry.' <Esc><Esc>:call mmtemplates#core#InsertTemplate('.a:t_lib_name.',"'.t_name.'","v")<CR>' +" endif + endif + " + endfor + " +endfunction " ---------- end of function s:CreateTemplateMenus ---------- +" +"---------------------------------------------------------------------- +" s:CreateSpecialsMenus : Create menus for a template library. {{{2 +"---------------------------------------------------------------------- +" +function! s:CreateSpecialsMenus ( t_lib, root_menu, global_name, t_lib_name, specials_menu, styles_only ) + " + " remove trailing point + let specials_menu = substitute( a:specials_menu, '\.$', '', '' ) + " + let map_ldr = mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::Mapleader' ], 'right' ) + let map_edit = map_ldr.mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::EditTemplates::Map' ], 'right' ) + let map_read = map_ldr.mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::RereadTemplates::Map' ], 'right' ) + let map_style = map_ldr.mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::ChooseStyle::Map' ], 'right' ) + let sc_edit = mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::EditTemplates::Shortcut' ], 'right' ) + let sc_read = mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::RereadTemplates::Shortcut' ], 'right' ) + let sc_style = mmtemplates#core#EscapeMenu ( a:t_lib.properties[ 'Templates::ChooseStyle::Shortcut' ], 'right' ) + " + " create the specials menu + call s:CreateSubmenu ( a:t_lib, a:root_menu, a:global_name, specials_menu, s:StandardPriority ) + " + if ! a:styles_only + " create edit and reread templates + let entry_edit = s:InsertShortcut ( '.edit\ templates', sc_edit, 1 ).'<TAB>'.map_edit + let entry_read = s:InsertShortcut ( '.reread\ templates', sc_read, 1 ).'<TAB>'.map_read + exe 'anoremenu <silent> '.a:root_menu.specials_menu.entry_edit + \ .' :call mmtemplates#core#EditTemplateFiles('.a:t_lib_name.',-1)<CR>' + exe 'anoremenu <silent> '.a:root_menu.specials_menu.entry_read + \ .' :call mmtemplates#core#ReadTemplates('.a:t_lib_name.',"reload","all")<CR>' + endif + " + " create a menu for all the styles + if sc_style == 's' | let entry_styles = '.choose &style<TAB>'.map_style + else | let entry_styles = s:InsertShortcut ( '.choose style', sc_style, 0 ).'<TAB>'.map_style + endif + call s:CreateSubmenu ( a:t_lib, a:root_menu, a:global_name, specials_menu.entry_styles, s:StandardPriority ) + " + for s in a:t_lib.styles + exe 'anoremenu <silent> '.a:root_menu.specials_menu.'.choose\ style.&'.s + \ .' :call mmtemplates#core#ChooseStyle('.a:t_lib_name.','.string(s).')<CR>' + endfor + " +endfunction " ---------- end of function s:CreateSpecialsMenus ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#CreateMenus : Create menus for a template library. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#CreateMenus ( library, root_menu, ... ) + " + " check for feature + if ! has ( 'menu' ) + return + endif + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + let s:library = t_lib + else + call s:ErrorMsg ( 'Argument "library" must be given as a string.' ) + return + endif + " + if type( a:root_menu ) != type( '' ) + call s:ErrorMsg ( 'Argument "root_menu" must be given as a string.' ) + return + endif + " + " ================================================== + " setup + " ================================================== + " + " options + let root_menu = substitute( a:root_menu, '&', '', 'g' ) + let global_name = substitute( root_menu, '\.$', '', '' ) + let root_menu = global_name.'.' + let specials_menu = '&Run' + let priority = s:StandardPriority + let existing = [] + " + " jobs + let do_reset = 0 + let do_templates = 0 + let do_specials = 0 " no specials + let submenus = [] + " + " ================================================== + " options + " ================================================== + " + let i = 1 + while i <= a:0 + " + if a:[i] == 'global_name' && i+1 <= a:0 + let global_name = a:[i+1] + let i += 2 + elseif a:[i] == 'existing_menu' && i+1 <= a:0 + if type ( a:[i+1] ) == type ( '' ) | call add ( existing, a:[i+1] ) + else | call extend ( existing, a:[i+1] ) | endif + let i += 2 + elseif a:[i] == 'sub_menu' && i+1 <= a:0 + if type ( a:[i+1] ) == type ( '' ) | call add ( submenus, a:[i+1] ) + else | call extend ( submenus, a:[i+1] ) | endif + let i += 2 + elseif a:[i] == 'specials_menu' && i+1 <= a:0 + let specials_menu = a:[i+1] + let i += 2 + elseif a:[i] == 'priority' && i+1 <= a:0 + let priority = a:[i+1] + let i += 2 + elseif a:[i] == 'do_all' + let do_reset = 1 + let do_templates = 1 + let do_specials = 1 + let i += 1 + elseif a:[i] == 'do_reset' + let do_reset = 1 + let i += 1 + elseif a:[i] == 'do_templates' + let do_templates = 1 + let i += 1 + elseif a:[i] == 'do_specials' + let do_specials = 1 + let i += 1 + elseif a:[i] == 'do_styles' + let do_specials = 2 + let i += 1 + else + if type ( a:[i] ) == type ( '' ) | call s:ErrorMsg ( 'Unknown option: "'.a:[i].'"' ) + else | call s:ErrorMsg ( 'Unknown option at position '.i.'.' ) | endif + let i += 1 + endif + " + endwhile + " + " ================================================== + " do the jobs + " ================================================== + " + " reset + if do_reset + let t_lib.menu_existing = { '!base' : 0 } + endif + " + " existing menus + for name in existing + let name = substitute( name, '&', '', 'g' ) + let name = substitute( name, '\.$', '', '' ) + let t_lib.menu_existing[ name ] = 0 + endfor + " + " sub-menus + for name in submenus + call s:CreateSubmenu ( t_lib, root_menu, global_name, name, priority ) + endfor + " + " templates + if do_templates + call s:CreateTemplateMenus ( t_lib, root_menu, global_name, a:library ) + endif + " + " specials + if do_specials == 1 + " all specials + call s:CreateSpecialsMenus ( t_lib, root_menu, global_name, a:library, specials_menu, 0 ) + elseif do_specials == 2 + " styles only + call s:CreateSpecialsMenus ( t_lib, root_menu, global_name, a:library, specials_menu, 1 ) + endif + " + " ================================================== + " wrap up + " ================================================== + " + unlet s:library " remove script variable + " +endfunction " ---------- end of function mmtemplates#core#CreateMenus ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#EscapeMenu : Escape a string so it can be used as a menu item. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#EscapeMenu ( str, ... ) + " + let mode = 'entry' + " + if a:0 > 0 + if type( a:1 ) != type( '' ) + return s:ErrorMsg ( 'Argument "mode" must be given as a string.' ) + elseif a:1 == 'menu' + let mode = 'menu' + elseif a:1 == 'entry' + let mode = 'entry' + elseif a:1 == 'right' + let mode = 'right' + else + return s:ErrorMsg ( 'Unknown mode: '.a:1 ) + endif + endif + " + " whole menu: do not escape '.' + if mode == 'menu' + let str = escape ( a:str, ' \|' ) + else + let str = escape ( a:str, ' \|.' ) + endif + " + " right-aligned text: do not escape '&' + if mode != 'right' + let str = substitute ( str, '&', '\&\&', 'g' ) + endif + " + return str + " +endfunction " ---------- end of function mmtemplates#core#EscapeMenu ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#ChooseStyle : Choose a style. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#ChooseStyle ( library, style ) + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + call s:ErrorMsg ( 'Argument "library" must be given as a dict or string.' ) + return + endif + " + if type( a:style ) != type( '' ) + call s:ErrorMsg ( 'Argument "style" must be given as a string.' ) + return + endif + " + " ================================================== + " change the style + " ================================================== + " + " pick the style + if a:style == '!pick' + try + let style = s:UserInput( 'Style (currently '.t_lib.current_style.') : ', '', + \ 'customlist', t_lib.styles ) + catch /Template:UserInputAborted/ + return + endtry + else + let style = a:style + endif + " + " check and set the new style + if style == '' + " noop + elseif -1 != index ( t_lib.styles, style ) + if t_lib.current_style != style + let t_lib.current_style = style + echo 'Changed style to "'.style.'".' + elseif a:style == '!pick' + echo 'Style stayed "'.style.'".' + endif + else + call s:ErrorMsg ( 'Style was not changed. Style "'.style.'" is not available.' ) + end + " +endfunction " ---------- end of function mmtemplates#core#ChooseStyle ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#Resource : Access to various resources. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#Resource ( library, mode, ... ) + " + " TODO mode 'special' for |DATE|, |TIME| and |year| + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + return [ '', 'Argument "library" must be given as a dict or string.' ] + endif + " + if type( a:mode ) != type( '' ) + return [ '', 'Argument "mode" must be given as a string.' ] + endif + " + " ================================================== + " special inquiries + " ================================================== + " + if a:mode == 'add' || a:mode == 'get' || a:mode == 'set' + " continue below + elseif a:mode == 'escaped_mapleader' + return [ mmtemplates#core#EscapeMenu( t_lib.properties[ 'Templates::Mapleader' ], 'right' ), '' ] + elseif a:mode == 'jumptag' + return [ t_lib.regex_template.JumpTagBoth, '' ] + elseif a:mode == 'style' + return [ t_lib.current_style, '' ] + else + return [ '', 'Mode "'.a:mode.'" is unknown.' ] + endif + " + " ================================================== + " options + " ================================================== + " + " type of 'resource' + let types = { 'list' : '[ld]', 'macro' : 's', 'path' : 's', 'property' : 's' } + " + if a:mode == 'add' && a:0 != 3 + return [ '', 'Mode "add" requires three additional arguments.' ] + elseif a:mode == 'get' && a:0 != 2 + return [ '', 'Mode "get" requires two additional arguments.' ] + elseif a:mode == 'set' && a:0 != 3 + return [ '', 'Mode "set" requires three additional arguments.' ] + elseif type( a:1 ) != type( '' ) + return [ '', 'Argument "resource" must be given as a string.' ] + elseif type( a:2 ) != type( '' ) + return [ '', 'Argument "key" must be given as a string.' ] + elseif ! has_key ( types, a:1 ) + return [ '', 'Resource "'.a:1.'" does not exist.' ] + elseif a:mode == 'add' && a:1 != 'property' + return [ '', 'Can not execute add for resource of type "'.a:1.'".' ] + endif + " + " ================================================== + " add, get or set + " ================================================== + " + let resource = a:1 + let key = a:2 + " + if a:mode == 'add' + " + let value = a:3 + " + " add (property only) + if type( value ) != type( '' ) + return [ '', 'Argument "value" must be given as a string.' ] + else + let t_lib.properties[ key ] = value + return [ '', '' ] + endif + " + return [ '', '' ] + elseif a:mode == 'get' + " + " get + if resource == 'list' + return [ get( t_lib.resources, 'list!'.key ), '' ] + elseif resource == 'macro' + return [ get( t_lib.macros, key ), '' ] + elseif resource == 'path' + return [ get( t_lib.resources, 'path!'.key ), '' ] + elseif resource == 'property' + if has_key ( t_lib.properties, key ) + return [ t_lib.properties[ key ], '' ] + else + return [ '', 'Property "'.key.'" does not exist.' ] + endif + endif + " + elseif a:mode == 'set' + " + let value = a:3 + " + " check type and set + if s:TypeNames[ type( value ) ] !~ types[ resource ] + return [ '', 'Argument "value" has the wrong type.' ] + elseif resource == 'list' + let t_lib.resources[ 'list!'.key ] = value + elseif resource == 'macro' + let t_lib.macros[ key ] = value + elseif resource == 'path' + let t_lib.resources[ 'path!'.key ] = value + elseif resource == 'property' + if has_key ( t_lib.properties, key ) + let t_lib.properties[ key ] = value + return [ '', '' ] + else + return [ '', 'Property "'.key.'" does not exist.' ] + endif + endif + " + return [ '', '' ] + endif + " +endfunction " ---------- end of function mmtemplates#core#Resource ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#ChangeSyntax : Change the syntax of the templates. {{{1 +"------------------------------------------------------------------------------- +" +function! mmtemplates#core#ChangeSyntax ( library, category, ... ) + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + return s:ErrorMsg ( 'Argument "library" must be given as a dict or string.' ) + endif + " + if type( a:category ) != type( '' ) + return s:ErrorMsg ( 'Argument "category" must be given as an integer or string.' ) + endif + " + " ================================================== + " set the syntax + " ================================================== + " + if a:category == 'comment' + " + if a:0 < 1 + return s:ErrorMsg ( 'Not enough arguments for '.a:category.'.' ) + elseif a:0 == 1 + let t_lib.regex_settings.CommentStart = a:1 + let t_lib.regex_settings.CommentHint = a:1[0] + elseif a:0 == 2 + let t_lib.regex_settings.CommentStart = a:1 + let t_lib.regex_settings.CommentHint = a:2[0] + endif + " + call s:UpdateFileReadRegex ( t_lib.regex_file, t_lib.regex_settings ) + " + else + return s:ErrorMsg ( 'Unknown category: '.a:category ) + endif + " +endfunction " ---------- end of function mmtemplates#core#ChangeSyntax ---------- +" +"------------------------------------------------------------------------------- +" mmtemplates#core#ExpandText : Expand the macros in a text. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#ExpandText ( library, text ) + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + return s:ErrorMsg ( 'Argument "library" must be given as a dict or string.' ) + endif + " + if type( a:text ) != type( '' ) + return s:ErrorMsg ( 'Argument "text" must be given as a string.' ) + endif + " + " ================================================== + " setup + " ================================================== + " + " library and runtime information + let s:library = t_lib + let s:t_runtime = { + \ 'macro_stack' : [], + \ } + " + " renew the predefined macros + let m_local = {} + let m_local[ 'BASENAME' ] = expand( '%:t:r' ) + let m_local[ 'FILENAME' ] = expand( '%:t' ) + let m_local[ 'PATH' ] = expand( '%:p:h' ) + let m_local[ 'SUFFIX' ] = expand( '%:e' ) + " + let m_local[ 'DATE' ] = strftime( t_lib.macros[ 'DATE' ] ) + let m_local[ 'TIME' ] = strftime( t_lib.macros[ 'TIME' ] ) + let m_local[ 'YEAR' ] = strftime( t_lib.macros[ 'YEAR' ] ) + " + " ================================================== + " do the job + " ================================================== + " + let res = '' + " + try + " + let res = s:ReplaceMacros ( a:text, m_local ) + " + catch /Template:MacroRecursion/ + " + let macro = s:t_runtime.macro_stack[ -1 ] + let idx1 = index ( s:t_runtime.macro_stack, macro ) + let cont = idx1 == 0 ? [] : [ '...' ] + call call ( 's:ErrorMsg', [ 'Recursion detected while replacing the macro/s:' ] + cont + + \ s:t_runtime.macro_stack[ idx1 : -1 ] ) + " + catch /Template:.*/ + " + let msg = v:exception[ len( 'Template:') : -1 ] + call s:ErrorMsg ( msg ) + " + finally + " + " ================================================== + " wrap up + " ================================================== + " + unlet s:library " remove script variables + unlet s:t_runtime " ... + " + endtry + " + return res + " +endfunction " ---------- end of function mmtemplates#core#ExpandText ---------- +" +"------------------------------------------------------------------------------- +" mmtemplates#core#EditTemplateFiles : Choose and edit a template file. {{{1 +"------------------------------------------------------------------------------- +" +function! mmtemplates#core#EditTemplateFiles ( library, file ) + " + " ================================================== + " parameters + " ================================================== + " + if type( a:library ) == type( '' ) + exe 'let t_lib = '.a:library + elseif type( a:library ) == type( {} ) + let t_lib = a:library + else + return s:ErrorMsg ( 'Argument "library" must be given as a dict or string.' ) + endif + " + if type( a:file ) == type( 0 ) + if get( t_lib.library_files, a:file, '' ) == '' + return s:ErrorMsg ( 'No template file with index '.a:file.'.' ) + endif + let file = t_lib.library_files[ a:file ] + elseif type( a:file ) == type( '' ) + " + let file = expand ( a:file ) + let file = s:ConcatNormalizedFilename ( file ) + " + if ! filereadable ( file ) + return s:ErrorMsg ( 'The file "'.file.'" does not exist.' ) + elseif index ( t_lib.library_files, file ) == -1 + return s:ErrorMsg ( 'The file "'.file.'" is not part of the template library.' ) + endif + " + else + return s:ErrorMsg ( 'Argument "file" must be given as an integer or string.' ) + endif + " + " ================================================== + " do the job + " ================================================== + " + " get the directory + let dir = fnamemodify ( file, ':h' ) + " + " TODO: method configurable + let method = 'explore' + let templatefile = '' + " + if ! filereadable ( file ) + return s:ErrorMsg ( 'The directory "'.dir.'" does not exist.' ) + elseif method == 'explore' + " open a file explorer + if ! exists ( 'g:loaded_netrwPlugin' ) | return s:ErrorMsg ( 'The plugin "netrw" is not available.' ) | endif + exe 'update! | split | Explore '.dir + elseif method == 'browse' + " open a file browser + if ! has ( 'browse' ) | return s:ErrorMsg ( 'The command "browse" is not available.' ) | endif + let templatefile = browse ( 0, 'edit a template file', dir, '' ) + " returns an empty string if "Cancel" is pressed + endif + " + " open a buffer and start editing + if ! empty ( templatefile ) + exe 'update! | split | edit '.templatefile + endif + " +endfunction " ---------- end of function mmtemplates#core#EditTemplateFiles ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#JumpToTag : Jump to the next tag. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#JumpToTag ( regex ) + " + let match = search( '\m'.a:regex, 'c' ) + if match > 0 + " remove the target + call setline( match, substitute( getline('.'), a:regex, '', '' ) ) + endif + " + return '' +endfunction " ---------- end of function mmtemplates#core#JumpToTag ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#SetMapleader : Set the local mapleader. {{{1 +"---------------------------------------------------------------------- +" +" list of lists: [ "<localleader>", "<globalleader>" ] +let s:mapleader_stack = [] +" +function! mmtemplates#core#SetMapleader ( localleader ) + " + if empty ( a:localleader ) + call add ( s:mapleader_stack, [] ) + else + if exists ( 'g:maplocalleader' ) + call add ( s:mapleader_stack, [ a:localleader, g:maplocalleader ] ) + else + call add ( s:mapleader_stack, [ a:localleader ] ) + endif + let g:maplocalleader = a:localleader + endif + " +endfunction " ---------- end of function mmtemplates#core#SetMapleader ---------- +" +"---------------------------------------------------------------------- +" mmtemplates#core#ResetMapleader : Reset the local mapleader. {{{1 +"---------------------------------------------------------------------- +" +function! mmtemplates#core#ResetMapleader () + " + let ll_save = remove ( s:mapleader_stack, -1 ) + " + if ! empty ( ll_save ) + if len ( ll_save ) > 1 + let g:maplocalleader = ll_save[1] + else + unlet g:maplocalleader + endif + endif + " +endfunction " ---------- end of function mmtemplates#core#ResetMapleader ---------- +" +" }}}1 +" +" ===================================================================================== +" vim: foldmethod=marker diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/README.bashsupport b/.config/nvim/plugged/bash-support.vim/bash-support/README.bashsupport new file mode 100644 index 0000000..db0c00a --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/README.bashsupport @@ -0,0 +1,193 @@ +README for bash-support.vim (Version 4.2.1) / March 25 2014 + + * INSTALLATION + * RELEASE NOTES + * FILES + * ADDITIONAL TIPS + +Bash Support implements a bash-IDE for Vim/gVim. It is written to considerably +speed up writing code in a consistent style. This is done by inserting +complete statements, comments, idioms, and code snippets. Syntax checking, +running a script, starting a debugger can be done with a keystroke. There are +many additional hints and options which can improve speed and comfort when +writing shell scripts. + +================================================================================ + INSTALLATION +================================================================================ + +(1) LINUX +---------- + +The subdirectories in the zip archive bash-support.zip mirror the directory +structure which is needed below the local installation directory $HOME/.vim/ +(find the value of $HOME with ":echo $HOME" from inside Vim). + +(1.0) Save the template files in '$HOME/.vim/bash-support/templates/Templates' if + you have changed any of them. + +(1.1) Copy the zip archive bash-support.zip to $HOME/.vim and run + + unzip bash-support.zip + +(1.2) Loading of plugin files must be enabled. If not use + + :filetype plugin on + + This is the minimal content of the file '$HOME/.vimrc'. Create one if there + is none or use the files in $HOME/.vim/bash-support/rc as a starting point. + +(1.3) Set at least some personal details in the file + '$HOME/.vim/bash-support/templates/Templates' + Here is the minimal personalization (my settings as an example): + + SetMacro( 'AUTHOR', 'Dr. Fritz Mehner' ) + SetMacro( 'AUTHORREF', 'fgm' ) + SetMacro( 'EMAIL', 'mehner.fritz@fh-swf.de' ) + SetMacro( 'ORGANIZATION','FH Südwestfalen, Iserlohn' ) + SetMacro( 'COPYRIGHT', 'Copyright (c) |YEAR|, |AUTHOR|' ) + + (Read more about the template system in the plugin documentation) + +(1.4) Make the plugin help accessable by typing the following command on the + Vim command line: + + :helptags $HOME/.vim/doc/ + +(1.5) Consider additional settings in the file '$HOME/.vimrc'. The files + customization.vimrc and customization.gvimrc are replacements or extensions + for your .vimrc and .gvimrc. You may want to use parts of them. The files + are documented. + + +(2) WINDOWS +------------ + +The subdirectories in the zip archive bash-support.zip mirror the directory +structure which is needed below the local installation directory +$HOME/vimfiles/ (find the value of $HOME with ":echo $HOME" from inside Vim). + +(2.0) Save the template files in '$HOME/vimfiles/bash-support/templates/Templates' + if you have changed any of them. + +(2.1) Copy the zip archive bash-support.zip to $HOME/vimfiles and run + + unzip bash-support.zip + +(2.2) Loading of plugin files must be enabled. If not use + + :filetype plugin on + + This is the minimal content of the file '$HOME/_vimrc'. Create one if there + is none or use the files in $HOME/vimfiles/bash-support/rc as a starting point. + +(2.3) Set at least some personal details in the file + '$HOME/vimfiles/bash-support/templates/Templates' + Here is the minimal personalization (my settings as an example): + + SetMacro( 'AUTHOR', 'Dr. Fritz Mehner' ) + SetMacro( 'AUTHORREF', 'fgm' ) + SetMacro( 'EMAIL', 'mehner.fritz@fh-swf.de' ) + SetMacro( 'ORGANIZATION','FH Südwestfalen, Iserlohn' ) + SetMacro( 'COPYRIGHT', 'Copyright (c) |YEAR|, |AUTHOR|' ) + + (Read more about the template system in the plugin documentation) + +(2.4) Make the plugin help accessable by typing the following command on the + Vim command line: + + :helptags $HOME\vimfiles\doc\ + +(2.5) Consider additional settings in the file '$HOME/_vimrc'. The files + customization.vimrc and customization.gvimrc are replacements or extensions + for your _vimrc and _gvimrc. You may want to use parts of them. The files + are documented. + +There are a lot of features and options which can be used and influenced: + + * use of template files and tags + * using and managing personal code snippets + * bash dictionary for keyword completion + * removing the root menu + * using additional plugins + +Look at the bashsupport help with + + :help bashsupport + + +-----------------------------------------------+ + | +-------------------------------------------+ | + | | ** Please read the documentation ** | | + | | Actions differ for different modes! | | + | +-------------------------------------------+ | + +-----------------------------------------------+ + +======================================================================================= + RELEASE NOTES FOR VERSION 4.2.1 +======================================================================================= +- Bugfix: Setup of local templates in case of global installation. +- Help: Bash and utility manuals wrapped on window width. +- Bugfix: \hm and \hh work wrong in insert mode. +- Bugfix: Better compatibility with custom mappings + (use "normal!" and "noremap" consistently). +- Added 'Bash_SetMapLeader' and 'Bash_ResetMapLeader'. +- Minor corrections and improvements. + + OLDER RELEASE NOTES : see file 'ChangeLog' +======================================================================================= + +======================================================================================= + FILES +======================================================================================= + +README.bashsupport This file. + +ftplugin/sh.vim The bash filetype plugin. +plugin/bash-support.vim The bash plugin for Vim/gVim. +bash-support/scripts/wrapper.sh A wrapper script for the use of an xterm. + +doc/bashsupport.txt The help file for the local online help. + +bash-support/codesnippets/* Some code snippets as a starting point. + +bash-support/templates/* bash template files (see bashsupport.txt). + +bash-support/wordlists/* Additional word lists (dictionaries). + +----------------------- ------------------------------------------------------------- +----------------------- The following files and extensions are for convenience only. + bash-support.vim will work without them. + ------------------------------------------------------------- + +bash-support/rc/customization.bashrc Additional settings I use in .bashrc: + set the prompt P2, P3, P4 (for debugging). + +bash-support/rc/customization.vimrc Additional settings I use in .vimrc: incremental + search, tabstop, hot keys, font, use of dictionaries, + ... The file is commented. Append it to your .vimrc + if you like. + +bash-support/rc/customization.gvimrc Additional settings I use in .gvimrc: hot keys, + mouse settings, ... The file is commented. + Append it to your .gvimrc if you like. + +bash-support/doc/* Hotkey reference card (PDF), changelog. + + +======================================================================================= + ADDITIONAL TIPS +======================================================================================= + +(1) gvim. Toggle 'insert mode' <--> 'normal mode' with the right mouse button + (see mapping in file customization.gvimrc). + +(2) gvim. Use tear off menus and + +(3) try 'Focus under mouse' as window behavior (No mouse click when the mouse + pointer is back from the menu entry). + +(4) Use Emulate3Buttons "on" (X11) even for a 3-button mouse. Pressing left and + right button simultaneously without moving your fingers is faster then + moving a finger to the middle button (often a wheel). + +======================================================================================= diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_DEBUG b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_DEBUG new file mode 100644 index 0000000..e8fa284 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_DEBUG @@ -0,0 +1,21 @@ +#=== FUNCTION ================================================================ +# NAME: _trap_DEBUG +# DESCRIPTION: Trap code for the pseudo-signal DEBUG. Generate a message. +# The DEBUG trap is not inherited by functions. +# Use 'set -o functrace' +# PARAMETERS: 1) identification (e.g. line number $LINENO) +# 2) variable name(s) to be tracked +#=============================================================================== +function _trap_DEBUG () +{ + declare identification=$1; + while [ ${#} -gt 1 ]; do + shift + echo -e "DEBUG [$identification] ${1} = '${!1}'" + done +} # ---------- end of function _trap_DEBUG ---------- + +trap '_trap_DEBUG $LINENO <-variable names->' DEBUG # trap DEBUG + +#trap - DEBUG # reset the DEBUG trap + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_ERR b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_ERR new file mode 100644 index 0000000..b747463 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_ERR @@ -0,0 +1,15 @@ +#=== FUNCTION ================================================================ +# NAME: _trap_ERROR +# DESCRIPTION: Trap code for the pseudo-signal ERR (A command returning a +# non-zero exit status). Generates an error message. +# PARAMETERS: The current line number given by $LINENO . +#=============================================================================== +function _trap_ERROR () +{ + echo -e "\nERROR line ${1}: Command exited with status ${?}" +} # ---------- end of function _trap_ERROR ---------- + +trap '_trap_ERROR $LINENO' ERR # trap ERR + +#trap - ERR # reset the ERR trap + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_EXIT b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_EXIT new file mode 100644 index 0000000..bfbab3a --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_EXIT @@ -0,0 +1,14 @@ +#=== FUNCTION ================================================================ +# NAME: _trap_EXIT +# DESCRIPTION: Trap code for the pseudo-signal EXIT. Generates an message. +# PARAMETERS: The current line number given by $LINENO . +#=============================================================================== +function _trap_EXIT () +{ + echo -e "\nEXIT line ${1}: Script exited with status ${?}" +} # ---------- end of function ---------- + +trap '_trap_EXIT $LINENO' EXIT # trap EXIT + +#trap - EXIT # reset the EXIT trap + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_RETURN b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_RETURN new file mode 100644 index 0000000..19b494e --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/_trap_RETURN @@ -0,0 +1,17 @@ +#=== FUNCTION ================================================================ +# NAME: _trap_RETURN +# DESCRIPTION: Trap code for the pseudo-signal RETURN. Generates a message. +# The RETURN trap is not inherited by functions. +# Use 'set -o functrace' +# PARAMETERS: The current line number given by $LINENO . +# variable(s) to be tracked +#=============================================================================== +function _trap_RETURN () +{ + echo -e "\nRETURN line ${1}: " +} # ---------- end of functionn _trap_RETURN ---------- + +trap '_trap_RETURN $LINENO' RETURN # trap RETURN + +#trap - RETURN # reset the RETURN trap + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/basename+pathname b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/basename+pathname new file mode 100644 index 0000000..d1bbc6d --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/basename+pathname @@ -0,0 +1,5 @@ +basename=${pathname##*/} +dirname=${pathname%/*} +filename=${basename%%.*} +lastextension=${basename##*.} +allextensions=${basename#*.} diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-signed-integer b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-signed-integer new file mode 100644 index 0000000..8921d70 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-signed-integer @@ -0,0 +1,3 @@ +if [[ $number =~ ^[+-]?[0-9]+$ ]] ; then + echo -e "match found : (signed) integer\n" +fi diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-unsigned-integer b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-unsigned-integer new file mode 100644 index 0000000..98a0e79 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-for-unsigned-integer @@ -0,0 +1,3 @@ +if [[ $number =~ ^[0-9]+$ ]] ; then + echo -e "match found : integer\n" +fi diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-number-of-command-line-arguments b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-number-of-command-line-arguments new file mode 100644 index 0000000..1db75cf --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/check-number-of-command-line-arguments @@ -0,0 +1,5 @@ +#----------------------------------------------------------------------- +# Check number of command line arguments +#----------------------------------------------------------------------- +[ $# -lt 1 ] && { echo -e "\n\tUsage: ${0##/*/} File\n"; exit 1; } + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile new file mode 100644 index 0000000..26e50a5 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile @@ -0,0 +1,3 @@ +TMPFILE=$( mktemp /tmp/example.XXXXXXXXXX ) || exit 1 + +rm --force $TMPFILE diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-in-secure-manner b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-in-secure-manner new file mode 100644 index 0000000..880b30d --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-in-secure-manner @@ -0,0 +1,17 @@ + +TMPDIR=${TMPDIR:-/tmp} # defaults to /tmp if unset + +#------------------------------------------------------------------------------- +# Creates a particular temporary directory inside $TMPDIR. +#------------------------------------------------------------------------------- +TEMPORARY_DIR=$(mktemp -d "$TMPDIR/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") || \ + { echo "ERROR creating a temporary file"; exit 1; } + +#------------------------------------------------------------------------------- +# When the program exits, it tries to remove the temporary folder. +# This code is executed even if the process receives a signal 1,2,3 or 15. +#------------------------------------------------------------------------------- +trap '[ "$TEMPORARY_DIR" ] && rm --recursive --force "$TEMPORARY_DIR"' 0 + +touch $TEMPORARY_DIR/tempfile # new tempfile inside folder + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-with-trap b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-with-trap new file mode 100644 index 0000000..0f81867 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/create-tempfile-with-trap @@ -0,0 +1,19 @@ + +#----------------------------------------------------------------------- +# cleanup temporary file in case of a keyboard interrupt (SIGINT) +# or a termination signal (SIGTERM) +#----------------------------------------------------------------------- +function cleanup_temp +{ + [ -e $tmpfile ] && rm --force $tmpfile + exit 0 +} + +trap cleanup_temp SIGHUP SIGINT SIGPIPE SIGTERM + +tmpfile=$(mktemp) || { echo "$0: creation of temporary file failed!"; exit 1; } + +# use tmpfile ... + +rm --force $tmpfile + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_PS4 b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_PS4 new file mode 100644 index 0000000..fbf5c57 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_PS4 @@ -0,0 +1,22 @@ +# PS4 : timestamp; the current time in 24-hour HH:MM:SS format +PS4='+[\t] ' + +# PS4 : timestamp; 'seconds.nanoseconds' since 1970-01-01 00:00:00 UT +PS4='+[$(date "+%s.%N")] ' + +# PS4 : position, line number, function name +# The following line avoids error messages due to an unset FUNCNAME[0] : +# set +o nounset # Treat unset variables as an error +# +PS4='+|${BASH_SOURCE##*/} ${LINENO}${FUNCNAME[0]:+ ${FUNCNAME[0]}}| ' + +# PS4 : position, line number, function name, subshell information +# The following line avoids error messages due to an unset FUNCNAME[0] : +# set +o nounset # Treat unset variables as an error +# +PS4='+(${BASH_SOURCE##*/}: ${LINENO}) : ${FUNCNAME[0]} - [level ${SHLVL}, ' +PS4=$PS4'subshell ${BASH_SUBSHELL}, return code $?]\n ' + +# PS4 : default prompt +PS4='+ ' + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_assert b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_assert new file mode 100644 index 0000000..e5a4618 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_assert @@ -0,0 +1,16 @@ +#=== FUNCTION ================================================================ +# NAME: _assert +# DESCRIPTION: Abort the script if assertion is false. +# PARAMETERS: 1) expression used as test inside brackets +# 2) optional information, e.g. $LINENO +# RETURNS: 0 / 99 assertion is true / false +#=============================================================================== +function _assert () +{ + if [ ! $1 ]; then + echo "${0##*/}${2:+:$2}: assertion '$1' failed." + exit 99 + fi + return 0 +} + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_function.noindent b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_function.noindent new file mode 100644 index 0000000..1a8281f --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_function.noindent @@ -0,0 +1,15 @@ + +DEBUG=${DEBUG:-0} # 0 = no debug output, 1 = show debug output, + # or enable debug with: DEBUG=1 script.sh + +#=== FUNCTION ================================================================ +# NAME: _debug +# DESCRIPTION: echo debug output controlled by a global variable +# PARAMETERS: list, e.g.; "$LINENO: x=$x" +# RETURNS: always 0 +#=============================================================================== +_debug () +{ + [ ${DEBUG} -ne 0 ] && echo -e "${@}" + return 0 +} # ---------- end of function _debug ---------- diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_print_pos_param b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_print_pos_param new file mode 100644 index 0000000..2b4114a --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_print_pos_param @@ -0,0 +1,3 @@ +# print the positional parameters +printf "'%b'\n" "$0" "$@" | nl -v0 -s': ' + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_timestamp.noindent b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_timestamp.noindent new file mode 100644 index 0000000..01ce833 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/debugging/_debug_timestamp.noindent @@ -0,0 +1,16 @@ + +DEBUG=${DEBUG:-0} # 0 = no debug output, 1 = show debug output, + # or enable debug with: DEBUG=1 script.sh + +#=== FUNCTION ================================================================ +# NAME: _debug_timestamp +# DESCRIPTION: timestamp + optional information +# timestamp: {seconds since 1970-01-01 00:00:00}.{nanoseconds} +# PARAMETERS: identification, e.g. $LINENO (optional) +# RETURNS: always 0 +#=============================================================================== +_debug_timestamp () +{ + [ ${DEBUG} -ne 0 ] && echo -e "[ $(date "+%s.%N") ]${@:+ -- ${@}}" + return 0 +} # ---------- end of function _debug_timestamp ---------- diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/free-software-comment b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/free-software-comment new file mode 100644 index 0000000..98c752d --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/free-software-comment @@ -0,0 +1,8 @@ +# +#========================================================================== +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +#========================================================================== +# diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/timestamp b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/timestamp new file mode 100644 index 0000000..fe89064 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/timestamp @@ -0,0 +1,3 @@ + +timestamp=$(date +"%Y%m%d-%H%M%S") # generate timestamp : YYYYMMDD-hhmmss + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/usage-and-command-line-arguments.noindent b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/usage-and-command-line-arguments.noindent new file mode 100644 index 0000000..519debc --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/usage-and-command-line-arguments.noindent @@ -0,0 +1,39 @@ + +ScriptVersion="1.0" + +#=== FUNCTION ================================================================ +# NAME: usage +# DESCRIPTION: Display usage information. +#=============================================================================== +function usage () +{ + cat <<- EOT + + Usage : ${0##/*/} [options] [--] + + Options: + -h|help Display this message + -v|version Display script version + + EOT +} # ---------- end of function usage ---------- + +#----------------------------------------------------------------------- +# Handle command line arguments +#----------------------------------------------------------------------- + +while getopts ":hv" opt +do + case $opt in + + h|help ) usage; exit 0 ;; + + v|version ) echo "$0 -- Version $ScriptVersion"; exit 0 ;; + + \? ) echo -e "\n Option does not exist : $OPTARG\n" + usage; exit 1 ;; + + esac # --- end of case --- +done +shift $(($OPTIND-1)) + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-read b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-read new file mode 100644 index 0000000..bfb8183 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-read @@ -0,0 +1,15 @@ + +infilename="" # input filename + +exec 3<"$infilename" +if [ $? -ne 0 ] ; then + echo -e "Could not link file descriptor with file '$infilename'\n" + exit 1 +fi + +while read line <&3 ; do + echo -e "$line" +done + +exec 3<&- # close file descriptor + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-write b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-write new file mode 100644 index 0000000..a660ae7 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/use-file-descriptor-write @@ -0,0 +1,13 @@ + +outfilename="" # output filename + +exec 4>"$outfilename" +if [ $? -ne 0 ] ; then + echo -e "Could not link file descriptor with file '$outfilename'\n" + exit 1 +fi + +echo -e "text" >&4 + +exec 4>&- # close file descriptor + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/well-behaved-script b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/well-behaved-script new file mode 100644 index 0000000..f3d72af --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/codesnippets/well-behaved-script @@ -0,0 +1,29 @@ +set -o nounset # treat unset variables as errors + +#=============================================================================== +# GLOBAL DECLARATIONS +#=============================================================================== +declare -rx SCRIPT=${0##*/} # the name of this script +declare -rx mkdir='/bin/mkdir' # the mkdir(1) command + +#=============================================================================== +# SANITY CHECKS +#=============================================================================== +if [ -z "$BASH" ] ; then + printf "$SCRIPT:$LINENO: run this script with the BASH shell\n" >&2 + exit 192 +fi + +if [ ! -x "$mkdir" ] ; then + printf "$SCRIPT:$LINENO: command '$mkdir' not available - aborting\n" >&2 + exit 192 +fi + +#=============================================================================== +# MAIN SCRIPT +#=============================================================================== + +#=============================================================================== +# STATISTICS / CLEANUP +#=============================================================================== +exit 0 diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.bashrc b/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.bashrc new file mode 100644 index 0000000..d592b0d --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.bashrc @@ -0,0 +1,9 @@ +#----------------------------------------------------------------------- +# set Bash prompts +# PS4 shows the function name when execution is inside a function and +# the xtrace option is set. +#----------------------------------------------------------------------- +export PS2='continue> ' +export PS3='choose: ' +export PS4='|${BASH_SOURCE} ${LINENO}${FUNCNAME[0]:+ ${FUNCNAME[0]}()}| ' + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.gvimrc b/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.gvimrc new file mode 100644 index 0000000..7a5b62f --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.gvimrc @@ -0,0 +1,63 @@ +"=============================================================================== +" +" File: customization.gvimrc +" +" Description: suggestion for a personal configuration file ~/.gvimrc +" +" VIM Version: 7.0+ +" Author: Dr. Fritz Mehner (fgm), mehner.fritz@fh-swf.de +" Organization: FH Südwestfalen, Iserlohn +" Version: 1.0 +" Created: 18.05.2013 21:58 +" Revision: --- +" License: Copyright (c) 2013, Dr. Fritz Mehner +"=============================================================================== +" +"=============================================================================== +" GENERAL SETTINGS +"=============================================================================== +set cmdheight=2 " Make command line two lines high +set mousehide " Hide the mouse when typing text + +highlight Normal guibg=grey90 +highlight Cursor guibg=Blue guifg=NONE +highlight lCursor guibg=Cyan guifg=NONE +highlight NonText guibg=grey80 +highlight Constant gui=NONE guibg=grey95 +highlight Special gui=NONE guibg=grey95 +" +let c_comment_strings=1 " highlight strings inside C comments +" +"------------------------------------------------------------------------------- +" Moving cursor to other windows +" +" shift down : change window focus to lower one (cyclic) +" shift up : change window focus to upper one (cyclic) +" shift left : change window focus to one on left +" shift right : change window focus to one on right +"------------------------------------------------------------------------------- +nnoremap <s-down> <c-w>w +nnoremap <s-up> <c-w>W +nnoremap <s-left> <c-w>h +nnoremap <s-right> <c-w>l +" +"------------------------------------------------------------------------------- +" some additional hot keys +"------------------------------------------------------------------------------- +" S-F3 - call gvim file browser +"------------------------------------------------------------------------------- + noremap <silent> <s-F3> :silent browse confirm e<CR> +inoremap <silent> <s-F3> <Esc>:silent browse confirm e<CR> +" +"------------------------------------------------------------------------------- +" toggle insert mode <--> 'normal mode with the <RightMouse>-key +"------------------------------------------------------------------------------- +" +nnoremap <RightMouse> <Insert> +inoremap <RightMouse> <ESC> +" +"------------------------------------------------------------------------------- +" use font with clearly distinguishable brackets : ()[]{} +"------------------------------------------------------------------------------- +"set guifont=Luxi\ Mono\ 14 +" diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.vimrc b/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.vimrc new file mode 100644 index 0000000..a56a20c --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/rc/customization.vimrc @@ -0,0 +1,210 @@ +"=============================================================================== +" +" File: customization.vimrc +" +" Description: suggestion for a personal configuration file ~/.vimrc +" +" VIM Version: 7.0+ +" Author: Dr. Fritz Mehner (fgm), mehner.fritz@fh-swf.de +" Organization: FH Südwestfalen, Iserlohn +" Version: 1.0 +" Created: 18.05.2013 21:59 +" Revision: --- +" License: Copyright (c) 2013, Dr. Fritz Mehner +"=============================================================================== + +" +"=============================================================================== +" GENERAL SETTINGS +"=============================================================================== + +"------------------------------------------------------------------------------- +" Use Vim settings, rather then Vi settings. +" This must be first, because it changes other options as a side effect. +"------------------------------------------------------------------------------- +set nocompatible +" +"------------------------------------------------------------------------------- +" Enable file type detection. Use the default filetype settings. +" Also load indent files, to automatically do language-dependent indenting. +"------------------------------------------------------------------------------- +filetype plugin on +filetype indent on +" +"------------------------------------------------------------------------------- +" Switch syntax highlighting on. +"------------------------------------------------------------------------------- +syntax on +" +" Platform specific items: +" - central backup directory (has to be created) +" - default dictionary +" Uncomment your choice. +if has("win16") || has("win32") || has("win64") || + \ has("win95") || has("win32unix") + " +" runtime mswin.vim +" set backupdir =$VIM\vimfiles\backupdir +" set dictionary=$VIM\vimfiles\wordlists/german.list +else +" set backupdir =$HOME/.vim.backupdir +" set dictionary=$HOME/.vim/wordlists/german.list +endif +" +" Using a backupdir under UNIX/Linux: you may want to include a line similar to +" find $HOME/.vim.backupdir -name "*" -type f -mtime +60 -exec rm -f {} \; +" in one of your shell startup files (e.g. $HOME/.profile) +" +"------------------------------------------------------------------------------- +" Various settings +"------------------------------------------------------------------------------- +set autoindent " copy indent from current line +set autoread " read open files again when changed outside Vim +set autowrite " write a modified buffer on each :next , ... +set backspace=indent,eol,start " backspacing over everything in insert mode +set backup " keep a backup file +set browsedir=current " which directory to use for the file browser +set complete+=k " scan the files given with the 'dictionary' option +set history=50 " keep 50 lines of command line history +set hlsearch " highlight the last used search pattern +set incsearch " do incremental searching +set listchars=tab:>.,eol:\$ " strings to use in 'list' mode +set mouse=a " enable the use of the mouse +set nowrap " do not wrap lines +set popt=left:8pc,right:3pc " print options +set ruler " show the cursor position all the time +set shiftwidth=2 " number of spaces to use for each step of indent +set showcmd " display incomplete commands +set smartindent " smart autoindenting when starting a new line +set tabstop=2 " number of spaces that a <Tab> counts for +set visualbell " visual bell instead of beeping +set wildignore=*.bak,*.o,*.e,*~ " wildmenu: ignore these extensions +set wildmenu " command-line completion in an enhanced mode +" +"=================================================================================== +" BUFFERS, WINDOWS +"=================================================================================== +" +"------------------------------------------------------------------------------- +" The current directory is the directory of the file in the current window. +"------------------------------------------------------------------------------- +if has("autocmd") + autocmd BufNewFile,BufRead * :lchdir %:p:h +endif +" +"------------------------------------------------------------------------------- +" close window (conflicts with the KDE setting for calling the process manager) +"------------------------------------------------------------------------------- + noremap <C-Esc> :close<CR> +inoremap <C-Esc> <C-C>:close<CR> +" +"------------------------------------------------------------------------------- +" Fast switching between buffers +" The current buffer will be saved before switching to the next one. +" Choose :bprevious or :bnext +"------------------------------------------------------------------------------- + noremap <silent> <s-tab> :if &modifiable && !&readonly && + \ &modified <CR> :write<CR> :endif<CR>:bprevious<CR> +inoremap <silent> <s-tab> <C-C>:if &modifiable && !&readonly && + \ &modified <CR> :write<CR> :endif<CR>:bprevious<CR> +" +"------------------------------------------------------------------------------- +" Leave the editor with Ctrl-q (KDE): Write all changed buffers and exit Vim +"------------------------------------------------------------------------------- +nnoremap <C-q> :wqall<CR> +" +"------------------------------------------------------------------------------- +" When editing a file, always jump to the last known cursor position. +" Don't do it when the position is invalid or when inside an event handler +" (happens when dropping a file on gvim). +"------------------------------------------------------------------------------- +if has("autocmd") + autocmd BufReadPost * + \ if line("'\"") > 0 && line("'\"") <= line("$") | + \ exe "normal! g`\"" | + \ endif +endif " has("autocmd") +" +"------------------------------------------------------------------------------- +" some additional hot keys +"------------------------------------------------------------------------------- +" F2 - write file without confirmation +" F3 - call file explorer Ex +" F4 - show tag under curser in the preview window (tagfile must exist!) +" F5 - open quickfix error window +" F6 - close quickfix error window +" F7 - display previous error +" F8 - display next error +"------------------------------------------------------------------------------- +" +noremap <silent> <F2> :write<CR> +noremap <silent> <F3> :Explore<CR> +nnoremap <silent> <F4> :exe ":ptag ".expand("<cword>")<CR> +noremap <silent> <F5> :copen<CR> +noremap <silent> <F6> :cclose<CR> +noremap <silent> <F7> :cp<CR> +noremap <silent> <F8> :cn<CR> +" +inoremap <silent> <F2> <Esc>:write<CR> +inoremap <silent> <F3> <Esc>:Explore<CR> +inoremap <silent> <F4> <Esc>:exe ":ptag ".expand("<cword>")<CR> +inoremap <silent> <F5> <Esc>:copen<CR> +inoremap <silent> <F6> <Esc>:cclose<CR> +inoremap <silent> <F7> <Esc>:cp<CR> +inoremap <silent> <F8> <Esc>:cn<CR> +"------------------------------------------------------------------------------- +" autocomplete parenthesis, brackets and braces +"------------------------------------------------------------------------------- +inoremap ( ()<Left> +inoremap [ []<Left> +inoremap { {}<Left> +" +vnoremap ( s()<Esc>P +vnoremap [ s[]<Esc>P +vnoremap { s{}<Esc>P +" +"------------------------------------------------------------------------------- +" autocomplete quotes +"------------------------------------------------------------------------------- +vnoremap ' s''<Esc>P<Right> +vnoremap " s""<Esc>P<Right> +vnoremap ` s``<Esc>P<Right> +" +inoremap ' '<Esc>:call QuoteInsertionWrapper("'")<CR>a +inoremap " "<Esc>:call QuoteInsertionWrapper('"')<CR>a +inoremap ` `<Esc>:call QuoteInsertionWrapper('`')<CR>a +" +"------------------------------------------------------------------------------- +" function QuoteInsertionWrapper {{{3 +" +" Add a second quote only if the left and the right character are not keyword +" characters and the right character is not the same quote. +"------------------------------------------------------------------------------- +function! QuoteInsertionWrapper (quote) + let col = col('.') + let line = getline('.') + if ( line[col-2] =~ '\k' ) + \ || ( line[col ] =~ '\k' ) + \ || ( line[col-2] =~ a:quote ) + \ || ( line[col ] =~ a:quote ) + return a:quote + else + return a:quote.a:quote."\<Left>" + endif +endfunction +" +"=============================================================================== +" VARIOUS PLUGIN CONFIGURATIONS +"=============================================================================== +" +"------------------------------------------------------------------------------- +" plugin bash-support.vim +"------------------------------------------------------------------------------- +" --empty -- +" +"------------------------------------------------------------------------------- +" taglist.vim : toggle the taglist window +"------------------------------------------------------------------------------- + noremap <silent> <F11> <Esc><Esc>:Tlist<CR> +inoremap <silent> <F11> <Esc><Esc>:Tlist<CR> + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/rc/sample_template_file b/.config/nvim/plugged/bash-support.vim/bash-support/rc/sample_template_file new file mode 100644 index 0000000..9a77343 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/rc/sample_template_file @@ -0,0 +1,16 @@ +§ ============================================================= +§ User Macros +§ ============================================================= + +SetMacro( 'AUTHOR', 'YOUR NAME' ) +SetMacro( 'AUTHORREF', '' ) +SetMacro( 'COMPANY', '' ) +SetMacro( 'COPYRIGHT', 'Copyright (c) |YEAR|, |AUTHOR|' ) +SetMacro( 'EMAIL', '' ) +SetMacro( 'LICENSE', 'GNU General Public License' ) +SetMacro( 'ORGANIZATION','' ) + +§ ============================================================= +§ File Includes and Shortcuts +§ ============================================================= + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/rc/sh.vim b/.config/nvim/plugged/bash-support.vim/bash-support/rc/sh.vim new file mode 100644 index 0000000..eef7a12 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/rc/sh.vim @@ -0,0 +1,35 @@ +"=============================================================================== +" +" File: sh.vim +" +" Description: Additonal maps for bash-support (version 4.0+) +" +" VIM Version: 7.0+ +" Author: Dr. Fritz Mehner (fgm), mehner.fritz@fh-swf.de +" Organization: FH Südwestfalen, Iserlohn +" Version: 1.0 +" Created: 20.05.2013 17:20 +" Revision: --- +" License: Copyright (c) 2013, Dr. Fritz Mehner +"=============================================================================== +" +"------------------------------------------------------------------------------- +" additional mapping : single quotes around a Word (non-whitespaces) +" masks the normal mode command '' (jump to the position +" before the latest jump) +" additional mapping : double quotes around a Word (non-whitespaces) +"------------------------------------------------------------------------------- +nnoremap <buffer> '' ciW''<Esc>P +nnoremap <buffer> "" ciW""<Esc>P +" +"------------------------------------------------------------------------------- +" generate tests +" additional mapping : \t1 expands to [ -<CURSOR> ] +" additional mapping : \t2 expands to [ <CURSOR> - ] +"------------------------------------------------------------------------------- +nnoremap <buffer> <silent> <LocalLeader>t1 a[ - ]<Left><Left><Left> +inoremap <buffer> <silent> <LocalLeader>t1 [ - ]<Left><Left><Left> +" +nnoremap <buffer> <silent> <LocalLeader>t2 a[ - ]<Left><Left><Left><Left><Left> +inoremap <buffer> <silent> <LocalLeader>t2 [ - ]<Left><Left><Left><Left><Left> +" diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/scripts/wrapper.sh b/.config/nvim/plugged/bash-support.vim/bash-support/scripts/wrapper.sh new file mode 100644 index 0000000..7a33b0a --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/scripts/wrapper.sh @@ -0,0 +1,34 @@ +#!/bin/bash +#=============================================================================== +# FILE: wrapper.sh +# USAGE: ./wrapper.sh scriptname [cmd-line-args] +# DESCRIPTION: Wraps the execution of a programm or script. +# Use with xterm: xterm -e wrapper.sh scriptname cmd-line-args +# This script is used by the Vim plugin bash-support.vim +# OPTIONS: --- +# REQUIREMENTS: --- +# BUGS: --- +# NOTES: --- +# AUTHOR: Dr.-Ing. Fritz Mehner (fgm), mehner.fritz@fh-swf.de +# COMPANY: Fachhochschule Südwestfalen, Iserlohn +# CREATED: 23.11.2004 18:04:01 CET +# REVISION: --- +#=============================================================================== + +scriptname="${1}" # name of the script to execute +returncode=0 # default return code + +if [ ${#} -ge 1 ] ; then + if [ -x "$scriptname" ] ; then # start an executable script? + "${@}" + else + $SHELL "${@}" # start a script which is not executable + fi + returncode=$? + [ $returncode -ne 0 ] && printf "'${@}' returned ${returncode}\n" +else + printf "\n!! ${0} : no argument(s) !!\n" +fi + +read -p "... press return key ... " dummy +exit $returncode diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/Templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/Templates new file mode 100644 index 0000000..1ee1874 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/Templates @@ -0,0 +1,42 @@ +§ ============================================================= +§ User Macros +§ ============================================================= + +SetMacro( 'AUTHOR', 'Marcin Woźniak' ) +SetMacro( 'AUTHORREF', '' ) +SetMacro( 'COMPANY', 'Cognifide Polska' ) +SetMacro( 'COPYRIGHT', '' ) +SetMacro( 'EMAIL', 'marcin.wozniak@cognifide.com' ) +SetMacro( 'LICENSE', '' ) +SetMacro( 'ORGANIZATION','' ) + +SetFormat( 'DATE', '%x' ) +SetFormat( 'TIME', '%H:%M' ) +SetFormat( 'YEAR', '%Y' ) + +SetStyle( 'default' ) + +§ ============================================================= +§ File Includes and Shortcuts +§ ============================================================= + +§ :TODO:14.07.13 12:50:WM: files "paramsub.templates" and "io-redirection.templates": maps, shortcuts? sort alphabetically? + +MenuShortcut( 'Comments', 'c' ) +MenuShortcut( 'Statements', 's' ) +MenuShortcut( 'Tests', 't' ) +MenuShortcut( 'ParamSub', 'p' ) +MenuShortcut( 'PatternMatching', 'p' ) +MenuShortcut( 'IO-Redir', 'i' ) + +IncludeFile( 'comments.templates' ) +IncludeFile( 'statements.templates' ) +IncludeFile( 'tests.templates' ) +IncludeFile( 'paramsub.templates' ) +IncludeFile( 'specialparams.templates' ) +IncludeFile( 'environment.templates' ) +IncludeFile( 'builtins.templates' ) +IncludeFile( 'set.templates' ) +IncludeFile( 'shelloptions.templates' ) +IncludeFile( 'io-redirection.templates' ) +IncludeFile( 'patternmatching.templates' ) diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/builtins.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/builtins.templates new file mode 100644 index 0000000..d87a671 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/builtins.templates @@ -0,0 +1,70 @@ +§ ============================================================= +§ Builtins +§ ============================================================= + +== LIST: builtins == list == +'alias', +'bg', +'bind', +'break', +'builtin', +'caller', +'cd', +'command', +'compgen', +'complete', +'continue', +'compopt', +'declare', +'dirs', +'disown', +'echo', +'enable', +'eval', +'exec', +'exit', +'export', +'false', +'fc', +'fg', +'getopts', +'hash', +'help', +'history', +'jobs', +'kill', +'let', +'local', +'logout', +'mapfile', +'popd', +'printf', +'pushd', +'pwd', +'read', +'readarray', +'readonly', +'return', +'set', +'shift', +'shopt', +'source', +'suspend', +'test', +'times', +'trap', +'true', +'type', +'typeset', +'ulimit', +'umask', +'unalias', +'unset', +'wait', +== ENDLIST == + +== Builtins == expandmenu, insert, map:bbu, sc:b == +|PickList( 'Builtins', 'builtins' )| +|PICK|<CURSOR> +== ENDTEMPLATE == + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/comments.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/comments.templates new file mode 100644 index 0000000..cb38c9e --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/comments.templates @@ -0,0 +1,142 @@ +§ ============================================================= +§ Comments +§ ============================================================= + +== Comments.end-of-line comment == nomenu, append == +# <CURSOR> +== Comments.frame == map:cfr, sc:r == +#------------------------------------------------------------------------------- +# <CURSOR> +#------------------------------------------------------------------------------- +== Comments.function == map:cfu, sc:f == +#--- FUNCTION ---------------------------------------------------------------- +# NAME: |?FUNCTION_NAME| +# DESCRIPTION: <CURSOR> +# PARAMETERS: +# RETURNS: +#------------------------------------------------------------------------------- +== Comments.file header == start, map:ch == +#!/bin/bash - +#=============================================================================== +# +# FILE: |FILENAME| +# +# USAGE: ./|FILENAME| +# +# DESCRIPTION: +# +# OPTIONS: --- +# REQUIREMENTS: --- +# BUGS: --- +# NOTES: --- +# AUTHOR: |AUTHOR| , |EMAIL| +# COMPANY: |COMPANY| +# CREATED: |DATE| |TIME| +# REVISION: --- +#=============================================================================== + +set -o nounset # Treat unset variables as an error + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd)/" +#source $DIR/settings.sh + +##################### +# SETTINGS FILE +EMAILSERVER="" +EMAILFROM="" +EMAILADMIN="" +ERRORTITLE=Error-$TITLE +# +##################### + +LOG="$DIR/log" +LOG_FILE="$LOG/log-$(date -I).log" + +function timestamp(){ + echo "[+] "$(date +'%F %T')" [INFO] $@" +} + +function err() { + echo "[-] "$(date +'%F %T')" [ERROR] $@" >&2 +} + +function command_start(){ + timestamp "Command $1 has been started." + if ! $1 ; then + err "Command $1 went wrong." + sendmailerr + exit + fi +} + +function removelogs(){ + find $LOG -mindepth 1 -mtime +365 -delete +} + +function sendmailerr (){ + echo -e "SERVER-IP: :$(ifconfig | awk '/inet /{print $2}' | sed '/127.0.0.1/d'| tr '\n' ' ')\nSCRIPTNAME: $(basename "$0")" | mailx -v -S smtp=$EMAILSERVER -r $EMAILFROM -s "$ERRORTITLE" -a $LOG_FILE $EMAILADMIN +} + +function main(){ + timestamp "Script has been started" + timestamp "Everything looks OK ;-)" +} + +main >>$LOG_FILE 2>&1 + + +<CURSOR> +== ENDTEMPLATE == + +§ ------------------------------------------------------------- + +== Comments.date == insert, map:cd, sc:d == +|DATE|<CURSOR> +== Comments.date+time == insert, map:ct, sc:t == +|DATE| |TIME|<CURSOR> +== ENDTEMPLATE == + +§ ------------------------------------------------------------- +§ Keywords, Special and Macros +§ ------------------------------------------------------------- + +== LIST: comments_sections == hash == + 'GLOBAL DECLARATIONS' : 'GLOBAL DECLARATIONS', + 'COMMAND LINE PROCESSING' : 'COMMAND LINE PROCESSING', + 'SANITY CHECKS' : 'SANITY CHECKS', + 'FUNCTION DEFINITIONS' : 'FUNCTION DEFINITIONS', + 'TRAPS' : 'TRAPS', + 'MAIN SCRIPT' : 'MAIN SCRIPT', + 'STATISTICS AND CLEAN-UP' : 'STATISTICS AND CLEAN-UP', +== LIST: comments_keywords == hash == + 'bug' : ':BUG:|DATE| |TIME|:|AUTHORREF|: <CURSOR>', + 'todo' : ':TODO:|DATE| |TIME|:|AUTHORREF|: <CURSOR>', + 'tricky' : ':TRICKY:|DATE| |TIME|:|AUTHORREF|: <CURSOR>', + 'warning' : ':WARNING:|DATE| |TIME|:|AUTHORREF|: <CURSOR>', + 'workaround' : ':WORKAROUND:|DATE| |TIME|:|AUTHORREF|: <CURSOR>', + 'new keyword' : ':<CURSOR>:|DATE| |TIME|:|AUTHORREF|: {+COMMENT+}', +== LIST: comments_macros == hash == + 'AUTHOR' : '|AUTHOR|', + 'AUTHORREF' : '|AUTHORREF|', + 'COMPANY' : '|COMPANY|', + 'COPYRIGHT' : '|COPYRIGHT|', + 'EMAIL' : '|EMAIL|', + 'ORGANIZATION' : '|ORGANIZATION|', +== ENDLIST == + +§ ------------------------------------------------------------- + +== Comments.script sections == expandmenu, map:css, sc:s == +|PickList( 'script sections', 'comments_sections' )| +#=============================================================================== +# |PICK| +#=============================================================================== +== Comments.keyword comments == expandmenu, append, map:ckc, sc:k == +|PickList( 'keyword comment', 'comments_keywords' )| + # |PICK| +== Comments.macros == expandmenu, insert, map:cma, sc:m == +|PickList( 'macro', 'comments_macros' )| +|PICK| +== ENDTEMPLATE == + +== SEP: Comments.sep1 == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/environment.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/environment.templates new file mode 100644 index 0000000..8be3e03 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/environment.templates @@ -0,0 +1,100 @@ +§ ============================================================= +§ Environment +§ ============================================================= + +== LIST: environment == list == +'BASH', +'BASHOPTS', +'BASHPID', +'BASH_ALIASES', +'BASH_ARGC', +'BASH_ARGV', +'BASH_CMDS', +'BASH_COMMAND', +'BASH_ENV', +'BASH_EXECUTION_STRING', +'BASH_LINENO', +'BASH_REMATCH', +'BASH_SOURCE', +'BASH_SUBSHELL', +'BASH_VERSINFO', +'BASH_VERSION', +'BASH_XTRACEFD', +'CDPATH', +'COLUMNS', +'COMPREPLY', +'COMP_CWORD', +'COMP_KEY', +'COMP_LINE', +'COMP_POINT', +'COMP_TYPE', +'COMP_WORDBREAKS', +'COMP_WORDS', +'DIRSTACK', +'EMAC&S', +'EUID', +'FCEDIT', +'FIGNORE', +'FUNCNAME', +'FUNCNEST', +'GLOBIGNORE', +'GROUPS', +'HISTCMD', +'HISTCONTROL', +'HISTFILE', +'HISTFILESIZE', +'HISTIGNORE', +'HISTSIZE', +'HISTTIMEFORMAT', +'HOME', +'HOSTFILE', +'HOSTNAME', +'HOSTTYPE', +'IFS', +'IGNOREEOF', +'INPUTRC', +'LANG', +'LC_ALL', +'LC_COLLATE', +'LC_CTYPE', +'LC_MESSAGES', +'LC_NUMERIC', +'LINENO', +'LINES', +'MACHTYPE', +'MAIL', +'MAILCHECK', +'MAILPATH', +'OLDPWD', +'OPTARG', +'OPTERR', +'OPTIND', +'OSTYPE', +'PATH', +'PIPESTATUS', +'POSIXLY_CORRECT', +'PPID', +'PROMPT_COMMAND', +'PROMPT_DIRTRIM', +'PS1', +'PS2', +'PS3', +'PS4', +'PWD', +'RANDOM', +'REPLY', +'SECONDS', +'SHELL', +'SHELLOPTS', +'SHLVL', +'TIMEFORMAT', +'TMOUT', +'TMPDIR', +'UID', +== ENDLIST == + +== Environment == expandmenu, insert, map:ben, sc:e == +|PickList( 'Environment', 'environment' )| +|PICK|<CURSOR> +== ENDTEMPLATE == + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/io-redirection.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/io-redirection.templates new file mode 100644 index 0000000..838b820 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/io-redirection.templates @@ -0,0 +1,32 @@ +§ ============================================================= +§ IO Redirection +§ ============================================================= + +== LIST: IORedirection == hash == + 'append STDOUT and STDERR &>>': ' &>> <CURSOR>', + 'close input from file descr n n<&-': ' <CURSOR><&- ', + 'close output from file descr n n>&-': ' <CURSOR>>&- ', + 'close STDIN <&-': ' <&- <CURSOR>', + 'close STDOUT >&-': ' >&- <CURSOR>', + 'direct file descr n to file, append n>>' : ' <CURSOR>>> ', + 'direct file descr n to file n>' : ' <CURSOR>> ', + 'direct STDOUT and STDERR to file &>' : ' &> <CURSOR>', + 'direct STDOUT to file, append >>' : ' >> <CURSOR>', + 'direct STDOUT to file >' : ' > <CURSOR>', + 'direct STDOUT to STDERR >&2' : ' >&2<CURSOR>', + 'duplicate STDIN from file descr n n<&' : ' <<CURSOR>& ', + 'duplicate STDOUT to file descr n n>&' : ' ><CURSOR>& ', + 'take file descr n from file n<' : ' <CURSOR>< ', + 'take STDIN from file <' : ' < <CURSOR>', +== ENDLIST == + +== IO-Redir.redir == expandmenu, insert, sc:r, map:ior == +|PickList( 'IO-Redir', 'IORedirection' )| +|PICK| +== ENDTEMPLATE == + +== IO-Redir.here-document == insert, sc:h, map:ioh == +<<-EOF +<SPLIT><CURSOR> +EOF +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/paramsub.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/paramsub.templates new file mode 100644 index 0000000..e80ed50 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/paramsub.templates @@ -0,0 +1,33 @@ +§ ============================================================= +§ Parameter Substitution +§ ============================================================= + +== LIST: ParameterSubstitution == hash == + 'all lower to upper ${ ^^ }' : '${<CURSOR>^^<+pattern+>}', + 'all upper to lower ${ ,, }' : '${<CURSOR>,,<+pattern+>}', + 'assign default value ${ := }' : '${<CURSOR>:=<+word+>}', + 'display error ${ :? }' : '${<CURSOR>:?<+word+>}', + 'first lower to upper ${ ^ }' : '${<CURSOR>^<+pattern+>}', + 'first upper to lower ${ , }' : '${<CURSOR>,<+pattern+>}', + 'indirect parameter expansion ${! }' : '${!<CURSOR>}', + 'names matching prefix ${! *}' : '${!<CURSOR>*}', + 'parameter length ${# }' : '${#<CURSOR>}', + 'pattern substitution all ${ // / }' : '${<CURSOR>//<+pattern+>/<+string+>}', + 'pattern substitution begin ${ /# / }' : '${<CURSOR>/#<+pattern+>/<+string+>}', + 'pattern substitution ${ / / }' : '${<CURSOR>/<+pattern+>/<+string+>}', + 'pattern substitution end ${ /% / }' : '${<CURSOR>/%<+pattern+>/<+string+>}', + 'remove all matching prefix pattern ${ ## }' : '${<CURSOR>##<+word+>}', + 'remove all matching suffix pattern ${ %% }' : '${<CURSOR>%%<+word+>}', + 'remove matching prefix pattern ${ # }' : '${<CURSOR>#<+word+>}', + 'remove matching suffix pattern ${ % }' : '${<CURSOR>%<+word+>}', + 'substitution ${ }' : '${<SPLIT><CURSOR>}', + 'substring expansion ${ : : }' : '${<CURSOR>:<+offset+>:<+length+>}', + 'use alternate value ${ :+ }' : '${<CURSOR>:+<+word+>}', + 'use default value ${ :- }' : '${<CURSOR>:-<+word+>}', +== ENDLIST == + +== ParamSub == expandmenu, insert, sc:p, map:bps == +|PickList( 'Parameter Substitution', 'ParameterSubstitution' )| +|PICK| +== ENDTEMPLATE == + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/patternmatching.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/patternmatching.templates new file mode 100644 index 0000000..2449957 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/patternmatching.templates @@ -0,0 +1,51 @@ +§ ============================================================= +§ RegExp +§ ============================================================= + +== PatternMatching.zero or one == insert, map:pzo, sc:z == +?(<SPLIT><CURSOR>|) +== PatternMatching.zero or more == insert, map:pzm, sc:z == +*(<SPLIT><CURSOR>|) +== PatternMatching.one or more == insert, map:pom, sc:o == ++(<SPLIT><CURSOR>|) +== PatternMatching.exactly one == insert, map:peo, sc:e == +@(<SPLIT><CURSOR>|) +== PatternMatching.anything except == insert, map:pae, sc:a == +!(<SPLIT><CURSOR>|) +== ENDTEMPLATE == + +== SEP: PatternMatching.sep1 == + +== LIST: POSIX_CharClasses == list == + 'alnum', + 'alpha', + 'ascii', + 'blank', + 'cntrl', + 'digit', + 'graph', + 'lower', + 'print', + 'punct', + 'space', + 'upper', + 'word', + 'xdigit', +== ENDLIST == + +== PatternMatching.POSIX classes == expandmenu, insert, sc:p, map:ppc == +|PickList( 'POSIX char. classes', 'POSIX_CharClasses' )| +[:|PICK|:]<CURSOR> +== ENDTEMPLATE == + +== LIST: BashRematch == list == + '${BASH_REMATCH[0]}', + '${BASH_REMATCH[1]}', + '${BASH_REMATCH[2]}', + '${BASH_REMATCH[3]}', +== ENDLIST == + +== PatternMatching.BASH_REMATCH == expandmenu, insert, sc:b, map:pbr == +|PickList( 'BASH_REMATCH', 'BashRematch' )| +|PICK|<CURSOR> +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/regexp.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/regexp.templates new file mode 100644 index 0000000..bd6d2a5 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/regexp.templates @@ -0,0 +1,51 @@ +§ ============================================================= +§ RegExp +§ ============================================================= + +== Regexp.zero or one == insert, map:xzo, sc:z == +?(<SPLIT><CURSOR>|) +== Regexp.zero or more == insert, map:xzm, sc:z == +*(<SPLIT><CURSOR>|) +== Regexp.one or more == insert, map:xom, sc:o == ++(<SPLIT><CURSOR>|) +== Regexp.exactly one == insert, map:xeo, sc:e == +@(<SPLIT><CURSOR>|) +== Regexp.anything except == insert, map:xae, sc:a == +!(<SPLIT><CURSOR>|) +== ENDTEMPLATE == + +== SEP: Regexp.sep1 == + +== LIST: POSIX_CharClasses == list == + 'alnum', + 'alpha', + 'ascii', + 'blank', + 'cntrl', + 'digit', + 'graph', + 'lower', + 'print', + 'punct', + 'space', + 'upper', + 'word', + 'xdigit', +== ENDLIST == + +== Regexp.POSIX classes == expandmenu, insert, sc:p, map:xpc == +|PickList( 'POSIX char. classes', 'POSIX_CharClasses' )| +[:|PICK|:]<CURSOR> +== ENDTEMPLATE == + +== LIST: BashRematch == list == + '${BASH_REMATCH[0]}', + '${BASH_REMATCH[1]}', + '${BASH_REMATCH[2]}', + '${BASH_REMATCH[3]}', +== ENDLIST == + +== Regexp.BASH_REMATCH == expandmenu, insert, sc:b, map:xbr == +|PickList( 'BASH_REMATCH', 'BashRematch' )| +|PICK|<CURSOR> +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/set.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/set.templates new file mode 100644 index 0000000..e15cef8 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/set.templates @@ -0,0 +1,36 @@ +§ ============================================================= +§ Set +§ ============================================================= + +== LIST: set == list == +'allexport', +'braceexpand', +'emacs', +'errexit', +'errtrace', +'functrace', +'hashall', +'histexpand', +'history', +'ignoreeof', +'keyword', +'monitor', +'noclobber', +'noexec', +'noglob', +'notify', +'nounset', +'onecmd', +'physical', +'pipefail', +'posix', +'privileged', +'verbose', +'vi', +'xtrace', +== ENDLIST == + +== Set == expandmenu, map:bse, sc:s == +|PickList( 'set option', 'set' )| +set -o |PICK|<CURSOR> +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/shelloptions.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/shelloptions.templates new file mode 100644 index 0000000..e01b5af --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/shelloptions.templates @@ -0,0 +1,54 @@ +§ ============================================================= +§ Shell Options +§ ============================================================= + +== LIST: shopt == list == +'autocd', +'cdable_vars', +'cdspell', +'checkhash', +'checkjobs', +'checkwinsize', +'cmdhist', +'compat31', +'compat32', +'compat40', +'compat41', +'dirspell', +'direxpand', +'dotglob', +'execfail', +'expand_aliases', +'extdebug', +'extglob', +'extquote', +'failglob', +'force_fignore', +'globstar', +'gnu_errfmt', +'histappend', +'histreedit', +'histverify', +'hostcomplete', +'huponexit', +'interactive_comments', +'lastpipe', +'lithist', +'login_shell', +'mailwarn', +'no_empty_cmd_completion', +'nocaseglob', +'nocasematch', +'nullglob', +'progcomp', +'promptvars', +'restricted_shell', +'shift_verbose', +'sourcepath', +'xpg_echo', +== ENDLIST == + +== Shopts == expandmenu, insert, map:bso, sc:o == +|PickList( 'Shopts', 'shopt' )| +shopt -s |PICK|<CURSOR> +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/specialparams.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/specialparams.templates new file mode 100644 index 0000000..fe8e373 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/specialparams.templates @@ -0,0 +1,21 @@ +§ ============================================================= +§ Special Parameters +§ ============================================================= + +== LIST: SpecialParameters == hash == + 'number of posit. param., ${#}' : '${#}', + 'all posit. param. (quoted spaces), ${*}' : '${*}', + 'all posit. param. (unquoted spaces), ${@}' : '${@}', + 'number of posit. parameters, ${#@}' : '${#@}', + 'return code of last command, ${?}' : '${?}', + 'PID of this shell, ${$}' : '${$}', + 'flags set, ${-}' : '${-}', + 'last argument of prev. command, ${_}' : '${_}', + 'PID of last background command, ${!}' : '${!}', +== ENDLIST == + +== SpecParams == expandmenu, insert, sc:p, map:bsp == +|PickList( 'Special Parameters', 'SpecialParameters' )| +|PICK|<CURSOR> +== ENDTEMPLATE == + diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/statements.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/statements.templates new file mode 100644 index 0000000..ccf7edd --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/statements.templates @@ -0,0 +1,79 @@ +§ ============================================================= +§ Statements +§ ============================================================= + +== Statements.case == map:sc, shortcut:c == +case <CURSOR> in + ) + ;; + + ) + ;; + + *) + ;; + +esac # --- end of case --- +== Statements.elif == map:sei, shortcut:e == +elif <CURSOR> ; then +== Statements.for-in == map:sf, shortcut:f == +for <CURSOR> in ; do +<SPLIT><-LOOP_BODY-> +done +== Statements.for == map:sfo, shortcut:f == +for (( CNTR=0; CNTR<<CURSOR>0; CNTR+=1 )); do +<SPLIT><-LOOP_BODY-> +done +== Statements.if == map:si, shortcut:i == +if <CURSOR> ; then +<SPLIT><-IF_PART-> +fi +== Statements.if-else == map:sie, shortcut:i == +if <CURSOR> ; then +<SPLIT><-IF_PART-> +else + <+ELSE_PART+> +fi +== Statements.select == map:ss, shortcut:s == +select <CURSOR> in ; do +<SPLIT>done +== Statements.until == map:su, shortcut:u == +until <CURSOR> ; do +<SPLIT>done +== Statements.while == map:sw, shortcut:w == +while <CURSOR> ; do +<SPLIT>done +== Statements.function == map:sfu, shortcut:f == +function |?FUNCTION_NAME| () +{ +<CURSOR><SPLIT> +} # ---------- end of function |FUNCTION_NAME| ---------- +== ENDTEMPLATE == + +§ ------------------------------------------------------------- + +== SEP: Statements.sep-print == + +== Statements.echo == insert, map:se, shortcut:e == +echo -e "<CURSOR><SPLIT>" +== Statements.printf == insert, map:sp, shortcut:p == +printf "%s\n" <CURSOR><SPLIT> +== ENDTEMPLATE == + +§ ------------------------------------------------------------- + +== SEP: Statements.sep-array == + +== Statements.array element == insert, map:sae, shortcut:a == +${<CURSOR><SPLIT>[]} +== Statements.array elements, all == insert, map:saa, shortcut:a == +${<CURSOR><SPLIT>[@]} +== Statements.array elements, string == insert, map:sas, shortcut:s == +${<CURSOR><SPLIT>[*]} +== Statements.subarray == insert, map:ssa, shortcut:s == +${<CURSOR><SPLIT>[@]::} +== Statements.no of element == insert, map:san, shortcut:n == +${#<CURSOR><SPLIT>[@]} +== Statements.array indices== insert, map:sai, shortcut:i == +${!<CURSOR><SPLIT>[@]} +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/templates/tests.templates b/.config/nvim/plugged/bash-support.vim/bash-support/templates/tests.templates new file mode 100644 index 0000000..9eca3ce --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/templates/tests.templates @@ -0,0 +1,86 @@ +§ ============================================================= +§ Tests +§ ============================================================= + +== LIST: TestsArithmetic == hash == + 'arg1 is equal to arg2, -eq' : '-eq', + 'arg1 not equal to arg2, -ne' : '-ne', + 'arg1 less than arg2, -lt' : '-lt', + 'arg1 less than or equal to arg2, -le' : '-le', + 'arg1 greater than arg2, -gt' : '-gt', + 'arg1 greater than or equal to arg2, -ge' : '-ge', +== ENDLIST == + +== Tests.arithmetic tests == expandmenu, insert, sc:a, map:ta == +|PickList( 'arithmetic tests', 'TestsArithmetic' )| +[ <CURSOR> |PICK| ] +== ENDTEMPLATE == + +== LIST: TestsFilePermission == hash == + 'readable, -r' : '-r', + 'writable, -w' : '-w', + 'executable, -x' : '-x', + 'SUID-bit is set, -u' : '-u', + 'SGID-bit is set, -g' : '-g', + 'sticky bit is set, -k' : '-k', +== ENDLIST == + +== Tests.file permissions == expandmenu, insert, sc:p, map:tfp == +|PickList( 'file permission', 'TestsFilePermission' )| +[ <CURSOR> |PICK| ] +== ENDTEMPLATE == + +== LIST: TestsFileTypes == hash == + 'block special file, -b' : '-b', + 'character special file, -c' : '-c', + 'directory, -d' : '-d', + 'named pipe (FIFO), -p' : '-p', + 'regular file, -f' : '-f', + 'socket, -S' : '-S', + 'symboloc link, -L, -h' : '-L', +== ENDLIST == + +== Tests.file types == expandmenu, insert, sc:t, map:tft == +|PickList( 'file type', 'TestsFileTypes' )| +[ <CURSOR> |PICK| ] +== ENDTEMPLATE == + +== LIST: TestsFileCharacteristics == hash == + 'file exists, -e, -a' : '-e', + 'file exists, size greater zero, -s' : '-s', + 'file exists, owned by eff UID, -O' : '-O', + 'file exists, owned by eff GID, -G' : '-G', + 'file exists, modified since last read, -N' : '-N', + 'file1 newer than file2, -nt' : '-nt', + 'file1 older than file2, -ot' : '-ot', + 'files have same device and inode numbers , -ef' : '-ef', +== ENDLIST == + +== Tests.file characteristics == expandmenu, insert, sc:c, map:tfc == +|PickList( 'file characteristics', 'TestsFileCharacteristics' )| +[ <CURSOR> |PICK| ] +== ENDTEMPLATE == + +== LIST: TestsStrings == hash == + 'length is zero, -z' : '-z', + 'length is non-zero, -n' : '-n', + 'strings are equal, ==' : '==', + 'strings are not equal, !=' : '!=', + 'sorts before, <' : '<', + 'sorts after, >' : '>', +== ENDLIST == + +== Tests.string comparison == expandmenu, insert, sc:s, map:ts == +|PickList( 'string comparisons', 'TestsStrings' )| +[ <CURSOR> |PICK| ] +== ENDTEMPLATE == + +== Tests.option is enabled, -o == insert, map:toe, sc:o == +[ -o <CURSOR> ] +== Tests.variable has been set, -v == insert, map:tvs, sc:v == +[ -v <CURSOR> ] +== Tests.file descriptor is open, refers to a terminal, -t == insert, map:tfd, sc:d == +[ -t <CURSOR> ] +== Tests.string matches regexp == insert, map:tm, sc:m == +[[ <CURSOR> =~ ]] +== ENDTEMPLATE == diff --git a/.config/nvim/plugged/bash-support.vim/bash-support/wordlists/bash-keywords.list b/.config/nvim/plugged/bash-support.vim/bash-support/wordlists/bash-keywords.list new file mode 100644 index 0000000..52d725d --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/bash-support/wordlists/bash-keywords.list @@ -0,0 +1,264 @@ +BASH +BASHPID +BASH_ALIASES +BASH_ARGC +BASH_ARGV +BASH_CMDS +BASH_COMMAND +BASH_ENV +BASH_EXECUTION_STRING +BASH_LINENO +BASHOPTS +BASH_REMATCH +BASH_SOURCE +BASH_SUBSHELL +BASH_VERSINFO +BASH_VERSION +BASH_XTRACEFD +CDPATH +COLUMNS +COMPREPLY +COMP_CWORD +COMP_KEY +COMP_LINE +COMP_POINT +COMP_TYPE +COMP_WORDBREAKS +COMP_WORDS +DIRSTACK +EMACS +EUID +FCEDIT +FIGNORE +FUNCNAME +FUNCNEST +GLOBIGNORE +GROUPS +HISTCMD +HISTCONTROL +HISTFILE +HISTFILESIZE +HISTIGNORE +HISTSIZE +HISTTIMEFORMAT +HOME +HOSTFILE +HOSTNAME +HOSTTYPE +IFS +IGNOREEOF +INPUTRC +LANG +LC_ALL +LC_COLLATE +LC_CTYPE +LC_MESSAGES +LC_NUMERIC +LINENO +LINES +MACHTYPE +MAIL +MAILCHECK +MAILPATH +OLDPWD +OPTARG +OPTERR +OPTIND +OSTYPE +PATH +PIPESTATUS +POSIXLY_CORRECT +PPID +PROMPT_COMMAND +PROMPT_DIRTRIM +PS1 +PS2 +PS3 +PS4 +PWD +RANDOM +REPLY +SECONDS +SHELL +SHELLOPTS +SHLVL +TIMEFORMAT +TMOUT +TMPDIR +UID +auto_resume +histchars + +alias +bg +bind +break +builtin +caller +cd +command +compgen +complete +compopt +continue +declare +dirs +disown +echo +enable +eval +exec +exit +export +false +fc +fg +getopts +hash +help +history +jobs +kill +let +local +logout +mapfile +popd +printf +pushd +pwd +read +readarray +readonly +return +set +shift +shopt +source +suspend +test +times +trap +true +type +typeset +ulimit +umask +unalias +unset +wait + +case +done +elif +else +esac +for +function +select +then +time +until +while + +allexport +braceexpand +emacs +errexit +errtrace +functrace +hashall +histexpand +history +ignoreeof +keyword +monitor +noclobber +noexec +noglob +notify +nounset +onecmd +physical +pipefail +posix +privileged +verbose +xtrace + +autocd +cdable_vars +cdspell +checkhash +checkjobs +checkwinsize +cmdhist +compat31 +compat32 +compat40 +compat41 +dirspell +dotglob +execfail +expand_aliases +extdebug +extglob +extquote +failglob +force_fignore +globstar +gnu_errfmt +histappend +histreedit +histverify +hostcomplete +huponexit +interactive_comments +lastpipe +lithist +login_shell +mailwarn +no_empty_cmd_completion +nocaseglob +nocasematch +nullglob +progcomp +promptvars +restricted_shell +shift_verbose +sourcepath +xpg_echo + +SIGABRT +SIGALRM +SIGBUS +SIGCHLD +SIGCONT +SIGFPE +SIGHUP +SIGILL +SIGINT +SIGIO +SIGKILL +SIGPIPE +SIGPROF +SIGPWR +SIGQUIT +SIGRTMAX +SIGRTMIN +SIGSEGV +SIGSTKFLT +SIGSTOP +SIGSYS +SIGTERM +SIGTRAP +SIGTSTP +SIGTTIN +SIGTTOU +SIGURG +SIGUSR1 +SIGUSR2 +SIGVTALRM +SIGWINCH +SIGXCPU +SIGXFSZ diff --git a/.config/nvim/plugged/bash-support.vim/doc/ChangeLog b/.config/nvim/plugged/bash-support.vim/doc/ChangeLog new file mode 100644 index 0000000..6bb2b65 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/doc/ChangeLog @@ -0,0 +1,437 @@ +======================================================================================= + RELEASE NOTES FOR VERSION 4.2 +======================================================================================= + +- Default shell can be set in ~/.vimrc via g:BASH_Executable. +- Errors can be parsed for bash, dash, ksh, zsh. +- Bugfix: QuickFix list doesn't work properly (thanks to @PengZheng) +- 'Run -> make script executable' (\re) is now a toggle. +- Minor corrections and improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 4.1 +======================================================================================= + +- Filetype plugin added. +- Bugfix: Setup of local templates in case of global installation. +- Adjusting end-of-line comments improved. +- Submenu 'Regexp' renamed to 'PatternMatching'. Appropriate hotkeys renamed. +- Minor bugfixes. +- Documentation updated. + +======================================================================================= + RELEASE NOTES FOR VERSION 4.0 +======================================================================================= + + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ++ The plug-in version 4.0+ is a rewriting of version 3.12.1. ++ + ++ The versions 4.0+ are based on a new and more powerful template system ++ + ++ (please see ":help template-support" for more information). ++ + ++ The template syntax has changed! ++ + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +- New template system (many thanks to Wolfgang Mehner) +- A few new hotkeys and menu item. +- A few hotkeys and menu items renamed. +- Footer did not appear in doc/bash-hotkeys.pdf + +======================================================================================= + RELEASE NOTES FOR VERSION 3.12.1 +======================================================================================= +- Minor additions and bugfixes in 2 menus. +- Test -v added. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.12 +======================================================================================= +- New global variable g:BASH_InsertFileHeader (suppress file description comment for new files) +- New menu item 'view code snippet' (\nv). +- New ex command BASH_ScriptCmdLineArguments. +- 3 ex commands renamed. +- Minor internal improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.11 +======================================================================================= +- Rendering of manuals (\hm) and Bash help (\hh). +- Bugfix: \hb, \hm, \hh not working. +- Minor internal improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.10 +======================================================================================= +- Resolve $HOME for linked home directories. +- Wrong insertion for parameter substitution "match beginning; del longest + part" (thanks to John Orr). +- Other minor bugs fixed. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.9 +======================================================================================= +- Hotkey renamed: \st -> \su +- New global variable allows loading menus only with filetype 'sh'. +- Comments: echo "<line>" escapes double quotes in original text. +- Other minor bugs fixed. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.8 +======================================================================================= +- New comment submenu 'script sections'. +- Two new hotkeys \css, \ckc for commenting. +- Two new plugin tags: LICENSE,ORGANIZATION +- Run menu: new item 'Bash cmd. line arg.' (\rba). +- I/O-Redir-menu: additional item'>&2' +- System-wide installation: minimal Template file for a user will automatically + be added. +- Hotkey renamed: \t -> \t1 +- A few code snippets for debugging added. +- Bugfix: \cl did not work in insert mode. +- Other minor bugs fixed. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.7 +======================================================================================= +- The three hotkeys \cl, \cj, \cc allow a range, e.g. '3\cl' (see help text and + bash-hot-key.pdf). +- Plugin loads faster: loading the templates is delayed until the first use. +- Plugin now works with pathogen.vim. +- Menus will always be generated (for the use with :emenu). +- Bugfix: no local templates available with a system-wide installation (thanks to Iain Arnell). +- Several improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.6 +======================================================================================= +- New hotkey \ssa and menu entry for the selection of a subarray. +- Bugfix: detection of a systemwide installation can fail. +- Minor improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.5 +======================================================================================= +- Bugfix: detection of a systemwide installation can fail. +- Minor improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.4 +======================================================================================= +- 2 new hotkeys: \t, \t2 (empty tests) +- Windows: user and system installation. +- Syntax check under Windows. +- Several minor bugsfixed. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.3 +======================================================================================= +- 3 hotkeys renamed: \sl -> \sei (elif), \sas -> \saa ( ${.[@]} ) , \hp -> \hbs. +- 3 new hotkeys: \sa1 ( ${.[*]} ), \san ( ${#.[@]} ), \sai ( ${!.[@]} ). +- 1 new menu entry (Tests) +- Minor improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.2 +======================================================================================= +- New hotkey and menu entry for [[ =~ ]] +- New for Bash 4.1: shopt 'compat40', variables '$BASHOPTS', '$BASH_XTRACEFD'. +- Bugfixes: local installation looks like a system-wide installation in seldom cases. +- Bugfixes: typo in 4 menu entries. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.1.1 +======================================================================================= +- Bugfixes: code snippets will not be found if plugin not installed beyond '$HOME/.vim'. +- Bugfixes: undocumented global variable used in above non-standard installation. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.1 +======================================================================================= +- The plugin now handles different template styles without editing and + reloading the main template file. +- New hotkey and ex-command to switch template styles. +- New global List/Dictionnary g:BASH_AlsoBash: add filename pattern (and + styles) for files not named *.sh . +- Minor improvements. +- Bugfixes: missing redraws in some cases. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.0.1 +======================================================================================= +- New global variable g:BASH_Errorformat: adapt the error format used to parse + runtime messages to your locale setting. +- Bugfix (Windows only): missing internal variable prevents proper initialization. + +======================================================================================= + RELEASE NOTES FOR VERSION 3.0 +======================================================================================= ++ Completely new template system. User can change templates on the fly. ++ Additional mapping Ctrl-j : jump behind parenthesis or strings in the current line. ++ A few Posix character classes have better shortcuts. ++ Bugfix: insert mode for Posix character classes. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.14 +======================================================================================= ++ Debugging: ddd always called with bashdb(1). ++ More complete adaption to Bash 4.0: options, builtins, environment variables. ++ Bugfix: running and starting the debugger causes error if working directory is not + the directory of the current file. ++ Minor improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.13 +======================================================================================= ++ New menu item 'array element'. ++ New hotkeys \sa, \sas. ++ New submenu 'Snippets'. ++ Hotkeys for the POSIX character classes. ++ Hardcopy (run menu) can print any buffer. ++ Bugfix: 'Run->save + run script' (\rr, <C-F9>) : visual mode broken. ++ Minor improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.12 +======================================================================================= ++ Hotkeys are shown in the menus. ++ New menu item and hotkey \hb : open the Bash manual. ++ New hotkey \rco : syntax check options. ++ File browser for code snippets choosable (new global variable). ++ Bugfix: wrapper script for use of a xterm could not handle parameters containing blanks. ++ Minor improvements. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.11 +======================================================================================= ++ Additions for Bash version 4.0. ++ Comments menu (\cj): adjustment of end-of-line comments improved. ++ Two submenus rearranged. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.10 +======================================================================================= +- new item in the Statements-menu: 'for ((...)) do done'. +- new item in the Statements-menu: 'printf "%s"'. +- new item in the Statements-menu: indirect parameter expansion ${!name} +- Bugfix: unnecessary submenu beyond 'Environ'. +- Bugfix: shopt menu had no insert mode. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.9.1 +======================================================================================= +- Map leader for hotkeys now user definable: new global variable g:BASH_MapLeader. +- Bugfix: 'Statements->no. of elem.s' inserts wrong text. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.9 +======================================================================================= ++ Can now be used under Windows, e.g. with win-bash (few restrictions). ++ Name completion when entering a builtin name. ++ Bugfix: help shows no selection when just 2 manuals are available. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.8 +======================================================================================= ++ New help menu: help reorganized, 3 new help hotkeys. ++ The help hotkeys now also work when Vim is run on the console. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.7.1 +======================================================================================= ++ Minor bugfix in the I/O-Redir-menu. ++ I/O-Redir-menu shows redirectors (sort of help). ++ I/O-Redir-menu: here-document item has a vmode. ++ File name expansion for the first command line argument entered with <S-F9>. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.7 +======================================================================================= ++ When a Bash script is started from the Vim command line errors and warnings (if any) + are caught in an error window allowing quickfix commands to be used. ++ Scripts which are not set executable can be run under Vim. ++ One new hotkey. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.6 +======================================================================================= ++ Superfluous control characters for mode switching (menus, hotkeys) removed. Caused beeps. ++ Most hotkeys now work in insert mode. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.5 +======================================================================================= ++ Menu item 'toggle comment' replaces 'code->comment' and 'comment->code' ++ Hotkey \co removed, \cc is now a toggle. ++ Bugfix. Adjusting comments (\cj): # in '$#' and '${#...}' is no longer + regarded as a start of a comment. ++ Bugfix. \cl in insert mode called function for visual mode. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.4 +======================================================================================= ++ Format for the macros |DATE|, |TIME|, and |YEAR| can be defined by the user. ++ Help text improved. ++ Option 'nocasematch' added ++ Additional menu entries: 1 parameter substitution, 1 special variable, array index list. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.3 +======================================================================================= ++ Changes to allow a system-wide installation. + +======================================================================================= + RELEASE NOTES FOR VERSION 2.2 +======================================================================================= ++ Snippets can now be managed in the console mode. ++ Three new key mappings for snippet handling. ++ Three items from the statements menu removed (quoting; but see file customization.vimrc). + +======================================================================================= + RELEASE NOTES FOR VERSION 2.1 +======================================================================================= ++ New menu item and key mapping to adjust end-of-line comments. ++ New insert mode mappings. ++ A few mappings have been renamed (to bring them into line with my C/C++ and Perl plugin). + +======================================================================================= + RELEASE NOTES FOR VERSION 2.0.1 +======================================================================================= ++ Bugfix: missing hotkey \ch added. ++ File wrapper.sh moved to the new directory 'bash-support/scripts'. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 2.0 +--------------------------------------------------------------------------------------- ++ PLUGIN DIRECTORIES REARRANGED. ++ One new mapping (\cs). ++ Statement menu extended. ++ Bash keyword help (S-F1) improved. ++ Bugfix: empty new file after removing the header template can't be closed. ++ Bugfix : Tools entry missing when root menu not shown from the start. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.15 +--------------------------------------------------------------------------------------- ++ Needs Vim version 7.0+. ++ Inserting a function can be used in visual mode (+ new key mapping). ++ Bugfix: cursor misplaced after some visual mode operations. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.14 +--------------------------------------------------------------------------------------- ++ Setting the column for the start of line-end comments improved. ++ Mac OS X : circumvent a Vim bug which caused a crash when loading plugin version 1.13. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.13 +--------------------------------------------------------------------------------------- ++ The hotkeys F9 and \rd now also starts the debugger if vim is running without GUI. ++ The debugger frontend ddd can be started as preferred debugger. ++ New help entry in the main menu of this plugin (shows the plugin documentation). ++ A hardcopy shows the localized date and time in the header line. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.12 +--------------------------------------------------------------------------------------- ++ Bugfix: hotkey <S-F9> now working again. ++ Syntax check recognizes shopt options. ++ New regex menu: compose regular expressions with a few keystrokes from the menu. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.11 +--------------------------------------------------------------------------------------- ++ Start debugger bashdb with a keystroke. ++ Parameter substitutions completed. ++ Environment variables completed / menu rearranged. ++ Builtins completed. ++ Code <-> comment working in all modes. ++ Insert/remove echo for commenting/uncommenting statements. ++ Script will be made executable before running it (e.g. after a "Save As..."). ++ Statement menu now in alphabetical order. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.10.1 +--------------------------------------------------------------------------------------- ++ Starting an xterm was not possible with some installations (bugfix). + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.10 +--------------------------------------------------------------------------------------- ++ New Bash 3.0 set options added. ++ Shopt-menu added. ++ More builtins. ++ <S-F1> or \h displays help for the Bash builtin command under the cursor. ++ Key mappings for all run menu entries. ++ Line end comments start in a fixed column now (can be set from the menu). ++ Spaces in path names and file names are now possible. ++ Template files and snippet files are no longer kept in the list of alternate files. ++ Global variable is_bash is set to avoid a wrong highlighting for $(..) and $((..)). + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.9 +--------------------------------------------------------------------------------------- ++ Running a Bash-script + (1) The script can be run from the command line as usual. + (2) The output can be directed into a window with name "Bash-Output". + The buffer and its content will disappear when closing the window. + The buffer is reused when still open. + (3) The script can be run in an xterm. ++ The new hotkey Shift-F9 or the "cmd. line arg." sets command line arguments for the + current buffer (that is, each buffer can have its own arguments). ++ A code snippet with the file name extension "ni" or "noindent" will not be + indented on insertion. ++ 'Line End Comments' ignores blank lines in a marked block. ++ Calling a set-command (submenu "Set") for a marked block will set this option above + this block and unset it below. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.8 +--------------------------------------------------------------------------------------- ++ Installation simplified. ++ Run syntax check / list errors in an error window ++ Append aligned comments to all lines of a marked block. ++ The root menu can be removed (default is not removed). ++ The dialog windows (GUI) have been replaced by more flexible command line inputs. ++ User will now be asked before a snippet file will be overwritten. ++ The undocumented and unnecessary hot key F12 has been removed. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.7 +--------------------------------------------------------------------------------------- ++ Only one entry in the gVim root menu. ++ All hotkeys are only defined for bash files. ++ Install script added. ++ Customization improved. ++ Documentation improved. ++ Bug fix (template file handling) + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.6 +--------------------------------------------------------------------------------------- ++ 28 key mappings for Vim without GUI. See bash-hot-keys.pdf (reference card). ++ Vim doc added (file bashsupport.txt). + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.5 +--------------------------------------------------------------------------------------- ++ Tag substitution rewritten (Some characters in a substitution text for a tag + prevented the tag from being substituted). ++ All bash variables can now be inserted from the menus. ++ A marked region can be surrounded by a for-, if, select- while- or until + statement (with indentation). ++ A marked text can be surrounded with quotes. ++ A marked region or a complete line can be surrounded with echo " ". ++ The echo " " can be removed from a line. + +--------------------------------------------------------------------------------------- + RELEASE NOTES FOR VERSION 1.4 +--------------------------------------------------------------------------------------- ++ Block comments are now read as templates or skeletons from files: + frame Comment, function description, file header ++ These templates can contain tags like |FILENAME|, |AUTHOR| etc. which are replaced + after reading. ++ indentation: multiline inserts and code snippets will be indented after insertion. ++ Most menu entries are now also active in normal mode. ++ Reading the templates is done in one function which can be called in an autocmd. ++ Code cleanup: register z no longer used. Most function calls are silent now. + diff --git a/.config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.pdf b/.config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6323ec372c766f6622a00a2c4e60ffc248a523c7 GIT binary patch literal 27562 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 z�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 literal 0 HcmV?d00001 diff --git a/.config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.tex b/.config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.tex new file mode 100644 index 0000000..f1107e5 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/doc/bash-hotkeys.tex @@ -0,0 +1,268 @@ +%%===================================================================================== +%% +%% File: bash-hotkeys.tex +%% +%% Description: bash-support.vim : Key mappings for Bash with/without GUI. +%% +%% Author: Dr.-Ing. Fritz Mehner +%% Email: mehner.fritz@fh-swf.de +%% Copyright: Copyright (C) 2013-2014 Dr.-Ing. Fritz Mehner (mehner.fritz@fh-swf.de) +%% Version: see \Pluginversion +%% Created: 20.05.2013 +%% +%%===================================================================================== + +%%====================================================================== +%% LaTeX settings [[[1 +%%====================================================================== + +\documentclass[oneside,11pt,landscape,DIV16]{scrartcl} + +\usepackage[english]{babel} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{times} +\usepackage{lastpage} +\usepackage{multicol} +\usepackage{fancyhdr} + +\setlength\parindent{0pt} + +\newcommand{\Pluginversion}{4.2.1} +\newcommand{\ReleaseDate}{\today} +\newcommand{\Rep}{{\scriptsize{[n]}}} + +%%---------------------------------------------------------------------- +%% fancyhdr +%%---------------------------------------------------------------------- +\pagestyle{fancyplain} +\fancyhf{} +\fancyfoot[L]{\small \ReleaseDate} +\fancyfoot[C]{\small bash-support.vim} +\fancyfoot[R]{\small \textbf{Page \thepage{} / \pageref{LastPage}}} +\renewcommand{\headrulewidth}{0.0pt} + +%%---------------------------------------------------------------------- +%% luximono : Type1-font +%% Makes keyword stand out by using semibold letters. +%%---------------------------------------------------------------------- +\usepackage[scaled]{luximono} + +%%---------------------------------------------------------------------- +%% hyperref +%%---------------------------------------------------------------------- +\usepackage[ps2pdf]{hyperref} +\hypersetup{pdfauthor={Dr.-Ing. Fritz Mehner, FH Südwestfalen, Iserlohn, Germany}} +\hypersetup{pdfkeywords={Vim, Perl}} +\hypersetup{pdfsubject={Vim-plug-in, bash-support.vim, hot keys}} +\hypersetup{pdftitle={Vim-plug-in, bash-support.vim, hot keys}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% START OF DOCUMENT +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document}% + +\begin{multicols}{3} +% +\begin{center} +% +%%====================================================================== +%% title [[[1 +%%====================================================================== +\textbf{\textsc{\small{Vim-Plug-in}}}\\ +\textbf{\LARGE{bash-support.vim}}\\ +\textbf{\textsc{\small{Version \Pluginversion}}}\\ +\vspace{5mm}% +\textbf{\textsc{\Huge{Hot keys}}}\\ +\vspace{5mm}% +Key mappings for Vim and gVim.\\ +Plug-in: http://vim.sourceforge.net\\ +Fritz Mehner (mehner.fritz@fh-swf.de)\\ +\vspace{1.0mm} +{\normalsize (i)} insert mode, {\normalsize (n)} normal mode, {\normalsize (v)} visual mode\\ +\vspace{4.0mm} + +%%====================================================================== +%% table, left part [[[1 +%%====================================================================== +%%---------------------------------------------------------------------- +%% main menu [[[2 +%%---------------------------------------------------------------------- +%%~~~~~ TABULAR : begin ~~~~~~~~~~ +\begin{tabular}[]{|p{11mm}|p{60mm}|} +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{B}ash}}\\[1.0ex] +\hline \verb'\bps' & \textbf{p}arameter \textbf{s}ubstitution (list) \hfill (n, i)\\ +\hline \verb'\bsp' & \textbf{s}pecial \textbf{p}arameters (list) \hfill (n, i)\\ +\hline \verb'\ben' & \textbf{en}vironment (list) \hfill (n, i)\\ +\hline \verb'\bbu' & \textbf{bu}iltins (list) \hfill (n, i)\\ +\hline \verb'\bse' & \textbf{se}t options (list) \hfill (n, i)\\ +\hline \verb'\bso' & \textbf{s}h\textbf{o}pts (list) \hfill (n, i)\\ +\hline +%%---------------------------------------------------------------------- +%% menu Comments [[[2 +%%---------------------------------------------------------------------- +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{C}omments}} \\[1.0ex] +\hline \Rep\verb'\cl' & end-of-line comment \hfill (n, i, v)\\ +\hline \Rep\verb'\cj' & adjust end-of-line comments \hfill (n, i, v)\\ +\hline \verb'\cs' & set end-of-line comment col. \hfill (n)\\ +% +\hline \Rep\verb'\cc' & code $\rightarrow$ comment \hfill (n, i, v)\\ +\hline \Rep\verb'\cu' & uncomment code \hfill (n, i, v)\\ +% +\hline \verb'\cfr' & frame comment \hfill (n, i)\\ +\hline \verb'\cfu' & function description \hfill (n, i)\\ +\hline \verb'\ch' & file header \hfill (n, i)\\ +\hline \verb'\cd' & date \hfill (n, i)\\ +\hline \verb'\ct' & date \& time \hfill (n, i)\\ +\hline \verb'\css' & script sections \hfill (n, i)\\ +\hline \verb'\ckc' & keyword comments \hfill (n, i)\\ +\hline \verb'\cma' & plug-in macros \hfill (n, i)\\ +% +\hline \verb'\ce' & \texttt{echo} "\textsl{actual line}" \hfill (n, i)\\ +\hline \verb'\cr' & remove \texttt{echo} from actual line \hfill (n, i)\\ +\hline +\end{tabular}\\ +%%~~~~~ TABULAR : end ~~~~~~~~~~ +% +%%====================================================================== +%% table, middle part [[[1 +%%====================================================================== +%%---------------------------------------------------------------------- +%% menu Statements [[[2 +%%---------------------------------------------------------------------- +%%~~~~~ TABULAR : begin ~~~~~~~~~~ +\begin{tabular}[]{|p{11mm}|p{60mm}|} +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{S}tatements}} \\[1.0ex] +\hline \verb'\sc' & \verb'case in ... esac' \hfill (n, i)\\ +\hline \verb'\sei' & \verb'elif then' \hfill (n, i)\\ +\hline \verb'\sf' & \verb'for in do done' \hfill (n, i, v)\\ +\hline \verb'\sfo' & \verb'for ((...)) do done' \hfill (n, i, v)\\ +\hline \verb'\si' & \verb'if then fi' \hfill (n, i, v)\\ +\hline \verb'\sie' & \verb'if then else fi' \hfill (n, i, v)\\ +\hline \verb'\ss' & \verb'select in do done' \hfill (n, i, v)\\ +\hline \verb'\su' & \verb'until do done' \hfill (n, i, v)\\ +\hline \verb'\sw' & \verb'while do done' \hfill (n, i, v)\\ +\hline \verb'\sfu' & \verb'function' \hfill (n, i, v)\\ +% +\hline \verb'\se' & \verb'echo -e ""' \hfill (n, i, v)\\ +\hline \verb'\sp' & \verb'printf "%s"' \hfill (n, i, v)\\ +% +\hline \verb'\sae' & array element\ \ \ \verb'${.[.]}' \hfill (n, i, v)\\ +\hline \verb'\saa' & arr. elem.s (all) \ \verb'${.[@]}' \hfill (n, i, v)\\ +\hline \verb'\sas' & arr. elem.s (1 word) \ \verb'${.[*]}' \hfill (n, i, v)\\ +\hline \verb'\ssa' & subarray \ \verb'${.[@]::}' \hfill (n, i, v)\\ +\hline \verb'\san' & no. of arr. elem.s \ \verb'${.[@]}' \hfill (n, i, v)\\ +\hline \verb'\sai' & list of indices \ \verb'${.[*]}' \hfill (n, i, v)\\ +\hline +%% +%%---------------------------------------------------------------------- +%% menu Tests [[[2 +%%---------------------------------------------------------------------- +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{T}ests}} \\[1.0ex] +\hline \verb'\ta' & arithmetic tests \hfill (n, i)\\ +\hline \verb'\tfp' & file permissions \hfill (n, i)\\ +\hline \verb'\tft' & file types \hfill (n, i)\\ +\hline \verb'\tfc' & file characteristics \hfill (n, i)\\ +\hline \verb'\ts' & string comparisons \hfill (n, i)\\ +\hline \verb'\toe' & option is enabled \hfill (n, i)\\ +\hline \verb'\tvs' & variables has been set \hfill (n, i)\\ +\hline \verb'\tfd' & file descr. refers to a terminal \hfill (n, i)\\ +\hline \verb'\tm' & string matches regexp \hfill (n, i)\\ +\hline +%% +%%---------------------------------------------------------------------- +%% menu IO-Redirection [[[2 +%%---------------------------------------------------------------------- +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{I}O-Redirection}} \\[1.0ex] +\hline \verb'\ior' & IO-redirections (list) \hfill (n, i)\\ +\hline \verb'\ioh' & here-document \hfill (n, i)\\ +\hline +% +\end{tabular}\\ +%%~~~~~ TABULAR : end ~~~~~~~~~~ +% +%%====================================================================== +%% table, right part [[[1 +%%====================================================================== +%%---------------------------------------------------------------------- +%% menu Pattern Matching [[[2 +%%---------------------------------------------------------------------- +%%~~~~~ TABULAR : begin ~~~~~~~~~~ +\begin{tabular}[]{|p{11mm}|p{62mm}|} +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{P}attern Matching}} \\[1.0ex] +\hline \verb'pzo' & zero or one, \verb' ?( | )' \hfill (n, i)\\ +\hline \verb'pzm' & zero or more, \verb' *( | )' \hfill (n, i)\\ +\hline \verb'pom' & one or more, \verb' +( | )' \hfill (n, i)\\ +\hline \verb'peo' & exactly one, \verb' @( | )' \hfill (n, i)\\ +\hline \verb'pae' & anything except, \verb' !( | )' \hfill (n, i)\\ +\hline \verb'ppc' & POSIX classes \hfill (n, i)\\ +\hline \verb'pbr' & \verb'${BASH_REMATCH[0'$\ldots$\verb'3]}' \hfill (n, i)\\ +\hline +% +%%---------------------------------------------------------------------- +%% menu Snippet [[[2 +%%---------------------------------------------------------------------- +\hline +\multicolumn{2}{|r|}{\textsl{S\textbf{n}ippets}} \\[1.0ex] +\hline \verb'\nr' & read code snippet \hfill (n, i)\\ +\hline \verb'\nv' & view code snippet \hfill (n, i)\\ +\hline \verb'\nw' & write code snippet \hfill (n, i, v)\\ +\hline \verb'\ne' & edit code snippet \hfill (n, i)\\ +\hline \verb'\ntl' & edit templates \hfill (n, i)\\ +\hline \verb'\ntr' & reread templates \hfill (n, i)\\ +\hline \verb'\nts' & choose style \hfill (n, i)\\ +\hline +%%---------------------------------------------------------------------- +%% menu Run [[[2 +%%---------------------------------------------------------------------- +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{R}un}} \\[1.0ex] +\hline \verb'\rr' & update file, run script \hfill (n, i, v$^1$)\\ +\hline \verb'\ra' & set script cmd. line arguments \hfill (n, i)\\ +\hline \verb'\rba' & set Bash cmd. line arguments \hfill (n, i)\\ +\hline \verb'\rc' & update file, check syntax \hfill (n, i)\\ +\hline \verb'\rco' & syntax check options \hfill (n, i)\\ +\hline \verb'\rd' & start debugger$^1$ \hfill (n, i)\\ +\hline \verb'\re' & make script executable/not exec.$^1$ \hfill (n, i)\\ +\hline \verb'\rh' & hardcopy buffer \hfill (n, i, v)\\ +\hline \verb'\rs' & plug-in settings \hfill (n, i)\\ +\hline \verb'\rx' & set xterm size$^{1,2}$ \hfill (n, i)\\ +\hline \verb'\ro' & change output destination \hfill (n, i)\\ +\hline +%%---------------------------------------------------------------------- +%% menu Help [[[2 +%%---------------------------------------------------------------------- +\hline +\multicolumn{2}{|r|}{\textsl{\textbf{H}elp}}\\[1.0ex] +\hline \verb'\hb' & display the Bash manual \hfill (n,i)\\ +\hline \verb'\hh' & help (Bash builtins) \hfill (n,i)\\ +\hline \verb'\hm' & show manual (cmd. line utilities) \hfill (n,i)\\ +\hline \verb'\hp' & help (plug-in) \hfill (n,i)\\ +\hline +\end{tabular}\\ +%%~~~~~ TABULAR : end ~~~~~~~~~~ +% +\vfill +% +\begin{minipage}[b]{75mm}% +\scriptsize{% +\vspace{2mm} +%\hrulefill\\ +$^1$ {Linux/U**x only}\\ +$^2$ {GUI only} +}% +\end{minipage}\\ +% +% +\end{center}% +\end{multicols}% +% +%%----- TABBING : end ---------- +\end{document} +% vim: foldmethod=marker foldmarker=[[[,]]] diff --git a/.config/nvim/plugged/bash-support.vim/doc/bashsupport.txt b/.config/nvim/plugged/bash-support.vim/doc/bashsupport.txt new file mode 100644 index 0000000..6b4ff6f --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/doc/bashsupport.txt @@ -0,0 +1,1298 @@ +*bashsupport.txt* Bash Support March 25 2014 + +Bash Support *bash-support* *bashsupport* + Plugin version 4.2.1 + for Vim version 7.0 and above + Fritz Mehner <mehner@fh-swf.de> + +Bash Support implements a bash-IDE for Vim/gVim. It is written to considerably +speed up writing code in a consistent style. This is done by inserting +complete statements, comments, idioms, and code snippets. Syntax checking, +running a script, starting a debugger can be done with a keystroke. There +are many additional hints and options which can improve speed and comfort when +writing shell scripts. This plug-in can be used for Bash version 4.0. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++ The plug-in version 4.0+ is a rewriting of version 3.12.1. ++ +++ The versions 4.0+ are based on a new and more powerful template system ++ +++ (please see |template-support|for more information). ++ +++ The template syntax has changed! ++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + 1. Usage with GUI |bashsupport-usage-gvim| + 1.1 Menu 'Comments' |bashsupport-comments| + 1.1.1 Append aligned comments |bashsupport-aligned-comm| + 1.1.2 Adjust end-of-line comments |bashsupport-comm-realign| + 1.1.3 Comment/uncomment |bashsupport-comm-toggle| + 1.1.4 Frame comments, file header, ... |bashsupport-comm-templates| + 1.1.5 Comment/uncomment with echo |bashsupport-comm-echo| + 1.1.6 KEYWORD + comment |bashsupport-comm-keywords| + 1.2 Menu 'Statements' |bashsupport-statements| + 1.2.1 Normal mode, insert mode |bashsupport-stat-norm-ins| + 1.2.2 Visual mode |bashsupport-stat-visual| + 1.3 Menus'Tests' ... 'Shopts' |bashsupport-tests| + 1.4 Menu 'PatternMatching' |bashsupport-pattern| + 1.5 Menu 'I/O-Redir' |bashsupport-io-redir| + 1.6 Menu 'Snippets' |bashsupport-snippets| + 1.6.1 Code Snippets |bashsupport-codesnippets| + 1.6.2 Edit Templates |bashsupport-templates-edit| + 1.7 Menu 'Run' |bashsupport-run| + 1.7.1 Save and run |bashsupport-run-script| + 1.7.2 Script command line arguments |bashsupport-cmdline-args| + 1.7.3 Bash command line arguments |bashsupport-bash-cmdline-args| + 1.7.4 Save and check syntax |bashsupport-syntax-check| + 1.7.4.1 Error format |bashsupport-errorformat| + 1.7.4.2 Syntax check options |bashsupport-syntax-check-options| + 1.7.5 Start debugger |bashsupport-debugger| + 1.7.6 Hardcopy |bashsupport-hardcopy| + 1.7.7 Xterm size |bashsupport-xterm| + 1.7.8 Output redirection |bashsupport-output| + 1.8 Menu 'Help' |bashsupport-help| + 2. Usage without GUI |bashsupport-usage-vim| + 3. Hot keys |bashsupport-hotkeys| + 4. Customization and configuration |bashsupport-customization| + 4.1 Files |bashsupport-custom-files| + 4.2 Global variables |bashsupport-custom-variables| + 4.3 The root menu |bashsupport-custom-root| + 4.4 System-wide installation |bashsupport-system-wide| + 5. Template files and tags |bashsupport-templates| + 5.1 Template files |bashsupport-templates-files| + 5.2 Macros |bashsupport-templates-macros| + 5.2.1 Formats for date and time |bashsupport-templates-date| + 5.3 Templates |bashsupport-templates-names| + 5.3.1 Template definition |bashsupport-templates-definition| + 5.3.1 Template names |bashsupport-templates-names| + 5.3.2 The jump tags <+text+> etc. |bashsupport-templates-jumptags| + 5.3.3 Command Ctrl-j |bashsupport-Ctrl-j| + 5.4 Additional filenames with filetype 'sh' |bashsupport-also-bash| + 6. Bash dictionary |bashsupport-dictionary| + 7. Additional Mappings |bashsupport-ad-mappings| + 8. Windows particularities |bashsupport-windows| + 9. TROUBLESHOOTING |bashsupport-troubleshooting| +10. Release Notes |bashsupport-release-notes| + + How to add this help file to Vim's help |add-local-help| + + +============================================================================== +1. USAGE with GUI (gVim) *bashsupport-usage-gvim* +============================================================================== + +If the menus are not visible call them with the entry "Load Bash Support" +in the standard Tools-menu. + +------------------------------------------------------------------------------ +1.1 MENU 'Comments' *bashsupport-comments* +------------------------------------------------------------------------------ + +1.1.1 APPEND ALIGNED COMMENTS TO CONSECUTIVE LINES *bashsupport-aligned-comm* +-------------------------------------------------- + +In NORMAL MODE the menu item 'end-of-line comment' will append a comment to +the current line. +In VISUAL MODE, this item will append aligned comments to all marked lines. +Marking the 4 lines +> + x11=11; + x1111=1111; + + x11111111=11111111; +< +and choosing 'end-of-line comment' will yield +> + x11=11; # | + x1111=1111; # + + x11111111=11111111; # +< +The cursor position above is marked by '|' . Empty lines will be ignored. + +The default starting column is 49 ( = (multiple of 2,4, or 8) + 1 ). This can +be changed by setting a global variable in the file '.vimrc', e.g. : +> + let g:BASH_LineEndCommColDefault = 45 +< +The starting column can also be set by the menu item 'Comments->adjust +end-of-line com.' . Just position the cursor in an arbitrary column (normal +mode; column number is shown in the Vim status line) and choose this menu +item. This setting is buffer related. +If the cursor was at the end of a line you will be asked for a column number +because this position is most likely not the desired starting column. Your +choice will be confirmed. + + +1.1.2 ADJUST END-OF-LINE COMMENTS *bashsupport-comm-realign* +--------------------------------- +After some copy/paste/change actions comments may be misaligned: +> + pathname=$(pwd) # the complete path + basename=${pathname##*/} # the basename + dirname=${pathname%/*} # the pathname +< +Realignment can be achieved with the menu item 'adjust end-of-line com.' In +normal mode the comment (if any) in the current line will be aligned to the +end-of-line comment column (see above) if possible. In visual mode the +comments in the marked block will be aligned: +> + pathname=$(pwd) # the complete path + basename=${pathname##*/} # the basename + dirname=${pathname%/*} # the pathname +< +Another way is to use the hotkey \cj. In normal and insert mode the current +line will be adjusted. To adjust n lines starting with the current one use +n\cj. + +1.1.3 COMMENT/UNCOMMENT *bashsupport-comm-toggle* +------------------------ +The comment sign # can be set or removed at the beginning of the current line +or for a marked block using the menu items 'comment' (or \cc) and 'uncomment' +(or \cu). A single line needs not to be marked (normal mode, insert mode). + +A marked block +> + pathname=$(pwd) # the complete path + basename=${pathname##*/} # the basename + dirname=${pathname%/*} # the pathname +< +will be changed into (and vice versa) +> + #pathname=$(pwd) # the complete path + #basename=${pathname##*/} # the basename + #dirname=${pathname%/*} # the pathname +< + +1.1.4 FRAME COMMENTS, FILE HEADER, ... *bashsupport-comm-templates* +-------------------------------------- + +Frame comments, function descriptions and file header comments are read as +templates from the appropriate files (see |bashsupport-templates|). + +1.1.5 COMMENT/UNCOMMENT WITH echo *bashsupport-comm-echo* +--------------------------------- + +The echo-entry in the Comments-menu can be used to put one or more statements +in a sort of comment. This is usually done for testing: +> + echo "rm -f $allfiles" +< +This can only be done in normal mode: The complete line (from the first +non-blank to the end) is framed with echo "..." ; the cursor will then be +moved to the next line. Now this line can be framed and so forth. + +The remove-echo-entry removes an echo. The keyword echo, the following double +quotation mark, and the last double quotation mark in the current line will be +removed; the cursor will then be moved to the next line. + +1.1.6 KEYWORD+comment *bashsupport-comm-keywords* +--------------------- + +Preliminary end-of-line comments to document (and find again!) places where +work will be resumed shortly, like +> + # :BUG:23.05.2013 16:43:fgm: +< +Here 'fgm' is the authors reference (see section 4. for templates and tags). +Usually these comments are not meant for the final documentation. + +------------------------------------------------------------------------------ +1.2 MENU 'Statements' *bashsupport-statements* +------------------------------------------------------------------------------ + +1.2.1 NORMAL MODE, INSERT MODE. *bashsupport-stat-norm-ins* +-------------------------------- + +An empty statement will be inserted and properly indented. The item 'if' +will insert an if-statement: +> + if | ; then + fi +< +The statement will be indented. + +1.2.2 VISUAL MODE *bashsupport-stat-visual* +------------------ +The highlighted area +> + xxxxx + xxxxx +< +can be surrounded by one of the following statements ( '|' +marks the cursor position after insertion): +> + +--------------------------+---------------------------------------+ + | | | + | for | in ; do | for (( CNTR=0; CNTR<|; CNTR++ )); do | + | xxxxx | xxxxx | + | xxxxx | xxxxx | + | done | done | + | | | + +--------------------------+---------------------------------------+ + | | | + | if | ; then | if | ; then | + | xxxxx | xxxxx | + | xxxxx | xxxxx | + | fi | else | + | | | + | | fi | + | | | + +--------------------------+---------------------------------------+ + | | | + | select | in ; do | until | ; do | + | xxxxx | xxxxx | + | xxxxx | xxxxx | + | done | done | + | | | + +--------------------------+---------------------------------------+ + | | | + | while | ; do | | + | xxxxx | | + | xxxxx | | + | done | | + | | | + +--------------------------+---------------------------------------+ + | | + | fname () | + | { | + | xxxxx | + | xxxxx | + | } # ---------- end of function fname ---------- | + | | + +------------------------------------------------------------------+ +< +The whole statement will be indented after insertion. + +------------------------------------------------------------------------------ +1.3 MENUS 'Tests' ... 'Shopts' *bashsupport-tests* +------------------------------------------------------------------------------ + +Insert tests, parameter substitutions, ... I/O-redirections. + +------------------------------------------------------------------------------ +1.4 MENU 'PatternMatching' *bashsupport-pattern* +------------------------------------------------------------------------------ + +This menu can be used to compose globs and regular expressions with a few +keystrokes. In normal and insert mode the items insert the shown constructs +after the cursor. The first group ( "zero or more" ... "anything expect") can +enclose a marked text. The marked text +> + xxxxx +< +will be changed into +> + *(xxxxx|) +< +by the first choice. + +------------------------------------------------------------------------------ +1.5 MENU 'I/O-Redir' *bashsupport-io-redir* +------------------------------------------------------------------------------ + +This menu can be used to insert I/O redirectors. The cursor will be positioned +at the obvious or most likely continuation point. +The item 'here-document' has a visual mode. A few marked lines will be +surrounded by the necessary statements, e.g. +> + << EOF + xxxxxxxxxxx + xxxxxxxxxxx + EOF + # ===== end of here-document ===== +< + +------------------------------------------------------------------------------ +1.6 MENU 'SNIPPETS' *bashsupport-snippets* +------------------------------------------------------------------------------ + +1.6.1 Code Snippets *bashsupport-codesnippets* +------------------- +Code snippets are pieces of code which are kept in separate files in a special +directory. File names are used to identify the snippets. The default snippet +directory is '$HOME/.vim/bash-support/codesnippets'. Snippets are managed +with the 4 items +> + 'read code snippet' + 'view code snippet' + 'write code snippet' + 'edit code snippet' +< +from the Snipptes submenu. + +Creating a new snippet: +----------------------- +When nothing is marked, 'write code snippet' will write the whole buffer +to a snippet file, otherwise the marked area will be written to a file. + +Insert a snippet: +----------------- +Select the appropriate file from the snippet directory ('read code snippet'). +The inserted lines will be indented. + +Indentation / no indentation +---------------------------- +Code snippets are normally indented after insertion. To suppress indentation +add the file extension "ni" or "noindent" to the snippet file name, e.g. +> + parameter_handling.noindent +< +Snippet browser +--------------- +Under a GUI a file requester will be put up. Without GUI the filename will be +read from the command line. You can change this behavior by setting a global +variable in your $HOME/.vimrc : +> + let g:BASH_GuiSnippetBrowser = 'commandline' +< +The default value is 'gui'. + + +1.6.2 Edit Templates *bashsupport-templates-edit* +--------------------- +Nearly all menu items insert code snippets or comments. All of these are +contained within template files and can be changed by the user to meet their +requirements (see|bashsupport-templates|on how to use the template system). + +The menu item 'edit templates' opens the main template file in a local plug-in +installation. This is usually the file +'$HOME/.vim/bash-support/templates/Templates'. There may be dependent files +loaded from the main file. Now change whatever file you want, save it, and +click on the menu item 'reread templates' to read in the file(s) and to +rebuild the internal representation of the templates. If menu items, hotkeys, +or shortcuts have been added or changed these changes will be applied with the +next start of Vim. + +------------------------------------------------------------------------------ +1.7 MENU 'Run' *bashsupport-run* +------------------------------------------------------------------------------ + +1.7.1 Save and run *bashsupport-run-script* +------------------ + +Save the current buffer to his file and run this file. The command line, the +applied parameters and the shell return code are shown in the bottom line. + + * In NORMAL MODE the whole buffer will be executed. + * In VISUAL MODE only the selected lines will be executed. + +There are three output destinations (see|bashsupport-output|). If the output +destination is VIM runtime errors are caught in an error window allowing +quickfix commands to be used (see|quickfix|). + +The shell used can be set in the file '.vimrc', e.g. : +> + let g:BASH_Executable = '/bin/zsh' +< +The default is the value of $SHELL (Linux/U**X) or 'bash.exe' (Windows). + +1.7.2 Script command line arguments *bashsupport-cmdline-args* +----------------------------------- + +The item 'script cmd. line arg.' calls an input dialog which asks for command +line arguments. These arguments are forwarded to the script which is run by +the 'run' item. The arguments are kept until you change them. For file names +tab-expansion will work. The ex command +> + :BashScriptArguments ... +< +can also be used to set the command line arguments for the current script. + +The arguments belong to the current buffer (that is, each buffer can have its +own arguments). The input dialog has a history. + +If the buffer gets a new name with "save as" the arguments will now belong to +the buffer with the new name. + +1.7.3 Bash command line arguments *bashsupport-bash-cmdline-args* +--------------------------------- + +The menu item 'Bash com. line arg.' calls an input dialog which asks for +command line options for the the Bash shell running the script in the actual +buffer (like -x or -v; see the Bash manual for possible options). These +arguments are forwarded to the invocation of Bash which is run by the 'run' +entry. The arguments are kept until you change them. + +The arguments belong to the current buffer (that is, each buffer can have its +own arguments). +If the buffer gets a new name with "save as" the arguments will now belong to +the buffer with the new name. + +1.7.4 Save and check syntax *bashsupport-syntax-check* +--------------------------- + +Save the current buffer to this file and run this file with the -n flag +(Bash: read commands but do not execute them; same for dash, ksh, zsh). +Errors are listed in an error window; now the quickfix commands can be used. + +1.7.4.1 ERROR FORMAT *bashsupport-errorformat* +-------------------- +The format used to parse runtime errors handle bash, dash, ksh, and zsh +errors. This format is appropriate for most locales including 'C' and +'POSIX'. + +1.7.4.2 SYNTAX CHECK OPTIONS *bashsupport-syntax-check-options* +---------------------------- + +The syntax check can be influenced by shopt options. Options which shall +always take effect can be declared in '.vimrc' , e.g. +> + let g:BASH_SyntaxCheckOptionsGlob = "-O extglob" +< +These options can be augmented or canceled using the menu entry 'syntax check +options' typing for instance +> + +O extglob -O nocaseglob +< +after the prompt. The options entered this way are buffer related. The global +options set in '.vimrc' and the buffer related options are checked. + + +1.7.5 START DEBUGGER *bashsupport-debugger* +-------------------- + +Start the debugger 'bashdb' or the frontend 'ddd' from the menu entry +Run->debug (GUI), with hotkey \rd or F9. Your version of the bash must be +prepared for debugging and the debugger must be installed (see +http://bashdb.sourceforge.net/). + +(1) Using bashdb +When using gvim or vim running under a GUI the debugger will be started in an +independent xterm. This is done because the shell integration in gvim has +deficiencies (see also :h shell-window). + +When using vim from a console terminal the debugger will be started as +> + :!xterm <xterm defaults> -e bashdb -- <script> <arguments> & +< +The debugger now will be run inside vim. + +(2) Using ddd +The frontend ddd can be started via the menu or the hotkeys instead of bashdb +as described above. The preference can be set with the global variable +g:BASH_Debugger (possible values: 'term', 'ddd' ) in '.vimrc' : +> + let g:BASH_Debugger = 'ddd' +< +The default is 'term'. + +In all cases the command line arguments from the argument setting +(|bashsupport-cmdline-args|) are passed to the debugger. + + +1.7.6 Hardcopy *bashsupport-hardcopy* +-------------- + +Generates a PostScript file from the whole buffer or from a marked region. +The hardcopy goes to the current working directory. If the buffer contains +documentation or other material from non-writable directories the hardcopy +goes to the HOME directory. The output destination will be shown in a message. + +The print header contains date and time for the current locale. The definition +used is +> + let s:BASH_Printheader = "%<%f%h%m%< %=%{strftime('%x %X')} Page %N" +< +The current locale can be overwritten by changing the language, e.g. +> + :language C +< +or by setting a global variable in the file '.vimrc', e.g. : +> + let g:BASH_Printheader = "%<%f%h%m%< %=%{strftime('%x %X')} SEITE %N" +< +See :h printheader and :h strftime() for more details. + + +1.7.7 Xterm size *bashsupport-xterm* +---------------- + +The size of the xterm (see below) can be changes for the current session. The +size has to be specified as COLUMNS LINES (e.g. 96 32 ). + +1.7.8 Output redirection *bashsupport-output* +------------------------ + +The last menu entry 'output: ... ' has 3 states: + 'output: VIM->buffer->xterm' + 'output: BUFFER->xterm->vim' + 'output: XTERM->vim->buffer' +The first state (upper-case) is the current one. + +Target VIM +---------- +The script is run from the command line like ":!${SHELL} % arguments". +This is suitable for scripts with dialog elements and few lines of output. + +When a script is started this way errors and warnings (if any) are caught in +an error window allowing quickfix commands to be used (see|quickfix|). + +Target BUFFER +------------- +The shell output will be displayed in a window with name "Bash-Output". This +buffer and its content will disappear when the window is closed. It is not +writable and it has no file. The content could be saved with "save as". +If the output fits completely into this window the cursor will stay in the +script window otherwise the cursor will be set into the output window (you may +want to scroll). +When the script is run again and the output buffer is still open it will be +reused. + +The buffer will not be opened if the script does not produce any output. +This is for convenience; you do not have to close an empty buffer. + +* This is suitable for scripts without dialog elements and many lines of output +* (e.g. from options like xtrace). Use Vim as pager (scroll, jump, search with +* regular expressions, .. ) + +Target XTERM +------------ +The script will be run in a xterm-window. A wrapper script will ask you to +close this window with Return or <C-D> (bash). +The wrapper shows the complete command line and the return code of the script. + +* This is suitable for scripts with dialog elements and many lines of output. +* The xterm is scrollable and independent from the editor window. + +Appearance of the xterm +----------------------- +The appearance of the xterm can be controlled by the global variable +g:BASH_XtermDefaults. The assignment +> + let g:BASH_XtermDefaults = "-fa courier -fs 10 -geometry 96x32" +< +placed in '.vimrc' would override the defaults. The defaults are +> + "-fa courier -fs 12 -geometry 80x24" +< +FreeType font 'courier', FreeType font size 12 point, window width 80 +characters, window height 24 lines. + +The default output method is VIM. The preferred output method can be selected +in '.vimrc' by the global variable g:BASH_OutputGvim, e.g. +> + let g:BASH_OutputGvim = "xterm" +< +The methods are "vim", "buffer" and "xterm". + +------------------------------------------------------------------------------ +1.8 MENU 'Help' *bashsupport-help* +------------------------------------------------------------------------------ + +Item 'Bash manual' +--------------------------- +Open the Bash manual. + +Item 'help (Bash builtins)' +--------------------------- +Look up Bash help for the word under the cursor. If there is no word under the +cursor you will be asked for the name of a builtin. The tab expansion can be +used. + +Item 'manual (utilities)' +------------------------- +Display the manual for the word under the cursor. If there is more than one +hit a list of possibilities will be displayed to choose from. + +If there is no word under the cursor you will be asked for the name of a +command line utility. In this case the command completion is on while entering +a name. +An interface to the on-line reference manuals must be installed (usually +man(1) for Linux/Unix, see|bashsupport-custom-variables|). + +Item 'bash-support' +------------------- +Display this help text if it was properly added with ':helptags'. + + +============================================================================== +2. USAGE without GUI (Vim) *bashsupport-usage-vim* +============================================================================== + +The frequently used constructs can be inserted with key mappings. The +mappings are also described in the document 'bash-hotkeys.pdf' (reference +card, part of this package). + + * All mappings are filetype specific: they are only + * defined for buffers with filetype 'sh' to minimize conflicts with mappings + * from other plug-ins. + +Hint: Typing speed matters. The combination of a leader ('\') and the +following character(s) will only be recognized for a short time. + +Some mappings can be used with line range. In normal mode +> + \cl +< +appends a end-of-line comment to the current line, whereas +> + 4\cl +< +appends end-of-line comments to the 4 lines starting with the current line. + +Legend: (i) insert mode, (n) normal mode, (v) visual mode + [n] range + + -- Submenus ---------------------------------------------- + + \bps parameter substitution (list) (n, i) + \bsp special parameters (list) (n, i) + \ben environment (list) (n, i) + \bbu builtin (list) (n, i) + \bse set options (list) (n, i) + \bso shopts (list) (n, i) + + -- Comments ---------------------------------------------- + + [n]\cl line end comment (n, i, v) + [n]\cj adjust end-of-line comments (n, i, v) + \cs set end-of-line comment column (n) + [n]\cc code -> comment (n, i, v) + [n]\cu uncomment code (n, i, v) + \cfr frame comment (n, i) + \cfu function description (n, i) + \ch file header (n, i) + \cd date (n, i, v) + \ct date & time (n, i, v) + \css script sections (n, i) + \ckc keyword comments (n, i) + \cma plug-in macros (n, i) + \ce echo "..." (n, i) + \cr remove echo "..." (n, i) + + -- Statements --------------------------------------------- + + \sc case in ... esac (n, i) + \sei elif then (n, i) + \sf for in do done (n, i, v) + \sfo for ((...)) do done (n, i, v) + \si if then fi (n, i, v) + \sie if then else fi (n, i, v) + \ss select in do done (n, i, v) + \su until do done (n, i, v) + \sw while do done (n, i, v) + \sfu function (n, i, v) + \se echo -e "..." (n, i, v) + \sp printf "..." (n, i, v) + \sa array element, ${.[.]} (n, i, v) + \saa array elements (all), ${.[@]} (n, i, v) + \sas array elements (string), ${.[*]} (n, i, v) + \ssa subarray, ${.[@]::} (n, i, v) + \san no. of array elements, ${#.[@]} (n, i, v) + \sai array indices, ${!.[*]} (n, i, v) + + -- Test --------------------------------------------------- + + \ta arithmetic tests (n, i) + \tfp file permission (n, i) + \tft file types (n, i) + \tfc file characteristics (n, i) + \ts string comparison (n, i) + \toe option is enabled (n, i) + \tvs variables has been set (n, i) + \tfd file descriptor is open (n, i) + \tm string matches regexp (n, i) + + -- I/O-Redirection ---------------------------------------- + \ior IO-redirections (list) (n, i) + \ioh here-document (n, i) + + -- Pattern Matching --------------------------------------- + + \pzo zero or more, ?( | ) (n, i) + \pzm zero or more, *( | ) (n, i) + \pom one or more, +( | ) (n, i) + \peo exactly one, @( | ) (n, i) + \pae anything except, !( | ) (n, i) + \ppc POSIX classes (n, i) + \pbr BASH_REMATCH (n, i) + + -- Snippets ----------------------------------------------- + + \nr read code snippet (n, i) + \nv view code snippet (readonly) (n, i) + \nw write code snippet (n, v, i) + \ne edit code snippet (n, i) + + \ntl edit templates (n, i) + \ntr reread the templates (n, i) + \nts switch template style (n, i) + + -- Run ---------------------------------------------------- + + [n]\rr update file, run script (n, i) + \ra set script cmd. line arguments (n, i) + \rba set Bash cmd. line arguments (n, i) + \rc update file, check syntax (n, i) + \rco syntax check options (n, i) + \rd start debugger (n, i) + \re make script executable/not exec.(*) (in ) + \rh hardcopy buffer to FILENAME.ps (n, i) + \rs plug-in settings (n, i) + \rt set xterm size (*) (n, i) + \ro change output destination (n, i) + + -- Bash help ---------------------------------------------- + + \hb Displays the Bash manual (n, i) + \hh Displays help for the builtin (n, i) + under the cursor (Bash help). + The tab expansion is active. + \hm displays the manual for the (n, i) + Bash command under the cursor + The tab expansion is active. + \hbs Displays the Vim help page for (n, i) + this plug-in. + +(*) Linux/UNIX only + +File 'bash-hotkeys.pdf' contains a reference card for these key mappings. +Multiline inserts and code snippets will be indented after insertion. + +Changing the default map leader '\' +----------------------------------- +The map leader can be changed by the user by setting a global variable in the +file .vimrc +> + let g:BASH_MapLeader = ',' +< +The map leader is now a comma. The 'line end comment' command is now defined +as ',cl'. This setting will be used as a so called local leader and influences +only files with filetype 'sh'. + +The configured mapleader can also be used in the ftplugin, by calling the +functions *Bash_SetMapLeader()* and *Bash_ResetMapLeader()* . The maps created +between the two calls will use |g:BASH_MapLeader| as the |<LocalLeader>|: +> + call Bash_SetMapLeader () + + map <buffer> <LocalLeader>eg :echo "Example Map :)"<CR> + + call Bash_ResetMapLeader () +< + +============================================================================== +3. HOT KEYS *bashsupport-hotkeys* +============================================================================== + +The following hot keys are defined in NORMAL, VISUAL and INSERT MODE: + + Ctrl-F9 run script + Alt-F9 run syntax check + Shift-F9 command line arguments (for the current buffer) + F9 start debugger (bashdb) + +See |bashsupport-usage-vim| for more hotkeys. + + +============================================================================== +4.0 CUSTOMIZATION *bashsupport-customization* +============================================================================== + +------------------------------------------------------------------------------ +4.1 FILES *bashsupport-custom-files* +------------------------------------------------------------------------------ + +README.bashsupport Release notes, installation description. + +plugin/bash-support.vim The Bash plug-in for Vim/gVim. +bash-support/scripts/wrapper.sh A wrapper script for the use of an xterm. + +doc/bashsupport.txt The help file for the local online help. + +bash-support/codesnippets/* Some code snippets as a starting point. + +bash-support/templates/* Bash template files (see |bashsupport-comm-templates|). + +bash-support/wordlists/* Additional word lists (dictionaries). + + ------------------------------------------------------------- + The following files and extensions are for convenience only. + bash-support.vim will work without them. + ------------------------------------------------------------- + +bash-support/rc/costumization.bashrc Additional settings I use in .bashrc: + set the prompt P2, P3, P4 (for debugging). + +bash-support/rc/costumization.vimrc Additional settings I use in '.vimrc': incremental + search, tabstop, hot keys, font, use of dictionaries, + ... The file is commented. Append it to your '.vimrc' + if you like. + +bash-support/rc/costumization.gvimrc Additional settings I use in '.gvimrc': hot keys, + mouse settings, ... The file is commented. + Append it to your '.gvimrc' if you like. +bash-support/rc/sh.vim Suggestions for additional maps. + +bash-support/doc/* Hotkey reference card (PDF), changelog. + + +------------------------------------------------------------------------------ +4.2 GLOBAL VARIABLES *bashsupport-custom-variables* +------------------------------------------------------------------------------ + +Several global variables are checked by the script to customize it: + +------------------------------------------------------------------------------ +global variable default value +------------------------------------------------------------------------------ +g:BASH_GlobalTemplateFile root_dir.'bash-support/templates/Templates' +g:BASH_LocalTemplateFile $HOME.'/.vim/bash-support/templates/Templates' + +g:BASH_CodeSnippets $HOME.'/.vim/bash-support/codesnippets' (Linux/U**X) + $VIM.'\vimfiles\bash-support/codesnippets/' (Windows) +g:BASH_LoadMenus 'yes' +g:BASH_CreateMenusDelayed 'no' +g:BASH_Dictionary_File $HOME."/.vim/bash-support/wordlists/bash.list" +g:BASH_RootMenu '&Bash.' +g:BASH_GuiSnippetBrowser 'gui' + +g:BASH_OutputGvim 'vim' (Linux/U**X) + 'xterm' (Windows) +g:BASH_XtermDefaults '-fa courier -fs 12 -geometry 80x24' +g:BASH_Debugger 'term' +g:BASH_LineEndCommColDefault 49 +g:BASH_SyntaxCheckOptionsGlob '' +g:BASH_Printheader '%<%f%h%m%< %=%{strftime('%x %X')} Page %N' +g:BASH_InsertFileHeader 'yes' +g:BASH_Executable $SHELL (Linux/U**X) + 'bash.exe' (Windows) +g:BASH_ManualReader 'man' (Linux/U**X) + 'man.exe' (Windows) +g:BASH_MapLeader '\' +g:BASH_Errorformat '%f:\ line\ %l:\ %m' +g:BASH_AlsoBash '' + +------------------------------------------------------------------------------ + + 1. group: Defines the text which will be inserted for the tags when a + template is read in (see |bashsupport-templates|). + + g:BASH_GlobalTemplateFile : sets the global template file + (see|bashsupport-templates|) + g:BASH_LocalTemplateFile : sets the local template file + (see|bashsupport-templates|) + + 2. group: g:BASH_CodeSnippets : The name of the code snippet directory + (see |bashsupport-snippets|). + g:BASH_LoadMenus : Load menus and mappings (yes/no) at start up. + g:BASH_CreateMenusDelayed : Load menus only with filetype 'sh' + g:BASH_Dictionary_File : Path and file name of the Bash word list used + for dictionary completion + (see |bashsupport-dictionary|). + g:BASH_RootMenu : Name of the root menu item of this plug-in + (see |bashsupport-custom-root|). + g:BASH_GuiSnippetBrowser : code snippet browser: 'gui', 'commandline' + + 3. group: g:BASH_OutputGvim : Target for a script output + (see |bashsupport-output|). + g:BASH_XtermDefaults : The xterm defaults (see |bashsupport-xterm|). + g:BASH_Debugger : the debugger called by F9 (term, ddd). + g:BASH_LineEndCommColDefault : default starting column for line end comments + g:BASH_SyntaxCheckOptionsGlob : shopt options used with syntax checking + g:BASH_Printheader : hardcopy header format + g:BASH_InsertFileHeader : suppress file header comment for new files + g:BASH_Executable : the shell used + g:BASH_ManualReader : the interface to the on-line manuals + g:BASH_MapLeader : the map leader for hotkeys + (see|bashsupport-usage-vim|) + g:BASH_Errorformat : errorforamat used to parse runtime errors + g:BASH_AlsoBash : filename patterns considered as Bash files + (see |bashsupport-also-bash|) + +To override the defaults add appropriate assignments in '.vimrc'. + + +------------------------------------------------------------------------------ +4.3 THE ROOT MENU *bashsupport-custom-root* +------------------------------------------------------------------------------ + +The variable g:BASH_RootMenu, if set (in '.vimrc' or in '.gvimrc'), gives the +name of the single gVim root menu entry in which the Bash submenus will be +put. The default is +> + '&Bash' + +If you want to set the plug-in root menu into another menu, e.g. 'Plugin', +this is done by the following line in '.vimrc' +> + let g:BASH_RootMenu = "&Plugin.&Bash" +< +------------------------------------------------------------------------------ +4.4 System-wide installation *bashsupport-system-wide* +------------------------------------------------------------------------------ + +A system-wide installation (one installation for all users) is done as +follows. + +As *** SUPERUSER *** : + +(1) Find the Vim installation directory. +The Vim ex command ':echo $VIM' gives '/usr/local/share/vim' or something like +that. Beyond this directory you will find the Vim installation, e.g. in +'/usr/local/share/vim/vim73' if Vim version 7.3 has been installed. + +(2) Create a new subdirectory 'vimfiles', e.g. '/usr/local/share/vim/vimfiles'. + +(3) Install Bash Support +Copy the archive 'bash-support.zip' to this new directory and unpack it: +> + unzip bash-support.zip +< +(4) Generate the help tags: +> + :helptags $VIM/vimfiles/doc +< +SPECIAL CASES. Some Linux distributions use non-standard names for Vim +directories. SUSE has a directory '/usr/share/vim/site' to put plug-ins in. +These directories will not be found automatically. After installing the +plug-in below '/usr/share/vim/site' the use of the templates will be enabled by +the following line in '~/.vimrc': +> + let g:BASH_GlobalTemplateFile = '/usr/share/vim/site/bash-support/templates/Templates' +< + +As ****** USER ****** : + +The plug-in tries to create a minimal template file 'Templates' (and the +necessary directory '$HOME/.vim/bash-support/templates') when the first buffer +with filetype 'vim' will be opened. You should edit this file to personalize +some macros. + +Create your private snippet directory: +> + mkdir --parents $HOME/.vim/bash-support/codesnippets +< +You may want to copy the snippets coming with this plug-in (in +$VIM/vimfiles/bash-support/codesnippets) into the new directory or to set a +link to the global directory. + + +============================================================================== +5. TEMPLATE FILES AND TAGS *bashsupport-templates* +============================================================================== + +------------------------------------------------------------------------------ +5.1 TEMPLATE FILES *bashsupport-templates-files* +------------------------------------------------------------------------------ + +Nearly all menu items insert code snippets or comments. All of these are +contained within template files and can be changed by the user to meet their +requirements. The menu shortcuts (e.g. 'c' for the Comments menu) and the +menu item hotkeys (e.g. '\ct' insert date and time) are also defined in the +templates. +The template engine comes as a separate plug-in contributed by Wolfgang Mehner. +This section is a short introduction to this template system. Please see +|templatesupport.txt| for more information. + +The master template file is '$HOME/.vim/bash-support/templates/Templates' for +a user installation and '$VIM/vimfiles/bash-support/templates/Templates' for +a system-wide installation (see |bashsupport-system-wide|). + +The master template file starts with a macro section followed by templates for +single menu items or better by including other template files grouping the +templates according to the menu structure of this plug-in. The master file +usually looks like this (my settings as an example): +> + § ============================================================= + § User Macros + § ============================================================= + + SetMacro( 'AUTHOR', 'Dr. Fritz Mehner' ) + SetMacro( 'AUTHORREF', 'fgm' ) + SetMacro( 'COMPANY', '' ) + SetMacro( 'COPYRIGHT', 'Copyright (c) |YEAR|, |AUTHOR|' ) + SetMacro( 'EMAIL', 'mehner.fritz@fh-swf.de' ) + SetMacro( 'LICENSE', 'GNU General Public License' ) + SetMacro( 'ORGANIZATION','FH Südwestfalen, Iserlohn, Germany' ) + + SetFormat( 'DATE', '%x' ) + SetFormat( 'TIME', '%H:%M' ) + SetFormat( 'YEAR', '%Y' ) + + SetStyle( 'default' ) + + § ============================================================= + § File Includes and Shortcuts + § ============================================================= + + MenuShortcut( 'Comments', 'c' ) + MenuShortcut( 'Statements', 's' ) + MenuShortcut( 'Tests', 't' ) + MenuShortcut( 'ParamSub', 'p' ) + MenuShortcut( 'PatternMatching', 'p' ) + MenuShortcut( 'IO-Redir', 'i' ) + + IncludeFile( 'comments.templates' ) + IncludeFile( 'statements.templates' ) + IncludeFile( 'tests.templates' ) + IncludeFile( 'paramsub.templates' ) + IncludeFile( 'specialparams.templates' ) + IncludeFile( 'environment.templates' ) + IncludeFile( 'builtins.templates' ) + IncludeFile( 'set.templates' ) + IncludeFile( 'shelloptions.templates' ) + IncludeFile( 'io-redirection.templates' ) + IncludeFile( 'patternmatching.templates' ) +< +Lines starting with a paragraph sign are comments. The section starting with +> + SetMacro( 'AUTHOR', 'Dr. Fritz Mehner' ) +< +assigns values to predefined tags (macros). Arbitrary user-defined macros are +possible. The macro name must follows the rules for a C language identifier: +first character letter or underscore; case matters; digits are allowed +beginning with the second character. + +The statement +> + IncludeFile( 'comments.templates' ) +< +includes the templates from the file 'comments.templates' (in the same +directory). An absolute path would also be possible. The statement +> + MenuShortcut( 'Comments', 'c' ) +< +sets 'c' as the shortcut for the Comments menu. + +------------------------------------------------------------------------------ +5.2 Macros *bashsupport-templates-macros* +------------------------------------------------------------------------------ + +The following macro names are predefined. The first group of macros is used to +personalize templates. + + ---------------------------------------------------------------------------- + PREDEFINED MACROS FOR PERSONALIZATION, DEFAULT VALUE is '' + ---------------------------------------------------------------------------- +*|AUTHOR|* +*|AUTHORREF|* +*|COMPANY|* +*|COPYRIGHT|* +*|EMAIL|* +*|LICENSE|* +*|ORGANIZATION|* + + ---------------------------------------------------------------------------- + PREDEFINED MACROS DEFAULT VALUE + ---------------------------------------------------------------------------- +*|BASENAME|* filename without path and suffix +*|DATE|* the preferred date representation for the current locale + without the time +*|FILENAME|* filename without path +*|PATH|* path without filename +*|SUFFIX|* filename suffix +*|TIME|* the preferred time representation for the current locale + without the date and the time zone or name or abbreviation +*|YEAR|* the year as a decimal number including the century + + ---------------------------------------------------------------------------- + PREDEFINED TAGS USED IN TEMPLATES + ---------------------------------------------------------------------------- + <CURSOR> The cursor position after insertion of a template. + <+text+>,<-text-> See |bashsupport-templates-jumptags|. + {+text+},{-text-} + + <SPLIT> The split point when inserting in visual mode + (see|bashsupport-templates|) + +A dependent template file can start with its own command section. There is no +need to have all user defined macros in the master file. + +------------------------------------------------------------------------------ +5.2.1 User defined formats for date and time *bashsupport-templates-date* +------------------------------------------------------------------------------ +The format for *|DATE|* ,*|TIME|* , and*|YEAR|* can be set by the user. The +defaults are + *|DATE|* '%x' + *|TIME|* '%X' + *|YEAR|* '%Y' +See the manual page of the C function strftime() for the format. The accepted +format depends on your system, thus this is not portable! The maximum length +of the result is 80 characters. + +User defined formats can be set using the following function calls in the +master template file is '$HOME/.vim/bash-support/templates/Templates', e.g. +> + SetFormat( 'DATE', '%D' ) + SetFormat( 'TIME', '%H:%M' ) + SetFormat( 'YEAR', 'year %Y' ) +< +------------------------------------------------------------------------------ +5.3 Templates *bashsupport-templates-names* +------------------------------------------------------------------------------ + +5.3.1 Template Definition *bashsupport-templates-definition* +The template behind a menu item is identified its name. The first part +of the name identifies the menu name, the second part identifies the item. +A template definition starts with a template header with the following syntax: + + == menu_name.template_name == options == + +The options are described here: |template-support-options|. + +5.3.2 The jump tags <+text+> etc. *bashsupport-templates-jumptags* + +There are four jump tag types which can be used as jump targets in templates: + + <+text+> Can be jumped to by hitting Ctrl-j. + {+text+} Same as <+text+>. Used in cases where indentation gives unwanted + results with the first one. + + <-text-> Same as the two above. Will be removed if the template is used + {-text-} in visual mode. + +The text inside the brackets is userdefined and can be empty. The text can be +composed from letters (uppercase and lowercase), digits, and underscores. +After the insertion of an template these jump targets will be highlighted. + +5.3.3 Command Ctrl-j *bashsupport-Ctrl-j* + +Use the command Ctrl-j to jump to the next target. The target will be removed +and the mode will switched to insertion. Ctrl-j works in normal and in insert +mode. The template for an if-else-statement can be written as follows: +> + == Statements.if-else == map:sie, shortcut:i == + if <CURSOR> ; then + <SPLIT><-IF_PART-> + else + <-ELSE_PART-> + fi +< +The cursor will be set as shown. When the condition is specified a Ctrl-j let +you jump to the target <-IF_PART-> and deletes it. When the block is written +a Ctrl-j leads you to the else-part. The target <-ELSE_PART-> disappears and +you can type on. + + +============================================================================== +5.4 ADDITIONAL FILENAMES WITH FILETYPE 'sh' *bashsupport-also-bash* +============================================================================== + +The standard extension for shell script files used by this plug-in is ".sh". +If you want to have other filenames recognized and treated as shell files +set the global variable g:BASH_AlsoBash in your '.vimrc' : + > + let g:BASH_AlsoBash = [ '*.SlackBuild' , 'rc.*' ] +< +This is a Vim List. Please quote the entries and separate them with commas. +Do not include the default extension '*.sh'. + + +============================================================================== +6. BASH DICTIONARY *bashsupport-dictionary* +============================================================================== + +The file 'bash.list' contains words used as dictionary for automatic word +completion. This feature is enabled by default. The default word list is +> + $HOME/.vim/bash-support/wordlists/bash.list +< +If you want to use an additional list 'MyBash.List' put the following line +into $HOME/.vimrc : +> + let g:BASH_Dictionary_File = "$HOME/.vim/bash-support/wordlists/bash.list,". + \ "$HOME/.vim/bash-support/wordlists/MyBash.List" +< +The right side is a comma separated list of files. Note the point at the end +of the first line (string concatenation) and the backslash in front of the +second line (continuation line). +You can use Vim's dictionary feature CTRL-X, CTRL-K (and CTRL-P, CTRL-N). + +============================================================================== +7. ADDITIONAL MAPPINGS *bashsupport-ad-mappings* +============================================================================== + +Some suggestions are in 'bash-support/rc/sh.vim'. This is a filetype plug-in +and would go to '$HOME/.vim/ftplugin/'. + +============================================================================== +8. WINDOWS PARTICULARITIES *bashsupport-windows* +============================================================================== + +For a user installation the plug-in should go into the directory structure +below +> + $HOME/vimfiles/ +< +for a system installation below +> + $VIM/vimfiles/ +< +The values of the two variables can be found from inside Vim: +> + :echo $VIM +< +or +> + :echo $HOME +< +The configuration files for a user are +> + $HOME/_vimrc and $HOME/_gvimrc +< +for the system +> + $VIM/_vimrc and $VIM/_gvimrc +< +A Bash shell is not a part of a Windows system and has to be installed in +addition. This plug-in assumes that the shell port bash.exe +(http://www.cygwin.com) is present and the that command line utilities you +want to use can be reached via your path variable. This shell can be changed +to xyz-shell.exe by setting the following line into the file _vimrc: +> + let g:BASH_Executable = 'xyz-shell.exe' +< +The run-menu and the corresponding hotkeys are restricted. Please see +the document 'bash-hotkeys.pdf' for this restrictions. + +The file format is switches to 'unix' on entering a buffer of type 'sh'. +The filetype can be changed by setting a global variable in file _vimrc: +> + let g:BASH_FileFormat = 'something_else' +< +CYGWIN +------ +Executing scripts with DOS style pathnames causes the error "MS-DOS style path +detected". To turn these messages off add the CYGWIN environment variable +CYGWIN with the value "nodosfilewarning". + +============================================================================== +9. TROUBLESHOOTING *bashsupport-troubleshooting* +============================================================================== + +* I do not see any new main menu item. + - Was the archive extracted into the right directory? + +* How can I see what was loaded? + - Use ':scriptnames' from the Vim command line. + +* No main menu item. + - Loading of plug-in files must be enabled. If not use +> + :filetype plugin on +< + This is the minimal content of the file '$HOME/.vimrc'. Create one if + there is none, or better use customization.vimrc. + +* Most key mappings do not work. + - They are defined in a filetype plugin in '$HOME/.vim/ftplugin/'. Use + ':filetype' to check if filetype plug-ins are enabled. If not, add the line +> + filetype plugin on +< + to the file '~/.vimrc'. + +* Some hotkeys do not work. + - The hotkeys might be in use by your graphical desktop environment. Under + KDE Ctrl-F9 is the hotkey which let you switch to the 9. desktop. The key + settings can usually be redefined. + +============================================================================== +10. Release Notes *bashsupport-release-notes* +============================================================================== + +See file 'README.bashsupport'. + +============================================================================== +vim:tw=78:noet:ts=2:ft=help:norl: diff --git a/.config/nvim/plugged/bash-support.vim/doc/tags b/.config/nvim/plugged/bash-support.vim/doc/tags new file mode 100644 index 0000000..01f8ccc --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/doc/tags @@ -0,0 +1,136 @@ +Bash_ResetMapLeader() bashsupport.txt /*Bash_ResetMapLeader()* +Bash_SetMapLeader() bashsupport.txt /*Bash_SetMapLeader()* +bash-support bashsupport.txt /*bash-support* +bashsupport bashsupport.txt /*bashsupport* +bashsupport-Ctrl-j bashsupport.txt /*bashsupport-Ctrl-j* +bashsupport-ad-mappings bashsupport.txt /*bashsupport-ad-mappings* +bashsupport-aligned-comm bashsupport.txt /*bashsupport-aligned-comm* +bashsupport-also-bash bashsupport.txt /*bashsupport-also-bash* +bashsupport-bash-cmdline-args bashsupport.txt /*bashsupport-bash-cmdline-args* +bashsupport-cmdline-args bashsupport.txt /*bashsupport-cmdline-args* +bashsupport-codesnippets bashsupport.txt /*bashsupport-codesnippets* +bashsupport-comm-echo bashsupport.txt /*bashsupport-comm-echo* +bashsupport-comm-keywords bashsupport.txt /*bashsupport-comm-keywords* +bashsupport-comm-realign bashsupport.txt /*bashsupport-comm-realign* +bashsupport-comm-templates bashsupport.txt /*bashsupport-comm-templates* +bashsupport-comm-toggle bashsupport.txt /*bashsupport-comm-toggle* +bashsupport-comments bashsupport.txt /*bashsupport-comments* +bashsupport-custom-files bashsupport.txt /*bashsupport-custom-files* +bashsupport-custom-root bashsupport.txt /*bashsupport-custom-root* +bashsupport-custom-variables bashsupport.txt /*bashsupport-custom-variables* +bashsupport-customization bashsupport.txt /*bashsupport-customization* +bashsupport-debugger bashsupport.txt /*bashsupport-debugger* +bashsupport-dictionary bashsupport.txt /*bashsupport-dictionary* +bashsupport-errorformat bashsupport.txt /*bashsupport-errorformat* +bashsupport-hardcopy bashsupport.txt /*bashsupport-hardcopy* +bashsupport-help bashsupport.txt /*bashsupport-help* +bashsupport-hotkeys bashsupport.txt /*bashsupport-hotkeys* +bashsupport-io-redir bashsupport.txt /*bashsupport-io-redir* +bashsupport-output bashsupport.txt /*bashsupport-output* +bashsupport-pattern bashsupport.txt /*bashsupport-pattern* +bashsupport-release-notes bashsupport.txt /*bashsupport-release-notes* +bashsupport-run bashsupport.txt /*bashsupport-run* +bashsupport-run-script bashsupport.txt /*bashsupport-run-script* +bashsupport-snippets bashsupport.txt /*bashsupport-snippets* +bashsupport-stat-norm-ins bashsupport.txt /*bashsupport-stat-norm-ins* +bashsupport-stat-visual bashsupport.txt /*bashsupport-stat-visual* +bashsupport-statements bashsupport.txt /*bashsupport-statements* +bashsupport-syntax-check bashsupport.txt /*bashsupport-syntax-check* +bashsupport-syntax-check-options bashsupport.txt /*bashsupport-syntax-check-options* +bashsupport-system-wide bashsupport.txt /*bashsupport-system-wide* +bashsupport-templates bashsupport.txt /*bashsupport-templates* +bashsupport-templates-date bashsupport.txt /*bashsupport-templates-date* +bashsupport-templates-definition bashsupport.txt /*bashsupport-templates-definition* +bashsupport-templates-edit bashsupport.txt /*bashsupport-templates-edit* +bashsupport-templates-files bashsupport.txt /*bashsupport-templates-files* +bashsupport-templates-jumptags bashsupport.txt /*bashsupport-templates-jumptags* +bashsupport-templates-macros bashsupport.txt /*bashsupport-templates-macros* +bashsupport-templates-names bashsupport.txt /*bashsupport-templates-names* +bashsupport-tests bashsupport.txt /*bashsupport-tests* +bashsupport-troubleshooting bashsupport.txt /*bashsupport-troubleshooting* +bashsupport-usage-gvim bashsupport.txt /*bashsupport-usage-gvim* +bashsupport-usage-vim bashsupport.txt /*bashsupport-usage-vim* +bashsupport-windows bashsupport.txt /*bashsupport-windows* +bashsupport-xterm bashsupport.txt /*bashsupport-xterm* +bashsupport.txt bashsupport.txt /*bashsupport.txt* +mmtemplates#core#ChooseStyle() templatesupport.txt /*mmtemplates#core#ChooseStyle()* +mmtemplates#core#CreateMaps() templatesupport.txt /*mmtemplates#core#CreateMaps()* +mmtemplates#core#CreateMenus() templatesupport.txt /*mmtemplates#core#CreateMenus()* +mmtemplates#core#EditTemplateFiles() templatesupport.txt /*mmtemplates#core#EditTemplateFiles()* +mmtemplates#core#EscapeMenu() templatesupport.txt /*mmtemplates#core#EscapeMenu()* +mmtemplates#core#ExpandText() templatesupport.txt /*mmtemplates#core#ExpandText()* +mmtemplates#core#InsertTemplate() templatesupport.txt /*mmtemplates#core#InsertTemplate()* +mmtemplates#core#JumpToTag() templatesupport.txt /*mmtemplates#core#JumpToTag()* +mmtemplates#core#NewLibrary() templatesupport.txt /*mmtemplates#core#NewLibrary()* +mmtemplates#core#ReadTemplates() templatesupport.txt /*mmtemplates#core#ReadTemplates()* +mmtemplates#core#ResetMapleader() templatesupport.txt /*mmtemplates#core#ResetMapleader()* +mmtemplates#core#Resource() templatesupport.txt /*mmtemplates#core#Resource()* +mmtemplates#core#SetMapleader() templatesupport.txt /*mmtemplates#core#SetMapleader()* +template-support templatesupport.txt /*template-support* +template-support-IncludeFile() templatesupport.txt /*template-support-IncludeFile()* +template-support-MenuShortcut() templatesupport.txt /*template-support-MenuShortcut()* +template-support-PickFile() templatesupport.txt /*template-support-PickFile()* +template-support-PickList() templatesupport.txt /*template-support-PickList()* +template-support-Prompt() templatesupport.txt /*template-support-Prompt()* +template-support-SetFormat() templatesupport.txt /*template-support-SetFormat()* +template-support-SetMacro() templatesupport.txt /*template-support-SetMacro()* +template-support-SetPath() templatesupport.txt /*template-support-SetPath()* +template-support-SetProperty() templatesupport.txt /*template-support-SetProperty()* +template-support-SetStyle() templatesupport.txt /*template-support-SetStyle()* +template-support-above templatesupport.txt /*template-support-above* +template-support-adv-files templatesupport.txt /*template-support-adv-files* +template-support-adv-styles templatesupport.txt /*template-support-adv-styles* +template-support-advanced templatesupport.txt /*template-support-advanced* +template-support-api templatesupport.txt /*template-support-api* +template-support-api-access templatesupport.txt /*template-support-api-access* +template-support-api-basic templatesupport.txt /*template-support-api-basic* +template-support-api-maps templatesupport.txt /*template-support-api-maps* +template-support-api-misc templatesupport.txt /*template-support-api-misc* +template-support-append templatesupport.txt /*template-support-append* +template-support-backwards templatesupport.txt /*template-support-backwards* +template-support-bare templatesupport.txt /*template-support-bare* +template-support-basics templatesupport.txt /*template-support-basics* +template-support-below templatesupport.txt /*template-support-below* +template-support-change-log templatesupport.txt /*template-support-change-log* +template-support-cmd-cmd-sct templatesupport.txt /*template-support-cmd-cmd-sct* +template-support-cmd-templates templatesupport.txt /*template-support-cmd-templates* +template-support-commands templatesupport.txt /*template-support-commands* +template-support-contents templatesupport.txt /*template-support-contents* +template-support-dict templatesupport.txt /*template-support-dict* +template-support-dictionary templatesupport.txt /*template-support-dictionary* +template-support-expandmenu templatesupport.txt /*template-support-expandmenu* +template-support-hash templatesupport.txt /*template-support-hash* +template-support-help-templ templatesupport.txt /*template-support-help-templ* +template-support-indent templatesupport.txt /*template-support-indent* +template-support-insert templatesupport.txt /*template-support-insert* +template-support-intro templatesupport.txt /*template-support-intro* +template-support-lib-person templatesupport.txt /*template-support-lib-person* +template-support-library templatesupport.txt /*template-support-library* +template-support-list templatesupport.txt /*template-support-list* +template-support-lists templatesupport.txt /*template-support-lists* +template-support-lists-format templatesupport.txt /*template-support-lists-format* +template-support-lists-hash templatesupport.txt /*template-support-lists-hash* +template-support-map templatesupport.txt /*template-support-map* +template-support-menus templatesupport.txt /*template-support-menus* +template-support-noindent templatesupport.txt /*template-support-noindent* +template-support-nomenu templatesupport.txt /*template-support-nomenu* +template-support-novisual templatesupport.txt /*template-support-novisual* +template-support-opt-list templatesupport.txt /*template-support-opt-list* +template-support-opt-templ templatesupport.txt /*template-support-opt-templ* +template-support-options templatesupport.txt /*template-support-options* +template-support-sc templatesupport.txt /*template-support-sc* +template-support-shortcut templatesupport.txt /*template-support-shortcut* +template-support-start templatesupport.txt /*template-support-start* +template-support-syntax templatesupport.txt /*template-support-syntax* +template-support-syntax-cmd templatesupport.txt /*template-support-syntax-cmd* +template-support-syntax-list templatesupport.txt /*template-support-syntax-list* +template-support-syntax-templ templatesupport.txt /*template-support-syntax-templ* +template-support-templ-macro templatesupport.txt /*template-support-templ-macro* +template-support-templ-maps templatesupport.txt /*template-support-templ-maps* +template-support-templ-place templatesupport.txt /*template-support-templ-place* +template-support-templ-predef templatesupport.txt /*template-support-templ-predef* +template-support-templ-tags templatesupport.txt /*template-support-templ-tags* +template-support-templ-visual templatesupport.txt /*template-support-templ-visual* +template-support-templates templatesupport.txt /*template-support-templates* +template-support-visual templatesupport.txt /*template-support-visual* +templatesupport.txt templatesupport.txt /*templatesupport.txt* diff --git a/.config/nvim/plugged/bash-support.vim/doc/tags-te b/.config/nvim/plugged/bash-support.vim/doc/tags-te new file mode 100644 index 0000000..e69de29 diff --git a/.config/nvim/plugged/bash-support.vim/doc/templatesupport.txt b/.config/nvim/plugged/bash-support.vim/doc/templatesupport.txt new file mode 100644 index 0000000..b8558c9 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/doc/templatesupport.txt @@ -0,0 +1,2368 @@ +*templatesupport.txt* MM Template Support Mar 28 2014 + +MM Template Support *template-support* + + Plug-in version 0.9.3 + for Vim version 7.0 and above + Wolfgang Mehner <wolfgang-mehner at web.de> + + + --- The Maps & Menus Template Support ... --- + +-- ... for Vim Users -- + +This plug-in aims at providing extendible template libraries. A template +library can assist in speeding up the writing of code, while at the same time +ensuring a consistent style. The templates are written in an easy to use +markup language, which enables the user to customize templates without much +hassle. + +Menus and maps to access the templates are created automatically. While maps +might or might not be the preferred way of inserting templates (as well as +using Vim in general), the menus always provide an overview of the templates +and the associated maps. This makes it quite easy to use the templates and +learn their maps at the same time. + +-- ... for Plug-Ins -- + +The template support is controlled by an API and thus can be integrated into +another plug-in. A template library is essentially an object, several of which +can exist in parallel. This makes it relatively easy to write a plug-in for +the programming language of your choice. + +Here is a list of high profile plug-ins which use the template support: +- Bash-Support (www.vim.org/scripts/script.php?script_id=365) +- C-Support (www.vim.org/scripts/script.php?script_id=213) +- Perl-Support (www.vim.org/scripts/script.php?script_id=556) + +============================================================================== +0. TABLE OF CONTENTS *template-support-contents* +============================================================================== + + 1. Introduction |template-support-intro| + 2. Basic Usage |template-support-basics| + 3. Template Library |template-support-library| + 3.1 Personalization |template-support-lib-person| + 4. Templates |template-support-templates| + 4.1 Macros |template-support-templ-macro| + 4.1.1 Predefined Macros |template-support-templ-predef| + 4.2 Tags |template-support-templ-tags| + 4.3 Placement |template-support-templ-place| + 4.3.1 Visual Mode |template-support-templ-visual| + 4.4 Maps & Menus |template-support-templ-maps| + 5. Lists |template-support-lists| + 5.1 Formats |template-support-lists-format| + 5.2 Hashes |template-support-lists-hash| + 6. Advanced Features |template-support-advanced| + 6.1 Coding Styles |template-support-adv-styles| + 6.2 File Pickers |template-support-adv-files| + 7. Menus |template-support-menus| + 8. Help Templates |template-support-help-templ| + + 9. API |template-support-api| + 9.1 Basic Usage |template-support-api-basic| + 9.2 Creating Maps and Menus |template-support-api-maps| + 9.3 Access |template-support-api-access| + 9.4 Miscellany |template-support-api-misc| + 10. Backwards Compatibility |template-support-backwards| + + A. Syntax |template-support-syntax| + A.1 Command Section |template-support-syntax-cmd| + A.2 Templates |template-support-syntax-templ| + A.3 Lists |template-support-syntax-list| + B. Commands |template-support-commands| + B.1 Command Section |template-support-cmd-cmd-sct| + B.2 Templates |template-support-cmd-templates| + C. Options |template-support-options| + C.1 Templates |template-support-opt-templ| + C.2 List |template-support-opt-list| + D. Change Log |template-support-change-log| + +============================================================================== +1. INTRODUCTION *template-support-intro* +============================================================================== + +The manual at hand documents the Maps & Menus Template Support. The next +chapter |template-support-basics|, gives a short preview of the capabilities of +the template support. Templates are listed, together with further +configuration, in a so-called template library. Template libraries are +explained in |template-support-library|, followed by the description of +templates in |template-support-templates|. These chapters will enable the +average user to configure his or her templates. + +Advanced topics are addressed in the following chapters. Lists are explained +in |template-support-lists|, followed in |template-support-advanced| by more +advanced features. The customization of the automatic menu creation is +explained in |template-support-menus|. Help templates offer a mechanism to +quickly access different documentations, they are documented in +|template-support-help-templ|. + +Plug-In developers will find information on the API in |template-support-api|. + +============================================================================== +2. BASIC USAGE *template-support-basics* +============================================================================== + +Templates are short pieces of text which can be included into source code or +text of any other kind. But they are not just plain text, they can be extended +with macros and tags to provide further convenience. Macros can be +automatically replaced with the date or the filename, or they can be replaced +with input from the user, for example the name of a new function. + +The following example shows two templates, as they appear in a so-called +template library. A template library is a text file which lists several +templates, along with their maps and menu shortcuts. +> + == file description == start == + // ================================================== + // File: |FILENAME| + // Description: <CURSOR> + // + // Author: |AUTHOR| + // Version: 1.0 + // Created: |DATE| + // ================================================== + + == function == below == + void |?FUNCTION_NAME| ( <CURSOR> ) + { + <SPLIT> + } /* end of function |FUNCTION_NAME| */ + == ENDTEMPLATE == +< +Each line (the so-called header) > + == <name> == <options> == +starts a new template, > + == ENDTEMPLATE == +marks the end of the template "function". + +When the template "file description" is inserted, it is placed at the start of +the file (option "start"). The filename and the date are inserted where the +macros *|FILENAME|* and *|DATE|* appear, the name of the user is also inserted. +After insertion, the cursor is placed where the <CURSOR> tag appears (the +cursor is represented by "|"): +> + // ================================================== + // File: helloworld.cc + // Description: | + // + // Author: Me! + // Version: 1.0 + // Created: 29.2.2000 + // ================================================== +< +The template "function" is inserted below the current line (option "below"). +The user is asked to provide a replacement for the macro *|FUNCTION_NAME|* (it +is marked with "?"), which is then inserted into the text: +> + void say_hello ( | ) + { + + } /* end of function say_hello */ +< +The macro can also be used in visual mode (it contains the tag <SPLIT>). The +template is then inserted surrounding the selected lines, which appear at the +position of the split tag. + +Assume the line "printf(...)" is selected: +> + // ... +< + printf ( "Hello world!" ); ~ +> + // ... +< +After inserting the template, the code looks like this: +> + // ... + + void say_hello ( | ) + { + printf ( "Hello world!" ); + } /* end of function say_hello */ + + // ... +< +============================================================================== +3. TEMPLATE LIBRARY *template-support-library* +============================================================================== + +A template library is a text file which lists several templates, along with +other objects, and commands to configure the behavior of the templates. This +file must be given to the template support in order to be loaded. If you are +working with a plug-in which uses the template support, the plug-in itself +will take care of that. + +Along with templates, a library file can contain comments. Comments always +start at the beginning of a line. The standard is for comments to start with +the character '§'. This may vary, depending on which plug-in uses the template +support. +Comment lines end the current template, so comments should only be used +outside of templates. + +Outside of templates, the library can contain commands. Among other things, +they configure the behavior of the templates and the menus the template +support creates. +Commands always start at the beginning of the line and, as all other names in +the library, are case sensitive. + +A template library can be organized in several files. The command: > + IncludeFile ( "<path>/<file>" ) +loads templates from another file (|template-support-IncludeFile|). The path +is given relative to the including file. The call: > + IncludeFile ( "<path>/<file>", "abs" ) +interprets the path as a absolute path instead. + +The names of the templates also define the menu structure which the template +support creates. Dots appearing in the names place the templates into +submenus. The following library will create two menus and a submenu "special". +> + == Comments.special.GNU license == below == + // License: Copyright (c) |YEAR|, |AUTHOR| + // + // This program is free software; you can redistribute it and/or + // modify it under the terms of the GNU General Public License as + // published by the Free Software Foundation, version 2 of the + // License. + // This program is distributed in the hope that it will be + // useful, but WITHOUT ANY WARRANTY; without even the implied + // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + // PURPOSE. + // See the GNU General Public License version 2 for more details. + == Comments.file description == start == + // ================================================== + // File: |FILENAME| + // Description: <CURSOR> + // + // Author: |AUTHOR| + // Version: 1.0 + // Created: |DATE| + // ================================================== + + == Idioms.function definition == below == + void |?FUNCTION_NAME| ( <CURSOR> ) + { + <SPLIT> + } /* end of function |FUNCTION_NAME| */ + == ENDTEMPLATE == +< +Menus and entries are generated in the order in which the corresponding +templates are encountered in the library. The above example will generate this +menu structure: +> + Plug-In Menu + >-+ Comments + | >-+ Special + | | >--- GNU license + | >-- file description + >-+ Idioms + | >-- function definition +< +This also means that a new menu entry can be added by simply putting a new +template at that position in the library. Details on the menu creation can be +found in |template-support-menus|. + +------------------------------------------------------------------------------ +3.1 PERSONALIZATION *template-support-lib-person* +------------------------------------------------------------------------------ + +A personalization of the template library can be achieved by using macros. The +command 'SetMacro' (|template-support-SetMacro|) is used to set replacements +for various macros (my settings as an example): +> + SetMacro( 'AUTHOR', 'Wolfgang Mehner' ) + SetMacro( 'AUTHORREF', 'wm' ) + SetMacro( 'EMAIL', 'wolfgang-mehner@web.de' ) + SetMacro( 'ORGANIZATION', '' ) + SetMacro( 'COPYRIGHT', 'Copyright (c) |YEAR|, |AUTHOR|' ) +< +The replacements may contain other macros. When a template is inserted all +macros will be substituted by the respective replacements. + +Other macros and replacements can be added at will, e.g. the following could +be used in a template library for Bash: > + SetMacro( 'INTERPRETER', '/bin/sh' ) +Then the template for the file description may look as follows: +> + == file description == start == + #! |INTERPRETER| + # ================================================== + # File: |FILENAME| + # Description: <CURSOR> + # + # Author: |AUTHOR| + # Version: 1.0 + # Created: |DATE| + # ================================================== + + == ENDTEMPLATE == +< +The format of the included dates and times can be set in a similar fashion, +using 'SetFormat' (|template-support-SetFormat|): +> + SetFormat( 'DATE', '%D' ) + SetFormat( 'TIME', '%H:%M' ) + SetFormat( 'YEAR', 'year %Y' ) +< +These special macros can never be set by 'SetMacro'. The following call will +have no effect and produce a warning: > + SetMacro( 'DATE', "April Fools' Day" ) +< +During template insertion, the macros *|DATE|* , *|TIME|* and *|YEAR|* will be +replaced with the current date and time. + +============================================================================== +4. TEMPLATES *template-support-templates* +============================================================================== + +Templates are short pieces of text which are enhanced by so-called macros and +tags. They define a simple markup language which determines the preparation of +the text before it is inserted and control is handed back to the user. +Beyond that, every template has a name which also determines its place in the +menu structure the template support creates. Together with the template, its +menu shortcut and map are defined. The whole accessibility of the template is +specified in this one place. + +Each template starts with a header: > + == <name> == [ <options> == ] +For consistency with other constructs, the following format is also supported: > + == TEMPLATE: <name> == [ <options> == ] +The list of options can be omitted. + +The name of the template starts with a letter or underscore, and can not end +with a whitespace. Whitespaces in between the name and "==" will be ignored. +The name can contain these characters: + a-z, A-Z, 0-9 + _ + - . , <Space> +Dots have a special meaning. They determine the menu structure the template +support will create (see |template-support-library| for a short introduction). + +The list of option defines the map and menu shortcut of the template, and some +aspects of its behavior during insertion into a text, such as its placement +relative to the position of the cursor. + +The following example shows a possible template for the C statement "if": +> + == Statements.if == below, map:si, sc:i == + if ( <CURSOR> ) + { + + } + == ENDTEMPLATE == +< +The option "below" specifies that the template should always be inserted in +the lines below the current cursor position. The map is set by the option +"map", it will be |<LocalLeader>|si. The option "sc" sets the shortcut of the +entry within the menu "Statements". + +------------------------------------------------------------------------------ +4.1 MACROS *template-support-templ-macro* +------------------------------------------------------------------------------ + +Templates are useful because in source code, certain structures are repeated +regularly. Within this structures however, certain parts a variable. Templates +represent those via macros. Macros have a name, which has to follow the same +rules as C identifiers. They start with a letter or underscore, and can +contain numbers after that. Within a template, macros are written as their +names, surrounded by two bars: + *|AUTHOR|* +Replacement for macros can be given in the template library itself: > + SetMacro( 'AUTHOR', 'Wolfgang Mehner' ) +These macros are replaced when inserting the template: +> + == Comments.file description == start == + # ================================================== + # File: |FILENAME| + # Description: <CURSOR> + # + # Author: |AUTHOR| + # Version: 1.0 + # Created: |DATE| + # ================================================== + + == ENDTEMPLATE == +< +The template library will appropriately replace *|FILENAME|* and *|DATE|* and +take the replacement for *|AUTHOR|* from the template library. + +Another option is to ask the user for a replacement every time the template is +inserted: +> + == Idioms.function == below == + void |?FUNCTION_NAME| ( <CURSOR> ) + { + <SPLIT> + } /* end of function |FUNCTION_NAME| */ + == ENDTEMPLATE == +< +The question mark in front of the name means the user will be prompted for a +replacement for "FUNCTION_NAME". This replacement is then inserted twice. This +becomes particularly useful if this name appears in another template. If a +replacement for a certain macro has been given before, this replacement will +be suggested the next time the user has to replace this macro: +> + == Comments.function description == below == + # ================================================== + # Function: |?FUNCTION_NAME| + # Purpose: <CURSOR> + # Description: TODO + # ================================================== + + == ENDTEMPLATE == +< +Certain uses come with special requirements on the format of the replacement. +Consider an include guard, where usually an upper case version of the files +name is used to name the guard, such as "_THISFILE_INC": +> + == Preprocessor.include guard == below, noindent == + #ifndef _|BASENAME:u|_INC + #define _|BASENAME:u|_INC + <CURSOR> + #endif // ----- #ifndef _|BASENAME:u|_INC ----- + == ENDTEMPLATE == +< +The macro *|BASENAME|* is automatically replaced with the name of the current +file, not including the extension. The flag ":u" means the replacement will be +inserted with all letters in uppercase. So a file named "string.h" will have +an include guard named "_STRING_INC". + +The possible flags are listed below: + :l - change text to lowercase + :u - change text to uppercase + :c - capitalize text (change first letter to uppercase) + :L - legalize name (replace all non-word characters with underscores) + +------------------------------------------------------------------------------ + +4.1.1 Predefined Macros *template-support-templ-predef* + +The replacements for various macros are handles automatically by the template +support. Mostly, they will help with the basic documentation of the file: What +was edited and when? + + *|PATH|* : the path of the current file + *|FILENAME|* : the name of the file + *|BASENAME|* : the name of the file without the suffix + *|SUFFIX|* : the suffix of the file + +Except for using flags, the user has no further influence on the replacements +of these macros, they can not be set via SetMacro(). + + *|TIME|* : the current time + *|DATE|* : the current date + *|YEAR|* : the current year + +The format of the inserted dates and times can be set via SetFormat (see +|template-support-SetFormat|). + +------------------------------------------------------------------------------ +4.2 TAGS *template-support-templ-tags* +------------------------------------------------------------------------------ + +Templates can contain tags, which influence the behavior after the template +has been inserted into the current buffer. The simplest one is <CURSOR>, +which specifies the position of the cursor after the template has been +inserted. Consider the following example: +> + == Statements.if == below == + if ( <CURSOR> ) + { + + } + == ENDTEMPLATE == +< +After template insertion the cursor is placed between the round brackets and +the user can write down the condition. + +The cursor tag may cause the indentation to be slightly off after template +insertion. Therefore a second version of the cursor tag exists: {CURSOR}. You +should always choose the one which is more naturally compatible with the +languages syntax, and in extension its automatic indentation: +> + == Statements.block == below == + { + {CURSOR} + } + == ENDTEMPLATE == +< +Further convenience is introduced by jump tags. Instead of moving into the +block using arrow keys, the user can be given the possibility to jump to the +next position where editing is required: +> + == Statements.if == below == + if ( <CURSOR> ) + { + <+IF_PART+> + } + == ENDTEMPLATE == +< +The standard map for jumping is <ctrl+j>, also it may vary with each plug-in +using the template support. +Jump tags have one of the following formats: + <+NAME+> <-NAME-> + {+NAME+} {-NAME-} +The text will be indented automatically with the jump tags still appearing in +it, so for every language the appropriate version has to be chosen. The name +consists of arbitrary word characters (letters, digits and underscores) and +can even be empty. The name has no other function than "documenting" the +inserted code: +> + == Statements.if, else == below == + if ( <CURSOR> ) + { + <+IF_PART+> + } + else + { + <+ELSE_PART+> + } + == ENDTEMPLATE == + +------------------------------------------------------------------------------ +4.3 PLACEMENT *template-support-templ-place* +------------------------------------------------------------------------------ + +Templates can be placed at different positions relative to the cursor. In most +examples above the option "below" has been used. It means the template is +inserted below the current line. The opposite can be achieved using "above", +while "start" places the template at the beginning of the file, which makes +sense for example for file descriptions: +> + == Comments.file description == start == + ... + == Idioms.function definition == below == + ... + == ENDTEMPLATE == +< +These options cause whole lines to be inserted. Two other options exist: +> + == Comments.end-of-line comment == append == + /* <CURSOR> */ + == Comments.date and time == insert == + |DATE|, |TIME|<CURSOR> + == ENDTEMPLATE == +< +The template "Comments.end-of-line comment" will be inserted at the end of the +current line, while "Comments.date and time" will insert a timestamp at the +cursor position. + +These placement modes are available: + start - the text is placed above the first line + above - the text is placed above the current line + below - the text is placed below the current line (default) + append - the text is appended to the current line + insert - the text is inserted at the cursor position + +By default, the lines containing a newly inserted template are automatically +indented. To suppress this behavior use the option "noindent". This can be +used for code fragments which contain constructs the indentation program does +not handle correctly. + +------------------------------------------------------------------------------ + +4.3.1 Visual Mode *template-support-templ-visual* + +Oftentimes, existing code needs to be rearranged, for example some lines of +code must be surrounded with an if-statement. For this reason, the <SPLIT> +tag exists: +> + == Statements.if == below == + if ( <CURSOR> ) + { + <SPLIT> + } + == ENDTEMPLATE == +< +If the template is inserted in normal or insert mode, nothing changes. The tag +will be removed automatically. In visual mode however, the selected line will +be surrounded with the template. Consider these lines of code, where the lines +containing "printf" are selected: +> + // ... +< + printf ( "Loading the file ..." ); ~ + printf ( "... reading %d bytes.", n ) ~ +> + // ... +< +After inserting the template "Statements.if", the code looks like this: +> + // ... + + if ( | ) + { + printf ( "Loading the file ..." ); ~ + printf ( "... reading %d bytes.", n ) ~ + } + + // ... +< +Now the user can type in the condition. + +Jump and split tags might be in conflict. Consider the following example: +> + == Statements.if, else == below == + if ( <CURSOR> ) + { + <SPLIT><+IF_PART+> + } + else + { + <+ELSE_PART+> + } + == ENDTEMPLATE == +< +When using the template in visual mode, the jump tag <+IF_PART+> should not +appear, since the if block already contains the selected line. This is why +jump tag exist in different versions. The two version <-NAME-> and {-NAME-} +are removed in visual mode. They behave opposite to the <SPLIT> tag, which is +removed in every other mode. A better version of the above example looks like +this: +> + == Statements.if, else == below == + if ( <CURSOR> ) + { + <SPLIT><-IF_PART-> + } + else + { + <+ELSE_PART+> + } + == ENDTEMPLATE == +< +For templates containing a split tag, the option "noindent" is particularly +useful, since it can prevent large sections of code from being indented +unnecessarily. The following example shows a template for an include guard, +using a C-macro "_THISFILE_INC": +> + == Preprocessor.include guard == below, noindent == + #ifndef _|BASENAME:u|_INC + #define _|BASENAME:u|_INC + <CURSOR><SPLIT> + #endif // ----- #ifndef _|BASENAME:u|_INC ----- + == ENDTEMPLATE == +< +Here, running the indentation program after insertion is an unnecessary effort +and may potentially destroy hand-crafted indentation in a large piece of code. + +------------------------------------------------------------------------------ +4.4 MAPS & MENUS *template-support-templ-maps* +------------------------------------------------------------------------------ + +The template support automatically creates maps and menu entries for the +templates in the library. The menu entries appear in the order the templates +have been read. Including a file via > + IncludeFile ( "<path>/<file>" ) +will cause this file to be processed first, then the rest of the including +file is read. + +The map and menu shortcut of a template are defined together with the +template: +> + == Statements.if == below, map:si, sc:i == + if ( <CURSOR> ) + { + <+IF_PART+> + } + == ENDTEMPLATE == +< +The templates will have the map |<LocalLeader>|si and the shortcut "i". + +Menu entries are created by default. The option "nomenu" suppresses this +behavior: +> + == Comments.fix this == nomenu, append, map:cfx == + // TODO: fix this + == ENDTEMPLATE == +< +This template will not clutter the menu and can only be inserted via its map. + +An overview of all the options: + nomenu - no menu entry is created + sc:<sc> - a shortcut is created for the menu entry of this template + shortcut:<sc> - long version of sc:<sc> + map:<map> - a map is created for this template + +============================================================================== +5. LISTS *template-support-lists* +============================================================================== + +Template libraries would regularly contain a huge number of templates with a +repetitive structure. Consider these templates for a C template library: +> + == Preprocessor.include math, map: pim == + #include <math.h> + == Preprocessor.include stdlib, map:pisl == + #include <stdlib.h> + == Preprocessor.include stdio, map:pisio == + #include <stdio.h> + == Preprocessor.include string, map:pistr == + #include <string.h> + == ENDTEMPLATE == +< +This has several disadvantages. Besides being difficult to write and maintain, +these templates would not be well accessible. The user would have to memorize +a map for each and every one of them. + +This is why lists exist. They appear as objects in the template library. The +header of a list starts with "LIST:" and then contains a name, which has to +follow the same rules as C identifiers. They start with a letter or +underscore, and can contain numbers after that. +> + == LIST: C_StandardLibs == + 'math', + 'stdlib', + 'stdio', + 'string', + == ENDLIST == + + == Preprocessor.c libs == below, map:pcl == + |PickList( '#include <~.h>', 'C_StandardLibs' )| + #include <|PICK|.h><CURSOR> + == ENDTEMPLATE == +< +The template "Preprocessor.c libs" uses this list. The command: > + "|PickList( '<prompt>', '<list>' )|" +determines which list is used. During template insertion the user is prompted +to choose an entry from the list, but can also type another name. The prompt +supports tab-completion and navigation with arrow keys. The first argument is +a string which is displayed on the command line, to clarify the meaning of the +choice. After the users makes the choice, the macro *|PICK|* is created, which +contains the chosen item. +Lists can be used again in another context, for example to support C++ +programming: +> + == Preprocessor.c++, c libs == below, map:ppc == + |PickList( '#include <c~>', 'C_StandardLibs' )| + #include <c|PICK|><CURSOR> + == ENDTEMPLATE == +< +When the template is inserted via a map, the user is prompted to choose an +entry from the list, thus only one map is required to choose from a huge +number of options. When the template is accessed via the menu, two +possibilities exists. Without further changes, the same prompt opens as when +the template is used via a map. But whenever the template includes the +"expandmenu" option, a submenu is created which lists all the entries, which +allows the user to choose in the menu, rather than on the command line: > + == Preprocessor.c libs == below, expandmenu, map:pcl == +< +------------------------------------------------------------------------------ +5.1 FORMATS *template-support-lists-format* +------------------------------------------------------------------------------ + +Lists also support options. The standard format for lists is named "list": +> + == LIST: C_StandardLibs == list == + 'math', 'stdlib', + 'stdio', 'string', + == ENDLIST == +< +The text contained between "== LIST: name ==" and "== ENDLIST ==" is a +comma-separated list of strings, which come as |expr-string| in double quotes +or |literal-string| in single quotes. + +An easier way of writing lists are bare lists, defined with the option "bare": +> + == LIST: C_StandardLibs == list, bare == + math + stdlib + stdio + string + == ENDLIST == +< +They contain each entry on a new line, leading and trailing whitespaces are +ignored. + +------------------------------------------------------------------------------ +5.2 HASHES *template-support-lists-hash* +------------------------------------------------------------------------------ + +Hashes, or dictionaries, are another type of lists. They associate a key with +a value: +> + == LIST: String_Functions == hash == + "strcpy" : "{+DEST+}, {+SRC+}", + "strncpy" : "{+DEST+}, {+SRC+}, {+N+}", + "strcmp" : "{+STR1+}, {+STR2+}", + "strncmp" : "{+STR1+}, {+STR2+}, {+N+}", + "strlen" : "{+STR+}", + == ENDLIST == +< +A hash is a comma-separated list of entries. Each entry contains a key and a +value, separated by a colon. + +During template insertion, the user has to choose one of the keys. Then two +macros *|KEY|* and *|VALUE|* are created, containing the chosen key and its +associated value. Both can be used in the template. +In this example, a function call is inserted, with jump tags named for the +parameters: +> + == Idioms.string function == insert, expandmenu == + |PickList( "function: ", "String_Functions" )| + |KEY|<CURSOR> ( |VALUE| ) + == ENDTEMPLATE == +< +These templates also support the option "expandmenu". The menu will list all +the keys. + +============================================================================== +6. ADVANCED FEATURES *template-support-advanced* +============================================================================== + +Editing source code comes with challenges common to many different languages +and systems. + +Different projects may require different coding styles. Template libraries can +be written to support multiple styles (|template-support-adv-styles|). + +Many languages deal with files placed in one or more significant directory, +such as C's include directories or modules in other languages. File pickers +assist in working with these directories (|template-support-adv-files|). + +------------------------------------------------------------------------------ +6.1 CODING STYLES *template-support-adv-styles* +------------------------------------------------------------------------------ + +Different software projects may require different styles for comments and +code. In the case of C/C++, different kinds of comments can be chosen, with +Doxygen introducing even more possibilities. The template engine assists with +these problems by offering so called styles. Styles are named using the same +rules as macros (see |template-support-templ-macro|). + +Every template is assigned to one or more styles. By default, all templates are +assigned to the style "default". Templates can be associated with different +styles by placing them inside a "USE STYLES" statement: +> + == USE STYLES : CPP == + + == Comments.function description == == + # ================================================== + # Function: |?FUNCTION_NAME| + # Purpose: <CURSOR> + # Description: TODO + # ================================================== + + == ENDTEMPLATE == + + == ENDSTYLES == + + == USE STYLES : Doxygen == + + == Comments.function description == == + /*! + * \brief <CURSOR> + * + * TODO + */ + + == ENDTEMPLATE == + + == ENDSTYLES == +< +Now the "function description" template inserts different code, depending on +whether the style "CPP" or "Doxygen" is chosen (see the documentation of your +plug-in for how to change the style). + +The "USE STYLES" statement can contain the names of several styles. Templates +inside are associated with all the styles appearing in the list. This makes +reuse of templates for different styles possible. +> + == USE STYLES : CPP, Doxygen == + + == Comments.end-of-line command == == + // <CURSOR> + == ENDTEMPLATE == + + == USE STYLES : CPP == + + == Comments.function description == == + ... + == ENDTEMPLATE == + + == ENDSTYLES == + + == USE STYLES : Doxygen == + + == Comments.function description == == + ... + == ENDTEMPLATE == + + == ENDSTYLES == + + == ENDSTYLES == +< +The template "end-of-line comment" inserts the same text for both styles, +while "function description" is different. If a template is not associated +with a given style it can be inserted anyway, using the version of the +template associated with the "default" style as a fallback. Only if a template +does not exist for the current style or the default style, an error message is +displayed and nothing inserted. + +Using nested "USE STYLES" statement is also possible. The styles listed in a +nested statement have to be a subset of the styles listed in the one +surrounding it. +Templates inside nested statements are only associated with the styles +listed in the innermost "USE STYLES" statement. + +When files are included inside a "USE STYLES" statement (see +|template-support-IncludeFile|), the templates inside the file are associated +with the style, as they would if they appeared in the including file itself. +The rules for nested "USE STYLES" statements also hold across included files. + +------------------------------------------------------------------------------ +6.2 FILE PICKERS *template-support-adv-files* +------------------------------------------------------------------------------ + +In many languages files are addressed in relation to some significant +directory, such the include mechanism of the C preprocessor or LaTeX's +\graphicspath{} command. To assist in dealing with those files, the template +support offers so-called file pickers. + +File pickers are templates which use the command PickFile( <prompt>, <path> ) +(|template-support-PickFile|), which asks the user to interactively select a +file: +> + SetPath( 'global_include', '/usr/include/' ) + + == Include.global include == below == + |PickFile( 'global include directory', 'global_include' )| + #include "|PICK|"<CURSOR> + == Include.global, filename only == below == + |PickFile( 'global include directory', 'global_include' )| + #include <|FILENAME|><CURSOR> + == ENDTEMPLATE == +< +The first argument to the function is a prompt which is being displayed while +the user selects the file. The second argument is the name of a path set +beforehand, such as "global_include". After the user selects a file, several +macros are created which can be used in the template. *|PICK|* is the path and +name of the file, relative to the path given as the second argument. +*|FILENAME|* is only the name of the file. For a list of all macros, see +|template-support-PickFile|. + +Names for paths are created using the function SetPath( <name>, <path> ) +(see |template-support-SetPath|), which is a lot like SetMacro. + +For example, if the user picks "/usr/include/GL/gl.h", the first template +would result in the line > + #include "GL/gl.h" +being inserted, while the second template would insert > + #include <gl.h> +The paths "/usr/include" or "/usr/include/GL" would have to be in the include +path, of course. + +The second argument can also be a path. In fact, if it does not match an +identifier, it is always assumed to be a path: +> + == Include.local include == below == + |PickFile( 'local include directory', './' )| + #include "|PICK|"<CURSOR> + == ENDTEMPLATE == +< +This template lets the user pick a file relative to the current working +directory. + +============================================================================== +7. MENUS *template-support-menus* +============================================================================== + +The template support automatically creates menus for every template. The user +has a measure of influence on the result. Some of these options where already +explained in |templates-support-templ-maps|, this chapter will introduce further +capabilities. + +The menu entries appear in the order the templates have been read. Including a +file via > + IncludeFile ( "<path>/<file>" ) +will cause this file to be processed first, then the rest of the including +file is read. + +The menu structure is defined by the names of the menus. Dots appearing in the +names place the templates into submenus: +> + == Comments.file description == start, sc:f == + ... + == Statements.if == below, sc:i == + ... + == ENDTEMPLATE == +< +The shortcut for the menu entry is defined in the header. The automatic +creation of a menu entry for a template can be suppressed using the option +"nomenu". + +The maps of submenus are set via the command 'MenuShortcut' +(see |template-support-MenuShortcut()|): +> + MenuShortcut ( "Comments.Special", "p" ) + MenuShortcut ( "Comments", "c" ) + MenuShortcut ( "Statements", "s" ) +< +Each call sets the shortcut for the last submenu mentioned. So the above +example sets the shortcut "c" for the menu "Comments", "s" for "Statements" +and "p" for the submenu "Special" within "Comments". The placement of these +calls has no influence on the order of menu creation, only the appearance of +their names in template headers. + +The template library can also contain menu separators, a solid line appearing +between two menu entries. They can help to provide a better overview in a menu +with lots of entries. Menu separators are defined outside of templates using +the syntax: > + == SEP: Statements.sep1 == +The header start with "SEP:" and then contains the name of the separator. The +dots in the name again define which submenu the separator will appear in, +while the relative position in relation to the other templates defines the +placement. The last part of the name following the last dot has no influence, +but must be unique. +Unlike templates and lists, separators do not have to be ended with a line +like "== ENDTEMPLATE ==". Separators only span one line. Separators could +utilize the syntax of function calls, such as "SetMacro()". However, they have +been designed in this way to visually be on the same level as templates. + +------------------------------------------------------------------------------ + +Note: A short remark for plug-in developers. + +Each menu entry also displays the map of the template, if it has one. By +default, it is prefixes with the standard mapleader, a backslash. Using the +API, this can be changed to the mapleader the user has set: > + call mmtemplates#core#Resource ( + \ <template-library>, "set", "Templates::Mapleader", "<mapleader>" ) +(see |mmtemplates#core#Resource()|). This mapleader may also appear in menu +entries the plug-in itself creates. As a convenience, the mapleader is +provided by the API, already correctly escaped for menu creation: > + let [ esc_mapleader, msg ] = mmtemplates#core#Resource ( + \ g:My_C_Templates, "escaped_mapleader" ) +< +============================================================================== +8. HELP TEMPLATES *template-support-help-templ* +============================================================================== + +A quick access to the documentation is important for every language. Help +templates offer a mechanism to pick up a word under the cursor and make a +system call using this text. For example, a browser could be opened with help +for a certain command. + +Help templates look a lot like templates in the library, but do not insert +text. They share a lot of other features with regular templates though, they +will create a menu entry and can have shortcuts and maps. + +The syntax of help templates is very close to that of regular templates, +except that their name is prefixed by "HELP:" +> + SetMacro( 'HELP_BROWSER', 'firefox' ) + SetMacro( 'HelpPathEnglish', 'http://en.wiktionary.org/wiki/' ) + + == HELP: Help.english == map:he, sc:e == + |Word( '' )| + |Substitute( '\W', '', 'g' )| + |System( '|HELP_BROWSER| |HelpPathEnglish||PICK:l|' )| + == ENDTEMPLATE == +< +The help template "Help.english" picks up the word under the cursor, removes +every non-word character from that string and then calls > + firefox http://en.wiktionary.org/wiki/... +This will open a new tab containing the article about the word under the +cursor, which is very helpful while writing documentation. + +A help template always performs three steps: +1. Pick up text under the cursor. +2. Change the text (optional). +3. Make a system call or a call on the Vim command line. + +1. Picking Text + +To pick up text under the cursor, the function Word(<flag>) is used. If the +flag is 'W', the |WORD| under the cursor is picked up: > + |Word('W')| +Otherwise the |word| under the cursor is picked: > + |Word('')| +Lastly, the word can be picked using a regular expression (see |regex|): > + |Pattern( '[\\@]\w\+' )| +This call picks a word prefix by "\" or "@", which in a C comment could be a +Doxygen command. +The text which has just been picked up is then stored in a sort of register, +which for the purpose of the further explanation shall be called "acc". + +2. Editing the Text + +After picking up text, the register "acc" can be changed by one or more calls +to the function Substitute( <pattern>, <sub>, <flag> ). For example, to remove +every non-word character: > + |Substitute( '\W', '', 'g' )| +Substitute replaces the contents of "acc" using Vim's |substitute()| function: + acc = substitute( acc, <pattern>, <sub>, <flag> ) +If the flag is an empty string, the first occurrence of <pattern> is replaced +with <sub>. If flag equals "g", all occurrences are replaced. The function +LiteralSub(<string>,<sub>,<flag>) works similarly, except that the first +argument is not interpreted as a regular expression. + +3. Calling Help + +After picking up and changing the text, a call is made using System(<call>) or +Vim(<call>). The argument is a string and it can contain macros which are +replaced before the call. The macro *|PICK|* is replaced with "acc", the +picked and changed text. The call is however only made if "acc" is not the +empty string. +If either an empty string has been picked up in step 1, or the string is empty +after step 2, the call is made using the command given in Default(<call>). If +no default call is given, no action is performed for an empty string. + +The following help template shows help for Doxygen commands: +> + SetMacro( 'HelpPathDoxygen', 'http://www.stack.nl/~dimitri/doxygen/commands.html' ) + + == HELP: Help.doxygen cmd == map:hd, sc:d == + |Pattern( '[\\@]\w\+' )| + |Substitute( '[\\@]', '', '' )| + |System( '|HELP_BROWSER| |HelpPathDoxygen|#cmd|PICK|' )| + |Default( '|HELP_BROWSER| |HelpPathDoxygen|' )| + == ENDTEMPLATE == +< +First, a Doxygen command is picked up under the cursor, then the leading "\" +or "@" is removed. Then a system call such as: > + firefox http://www.stack.nl/~dimitri/doxygen/commands.html#cmdparam +is made. If there was no Doxygen command under the cursor, the following call +is made instead, which will show a table of all Doxygen commands: > + firefox http://www.stack.nl/~dimitri/doxygen/commands.html +< +Note: The examples still worked in November, 2013. + + + + -------------------------------------------------------------------------- ~ + + -------------------------------------------------------------------------- ~ + + -------------------------------------------------------------------------- ~ + + + +============================================================================== +9. API *template-support-api* +============================================================================== + +This chapter is only relevant if you want to use the template system with your +own plug-in! + +The API enables other plug-ins to use the template system. + +Each template library is stored in a dictionary (|Dictionary|). +- This dictionary must be a global variable, because it it used for purposes + such as callback functions for menu entries and maps. +- Do not change the entries of the dictionary directly, since the internal + structure may change. The API provides access to the stored information. + +------------------------------------------------------------------------------ +9.1 BASIC USAGE *template-support-api-basic* +------------------------------------------------------------------------------ + +These functions provide the basic functionality to load template libraries and +insert templates into a buffer. A further function expands macros in a text. + +------------------------------------------------------------------------------ + *mmtemplates#core#NewLibrary()* +To create a new template library call: + + library = mmtemplates#core#NewLibrary ( ... ) ~ + +Optional parameters: + "debug", level - View debug information with the given level of detail. + (integer, default: show no debug information) +Returns: + library - The template library. (dict) + +Example: + +Create a new library and store it in the variable 'g:My_C_Templates': > + let g:My_C_Templates = mmtemplates#core#NewLibrary () +< +------------------------------------------------------------------------------ + *mmtemplates#core#ReadTemplates()* +Templates are loaded using the function: + + mmtemplates#core#ReadTemplates ( library, ... ) ~ + +Parameters: + library - The template library. (string or dict) +Optional parameters: + "load", file - Load templates from 'file'. (string) + "reload", what - Reload templates according to 'what', see below. + (string or integer) + "overwrite_warning" - Print a warning each time a template is overwritten. + "debug", level - View debug information with the given level of detail. + (integer, default: show no debug information) +No returns. + +The library can either be given directly, or as the name of the global +variable containing the library. + +When loading a new file, it must be given with a path and filename. > + mmtemplates#core#ReadTemplates ( library, "load", "path/file.templates" ) +< +The entire library can be reloaded by calling: > + mmtemplates#core#ReadTemplates ( library, "reload", "all" ) +A file can be reloaded, but only if it has been loaded before: > + mmtemplates#core#ReadTemplates ( library, "reload", "path/file.templates" ) +The i'th file which has been loaded can be reloaded via: > + mmtemplates#core#ReadTemplates ( library, "reload", i ) +< +With the switch "overwrite_warning", a warning is displayed whenever a +template is encountered which already has been set for the current style. + + +Example 1: + +Load a file: > + call mmtemplates#core#ReadTemplates ( g:My_C_Templates, + \ "load", "$HOME/.vim/c-support/templates/lib.templates", + \ "debug", 1, "overwrite_warning" ) +Load the templates in the given file and print very little debug information. +Print a warning whenever a template is overwritten. + + +Example 2.1: + +Load several files: > + call mmtemplates#core#ReadTemplates ( g:My_C_Templates, + \ "load", "/usr/share/vim/.../global.templates" ) + + call mmtemplates#core#ReadTemplates ( g:My_C_Templates, + \ "load", "$HOME/.vim/.../local.templates" ) +Loads the templates in the two files. + + +Example 2.2: + +Reload specific templates: > + call mmtemplates#core#ReadTemplates ( g:My_C_Templates, "reload", -1 ) +Reload the last template which has been loaded. +(".../local.templates" from above) + + +Example 2.3: + +Reload templates by name: > + call mmtemplates#core#ReadTemplates ( g:My_C_Templates, + \ "reload", "$HOME/.vim/.../local.templates" ) +< +------------------------------------------------------------------------------ + *mmtemplates#core#InsertTemplate()* +To insert templates into the current buffer use: + + mmtemplates#core#InsertTemplate ( library, name, ... ) ~ + +Parameters: + library - The template library. (string or dict) + name - The name of the template. (string) +Optional parameters: + "i" - > "insert" + "insert" - Insert mode, special treatment of placement 'insert'. + "v" - > "visual" + "visual" - Visual mode, use the <SPLIT> tag. + "placement", place - Overwrite the template's placement. (string) + "range", a, b - Use the range from lines 'a' to 'b'. (integers) + "<macro>", replace - Set the replacement for the given macro. The string + <macro> must match a macro, e.g. *|FUNCTION_NAME|* . + (string) + "pick", choice - When inserting a list use 'choice', do not ask the user + to pick an entry. (string) + "debug", level - View debug information with the given level of detail. + (integer, default: show no debug information) +No returns. + +The library can either be given directly, or as the name of the global +variable containing the library. +It the template 'name' does not exist, an error message is displayed. + +Examples: + +Include "Statement.If", surround the selected lines: > + call mmtemplates#core#InsertTemplate ( g:My_C_Templates, + \ "Statement.If", "v" ) + +------------------------------------------------------------------------------ + *mmtemplates#core#ExpandText()* +To perform macro expansion in a text use: + + rtext = mmtemplates#core#ExpandText ( library, text ) ~ + +Parameters: + library - The template library. (string or dict) + text - A text. (string) +Returns: + rtext - The text after the macro expansion (string). + +The library can either be given directly, or as the name of the global +variable containing the library. +The expansion is done using all the settings in the library, as well as the +global macro replacements such as *|AUTHOR|* . + +Examples: + +Calling the function: > + let text = mmtemplates#core#ExpandText ( g:My_C_Templates, "|DATE| |TIME|" ) +returns "29.2.2000 12:00", depending on the format set in the library. + +This can be used for special menu entries such as: > + exe 'amenu Comments.Special.Date\ Time ' + \ .':exe "normal! a".mmtemplates#core#ExpandText ( ' + \ .'g:My_C_Templates, "\|DATE\| \|TIME\|" )<CR>' +< +------------------------------------------------------------------------------ + *mmtemplates#core#EditTemplateFiles()* +Open the library for editing: + + mmtemplates#core#EditTemplateFiles ( library, file ) ~ + +Parameters: + library - The template library. (string or dict) + file - A file. (string or integer) +No returns. + +The library can either be given directly, or as the name of the global +variable containing the library. + +The argument 'file' can be given as a filename, in which case it must have +been loaded before via |mmtemplates#core#ReadTemplates()|. +'file' can also be an integer i, which refers to the i'th file that has been +loaded. + +A file browser is then opened for the directory containing the file. + +Example: + +Open a file browser in the directory "$HOME/.vim/.../templates/": +> + " load the last template file: + call mmtemplates#core#ReadTemplates ( g:My_C_Templates, + \ "load", "$HOME/.vim/.../templates/local.templates" ) + + " ... + + " edit the library + call mmtemplates#core#EditTemplateFiles ( g:My_C_Templates, -1 ) +< +------------------------------------------------------------------------------ + *mmtemplates#core#JumpToTag()* +The jump to the next tag is performed by: + + e = mmtemplates#core#JumpToTag ( regex ) ~ + +Parameters: + regex - The regex to jump to. (string) +Returns: + e - An empty string. + +Jumps to the next occurrence of 'regex' and removes it from the buffer. Then +the function returns an empty string. +The regular expression can be obtained from the template library via the +function |mmtemplates#core#Resource()|. + +Example: + +This function is best used in maps such as this: +> + let regex = mmtemplates#core#Resource ( g:My_C_Templates, "jumptag" )[0] + + " ... + + nnoremap <buffer> <C-j> i<C-R>=mmtemplates#core#JumpToTag ( regex )<CR> + inoremap <buffer> <C-j> <C-R>=mmtemplates#core#JumpToTag ( regex )<CR> +< +This maps can be created automatically using |mmtemplates#core#CreateMaps()|. + +------------------------------------------------------------------------------ +9.2 CREATING MENUS AND MAPS *template-support-api-maps* +------------------------------------------------------------------------------ + +The automated generation of maps and menus is carried out by these functions. + +------------------------------------------------------------------------------ + *mmtemplates#core#CreateMaps()* +The automatic creation of maps is carried out by the function: + + mmtemplates#core#CreateMaps ( library, localleader, ... ) ~ + +Parameters: + library - The name of the variable containing the library. (string) + localleader - The local mapleader. (string) +Optional parameters: + "do_jump_map" - Create a map for |mmtemplates#core#JumpToTag()|. + "do_special_maps" - Create maps for the special operations. +No returns. + +If 'localleader' is an empty string, the standard mapleader is used. +Otherwise > + let maplocalleader = localleader +is executed before the maps are created. (see |mapleader|) + +The maps for the jump and the special operations (choose a template/style, +reread/edit the library) are not created unless the corresponding options are +given. + +This function creates maps which are local to the buffer, so it must be called +in the appropriate filetype-plugin, or by an autocommand. +An error message is displayed whenever a mapping already exists. The existing +mapping will not be overwritten. + +Example: + +Create maps using the standard mapleader: > + call mmtemplates#core#CreateMaps ( "g:My_C_Templates", "", "do_jump_map" ) +A map to jump to the next tag is also created. + +Technical Details: +- The library must be given as the name of the global variable, since this + name is required to create the maps. +- The function creates maps of the following types: + noremap, inoremap, vnoremap + +------------------------------------------------------------------------------ + *mmtemplates#core#CreateMenus()* +The automatic creation of menus is carried out by the function: + + mmtemplates#core#CreateMenus ( library, rootmenu, ... ) ~ + +Parameters: + library - The name of the variable containing the library. (string) + rootmenu - The name of the root menu. (string) +Optional parameters: + "global_name", name - The name used in the menu headers. + (string, default: the value of 'rootmenu') + "existing_menu", names - The menus which already exist. + (string or list of strings) + "sub_menu", names - Additional sub-menus which should be created. + (string or list of strings) + "specials_menu", name - The name of the menu containing the special + operations. (string, default: "Run") + "priority", p - Create the sub-menu with priority p. + (integer, default: 500) + "do_all" - Action: Reset and create all menus. + "do_reset" - Action: Reset. + "do_templates" - Action: Create menus for all the templates. + "do_specials" - Action: Create a menu with the special entries. + "do_styles" - Action: Create a menu for selecting the style. +No returns. + +"do_all", "do_templates", "do_specials" and "do_styles" starts the automatic +creation of menu entries. Sub-menus are created automatically as needed. +The special operations are: choose a template/style, reread/edit the library. +The corresponding menu entries are put in the sub-menus given by the option +"specials_menu". + +Each sub-menu looks like this, starting with a header: +> + <menu name> <global name> + --- <separator> ------------- + <entry1> <map> + <entry2> + ... ... +< +The global name (option "global_name") helps to keep track of tear-off menus. +"sub_menu" can be used to create additional menus, which have the same header. +When a sub-menu is created through use of the API like this, an optional +priority can be specified. + +The library keeps track of all created sub-menus, to be able to add the +headers correctly. "existing_menu" adds menus to this list. +"do_reset" resets this list and allows for the menus to be created once more. +"do_all" also reset the list before it carries out further operations. + +The "&" and the trailing points in 'rootmenu' and "existing_menus" are +ignored. "sub_menus" and "specials_menu" also ignore trailing points, but use +the "&" to create shortcuts. However, if a shortcut for the menu has been set +in the library, that one is preferred. + + +Example 1: Basic usage. + +Suppose a plug-in creates the following menus: +> + C-Support + >-+ Comments + | >-- code->comment + | >-- comment->code + | >-+ Special + | | >--- ... + >-+ Run + | >-- run + | >-- ... +< +Then the call has to look like this: > + call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "&C-Support", + \ "do_all", "existing_menu", [ "&Comments","Comments.&Special.","&Run." ] ) +< +To create headers for each sub-menu, similar to those the template support +creates, use code like this: +> + let root_menu = "&C-Support" + let global_name = "C/C++" + exe 'amenu '.root_menu.'.'.root_menu.' <Nop>' + exe 'amenu '.root_menu.'.-Sep0- <Nop>' + exe 'amenu '.root_menu.'.&Run.Run<TAB>'.global_name.' <Nop>' + exe 'amenu '.root_menu.'.Run.-Sep00- <Nop>' +< + +Example 2: Advanced usage. + +This facility can be used to create all the menu headers. +It also gives more control over the order of the menu entries. + +First, reset the list of created menus: > + call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support", + \ "do_reset" ) +Then create a sub-menu (shortcut "c"): > + call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support", + \ "sub_menu", "&Comments" ) + " entries: comment/uncomment/... : + ... +Create entries for the templates: > + call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support", + \ "do_templates" ) +Create a run menu (shortcut "r"): > + call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support", + \ "sub_menu", "&Run" ) + " entries: compile/run/test/... : + ... +Create the special entries at the end of the run menu: > + call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support", + \ "do_specials", "specials_menu", "Run." ) +> + +Technical Details: +- The library must be given as the name of the global variable, since this + name is required to create the menus. +- The function creates menus of the following types: + amenu, imenu and vmenu (where appropriate) + +------------------------------------------------------------------------------ +9.3 ACCESS *template-support-api-access* +------------------------------------------------------------------------------ + +The following functions are used to query and change the resources of a +template library. For example, they are used to change the style or to change +the format of the date and time. + +------------------------------------------------------------------------------ + *mmtemplates#core#ChooseStyle()* +The style is changed using the function: + + mmtemplates#core#ChooseStyle ( library, style ) ~ + +Parameters: + library - The template library. (string or dict) + style - The name of the style or "!pick". (string) +No returns. + +The library can either be given directly, or as the name of the global +variable containing the library. +If 'style' is "!pick", the user is presented with a list of all styles, and +can choose one. +It the style 'style' does not exist, an error message is displayed and the +style remains unchanged. + +Example: + +Prompt the user for a new style: > + call mmtemplates#core#ChooseStyle ( g:My_C_Templates, "!pick" ) + +------------------------------------------------------------------------------ + *mmtemplates#core#Resource()* +Access to a number of resources is provided by: + + [ rval, msg ] = mmtemplates#core#Resource ( library, mode, ... ) ~ + + [ rval, msg ] ~ + = mmtemplates#core#Resource ( library, "get", resource, key ) ~ + [ rval, msg ] ~ + = mmtemplates#core#Resource ( library, "set", resource, key, val ) ~ + +Parameters: + library - The template library. (string or dict) + mode - The operation which should be executed. (string) +Optional parameters: + ... - Depending on 'mode'. +Returns: + rval - Content and type depending on 'mode'. + msg - In case of success: An empty string. (string) + In case of failure: An error message. (string) + +The library can either be given directly, or as the name of the global +variable containing the library. + +Special resources: + +- "escaped_mapleader" : Return the mapleader, escaped for use in a menu. +- "jumptag" : Return the regex used to find jump tags. +- "style" : Return the name of the current style. + +Regular resources: + +- "add" : Add the property with the given key and set it to 'val'. +- "get" : Return the resource with the given key or 0. +- "set" : Change the resource with the given key to 'val'. + +The mode "get" supports the following resources: +- "list", "l": The list as generated by: == List: l == ... == +- "macro", "m": A macro as set by: SetMacro( "m", ... ) +- "path", "p": A path as set by: SetPath( "p", ... ) +- "property", "p": An existing resource named "p". +It returns the integer 0, if the resource 'key' does not exist. +The mode "set" can be used to overwrite these resources. +The resource "list" is returned as a reference, use it responsibly. + +For "add" and "set" 'rval' is undefined. + +Macros: + +Setting the special macros "DATE", "TIME", and "YEAR" changes the format of +the date and time. they use the same format as the function |strftime()|. +Setting "BASENAME", "FILENAME", "PATH" and "SUFFIX" has no effect. + +Properties: + +The mode "get" returns the property named 'key', but only if it already +exists. Only an existing property can be set in the mode "set". To create and +set a new property, the mode "add" must be used. + + +Example 1: + +The format of the macro *|TIME|* can be changed by calling: > + call mmtemplates#core#Resource ( + \ g:My_C_Templates, "set", "macro", "TIME", "%H:%M" ) +< + +Example 2: + +Suppose there is a template like this: +> + == Include.project include == insert, pick-file == + |Prompt( "project include directory" )| + |GetPath( "project_include" )| + #include "|PICK|" + == ENDTEMPLATE == +< +When switching to a new project, execute: > + call mmtemplates#core#Resource ( + \ g:My_C_Templates, "set", "path", "project_include", project_incl_dir ) +< +The next time the template "Include.project include" is inserted, the file +browser will already be set to the project include directory. + + +Example 3: + +Set the property "Templates::Mapleader": > + call mmtemplates#core#Resource ( + \ g:My_C_Templates, "set", "Templates::Mapleader", "." ) +< +Create a new property "C::RunCompiler::Map": > + call mmtemplates#core#Resource ( + \ g:My_C_Templates, "add","C::RunCompiler::Map", "rc" ) +< +Get the mapleader (already escaped): > + let [ esc_mapleader, msg ] = mmtemplates#core#Resource ( + \ g:My_C_Templates, "escaped_mapleader" ) +< +Get the map (not escaped!): > + let [ map_run, msg ] = mmtemplates#core#Resource ( + \ g:My_C_Templates, "get", "C::RunCompiler::Map" ) + +Create the menu entry: > + if empty ( msg ) + exe 'amenu '.root_menu + \ .'.Run.run\ &compiler<TAB>'.esc_mapleader.map_run.' :call Run()<CR>' + else + " handle error ... + endif +< + +Example 4: + +Get the current style: > + let [ current_style, msg ] = mmtemplates#core#Resource ( + \ g:My_C_Templates, "style" ) +< +------------------------------------------------------------------------------ +9.4 MISCELLANY *template-support-api-misc* +------------------------------------------------------------------------------ + +This section describes various functions, provided for convenience. + +------------------------------------------------------------------------------ + *mmtemplates#core#SetMapleader()* + *mmtemplates#core#ResetMapleader()* +Set and reset |maplocalleader|: + + mmtemplates#core#SetMapleader ( localleader ) ~ + mmtemplates#core#ResetMapleader () ~ + +Parameters: + localleader - The new value for |maplocalleader|. (string) +No returns. + +A call to mmtemplates#core#SetMapleader sets maplocalleader to the given +value. A subsequent call to mmtemplates#core#ResetMapleader restores the +previous setting, which can also mean that maplocalleader is undefined again. +Calls to SetMapleader and ResetMapleader can be nested. +If the argument 'localleader' is an empty string, maplocalleader remains +unchanged. + +------------------------------------------------------------------------------ + *mmtemplates#core#EscapeMenu()* +Escape a string to be used as a menu entry: + + str = mmtemplates#core#EscapeMenu ( str ) ~ + +Parameters: + str - The menu item. (string) +Optional parameters: + mode - How to escape the string. (string, default "entry") +Returns: + str - The same string with appropriately escaped characters. (string) + +The following modes are supported: +- "menu" : A menu name with possible submenus, escapes <space> \ | & +- "entry" : A menu entry, dots are escaped as well, escapes <space> . \ | & +- "right" : The right-aligned side of a menu entry, escapes <space> . \ | + +In mode "entry" the function even escapes '.', so the menu and the entry must +be escaped separately, otherwise the entry 'frame comment' in the menu +'Comments': > + "Comments.frame comment" +would turn into the entry: > + "Comments\.frame\ comment" + +============================================================================== +10. BACKWARDS COMPATIBILITY *template-support-backwards* +============================================================================== + +The following behavior is not compatible with the old template systems of +various plug-ins. This list does not include new features which are now +supported. + +c-support: +doxygen-support: +perl-support: +- No automatic uppercase for *|BASENAME|* . +- The format for *|DATE|* , *|TIME|* and *|YEAR|* is now configured via the + template library. Plug-ins may provide other ways to do the configuration. + +perl-support: +- The template header can not have the format > + == templatename == [ position == ] [ indentation == ] +< anymore, since the last part would be ignored. Use the list of template + options instead: > + == templatename == [ position, indentation == ] +< Both 'position' and 'indentation' are optional, of course. + + + + -------------------------------------------------------------------------- ~ + + -------------------------------------------------------------------------- ~ + + -------------------------------------------------------------------------- ~ + + + +============================================================================== +A. SYNTAX *template-support-syntax* +============================================================================== + +The standards for the idioms are as follows, but may be changed via the API: + +Idiom Changeable? Standard + +CommentStart yes $ +BlockDelimiter no == + +CommandName no same as MacroName +MacroName no a-z, A-Z, 0-9 and _ + starting with a letter or underscore +OptionName no same as MacroName +ResourceName no same as MacroName +SeparatorName no same as MacroName +StyleName no same as MacroName +TemplateName no a-z, A-Z, 0-9 and _ + - . , <Space> + starting with a letter or underscore, + not ending with a whitespace +Mapping no a-z, A-Z, 0-9 and _ + - + +The rules in the next sections use the following notation: + +- Syntax category: StartsWithCapitalLetters +- Keyword: ALLCAPS +- Various items: -something- +- Square brackets [ ] mark an optional part of the rule. +- All other characters are as printed. +- Whitespaces are ignored, except where <start> marks the start of the line. + Whitespaces can not appear there. + +------------------------------------------------------------------------------ +A.1 COMMAND SECTION *template-support-syntax-cmd* +------------------------------------------------------------------------------ + +MacroAssignment (one of): + -text- + ' -text- ' + " -text- " + +Note: Trailing whitespaces are ignored, even with the first rule. + + +Statement (one of): + -empty line- + <start> CommentStart -anything- + <start> CommandName ( ParameterList ) + <start> *|MacroName|* = MacroAssignment + StyleBlock1 + StyleBlock2 + Template + HelpTemplate + MenuSeparator + List + + +StyleBlock1 (sequence): + <start> == IF *|STYLE|* IS MacroName == + StatementList + <start> == ENDIF == + + +StyleBlock2 (sequence): + <start> == USE STYLES : MacroNameList == + StatementList + <start> == ENDSTYLES == + + +Template (sequence): + <start> == [ TEMPLATE : ] TemplateName == [ OptionList == ] + -several lines- + <start> == ENDTEMPLATE == + +Note: The " TEMPLATE : " in the first line is optional, as opposed to the + structure of the next three rules. + + +HelpTemplate (sequence): + <start> == HELP : TemplateName == [ OptionList == ] + -several lines- + <start> == ENDTEMPLATE == + + +MenuSeparator (one line): + <start> == SEP : SeparatorName == + + +List (sequence): + <start> == LIST : MacroName == [ OptionList == ] + -several lines- + <start> == ENDLIST == + + +MacroNameList (one of): + MacroName + MacroName , MacroNameList + + +OptionList (one of): + -empty- + Option + Option , OptionList + + +Option (one of): + OptionName + OptionName : MacroName + OptionName : Mapping + +------------------------------------------------------------------------------ +A.2 TEMPLATES *template-support-syntax-templ* +------------------------------------------------------------------------------ + + *Todo syntax templates + +------------------------------------------------------------------------------ +A.3 LISTS *template-support-syntax-list* +------------------------------------------------------------------------------ + +Lists can either be lists or dictionaries. (Corresponding to the types Vim +uses: |List| and |Dictionary|.) + +Lists are a comma separated list of strings: +> + == LIST: Options == list == + "tabstop", "shiftwidth", + "wrap", "nowrap", + "filetype" + == ENDLIST == +< +Bare lists do not require quotes, each line is interpreted as an entry. +Leading and trailing whitespaces are ignored: +> + == LIST: Options == list, bare == + tabstop + shiftwidth + wrap + nowrap + filetype + == ENDLIST == +< +Dictionaries associate a key with a value. Key and value are separated by a +colon, different entries by a comma. +> + == LIST: FileEndings == dict == + "C" : ".c" , + "C++" : ".cc" , + "Perl" : ".pl" , + "Shell" : ".sh" , + "Vimscript" : ".vim" , + == ENDLIST == +< +============================================================================== +B. COMMANDS *template-support-commands* +============================================================================== + +This sections list the commands supported by the template system. + +------------------------------------------------------------------------------ +B.1 COMMAND SECTION *template-support-cmd-cmd-sct* +------------------------------------------------------------------------------ + +The following commands can be used outside of templates, in the so-called +command section. + +------------------------------------------------------------------------------ + *template-support-IncludeFile()* +Include the file 'filename': + + IncludeFile ( filename [, "abs"] ) ~ + +'filename' can contain a path which can be absolute or relative. Relative +paths are interpreted in relation to the directory of the file containing the +command. The path is always understood to be relative, except when the +optional second argument "abs" is given. + +------------------------------------------------------------------------------ + *template-support-SetFormat()* +Set the format of 'item' to 'format': + + SetFormat ( item, format ) ~ + +This changes the way the macros "TIME", "DATE" and "YEAR" are replaced. It +sets the format of the date and time. They use the same format as the function +|strftime()|. + +Example: > + SetFormat ( "TIME", "%H:%M" ) +The macro *|TIME|* will now be replaced by something like 10:24. + +------------------------------------------------------------------------------ + *template-support-SetMacro()* +Set the macro 'name' to 'text': + + SetMacro ( name, text ) ~ + +This is used to set replacements for macros. + +Setting the macros "TIME", "DATE", "YEAR", "BASENAME", "FILENAME" , "PATH" and +"SUFFIX" is not allowed. They are set to the appropriate values before +insertion of a template. + +Example: > + SetMacro ( "AUTHOR", "My cat." ) + +------------------------------------------------------------------------------ + *template-support-SetPath()* +Set the resource 'name' to the given path. + + SetPath ( name, path ) ~ + +Subsequently the path can be used in templates. + +------------------------------------------------------------------------------ + *template-support-SetProperty()* +Set the property 'name' to the given value. + + SetProperty ( name, value ) ~ + +Only existing properties can be set. If 'name' does not refer to an existing +property, an error will be printed. + +------------------------------------------------------------------------------ + *template-support-SetStyle()* +Set the active style to 'name': + + SetStyle ( name ) ~ + +This style will be used after the library has been loaded. + +------------------------------------------------------------------------------ + *template-support-MenuShortcut()* +Set the shortcut for the submenu 'menu' to 'shortcut': + + MenuShortcut ( menu, shortcut ) ~ + +The shortcut is set for the menu named by the last component of 'menu', which +can consist of several parts, separated by points. Trailing points are +ignored. + +Example: > + MenuShortcut ( "Comments.Frames.", "r" ) +Sets the shortcut for the submenu "Frames", not "Comments". + +------------------------------------------------------------------------------ +B.2 TEMPLATES *template-support-cmd-templates* +------------------------------------------------------------------------------ + +Templates themselves support various commands, either in the command block at +the beginning of the template, or in the text itself. + +------------------------------------------------------------------------------ + *template-support-PickFile()* +Open a prompt and let the user select a file: + + |PickFile ( prompt, path )| ~ + +Displays 'prompt' and lets the user select a file. The file browser starts out +in the directory named by 'path'. If 'path' matches an identifier, the path +resource by this name serves as the path. Otherwise the string path is used as +the path directly. + +After the user selected a file, several replacements for macros are created, +which can be inserted into the template: +- *|PICK_COMPL|* : the complete path and name of the selected file +- *|PATH_COMPL|* : the complete path of the selected file +- *|PICK|* : the selected path and file relative to the directory given + in 'path' +- *|PATH|* : the path in *|PICK|* +- *|FILENAME|* : the name of the file +- *|BASENAME|* : the name of the file without the suffix +- *|SUFFIX|* : the suffix of the file + +Example: > + + SetPath ( "global", "/usr/include/" ) + + == global include == below == + |PickFile( "select a file: ", "global" )| + #include <|PICK|> + == local include == below == + |PickFile( "select a file: ", "global/" )| + #include "|PICK|" + == ENDTEMPLATE == +< +The path in the first template is the resource "global", which in turn is +"/usr/include/". The path in the second template will be "global/", since the +string does not match an identifier. + +If the user inserts the template "global include", he will be asked to select +a file, starting in the directory "/usr/include/". If we selects the file: > + /usr/include/QtGui/QPushButton +the macro *|PICK|* will be set to "QtGui/QPushButton", and *|PATH|* to +"QtGui". + +------------------------------------------------------------------------------ + *template-support-PickList()* +Open a prompt and let the user select an entry from a list: + + |PickList ( prompt, list )| ~ + +Displays 'prompt' and lets the user select an entry from a list. If 'list' is +a string and matches an identifier, the list resource by this name is used. +If 'list' is a list or a dictionary, it is used directly. + +In case of lists, the user has to choose an entry from the list. In case of +dictionaries, the user has to choose one of the keys. + +After the user selected an entry, several replacements for macros are created, +which can be inserted in the template: +- *|VALUE|* : the selected entry from the list or dictionary +- *|KEY|* : the selected key (dictionaries only) +- *|PICK|* : same as *|VALUE|* + +Example: +> + == LIST: headers == list == + "stdlib", + "stdio", + "string", + == LIST: functions == hash == + "strcpy" : "{+DEST+}, {+SRC+}", + "strncpy" : "{+DEST+}, {+SRC+}, {+N+}", + "strcmp" : "{+STR1+}, {+STR2+}", + "strncmp" : "{+STR1+}, {+STR2+}, {+N+}", + "strlen" : "{+STR+}", + == ENDLIST == + + == header include == below == + |PickList( "header file: ", "headers" )| + #include <|PICK|.h> + == function call == insert == + |PickList( "function: ", "functions" )| + |KEY|<CURSOR> ( |VALUE| ) + == ENDTEMPLATE == +< +The first template is quite simple. The user selects a header from the list, +then the preprocessor directive is inserted. + +The second template uses a dictionary. The user has to pick an entry from the +list of function names. The template is inserted using both the selected key +and value. Each value is a list of jump tags, named for the arguments of the +corresponding function. + +Inserting the template "function call" and selecting "strcpy" will results in +the following text to be inserted: > + strcpy | ( {+DEST+}, {+SRC+} ) +The position of the cursor is marked by "|". The jump key can be used to jump +ahead and replace the tags. + +------------------------------------------------------------------------------ + *template-support-Prompt()* +Prompt the user for a replacement of the macro: + + |Prompt ( macro, flag )| ~ + +The user is prompted for a replacement of 'macro'. After the user has entered +a text, the flag is applied. The replacement is saved to be reused later. + +Flags: +- "" : no change to the text +- "l" : change text to lowercase +- "u" : change text to uppercase +- "c" : capitalize text (change first letter to uppercase) +- "L" : legalize name (replace all non-word characters with underscores) + +Example: +> + == chapter, alt1 == below == + ============================================================================ + |?NUMBER| |?NAME:u| + ============================================================================ + + <CURSOR> + + == chapter, alt2 == below == + |Prompt( 'NAME', '' )| + |Prompt( 'NUMBER', '' )| + ============================================================================ + |NUMBER| |NAME:u| + ============================================================================ + + <CURSOR> + + == chapter, toc == below == + |NUMBER| |NAME:c| + == ENDTEMPLATE == +< +This inserts captions for chapters as used in this document. With the first +alternative, the user is first prompted for a replacement of *|NUMBER|* , +because of the order both macros appear in the text. The name is saved in +uppercase. +Using the second alternative, the user is prompted for the name first. The +name is saved as entered and only inserted in uppercase. Now it can be +inserted into the table of contents as entered by the user. + +============================================================================== +C. OPTIONS *template-support-options* +============================================================================== + +The following sections list the options for templates and lists. + +------------------------------------------------------------------------------ +C.1 TEMPLATES *template-support-opt-templ* +------------------------------------------------------------------------------ + +The template options appear in the header of the template: + == <name> == <options> == ~ + +It is not required to specify any options. The defaults are given below. +Help templates use the same options as normal templates. + +------------------------------------------------------------------------------ + *template-support-start* *template-support-append* + *template-support-above* *template-support-insert* + *template-support-below* +Placement: + + start - The text is placed above the first line. + above - The text is placed above the current line. + below - The text is placed below the current line (default). + append - The text is appended to the current line. + insert - The text is inserted at the cursor position. + +Note: "below" and "insert" support split tag in visual mode. + +------------------------------------------------------------------------------ + *template-support-visual* *template-support-indent* + *template-support-novisual* *template-support-noindent* +Insertion: + + visual - Use the split tag in visual mode (default?). + novisual - No special behavior in visual mode (default?). + + indent - The inserted text is indented (default). + noindent - No automatic indentation. + +Note: "visual" is the default for templates containing the split tag, + "novisual" for templates without the split tag. + +------------------------------------------------------------------------------ + *template-support-sc* *template-support-nomenu* + *template-support-shortcut* *template-support-expandmenu* + *template-support-map* +Menus and Maps: + + nomenu - No menu entry is created. + expandmenu - A submenu is created for this template with entries matching + those of a given list. + sc:<sc> - A shortcut is created for the menu entry of this template. + shortcut:<sc> - Long version of sc:<sc>. + map:<map> - A map is created for this template. + +Note: The default is for a menu entry to be created. +Note: A shortcut can only be one character long. A map can be several + characters long. It is always preceded by the local mapleader. + +------------------------------------------------------------------------------ +C.2 LISTS *template-support-opt-list* +------------------------------------------------------------------------------ + +The list options appear in the header of the list: + == List: OutputModifiers == <options> == ~ + +It is not required to specify any options. The defaults are given below. + +------------------------------------------------------------------------------ + *template-support-list* *template-support-dict* + *template-support-hash* *template-support-dictionary* +Type: + + list - The object is given as a list. (default) + hash - The object is a hash, or dictionary. + dict - Same as hash. + dictionary - Same as hash. + +For a description see |template-support-syntax-list|. + +------------------------------------------------------------------------------ + *template-support-bare* +Interpretation: + + bare - The list is interpreted as a bare list. Each line is considered to be + a new entry. + +Note: Bare lists are not the default. + +============================================================================== +D. CHANGE LOG *template-support-change-log* +============================================================================== + +------------------------------------------------------------------------------ + RELEASE NOTES FOR VERSION 0.9.3 +------------------------------------------------------------------------------ + +- Change: In case several version of autoload/mmtemplates/core.vim are + available on 'runtimepath', pick out the newest one to load. + +Includes the patches 0.9.2-1 to 0.9.2-2: +- Change: More checks when rereading templates. +- Change: Better compatibility with custom mappings + (use "normal!", "noremap" and "noremenu" consistently). +- Change: During template insertion, find <CURSOR> tag independent of the + settings 'magic' and 'startofline'. +- Added: API functions "mmtemplates#core#SetMapleader" and + "mmtemplates#core#ResetMapleader". +- Extended the documentation. + +------------------------------------------------------------------------------ + RELEASE NOTES FOR VERSION 0.9.2 +------------------------------------------------------------------------------ + +- Added: 'SetProperty' to set properties using a template library. +- Change: Improved list picker. + +API: +- Change: Extended 'mmtemplates#core#EscapeMenu'. + +Includes the patches 0.9.1-1 to 0.9.1-3: +- Bugfix: Problem with macro replacements containing macros with flags. +- Change: Syntax highlighting. +- Change: Warnings about overwritten maps are only printed once for every + filetype. +- Bugfix: Inserting templates in visual mode with placement "insert" could + cause rare problems interacting with the indent program. +- Extended the documentation. + +------------------------------------------------------------------------------ + +PATCH 0.9.2-1: +- Released with slight changes in the core functionality. +- Change: More checks when rereading templates. +- Extended the documentation. + +------------------------------------------------------------------------------ + +PATCH 0.9.2-2: +- Released with slight changes in the core functionality. +- Change: Better compatibility with custom mappings + (use "normal!", "noremap" and "noremenu" consistently). +- Change: During template insertion, find <CURSOR> tag independent of the + settings 'magic' and 'startofline'. +- Added: API functions "mmtemplates#core#SetMapleader" and + "mmtemplates#core#ResetMapleader". + +------------------------------------------------------------------------------ + RELEASE NOTES FOR VERSION 0.9.1 +------------------------------------------------------------------------------ + +- Change: When checking for already existing maps: Check each mode individually. +- Added: Menu separators can be inserted via the template library. +- Bugfix: Changing the mapleader now works. +- Bugfix: Inserting templates with placement "insert" did not work in some + cases. +- Minor improvements and bugfixes. + +API: +- Added: Sub-menus can be created with priorities. +- Added: Properties. +- Added: The mapleader shown in the menu is configurable. +- Added: The maps for "edit templates", "reread templates" and "choose style" + are configurable. + +Internal Changes: +- Changes to the template data structure. +- Major code cleanup. + +------------------------------------------------------------------------------ + +PATCH 0.9.1-1: +- Released with no changes in the core functionality. +- Change: Some commands are now executed silently. +- Bugfix: Syntax highlighting. +- Extended the documentation. + +PATCH 0.9.1-2: +- Released with slight changes in the core functionality. +- Bugfix: Problem with macro replacements containing macros with flags. +- Change: Syntax highlighting. +- Slightly extended the documentation. + +PATCH 0.9.1-3: +- Released with slight changes in the core functionality. +- Change: Warnings about overwritten maps are only printed once for every + filetype. +- Bugfix: Inserting templates in visual mode with placement "insert" could + cause rare problems interacting with the indent program. +- Extended the documentation. + +------------------------------------------------------------------------------ + RELEASE NOTES FOR VERSION 0.9 +------------------------------------------------------------------------------ + +- Initial upload. + +============================================================================== +vim:tw=78:noet:ts=2:ft=help:norl:expandtab: diff --git a/.config/nvim/plugged/bash-support.vim/ftplugin/sh.vim b/.config/nvim/plugged/bash-support.vim/ftplugin/sh.vim new file mode 100644 index 0000000..cfbbb42 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/ftplugin/sh.vim @@ -0,0 +1,43 @@ +" Vim filetype plugin file +" +" Language : bash +" Plugin : bash-support.vim +" Maintainer : Fritz Mehner <mehner@fh-swf.de> +" +" ----------------------------------------------------------------- +" +" Only do this when not done yet for this buffer +" +if exists("b:did_BASH_ftplugin") + finish +endif +let b:did_BASH_ftplugin = 1 +" +"------------------------------------------------------------------------------ +" Avoid a wrong syntax highlighting for $(..) and $((..)) +"------------------------------------------------------------------------------ +let b:is_bash = 1 +" +"------------------------------------------------------------------------------- +" additional mapping : single quotes around a Word (non-whitespaces) +" masks the normal mode command '' (jump to the position +" before the latest jump) +" additional mapping : double quotes around a Word (non-whitespaces) +"------------------------------------------------------------------------------- +nnoremap <buffer> '' ciW''<Esc>P +nnoremap <buffer> "" ciW""<Esc>P +" +"------------------------------------------------------------------------------- +" set "maplocalleader" as configured using "g:BASH_MapLeader" +"------------------------------------------------------------------------------- +call Bash_SetMapLeader () +" +" maps defined here will use "g:BASH_MapLeader" as <LocalLeader> +" example: +"map <buffer> <LocalLeader>eg :echo "Example Map :)"<CR> +" +"------------------------------------------------------------------------------- +" reset "maplocalleader" +"------------------------------------------------------------------------------- +call Bash_ResetMapLeader () +" diff --git a/.config/nvim/plugged/bash-support.vim/plugin/bash-support.vim b/.config/nvim/plugged/bash-support.vim/plugin/bash-support.vim new file mode 100644 index 0000000..6cda5c1 --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/plugin/bash-support.vim @@ -0,0 +1,1879 @@ +"=============================================================================== +" +" File: bash-support.vim +" +" Description: bash support +" +" Write bash scripts by inserting comments, statements, +" variables and builtins. +" +" VIM Version: 7.0+ +" Author: Dr. Fritz Mehner (fgm), mehner.fritz@fh-swf.de +" Organization: FH Südwestfalen, Iserlohn, Germany +" Version: see g:BASH_Version below +" Created: 26.02.2001 +" License: Copyright (c) 2001-2014, Dr. Fritz Mehner +" This program is free software; you can redistribute it and/or +" modify it under the terms of the GNU General Public License as +" published by the Free Software Foundation, version 2 of the +" License. +" This program is distributed in the hope that it will be +" useful, but WITHOUT ANY WARRANTY; without even the implied +" warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +" PURPOSE. +" See the GNU General Public License version 2 for more details. +"=============================================================================== +" +if v:version < 700 + echohl WarningMsg | echo 'plugin bash-support.vim needs Vim version >= 7'| echohl None + finish +endif +" +" Prevent duplicate loading: +" +if exists("g:BASH_Version") || &cp + finish +endif +" +let g:BASH_Version= "4.2.1" " version number of this script; do not change +" +"=== FUNCTION ================================================================ +" NAME: BASH_SetGlobalVariable {{{1 +" DESCRIPTION: Define a global variable and assign a default value if nor +" already defined +" PARAMETERS: name - global variable +" default - default value +"=============================================================================== +function! s:BASH_SetGlobalVariable ( name, default ) + if !exists('g:'.a:name) + exe 'let g:'.a:name." = '".a:default."'" + else + " check for an empty initialization + exe 'let val = g:'.a:name + if empty(val) + exe 'let g:'.a:name." = '".a:default."'" + endif + endif +endfunction " ---------- end of function s:BASH_SetGlobalVariable ---------- +" +"=== FUNCTION ================================================================ +" NAME: GetGlobalSetting {{{1 +" DESCRIPTION: take over a global setting +" PARAMETERS: varname - variable to set +" RETURNS: +"=============================================================================== +function! s:GetGlobalSetting ( varname ) + if exists ( 'g:'.a:varname ) + exe 'let s:'.a:varname.' = g:'.a:varname + endif +endfunction " ---------- end of function s:GetGlobalSetting ---------- +" +"------------------------------------------------------------------------------ +" *** PLATFORM SPECIFIC ITEMS *** {{{1 +"------------------------------------------------------------------------------ +let s:MSWIN = has("win16") || has("win32") || has("win64") || has("win95") +let s:UNIX = has("unix") || has("macunix") || has("win32unix") +" +let s:installation = '*undefined*' +let s:BASH_GlobalTemplateFile = '' +let s:BASH_LocalTemplateFile = '' +let s:BASH_FilenameEscChar = '' +let s:BASH_XtermDefaults = '-fa courier -fs 12 -geometry 80x24' + + +if s:MSWIN + " ========== MS Windows ====================================================== + " + " change '\' to '/' to avoid interpretation as escape character + if match( substitute( expand("<sfile>"), '\', '/', 'g' ), + \ substitute( expand("$HOME"), '\', '/', 'g' ) ) == 0 + " + " USER INSTALLATION ASSUMED + let s:installation = 'local' + let s:BASH_PluginDir = substitute( expand('<sfile>:p:h:h'), '\', '/', 'g' ) + let s:BASH_LocalTemplateFile = s:BASH_PluginDir.'/bash-support/templates/Templates' + else + " + " SYSTEM WIDE INSTALLATION + let s:installation = 'system' + let s:BASH_PluginDir = $VIM.'/vimfiles' + let s:BASH_GlobalTemplateFile = s:BASH_PluginDir.'/bash-support/templates/Templates' + let s:BASH_LocalTemplateFile = $HOME.'/vimfiles/bash-support/templates/Templates' + endif + " + let s:BASH_FilenameEscChar = '' + let s:BASH_Display = '' + let s:BASH_ManualReader = 'man.exe' + let s:BASH_Executable = 'bash.exe' + let s:BASH_OutputGvim = 'xterm' + " +else + " ========== Linux/Unix ====================================================== + " + if match( expand("<sfile>"), resolve( expand("$HOME") ) ) == 0 + " + " USER INSTALLATION ASSUMED + let s:installation = 'local' + let s:BASH_PluginDir = expand('<sfile>:p:h:h') + let s:BASH_LocalTemplateFile = s:BASH_PluginDir.'/bash-support/templates/Templates' + else + " + " SYSTEM WIDE INSTALLATION + let s:installation = 'system' + let s:BASH_PluginDir = $VIM.'/vimfiles' + let s:BASH_GlobalTemplateFile = s:BASH_PluginDir.'/bash-support/templates/Templates' + let s:BASH_LocalTemplateFile = $HOME.'/.vim/bash-support/templates/Templates' + endif + " + let s:BASH_Executable = $SHELL + let s:BASH_FilenameEscChar = ' \%#[]' + let s:BASH_Display = $DISPLAY + let s:BASH_ManualReader = '/usr/bin/man' + let s:BASH_OutputGvim = 'vim' + " +endif +" +let s:BASH_CodeSnippets = s:BASH_PluginDir.'/bash-support/codesnippets/' +call s:BASH_SetGlobalVariable( 'BASH_CodeSnippets', s:BASH_CodeSnippets ) +" +" +" g:BASH_Dictionary_File must be global +" +if !exists("g:BASH_Dictionary_File") + let g:BASH_Dictionary_File = s:BASH_PluginDir.'/bash-support/wordlists/bash-keywords.list' +endif +" +"---------------------------------------------------------------------- +" *** MODUL GLOBAL VARIABLES *** {{{1 +"---------------------------------------------------------------------- +" +let s:BASH_CreateMenusDelayed = 'yes' +let s:BASH_MenuVisible = 'no' +let s:BASH_GuiSnippetBrowser = 'gui' " gui / commandline +let s:BASH_LoadMenus = 'yes' " load the menus? +let s:BASH_RootMenu = '&Bash' " name of the root menu +let s:BASH_Debugger = 'term' +let s:BASH_bashdb = 'bashdb' +" +let s:BASH_LineEndCommColDefault = 49 +let s:BASH_Printheader = "%<%f%h%m%< %=%{strftime('%x %X')} Page %N" +let s:BASH_TemplateJumpTarget = '' +let s:BASH_Errorformat = '%f:\ %[%^0-9]%#\ %l:%m,%f:\ %l:%m,%f:%l:%m,%f[%l]:%m' +let s:BASH_Wrapper = s:BASH_PluginDir.'/bash-support/scripts/wrapper.sh' +let s:BASH_InsertFileHeader = 'yes' +let s:BASH_SyntaxCheckOptionsGlob = '' +" +call s:GetGlobalSetting ( 'BASH_Debugger' ) +call s:GetGlobalSetting ( 'BASH_bashdb' ) +call s:GetGlobalSetting ( 'BASH_SyntaxCheckOptionsGlob' ) +call s:GetGlobalSetting ( 'BASH_Executable' ) +call s:GetGlobalSetting ( 'BASH_InsertFileHeader' ) +call s:GetGlobalSetting ( 'BASH_GuiSnippetBrowser' ) +call s:GetGlobalSetting ( 'BASH_LoadMenus' ) +call s:GetGlobalSetting ( 'BASH_RootMenu' ) +call s:GetGlobalSetting ( 'BASH_Printheader' ) +call s:GetGlobalSetting ( 'BASH_ManualReader' ) +call s:GetGlobalSetting ( 'BASH_OutputGvim' ) +call s:GetGlobalSetting ( 'BASH_XtermDefaults' ) +call s:GetGlobalSetting ( 'BASH_LocalTemplateFile' ) +call s:GetGlobalSetting ( 'BASH_GlobalTemplateFile' ) +call s:GetGlobalSetting ( 'BASH_CreateMenusDelayed' ) +call s:GetGlobalSetting ( 'BASH_LineEndCommColDefault' ) + +call s:BASH_SetGlobalVariable ( 'BASH_MapLeader', '' ) " default: do not overwrite 'maplocalleader' +" +" set default geometry if not specified +" +if match( s:BASH_XtermDefaults, "-geometry\\s\\+\\d\\+x\\d\\+" ) < 0 + let s:BASH_XtermDefaults = s:BASH_XtermDefaults." -geometry 80x24" +endif +" +let s:BASH_Printheader = escape( s:BASH_Printheader, ' %' ) +let s:BASH_saved_global_option = {} +let b:BASH_BashCmdLineArgs = '' +" +"=== FUNCTION ================================================================ +" NAME: BASH_SaveGlobalOption {{{1 +" DESCRIPTION: +" PARAMETERS: option name +" characters to be escaped (optional) +" RETURNS: +"=============================================================================== +function! s:BASH_SaveGlobalOption ( option, ... ) + exe 'let escaped =&'.a:option + if a:0 == 0 + let escaped = escape( escaped, ' |"\' ) + else + let escaped = escape( escaped, ' |"\'.a:1 ) + endif + let s:BASH_saved_global_option[a:option] = escaped +endfunction " ---------- end of function BASH_SaveGlobalOption ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_RestoreGlobalOption {{{1 +" DESCRIPTION: +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! s:BASH_RestoreGlobalOption ( option ) + exe ':set '.a:option.'='.s:BASH_saved_global_option[a:option] +endfunction " ---------- end of function BASH_RestoreGlobalOption ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Input {{{1 +" DESCRIPTION: Input after a highlighted prompt +" PARAMETERS: prompt - prompt string +" defaultreply - default reply +" ... - completion +" RETURNS: reply +"=============================================================================== +function! BASH_Input ( prompt, defaultreply, ... ) + echohl Search " highlight prompt + call inputsave() " preserve typeahead + if a:0 == 0 || empty(a:1) + let retval =input( a:prompt, a:defaultreply ) + else + let retval =input( a:prompt, a:defaultreply, a:1 ) + endif + call inputrestore() " restore typeahead + echohl None " reset highlighting + let retval = substitute( retval, '^\s\+', '', '' ) " remove leading whitespaces + let retval = substitute( retval, '\s\+$', '', '' ) " remove trailing whitespaces + return retval +endfunction " ---------- end of function BASH_Input ---------- +" +"------------------------------------------------------------------------------ +" BASH_AdjustLineEndComm: adjust line-end comments +"------------------------------------------------------------------------------ +" +" patterns to ignore when adjusting line-end comments (incomplete): +let s:AlignRegex = [ + \ '\$#' , + \ '\${.*}' , + \ "'\\%(\\\\'\\|[^']\\)*'" , + \ '"\%(\\.\|[^"]\)*"' , + \ '`[^`]\+`' , + \ ] +" +"=== FUNCTION ================================================================ +" NAME: BASH_AdjustLineEndComm {{{1 +" DESCRIPTION: adjust end-of-line comments +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_AdjustLineEndComm ( ) range + " + " comment character (for use in regular expression) + let cc = '#' " start of a Perl comment + " + " patterns to ignore when adjusting line-end comments (maybe incomplete): + let align_regex = join( s:AlignRegex, '\|' ) + " + " local position + if !exists( 'b:BASH_LineEndCommentColumn' ) + let b:BASH_LineEndCommentColumn = s:BASH_LineEndCommColDefault + endif + let correct_idx = b:BASH_LineEndCommentColumn + " + " === plug-in specific code ends here === + " === the behavior is governed by the variables above === + " + " save the cursor position + let save_cursor = getpos('.') + " + for line in range( a:firstline, a:lastline ) + silent exe ':'.line + " + let linetxt = getline('.') + " + " "pure" comment line left unchanged + if match ( linetxt, '^\s*'.cc ) == 0 + "echo 'line '.line.': "pure" comment' + continue + endif + " + let b_idx1 = 1 + match ( linetxt, '\s*'.cc.'.*$', 0 ) + let b_idx2 = 1 + match ( linetxt, cc.'.*$', 0 ) + " + " not found? + if b_idx1 == 0 + "echo 'line '.line.': no end-of-line comment' + continue + endif + " + " walk through ignored patterns + let idx_start = 0 + " + while 1 + let this_start = match ( linetxt, align_regex, idx_start ) + " + if this_start == -1 + break + else + let idx_start = matchend ( linetxt, align_regex, idx_start ) + "echo 'line '.line.': ignoring >>>'.strpart(linetxt,this_start,idx_start-this_start).'<<<' + endif + endwhile + " + let b_idx1 = 1 + match ( linetxt, '\s*'.cc.'.*$', idx_start ) + let b_idx2 = 1 + match ( linetxt, cc.'.*$', idx_start ) + " + " not found? + if b_idx1 == 0 + "echo 'line '.line.': no end-of-line comment' + continue + endif + " + call cursor ( line, b_idx2 ) + let v_idx2 = virtcol('.') + " + " do b_idx1 last, so the cursor is in the right position for substitute below + call cursor ( line, b_idx1 ) + let v_idx1 = virtcol('.') + " + " already at right position? + if ( v_idx2 == correct_idx ) + "echo 'line '.line.': already at right position' + continue + endif + " ... or line too long? + if ( v_idx1 > correct_idx ) + "echo 'line '.line.': line too long' + continue + endif + " + " substitute all whitespaces behind the cursor (regex '\%#') and the next character, + " to ensure the match is at least one character long + silent exe 'substitute/\%#\s*\(\S\)/'.repeat( ' ', correct_idx - v_idx1 ).'\1/' + "echo 'line '.line.': adjusted' + " + endfor + " + " restore the cursor position + call setpos ( '.', save_cursor ) + " +endfunction " ---------- end of function BASH_AdjustLineEndComm ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_GetLineEndCommCol {{{1 +" DESCRIPTION: get end-of-line comment position +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_GetLineEndCommCol () + let actcol = virtcol(".") + if actcol+1 == virtcol("$") + let b:BASH_LineEndCommentColumn = '' + while match( b:BASH_LineEndCommentColumn, '^\s*\d\+\s*$' ) < 0 + let b:BASH_LineEndCommentColumn = BASH_Input( 'start line-end comment at virtual column : ', actcol, '' ) + endwhile + else + let b:BASH_LineEndCommentColumn = virtcol(".") + endif + echomsg "line end comments will start at column ".b:BASH_LineEndCommentColumn +endfunction " ---------- end of function BASH_GetLineEndCommCol ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_EndOfLineComment {{{1 +" DESCRIPTION: single end-of-line comment +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_EndOfLineComment ( ) range + if !exists("b:BASH_LineEndCommentColumn") + let b:BASH_LineEndCommentColumn = s:BASH_LineEndCommColDefault + endif + " ----- trim whitespaces ----- + exe a:firstline.','.a:lastline.'s/\s*$//' + + for line in range( a:lastline, a:firstline, -1 ) + silent exe ":".line + if getline(line) !~ '^\s*$' + let linelength = virtcol( [line, "$"] ) - 1 + let diff = 1 + if linelength < b:BASH_LineEndCommentColumn + let diff = b:BASH_LineEndCommentColumn -1 -linelength + endif + exe "normal! ".diff."A " + call mmtemplates#core#InsertTemplate(g:BASH_Templates, 'Comments.end-of-line comment') + endif + endfor +endfunction " ---------- end of function BASH_EndOfLineComment ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_CodeComment {{{1 +" DESCRIPTION: Code -> Comment +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_CodeComment() range + " add '# ' at the beginning of the lines + for line in range( a:firstline, a:lastline ) + exe line.'s/^/# /' + endfor +endfunction " ---------- end of function BASH_CodeComment ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_CommentCode {{{1 +" DESCRIPTION: Comment -> Code +" PARAMETERS: toggle - 0 : uncomment, 1 : toggle comment +" RETURNS: +"=============================================================================== +function! BASH_CommentCode( toggle ) range + for i in range( a:firstline, a:lastline ) + if getline( i ) =~ '^# ' + silent exe i.'s/^# //' + elseif getline( i ) =~ '^#' + silent exe i.'s/^#//' + elseif a:toggle + silent exe i.'s/^/# /' + endif + endfor + " +endfunction " ---------- end of function BASH_CommentCode ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_echo_comment {{{1 +" DESCRIPTION: put statement in an echo +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_echo_comment () + let line = escape( getline("."), '"' ) + let line = substitute( line, '^\s*', '', '' ) + call setline( line("."), 'echo "'.line.'"' ) + silent exe "normal! ==" + return +endfunction " ---------- end of function BASH_echo_comment ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_remove_echo {{{1 +" DESCRIPTION: remove echo from statement +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_remove_echo () + let line = substitute( getline("."), '\\"', '"', 'g' ) + let line = substitute( line, '^\s*echo\s\+"', '', '' ) + let line = substitute( line, '"$', '', '' ) + call setline( line("."), line ) + silent exe "normal! ==" + return +endfunction " ---------- end of function BASH_remove_echo ---------- +" +"------------------------------------------------------------------------------ +" === Templates API === {{{1 +"------------------------------------------------------------------------------ +" +"------------------------------------------------------------------------------ +" Bash_SetMapLeader {{{2 +"------------------------------------------------------------------------------ +function! Bash_SetMapLeader () + if exists ( 'g:BASH_MapLeader' ) + call mmtemplates#core#SetMapleader ( g:BASH_MapLeader ) + endif +endfunction " ---------- end of function Bash_SetMapLeader ---------- +" +"------------------------------------------------------------------------------ +" Bash_ResetMapLeader {{{2 +"------------------------------------------------------------------------------ +function! Bash_ResetMapLeader () + if exists ( 'g:BASH_MapLeader' ) + call mmtemplates#core#ResetMapleader () + endif +endfunction " ---------- end of function Bash_ResetMapLeader ---------- +" }}}2 +" +"=== FUNCTION ================================================================ +" NAME: BASH_RereadTemplates {{{1 +" DESCRIPTION: Reread the templates. Also set the character which starts +" the comments in the template files. +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! g:BASH_RereadTemplates ( displaymsg ) + " + "------------------------------------------------------------------------------- + " SETUP TEMPLATE LIBRARY + "------------------------------------------------------------------------------- + let g:BASH_Templates = mmtemplates#core#NewLibrary () + " + " mapleader + if empty ( g:BASH_MapLeader ) + call mmtemplates#core#Resource ( g:BASH_Templates, 'set', 'property', 'Templates::Mapleader', '\' ) + else + call mmtemplates#core#Resource ( g:BASH_Templates, 'set', 'property', 'Templates::Mapleader', g:BASH_MapLeader ) + endif + " + " map: choose style + call mmtemplates#core#Resource ( g:BASH_Templates, 'set', 'property', 'Templates::EditTemplates::Map', 'ntl' ) + call mmtemplates#core#Resource ( g:BASH_Templates, 'set', 'property', 'Templates::RereadTemplates::Map', 'ntr' ) + call mmtemplates#core#Resource ( g:BASH_Templates, 'set', 'property', 'Templates::ChooseStyle::Map', 'nts' ) + " + " syntax: comments + call mmtemplates#core#ChangeSyntax ( g:BASH_Templates, 'comment', '§' ) + let s:BASH_TemplateJumpTarget = mmtemplates#core#Resource ( g:BASH_Templates, "jumptag" )[0] + " + let messsage = '' + " + if s:installation == 'system' + "------------------------------------------------------------------------------- + " SYSTEM INSTALLATION + "------------------------------------------------------------------------------- + if filereadable( s:BASH_GlobalTemplateFile ) + call mmtemplates#core#ReadTemplates ( g:BASH_Templates, 'load', s:BASH_GlobalTemplateFile ) + else + echomsg "Global template file '".s:BASH_GlobalTemplateFile."' not readable." + return + endif + let messsage = "Templates read from '".s:BASH_GlobalTemplateFile."'" + " + "------------------------------------------------------------------------------- + " handle local template files + "------------------------------------------------------------------------------- + let templ_dir = fnamemodify( s:BASH_LocalTemplateFile, ":p:h" ).'/' + if finddir( templ_dir ) == '' + " try to create a local template directory + if exists("*mkdir") + try + call mkdir( templ_dir, "p" ) + catch /.*/ + endtry + endif + endif + + if isdirectory( templ_dir ) && !filereadable( s:BASH_LocalTemplateFile ) + " write a default local template file + let template = [ ] + let sample_template_file = s:BASH_PluginDir.'/bash-support/rc/sample_template_file' + if filereadable( sample_template_file ) + for line in readfile( sample_template_file ) + call add( template, line ) + endfor + call writefile( template, s:BASH_LocalTemplateFile ) + endif + endif + " + if filereadable( s:BASH_LocalTemplateFile ) + call mmtemplates#core#ReadTemplates ( g:BASH_Templates, 'load', s:BASH_LocalTemplateFile ) + let messsage = messsage." and '".s:BASH_LocalTemplateFile."'" + if mmtemplates#core#ExpandText( g:BASH_Templates, '|AUTHOR|' ) == 'YOUR NAME' + echomsg "Please set your personal details in file '".s:BASH_LocalTemplateFile."'." + endif + endif + " + else + "------------------------------------------------------------------------------- + " LOCAL INSTALLATION + "------------------------------------------------------------------------------- + if filereadable( s:BASH_LocalTemplateFile ) + call mmtemplates#core#ReadTemplates ( g:BASH_Templates, 'load', s:BASH_LocalTemplateFile ) + let messsage = "Templates read from '".s:BASH_LocalTemplateFile."'" + else + echomsg "Local template file '".s:BASH_LocalTemplateFile."' not readable." + return + endif + " + endif + if a:displaymsg == 'yes' + echomsg messsage.'.' + endif + +endfunction " ---------- end of function BASH_RereadTemplates ---------- +" +"=== FUNCTION ================================================================ +" NAME: InitMenus {{{1 +" DESCRIPTION: Initialize menus. +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! s:InitMenus() + " + if ! has ( 'menu' ) + return + endif + " + "------------------------------------------------------------------------------- + " preparation {{{2 + "------------------------------------------------------------------------------- + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'do_reset' ) + " + " get the mapleader (correctly escaped) + let [ esc_mapl, err ] = mmtemplates#core#Resource ( g:BASH_Templates, 'escaped_mapleader' ) + " + exe 'amenu '.s:BASH_RootMenu.'.Bash <Nop>' + exe 'amenu '.s:BASH_RootMenu.'.-Sep00- <Nop>' + " + "------------------------------------------------------------------------------- + " menu headers {{{2 + "------------------------------------------------------------------------------- + " + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'sub_menu', '&Comments', 'priority', 500 ) + " the other, automatically created menus go here; their priority is the standard priority 500 + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'sub_menu', 'S&nippets', 'priority', 600 ) + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'sub_menu', '&Run' , 'priority', 700 ) + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'sub_menu', '&Help' , 'priority', 800 ) + " + "------------------------------------------------------------------------------- + " comments {{{2 + "------------------------------------------------------------------------------- + " + let head = 'noremenu <silent> '.s:BASH_RootMenu.'.Comments.' + let ahead = 'anoremenu <silent> '.s:BASH_RootMenu.'.Comments.' + let vhead = 'vnoremenu <silent> '.s:BASH_RootMenu.'.Comments.' + let ihead = 'inoremenu <silent> '.s:BASH_RootMenu.'.Comments.' + " + exe ahead.'end-of-&line\ comment<Tab>'.esc_mapl.'cl :call BASH_EndOfLineComment()<CR>' + exe vhead.'end-of-&line\ comment<Tab>'.esc_mapl.'cl :call BASH_EndOfLineComment()<CR>' + + exe ahead.'ad&just\ end-of-line\ com\.<Tab>'.esc_mapl.'cj :call BASH_AdjustLineEndComm()<CR>' + exe ihead.'ad&just\ end-of-line\ com\.<Tab>'.esc_mapl.'cj <Esc>:call BASH_AdjustLineEndComm()<CR>' + exe vhead.'ad&just\ end-of-line\ com\.<Tab>'.esc_mapl.'cj :call BASH_AdjustLineEndComm()<CR>' + exe head.'&set\ end-of-line\ com\.\ col\.<Tab>'.esc_mapl.'cs <Esc>:call BASH_GetLineEndCommCol()<CR>' + " + exe ahead.'-Sep01- <Nop>' + exe ahead.'&comment<TAB>'.esc_mapl.'cc :call BASH_CodeComment()<CR>' + exe vhead.'&comment<TAB>'.esc_mapl.'cc :call BASH_CodeComment()<CR>' + exe ahead.'&uncomment<TAB>'.esc_mapl.'cu :call BASH_CommentCode(0)<CR>' + exe vhead.'&uncomment<TAB>'.esc_mapl.'cu :call BASH_CommentCode(0)<CR>' + exe ahead.'-Sep02- <Nop>' + " + "------------------------------------------------------------------------------- + " generate menus from the templates + "------------------------------------------------------------------------------- + " + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'do_templates' ) + " + "------------------------------------------------------------------------------- + " snippets {{{2 + "------------------------------------------------------------------------------- + " + if !empty(s:BASH_CodeSnippets) + " + exe "amenu <silent> ".s:BASH_RootMenu.'.S&nippets.&read\ code\ snippet<Tab>'.esc_mapl.'nr :call BASH_CodeSnippet("read")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.S&nippets.&read\ code\ snippet<Tab>'.esc_mapl.'nr <C-C>:call BASH_CodeSnippet("read")<CR>' + exe "amenu <silent> ".s:BASH_RootMenu.'.S&nippets.&view\ code\ snippet<Tab>'.esc_mapl.'nv :call BASH_CodeSnippet("view")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.S&nippets.&view\ code\ snippet<Tab>'.esc_mapl.'nv <C-C>:call BASH_CodeSnippet("view")<CR>' + exe "amenu <silent> ".s:BASH_RootMenu.'.S&nippets.&write\ code\ snippet<Tab>'.esc_mapl.'nw :call BASH_CodeSnippet("write")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.S&nippets.&write\ code\ snippet<Tab>'.esc_mapl.'nw <C-C>:call BASH_CodeSnippet("write")<CR>' + exe "vmenu <silent> ".s:BASH_RootMenu.'.S&nippets.&write\ code\ snippet<Tab>'.esc_mapl.'nw <C-C>:call BASH_CodeSnippet("writemarked")<CR>' + exe "amenu <silent> ".s:BASH_RootMenu.'.S&nippets.&edit\ code\ snippet<Tab>'.esc_mapl.'ne :call BASH_CodeSnippet("edit")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.S&nippets.&edit\ code\ snippet<Tab>'.esc_mapl.'ne <C-C>:call BASH_CodeSnippet("edit")<CR>' + exe "amenu <silent> ".s:BASH_RootMenu.'.S&nippets.-SepSnippets- :' + " + endif + " + call mmtemplates#core#CreateMenus ( 'g:BASH_Templates', s:BASH_RootMenu, 'do_specials', 'specials_menu', 'S&nippets' ) + " + "------------------------------------------------------------------------------- + " run {{{2 + "------------------------------------------------------------------------------- + " + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.save\ +\ &run\ script<Tab><C-F9>\ \ '.esc_mapl.'rr :call BASH_Run("n")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.save\ +\ &run\ script<Tab><C-F9>\ \ '.esc_mapl.'rr <C-C>:call BASH_Run("n")<CR>' + exe "vmenu <silent> ".s:BASH_RootMenu.'.&Run.save\ +\ &run\ script<Tab><C-F9>\ \ '.esc_mapl.'rr <C-C>:call BASH_Run("v")<CR>' + " + exe " menu ".s:BASH_RootMenu.'.&Run.script\ cmd\.\ line\ &arg\.<Tab><S-F9>\ \ '.esc_mapl.'ra :BashScriptArguments<Space>' + exe "imenu ".s:BASH_RootMenu.'.&Run.script\ cmd\.\ line\ &arg\.<Tab><S-F9>\ \ '.esc_mapl.'ra <C-C>:BashScriptArguments<Space>' + " + exe " menu ".s:BASH_RootMenu.'.&Run.Bash\ cmd\.\ line\ &arg\.<Tab>'.esc_mapl.'rba :BashArguments<Space>' + exe "imenu ".s:BASH_RootMenu.'.&Run.Bash\ cmd\.\ line\ &arg\.<Tab>'.esc_mapl.'rba <C-C>:BashArguments<Space>' + " + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.update,\ check\ &syntax<Tab><A-F9>\ \ '.esc_mapl.'rc :call BASH_SyntaxCheck()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.update,\ check\ &syntax<Tab><A-F9>\ \ '.esc_mapl.'rc <C-C>:call BASH_SyntaxCheck()<CR>' + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.syntax\ check\ o&ptions<Tab>'.esc_mapl.'rco :call BASH_SyntaxCheckOptionsLocal()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.syntax\ check\ o&ptions<Tab>'.esc_mapl.'rco <C-C>:call BASH_SyntaxCheckOptionsLocal()<CR>' + " + let ahead = 'amenu <silent> '.s:BASH_RootMenu.'.Run.' + let vhead = 'vmenu <silent> '.s:BASH_RootMenu.'.Run.' + " + " + if !s:MSWIN + exe "amenu <silent> ".s:BASH_RootMenu.'.&Run.start\ &debugger<Tab><F9>\ \ '.esc_mapl.'rd :call BASH_Debugger()<CR>' + exe "amenu <silent> ".s:BASH_RootMenu.'.&Run.make\ script\ &exec\./not\ exec\.<Tab>'.esc_mapl.'re :call BASH_MakeScriptExecutable()<CR>' + endif + " + exe ahead.'-SEP1- :' + if s:MSWIN + exe ahead.'&hardcopy\ to\ printer<Tab>'.esc_mapl.'rh <C-C>:call BASH_Hardcopy("n")<CR>' + exe vhead.'&hardcopy\ to\ printer<Tab>'.esc_mapl.'rh <C-C>:call BASH_Hardcopy("v")<CR>' + else + exe ahead.'&hardcopy\ to\ FILENAME\.ps<Tab>'.esc_mapl.'rh <C-C>:call BASH_Hardcopy("n")<CR>' + exe vhead.'&hardcopy\ to\ FILENAME\.ps<Tab>'.esc_mapl.'rh <C-C>:call BASH_Hardcopy("v")<CR>' + endif + " + exe ahead.'-SEP2- :' + exe ahead.'plugin\ &settings<Tab>'.esc_mapl.'rs :call BASH_Settings()<CR>' + " + if !s:MSWIN + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.x&term\ size<Tab>'.esc_mapl.'rx :call BASH_XtermSize()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.x&term\ size<Tab>'.esc_mapl.'rx <C-C>:call BASH_XtermSize()<CR>' + endif + " + if s:MSWIN + if s:BASH_OutputGvim == "buffer" + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->term<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm_MS()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->term<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm_MS()<CR>' + else + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ TERM->buffer<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm_MS()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ TERM->buffer<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm_MS()<CR>' + endif + else + if s:BASH_OutputGvim == "vim" + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ VIM->buffer->xterm<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ VIM->buffer->xterm<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm()<CR>' + else + if s:BASH_OutputGvim == "buffer" + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->xterm->vim<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->xterm->vim<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm()<CR>' + else + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ XTERM->vim->buffer<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ XTERM->vim->buffer<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm()<CR>' + endif + endif + endif + " + "------------------------------------------------------------------------------- + " comments {{{2 + "------------------------------------------------------------------------------- + exe " noremenu ".s:BASH_RootMenu.'.&Comments.&echo\ "<line>"<Tab>'.esc_mapl.'ce :call BASH_echo_comment()<CR>j' + exe "inoremenu ".s:BASH_RootMenu.'.&Comments.&echo\ "<line>"<Tab>'.esc_mapl.'ce <C-C>:call BASH_echo_comment()<CR>j' + exe " noremenu ".s:BASH_RootMenu.'.&Comments.&remove\ echo<Tab>'.esc_mapl.'cr :call BASH_remove_echo()<CR>j' + exe "inoremenu ".s:BASH_RootMenu.'.&Comments.&remove\ echo<Tab>'.esc_mapl.'cr <C-C>:call BASH_remove_echo()<CR>j' + " + "------------------------------------------------------------------------------- + " help {{{2 + "------------------------------------------------------------------------------- + " + exe " menu <silent> ".s:BASH_RootMenu.'.&Help.&Bash\ manual<Tab>'.esc_mapl.'hb :call BASH_help("bash")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Help.&Bash\ manual<Tab>'.esc_mapl.'hb <C-C>:call BASH_help("bash")<CR>' + " + exe " menu <silent> ".s:BASH_RootMenu.'.&Help.&help\ (Bash\ builtins)<Tab>'.esc_mapl.'hh :call BASH_help("help")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Help.&help\ (Bash\ builtins)<Tab>'.esc_mapl.'hh <C-C>:call BASH_help("help")<CR>' + " + exe " menu <silent> ".s:BASH_RootMenu.'.&Help.&manual\ (utilities)<Tab>'.esc_mapl.'hm :call BASH_help("man")<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Help.&manual\ (utilities)<Tab>'.esc_mapl.'hm <C-C>:call BASH_help("man")<CR>' + " + exe " menu <silent> ".s:BASH_RootMenu.'.&Help.-SEP1- :' + exe " menu <silent> ".s:BASH_RootMenu.'.&Help.help\ (Bash-&Support)<Tab>'.esc_mapl.'hbs :call BASH_HelpBashSupport()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Help.help\ (Bash-&Support)<Tab>'.esc_mapl.'hbs <C-C>:call BASH_HelpBashSupport()<CR>' + " +endfunction " ---------- end of function s:InitMenus ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_JumpForward {{{1 +" DESCRIPTION: Jump to the next target, otherwise behind the current string. +" PARAMETERS: - +" RETURNS: empty string +"=============================================================================== +function! BASH_JumpForward () + let match = search( s:BASH_TemplateJumpTarget, 'c' ) + if match > 0 + " remove the target + call setline( match, substitute( getline('.'), s:BASH_TemplateJumpTarget, '', '' ) ) + else + " try to jump behind parenthesis or strings + call search( "[\]})\"'`]", 'W' ) + normal! l + endif + return '' +endfunction " ---------- end of function BASH_JumpForward ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_CodeSnippet {{{1 +" DESCRIPTION: read / write / edit code sni +" PARAMETERS: mode - edit, read, write, writemarked, view +"=============================================================================== +function! BASH_CodeSnippet(mode) + if isdirectory(g:BASH_CodeSnippets) + " + " read snippet file, put content below current line + " + if a:mode == "read" + if has("gui_running") && s:BASH_GuiSnippetBrowser == 'gui' + let l:snippetfile=browse(0,"read a code snippet",g:BASH_CodeSnippets,"") + else + let l:snippetfile=input("read snippet ", g:BASH_CodeSnippets, "file" ) + endif + if filereadable(l:snippetfile) + let linesread= line("$") + let l:old_cpoptions = &cpoptions " Prevent the alternate buffer from being set to this files + setlocal cpoptions-=a + :execute "read ".l:snippetfile + let &cpoptions = l:old_cpoptions " restore previous options + " + let linesread= line("$")-linesread-1 + if linesread>=0 && match( l:snippetfile, '\.\(ni\|noindent\)$' ) < 0 + silent exe "normal! =".linesread."+" + endif + endif + endif + " + " update current buffer / split window / edit snippet file + " + if a:mode == "edit" + if has("gui_running") && s:BASH_GuiSnippetBrowser == 'gui' + let l:snippetfile=browse(0,"edit a code snippet",g:BASH_CodeSnippets,"") + else + let l:snippetfile=input("edit snippet ", g:BASH_CodeSnippets, "file" ) + endif + if !empty(l:snippetfile) + :execute "update! | split | edit ".l:snippetfile + endif + endif + " + " update current buffer / split window / view snippet file + " + if a:mode == "view" + if has("gui_running") && s:BASH_GuiSnippetBrowser == 'gui' + let l:snippetfile=browse(0,"view a code snippet",g:BASH_CodeSnippets,"") + else + let l:snippetfile=input("view snippet ", g:BASH_CodeSnippets, "file" ) + endif + if !empty(l:snippetfile) + :execute "update! | split | view ".l:snippetfile + endif + endif + " + " write whole buffer or marked area into snippet file + " + if a:mode == "write" || a:mode == "writemarked" + if has("gui_running") && s:BASH_GuiSnippetBrowser == 'gui' + let l:snippetfile=browse(1,"write a code snippet",g:BASH_CodeSnippets,"") + else + let l:snippetfile=input("write snippet ", g:BASH_CodeSnippets, "file" ) + endif + if !empty(l:snippetfile) + if filereadable(l:snippetfile) + if confirm("File ".l:snippetfile." exists ! Overwrite ? ", "&Cancel\n&No\n&Yes") != 3 + return + endif + endif + if a:mode == "write" + :execute ":write! ".l:snippetfile + else + :execute ":*write! ".l:snippetfile + endif + endif + endif + + else + redraw! + echohl ErrorMsg + echo "code snippet directory ".g:BASH_CodeSnippets." does not exist" + echohl None + endif +endfunction " ---------- end of function BASH_CodeSnippet ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Hardcopy {{{1 +" DESCRIPTION: Make PostScript document from current buffer +" MSWIN : display printer dialog +" PARAMETERS: mode - n : print complete buffer, v : print marked area +" RETURNS: +"=============================================================================== +function! BASH_Hardcopy (mode) + let outfile = expand("%") + if outfile == "" + redraw + echohl WarningMsg | echo " no file name " | echohl None + return + endif + let outdir = getcwd() + if filewritable(outdir) != 2 + let outdir = $HOME + endif + if !s:MSWIN + let outdir = outdir.'/' + endif + let old_printheader=&printheader + exe ':set printheader='.s:BASH_Printheader + " ----- normal mode ---------------- + if a:mode=="n" + silent exe 'hardcopy > '.outdir.outfile.'.ps' + if !s:MSWIN + echo 'file "'.outfile.'" printed to "'.outdir.outfile.'.ps"' + endif + endif + " ----- visual mode ---------------- + if a:mode=="v" + silent exe "*hardcopy > ".outdir.outfile.".ps" + if !s:MSWIN + echo 'file "'.outfile.'" (lines '.line("'<").'-'.line("'>").') printed to "'.outdir.outfile.'.ps"' + endif + endif + exe ':set printheader='.escape( old_printheader, ' %' ) +endfunction " ---------- end of function BASH_Hardcopy ---------- +" +"=== FUNCTION ================================================================ +" NAME: CreateAdditionalMaps {{{1 +" DESCRIPTION: create additional maps +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! s:CreateAdditionalMaps () + " + " ---------- Bash dictionary ------------------------------------------------- + " This will enable keyword completion for Bash + " using Vim's dictionary feature |i_CTRL-X_CTRL-K|. + " + if exists("g:BASH_Dictionary_File") + silent! exe 'setlocal dictionary+='.g:BASH_Dictionary_File + endif + " + "------------------------------------------------------------------------------- + " USER DEFINED COMMANDS + "------------------------------------------------------------------------------- + command! -buffer -nargs=* -complete=file BashScriptArguments call BASH_ScriptCmdLineArguments(<q-args>) + command! -buffer -nargs=* -complete=file BashArguments call BASH_BashCmdLineArguments(<q-args>) + " + "------------------------------------------------------------------------------- + " settings - local leader + "------------------------------------------------------------------------------- + if ! empty ( g:BASH_MapLeader ) + if exists ( 'g:maplocalleader' ) + let ll_save = g:maplocalleader + endif + let g:maplocalleader = g:BASH_MapLeader + endif + " + "------------------------------------------------------------------------------- + " comments + "------------------------------------------------------------------------------- + nnoremap <buffer> <silent> <LocalLeader>cl :call BASH_EndOfLineComment()<CR> + inoremap <buffer> <silent> <LocalLeader>cl <C-C>:call BASH_EndOfLineComment()<CR> + vnoremap <buffer> <silent> <LocalLeader>cl :call BASH_EndOfLineComment()<CR> + " + nnoremap <buffer> <silent> <LocalLeader>cj :call BASH_AdjustLineEndComm()<CR> + inoremap <buffer> <silent> <LocalLeader>cj <C-C>:call BASH_AdjustLineEndComm()<CR> + vnoremap <buffer> <silent> <LocalLeader>cj :call BASH_AdjustLineEndComm()<CR> + " + nnoremap <buffer> <silent> <LocalLeader>cs :call BASH_GetLineEndCommCol()<CR> + inoremap <buffer> <silent> <LocalLeader>cs <C-C>:call BASH_GetLineEndCommCol()<CR> + vnoremap <buffer> <silent> <LocalLeader>cs <C-C>:call BASH_GetLineEndCommCol()<CR> + " + nnoremap <buffer> <silent> <LocalLeader>cc :call BASH_CodeComment()<CR> + inoremap <buffer> <silent> <LocalLeader>cc <C-C>:call BASH_CodeComment()<CR> + vnoremap <buffer> <silent> <LocalLeader>cc :call BASH_CodeComment()<CR> + " + nnoremap <buffer> <silent> <LocalLeader>cu :call BASH_CommentCode(0)<CR> + inoremap <buffer> <silent> <LocalLeader>cu <C-C>:call BASH_CommentCode(0)<CR> + vnoremap <buffer> <silent> <LocalLeader>cu :call BASH_CommentCode(0)<CR> + " + noremap <buffer> <silent> <LocalLeader>ce :call BASH_echo_comment()<CR>j' + inoremap <buffer> <silent> <LocalLeader>ce <C-C>:call BASH_echo_comment()<CR>j' + noremap <buffer> <silent> <LocalLeader>cr :call BASH_remove_echo()<CR>j' + inoremap <buffer> <silent> <LocalLeader>cr <C-C>:call BASH_remove_echo()<CR>j' + " + "------------------------------------------------------------------------------- + " snippets + "------------------------------------------------------------------------------- + " + nnoremap <buffer> <silent> <LocalLeader>nr :call BASH_CodeSnippet("read")<CR> + inoremap <buffer> <silent> <LocalLeader>nr <Esc>:call BASH_CodeSnippet("read")<CR> + nnoremap <buffer> <silent> <LocalLeader>nw :call BASH_CodeSnippet("write")<CR> + inoremap <buffer> <silent> <LocalLeader>nw <Esc>:call BASH_CodeSnippet("write")<CR> + vnoremap <buffer> <silent> <LocalLeader>nw <Esc>:call BASH_CodeSnippet("writemarked")<CR> + nnoremap <buffer> <silent> <LocalLeader>ne :call BASH_CodeSnippet("edit")<CR> + inoremap <buffer> <silent> <LocalLeader>ne <Esc>:call BASH_CodeSnippet("edit")<CR> + nnoremap <buffer> <silent> <LocalLeader>nv :call BASH_CodeSnippet("view")<CR> + inoremap <buffer> <silent> <LocalLeader>nv <Esc>:call BASH_CodeSnippet("view")<CR> + " + "------------------------------------------------------------------------------- + " run + "------------------------------------------------------------------------------- + " + noremap <buffer> <silent> <LocalLeader>rr :call BASH_Run("n")<CR> + inoremap <buffer> <silent> <LocalLeader>rr <Esc>:call BASH_Run("n")<CR> + vnoremap <buffer> <silent> <LocalLeader>rr <Esc>:call BASH_Run("v")<CR> + noremap <buffer> <silent> <LocalLeader>rc :call BASH_SyntaxCheck()<CR> + inoremap <buffer> <silent> <LocalLeader>rc <C-C>:call BASH_SyntaxCheck()<CR> + noremap <buffer> <silent> <LocalLeader>rco :call BASH_SyntaxCheckOptionsLocal()<CR> + inoremap <buffer> <silent> <LocalLeader>rco <C-C>:call BASH_SyntaxCheckOptionsLocal()<CR> + noremap <buffer> <LocalLeader>ra :BashScriptArguments<Space> + inoremap <buffer> <LocalLeader>ra <Esc>:BashScriptArguments<Space> + noremap <buffer> <LocalLeader>rba :BashArguments<Space> + inoremap <buffer> <LocalLeader>rba <Esc>:BashArguments<Space> + " + if s:UNIX + noremap <buffer> <silent> <LocalLeader>re :call BASH_MakeScriptExecutable()<CR> + inoremap <buffer> <silent> <LocalLeader>re <C-C>:call BASH_MakeScriptExecutable()<CR> + endif + nnoremap <buffer> <silent> <LocalLeader>rh :call BASH_Hardcopy("n")<CR> + vnoremap <buffer> <silent> <LocalLeader>rh <C-C>:call BASH_Hardcopy("v")<CR> + " + noremap <buffer> <silent> <C-F9> :call BASH_Run("n")<CR> + inoremap <buffer> <silent> <C-F9> <C-C>:call BASH_Run("n")<CR> + vnoremap <buffer> <silent> <C-F9> <C-C>:call BASH_Run("v")<CR> + " + noremap <buffer> <silent> <A-F9> :call BASH_SyntaxCheck()<CR> + inoremap <buffer> <silent> <A-F9> <C-C>:call BASH_SyntaxCheck()<CR> + " + noremap <buffer> <S-F9> :BashScriptArguments<Space> + inoremap <buffer> <S-F9> <C-C>:BashScriptArguments<Space> + + if s:MSWIN + noremap <buffer> <silent> <LocalLeader>ro :call BASH_Toggle_Gvim_Xterm_MS()<CR> + inoremap <buffer> <silent> <LocalLeader>ro <Esc>:call BASH_Toggle_Gvim_Xterm_MS()<CR> + else + noremap <buffer> <silent> <LocalLeader>ro :call BASH_Toggle_Gvim_Xterm()<CR> + inoremap <buffer> <silent> <LocalLeader>ro <Esc>:call BASH_Toggle_Gvim_Xterm()<CR> + noremap <buffer> <silent> <LocalLeader>rd :call BASH_Debugger()<CR> + inoremap <buffer> <silent> <LocalLeader>rd <Esc>:call BASH_Debugger()<CR> + noremap <buffer> <silent> <F9> :call BASH_Debugger()<CR> + inoremap <buffer> <silent> <F9> <C-C>:call BASH_Debugger()<CR> + if has("gui_running") + noremap <buffer> <silent> <LocalLeader>rx :call BASH_XtermSize()<CR> + inoremap <buffer> <silent> <LocalLeader>rx <Esc>:call BASH_XtermSize()<CR> + endif + endif + " + "------------------------------------------------------------------------------- + " help + "------------------------------------------------------------------------------- + nnoremap <buffer> <silent> <LocalLeader>rs :call BASH_Settings()<CR> + " + noremap <buffer> <silent> <LocalLeader>hb :call BASH_help('bash')<CR> + inoremap <buffer> <silent> <LocalLeader>hb <Esc>:call BASH_help('bash')<CR> + noremap <buffer> <silent> <LocalLeader>hh :call BASH_help('help')<CR> + inoremap <buffer> <silent> <LocalLeader>hh <Esc>:call BASH_help('help')<CR> + noremap <buffer> <silent> <LocalLeader>hm :call BASH_help('man')<CR> + inoremap <buffer> <silent> <LocalLeader>hm <Esc>:call BASH_help('man')<CR> + noremap <buffer> <silent> <LocalLeader>hbs :call BASH_HelpBashSupport()<CR> + inoremap <buffer> <silent> <LocalLeader>hbs <C-C>:call BASH_HelpBashSupport()<CR> + " + nnoremap <buffer> <silent> <C-j> i<C-R>=BASH_JumpForward()<CR> + inoremap <buffer> <silent> <C-j> <C-R>=BASH_JumpForward()<CR> + " + "------------------------------------------------------------------------------- + " settings - reset local leader + "------------------------------------------------------------------------------- + if ! empty ( g:BASH_MapLeader ) + if exists ( 'll_save' ) + let g:maplocalleader = ll_save + else + unlet g:maplocalleader + endif + endif + " +endfunction " ---------- end of function s:CreateAdditionalMaps ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_HelpBashSupport {{{1 +" DESCRIPTION: help bash-support +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_HelpBashSupport () + try + :help bashsupport + catch + exe ':helptags '.s:BASH_PluginDir.'/doc' + :help bashsupport + endtry +endfunction " ---------- end of function BASH_HelpBashSupport ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_help {{{1 +" DESCRIPTION: lookup word under the cursor or ask +" PARAMETERS: - +" RETURNS: +"=============================================================================== +let s:BASH_DocBufferName = "BASH_HELP" +let s:BASH_DocHelpBufferNumber = -1 +" +function! BASH_help( type ) + + let cuc = getline(".")[col(".") - 1] " character under the cursor + let item = expand("<cword>") " word under the cursor + if empty(item) || match( item, cuc ) == -1 + if a:type == 'man' + let item=BASH_Input('[tab compl. on] name of command line utility : ', '', 'shellcmd' ) + endif + if a:type == 'help' + let item=BASH_Input('[tab compl. on] name of bash builtin : ', '', 'customlist,BASH_BuiltinComplete' ) + endif + endif + + if empty(item) && a:type != 'bash' + return + endif + "------------------------------------------------------------------------------ + " replace buffer content with bash help text + "------------------------------------------------------------------------------ + " + " jump to an already open bash help window or create one + " + if bufloaded(s:BASH_DocBufferName) != 0 && bufwinnr(s:BASH_DocHelpBufferNumber) != -1 + exe bufwinnr(s:BASH_DocHelpBufferNumber) . "wincmd w" + " buffer number may have changed, e.g. after a 'save as' + if bufnr("%") != s:BASH_DocHelpBufferNumber + let s:BASH_DocHelpBufferNumber=bufnr(s:BASH_OutputBufferName) + exe ":bn ".s:BASH_DocHelpBufferNumber + endif + else + exe ":new ".s:BASH_DocBufferName + let s:BASH_DocHelpBufferNumber=bufnr("%") + setlocal buftype=nofile + setlocal noswapfile + setlocal bufhidden=delete + setlocal syntax=OFF + endif + setlocal modifiable + setlocal filetype=man + " + "------------------------------------------------------------------------------- + " read Bash help + "------------------------------------------------------------------------------- + if a:type == 'help' + setlocal wrap + if s:UNIX + silent exe ":%!help -m ".item + else + silent exe ":%!".s:BASH_Executable." -c 'help -m ".item."'" + endif + setlocal nomodifiable + return + endif + " + "------------------------------------------------------------------------------- + " open a manual (utilities) + "------------------------------------------------------------------------------- + if a:type == 'man' + " + " Is there more than one manual ? + " + let manpages = system( s:BASH_ManualReader.' -k '.item ) + if v:shell_error + echomsg "shell command '".s:BASH_ManualReader." -k ".item."' failed" + :close + return + endif + let catalogs = split( manpages, '\n', ) + let manual = {} + " + " Select manuals where the name exactly matches + " + for line in catalogs + if line =~ '^'.item.'\s\+(' + let itempart = split( line, '\s\+' ) + let catalog = itempart[1][1:-2] + let manual[catalog] = catalog + endif + endfor + " + " Build a selection list if there are more than one manual + " + let catalog = "" + if len(keys(manual)) > 1 + for key in keys(manual) + echo ' '.item.' '.key + endfor + let defaultcatalog = '' + if has_key( manual, '1' ) + let defaultcatalog = '1' + else + if has_key( manual, '8' ) + let defaultcatalog = '8' + endif + endif + let catalog = input( 'select manual section (<Enter> cancels) : ', defaultcatalog ) + if ! has_key( manual, catalog ) + :close + :redraw + echomsg "no appropriate manual section '".catalog."'" + return + endif + endif + endif + + "------------------------------------------------------------------------------- + " open the bash manual + "------------------------------------------------------------------------------- + if a:type == 'bash' + let catalog = 1 + let item = 'bash' + endif + + let win_w = winwidth( winnr() ) + if s:UNIX && win_w > 0 + silent exe ":%! MANWIDTH=".win_w." ".s:BASH_ManualReader." ".catalog." ".item + else + silent exe ":%!".s:BASH_ManualReader." ".catalog." ".item + endif + + if s:MSWIN + call s:bash_RemoveSpecialCharacters() + endif + + setlocal nomodifiable +endfunction " ---------- end of function BASH_help ---------- +" +"=== FUNCTION ================================================================ +" NAME: Bash_RemoveSpecialCharacters {{{1 +" DESCRIPTION: remove <backspace><any character> in CYGWIN man(1) output +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! s:bash_RemoveSpecialCharacters ( ) + let patternunderline = '_\%x08' + let patternbold = '\%x08.' + setlocal modifiable + if search(patternunderline) != 0 + silent exe ':%s/'.patternunderline.'//g' + endif + if search(patternbold) != 0 + silent exe ':%s/'.patternbold.'//g' + endif + setlocal nomodifiable + silent normal! gg +endfunction " ---------- end of function s:bash_RemoveSpecialCharacters ---------- +" +"------------------------------------------------------------------------------ +" Bash shopt options +"------------------------------------------------------------------------------ +" +"=== FUNCTION ================================================================ +" NAME: Bash_find_option {{{1 +" DESCRIPTION: check if local options does exist +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! s:bash_find_option ( list, option ) + for item in a:list + if item == a:option + return 0 + endif + endfor + return -1 +endfunction " ---------- end of function s:bash_find_option ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_SyntaxCheckOptions {{{1 +" DESCRIPTION: Syntax Check, options +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_SyntaxCheckOptions( options ) + let startpos=0 + while startpos < strlen( a:options ) + " match option switch ' -O ' or ' +O ' + let startpos = matchend ( a:options, '\s*[+-]O\s\+', startpos ) + " match option name + let optionname = matchstr ( a:options, '\h\w*\s*', startpos ) + " remove trailing whitespaces + let optionname = substitute ( optionname, '\s\+$', "", "" ) + " check name + " increment start position for next search + let startpos = matchend ( a:options, '\h\w*\s*', startpos ) + endwhile + return 0 +endfunction " ---------- end of function BASH_SyntaxCheckOptions---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_SyntaxCheckOptionsLocal {{{1 +" DESCRIPTION: Syntax Check, local options +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_SyntaxCheckOptionsLocal () + let filename = expand("%") + if empty(filename) + redraw + echohl WarningMsg | echo " no file name or not a shell file " | echohl None + return + endif + let prompt = 'syntax check options for "'.filename.'" : ' + + if exists("b:BASH_SyntaxCheckOptionsLocal") + let b:BASH_SyntaxCheckOptionsLocal= BASH_Input( prompt, b:BASH_SyntaxCheckOptionsLocal, '' ) + else + let b:BASH_SyntaxCheckOptionsLocal= BASH_Input( prompt , "", '' ) + endif + + if BASH_SyntaxCheckOptions( b:BASH_SyntaxCheckOptionsLocal ) != 0 + let b:BASH_SyntaxCheckOptionsLocal = "" + endif +endfunction " ---------- end of function BASH_SyntaxCheckOptionsLocal ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Settings {{{1 +" DESCRIPTION: Display plugin settings +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_Settings () + let txt = " Bash-Support settings\n\n" + let txt = txt.' author : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|AUTHOR|' )."\"\n" + let txt = txt.' authorref : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|AUTHORREF|' )."\"\n" + let txt = txt.' company : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|COMPANY|' )."\"\n" + let txt = txt.' copyright holder : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|COPYRIGHT|' )."\"\n" + let txt = txt.' email : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|EMAIL|' )."\"\n" + let txt = txt.' licence : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|LICENSE|' )."\"\n" + let txt = txt.' organization : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|ORGANIZATION|')."\"\n" + let txt = txt.' project : "'.mmtemplates#core#ExpandText( g:BASH_Templates, '|PROJECT|' )."\"\n" + let txt = txt.' Bash executable : "'.s:BASH_Executable."\"\n" + if exists( "b:BASH_BashCmdLineArgs" ) + let txt = txt.' Bash cmd. line arguments : '.b:BASH_BashCmdLineArgs."\n" + endif + let txt = txt.' plugin installation : "'.s:installation."\"\n" + let txt = txt.' code snippet directory : "'.s:BASH_CodeSnippets."\"\n" + if s:installation == 'system' + let txt = txt.' global template file : "'.s:BASH_GlobalTemplateFile."\"\n" + if filereadable( s:BASH_LocalTemplateFile ) + let txt = txt.' local template file : "'.s:BASH_LocalTemplateFile."\"\n" + endif + else + let txt = txt.' local template file : "'.s:BASH_LocalTemplateFile."\"\n" + endif + let txt = txt.'glob. syntax check options : "'.s:BASH_SyntaxCheckOptionsGlob."\"\n" + if exists("b:BASH_SyntaxCheckOptionsLocal") + let txt = txt.' buf. syntax check options : "'.b:BASH_SyntaxCheckOptionsLocal."\"\n" + endif + " ----- dictionaries ------------------------ + if !empty(g:BASH_Dictionary_File) + let ausgabe= &dictionary + let ausgabe= substitute( ausgabe, ",", "\",\n + \"", "g" ) + let txt = txt." dictionary file(s) : \"".ausgabe."\"\n" + endif + " ----- Bash commandline arguments ------------------------ + if exists("b:BASH_BashCmdLineArgs") + let ausgabe = b:BASH_BashCmdLineArgs + else + let ausgabe = "" + endif + let txt = txt." Bash cmd.line argument(s) : ".ausgabe."\n" + let txt = txt."\n" + let txt = txt."__________________________________________________________________________\n" + let txt = txt." bash-support, version ".g:BASH_Version." / Dr.-Ing. Fritz Mehner / mehner.fritz@fh-swf.de\n\n" + echo txt +endfunction " ---------- end of function BASH_Settings ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_CreateGuiMenus {{{1 +" DESCRIPTION: +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_CreateGuiMenus () + if s:BASH_MenuVisible == 'no' + aunmenu <silent> &Tools.Load\ Bash\ Support + amenu <silent> 40.1000 &Tools.-SEP100- : + amenu <silent> 40.1020 &Tools.Unload\ Bash\ Support :call BASH_RemoveGuiMenus()<CR> + " + call g:BASH_RereadTemplates('no') + call s:InitMenus () + " + let s:BASH_MenuVisible = 'yes' + endif +endfunction " ---------- end of function BASH_CreateGuiMenus ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_ToolMenu {{{1 +" DESCRIPTION: +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_ToolMenu () + amenu <silent> 40.1000 &Tools.-SEP100- : + amenu <silent> 40.1020 &Tools.Load\ Bash\ Support :call BASH_CreateGuiMenus()<CR> +endfunction " ---------- end of function BASH_ToolMenu ---------- + +"=== FUNCTION ================================================================ +" NAME: BASH_RemoveGuiMenus {{{1 +" DESCRIPTION: +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_RemoveGuiMenus () + if s:BASH_MenuVisible == 'yes' + exe "aunmenu <silent> ".s:BASH_RootMenu + " + aunmenu <silent> &Tools.Unload\ Bash\ Support + call BASH_ToolMenu() + " + let s:BASH_MenuVisible = 'no' + endif +endfunction " ---------- end of function BASH_RemoveGuiMenus ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Toggle_Gvim_Xterm {{{1 +" DESCRIPTION: toggle output destination (Linux/Unix) +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_Toggle_Gvim_Xterm () + + if has("gui_running") + let [ esc_mapl, err ] = mmtemplates#core#Resource ( g:BASH_Templates, 'escaped_mapleader' ) + if s:BASH_OutputGvim == "vim" + exe "aunmenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ VIM->buffer->xterm' + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->xterm->vim<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->xterm->vim<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm()<CR>' + let s:BASH_OutputGvim = "buffer" + else + if s:BASH_OutputGvim == "buffer" + exe "aunmenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->xterm->vim' + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ XTERM->vim->buffer<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ XTERM->vim->buffer<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm()<CR>' + let s:BASH_OutputGvim = "xterm" + else + " ---------- output : xterm -> gvim + exe "aunmenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ XTERM->vim->buffer' + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ VIM->buffer->xterm<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ VIM->buffer->xterm<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm()<CR>' + let s:BASH_OutputGvim = "vim" + endif + endif + else + if s:BASH_OutputGvim == "vim" + let s:BASH_OutputGvim = "buffer" + else + let s:BASH_OutputGvim = "vim" + endif + endif + echomsg "output destination is '".s:BASH_OutputGvim."'" + +endfunction " ---------- end of function BASH_Toggle_Gvim_Xterm ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Toggle_Gvim_Xterm_MS {{{1 +" DESCRIPTION: toggle output destination (Windows) +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_Toggle_Gvim_Xterm_MS () + if has("gui_running") + let [ esc_mapl, err ] = mmtemplates#core#Resource ( g:BASH_Templates, 'escaped_mapleader' ) + if s:BASH_OutputGvim == "buffer" + exe "aunmenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->term' + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ TERM->buffer<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm_MS()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ TERM->buffer<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm_MS()<CR>' + let s:BASH_OutputGvim = "xterm" + else + exe "aunmenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ TERM->buffer' + exe " menu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->term<Tab>'.esc_mapl.'ro :call BASH_Toggle_Gvim_Xterm_MS()<CR>' + exe "imenu <silent> ".s:BASH_RootMenu.'.&Run.&output:\ BUFFER->term<Tab>'.esc_mapl.'ro <C-C>:call BASH_Toggle_Gvim_Xterm_MS()<CR>' + let s:BASH_OutputGvim = "buffer" + endif + endif +endfunction " ---------- end of function BASH_Toggle_Gvim_Xterm_MS ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_XtermSize {{{1 +" DESCRIPTION: set xterm size +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_XtermSize () + let regex = '-geometry\s\+\d\+x\d\+' + let geom = matchstr( s:BASH_XtermDefaults, regex ) + let geom = matchstr( geom, '\d\+x\d\+' ) + let geom = substitute( geom, 'x', ' ', "" ) + let answer= BASH_Input(" xterm size (COLUMNS LINES) : ", geom, '' ) + while match(answer, '^\s*\d\+\s\+\d\+\s*$' ) < 0 + let answer= BASH_Input(" + xterm size (COLUMNS LINES) : ", geom, '' ) + endwhile + let answer = substitute( answer, '^\s\+', "", "" ) " remove leading whitespaces + let answer = substitute( answer, '\s\+$', "", "" ) " remove trailing whitespaces + let answer = substitute( answer, '\s\+', "x", "" ) " replace inner whitespaces + let s:BASH_XtermDefaults = substitute( s:BASH_XtermDefaults, regex, "-geometry ".answer , "" ) +endfunction " ---------- end of function BASH_XtermSize ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_SaveOption {{{1 +" DESCRIPTION: save option +" PARAMETERS: option name +" characters to be escaped (optional) +" RETURNS: +"=============================================================================== +function! BASH_SaveOption ( option, ... ) + exe 'let escaped =&'.a:option + if a:0 == 0 + let escaped = escape( escaped, ' |"\' ) + else + let escaped = escape( escaped, ' |"\'.a:1 ) + endif + let s:BASH_saved_option[a:option] = escaped +endfunction " ---------- end of function BASH_SaveOption ---------- +" +let s:BASH_saved_option = {} +" +"=== FUNCTION ================================================================ +" NAME: BASH_RestoreOption {{{1 +" DESCRIPTION: restore option +" PARAMETERS: option name +" RETURNS: +"=============================================================================== +function! BASH_RestoreOption ( option ) + exe ':setlocal '.a:option.'='.s:BASH_saved_option[a:option] +endfunction " ---------- end of function BASH_RestoreOption ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_ScriptCmdLineArguments {{{1 +" DESCRIPTION: stringify script command line arguments +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_ScriptCmdLineArguments ( ... ) + let b:BASH_ScriptCmdLineArgs = join( a:000 ) +endfunction " ---------- end of function BASH_ScriptCmdLineArguments ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_BashCmdLineArguments {{{1 +" DESCRIPTION: stringify Bash command line arguments +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_BashCmdLineArguments ( ... ) + let b:BASH_BashCmdLineArgs = join( a:000 ) +endfunction " ---------- end of function BASH_BashCmdLineArguments ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Run {{{1 +" DESCRIPTION: +" PARAMETERS: - +" RETURNS: +"=============================================================================== +" +let s:BASH_OutputBufferName = "Bash-Output" +let s:BASH_OutputBufferNumber = -1 +" +function! BASH_Run ( mode ) range + + silent exe ':cclose' +" + let l:arguments = exists("b:BASH_ScriptCmdLineArgs") ? " ".b:BASH_ScriptCmdLineArgs : "" + let l:currentbuffer = bufname("%") + let l:fullname = expand("%:p") + let l:fullnameesc = fnameescape( l:fullname ) + " + silent exe ":update" + " + if a:firstline != a:lastline + let tmpfile = tempname() + silent exe ':'.a:firstline.','.a:lastline.'write '.tmpfile + endif + " + if a:mode=="v" + let tmpfile = tempname() + silent exe ":'<,'>write ".tmpfile + endif + + let l:bashCmdLineArgs = exists("b:BASH_BashCmdLineArgs") ? ' '.b:BASH_BashCmdLineArgs.' ' : '' + " + "------------------------------------------------------------------------------ + " Run : run from the vim command line (Linux only) {{{2 + "------------------------------------------------------------------------------ + " + if s:BASH_OutputGvim == 'vim' + " + " ----- visual mode ---------- + " + if ( a:mode=="v" ) || ( a:firstline != a:lastline ) + exe ":!".s:BASH_Executable.l:bashCmdLineArgs." < ".tmpfile." -s ".l:arguments + call delete(tmpfile) + return + endif + " + " ----- normal mode ---------- + " + call BASH_SaveOption( 'makeprg' ) + exe ":setlocal makeprg=".s:BASH_Executable + exe ':setlocal errorformat='.s:BASH_Errorformat + " + if a:mode=="n" + exe ":make ".l:bashCmdLineArgs.l:fullnameesc.l:arguments + endif + if &term == 'xterm' + redraw! + endif + " + call BASH_RestoreOption( 'makeprg' ) + exe ":botright cwindow" + + if l:currentbuffer != bufname("%") && a:mode=="n" + let pattern = '^||.*\n\?' + setlocal modifiable + " remove the regular script output (appears as comment) + if search(pattern) != 0 + silent exe ':%s/'.pattern.'//' + endif + " read the buffer back to have it parsed and used as the new error list + silent exe ':cgetbuffer' + setlocal nomodifiable + setlocal nomodified + silent exe ':cc' + endif + " + exe ':setlocal errorformat=' + endif + " + "------------------------------------------------------------------------------ + " Run : redirect output to an output buffer {{{2 + "------------------------------------------------------------------------------ + if s:BASH_OutputGvim == 'buffer' + + let l:currentbuffernr = bufnr("%") + + if l:currentbuffer == bufname("%") + " + if bufloaded(s:BASH_OutputBufferName) != 0 && bufwinnr(s:BASH_OutputBufferNumber)!=-1 + exe bufwinnr(s:BASH_OutputBufferNumber) . "wincmd w" + " buffer number may have changed, e.g. after a 'save as' + if bufnr("%") != s:BASH_OutputBufferNumber + let s:BASH_OutputBufferNumber = bufnr(s:BASH_OutputBufferName) + exe ":bn ".s:BASH_OutputBufferNumber + endif + else + silent exe ":new ".s:BASH_OutputBufferName + let s:BASH_OutputBufferNumber=bufnr("%") + setlocal noswapfile + setlocal buftype=nofile + setlocal syntax=none + setlocal bufhidden=delete + setlocal tabstop=8 + endif + " + " run script + " + setlocal modifiable + if a:mode=="n" + if s:MSWIN + silent exe ":%!".s:BASH_Executable.l:bashCmdLineArgs.' "'.l:fullname.'" '.l:arguments + else + silent exe ":%!".s:BASH_Executable.l:bashCmdLineArgs." ".l:fullnameesc.l:arguments + endif + endif + " + if ( a:mode=="v" ) || ( a:firstline != a:lastline ) + silent exe ":%!".s:BASH_Executable.l:bashCmdLineArgs." < ".tmpfile." -s ".l:arguments + endif + setlocal nomodifiable + " + " stdout is empty / not empty + " + if line("$")==1 && col("$")==1 + silent exe ":bdelete" + else + if winheight(winnr()) >= line("$") + exe bufwinnr(l:currentbuffernr) . "wincmd w" + endif + endif + " + endif + endif + " + "------------------------------------------------------------------------------ + " Run : run in a detached xterm {{{2 + "------------------------------------------------------------------------------ + if s:BASH_OutputGvim == 'xterm' + " + if s:MSWIN + exe ':!'.s:BASH_Executable.l:bashCmdLineArgs.' "'.l:fullname.'" '.l:arguments + else + if a:mode=='n' + if a:firstline != a:lastline + let titlestring = l:fullnameesc.'\ lines\ \ '.a:firstline.'\ -\ '.a:lastline + silent exe ':!xterm -title '.titlestring.' '.s:BASH_XtermDefaults + \ .' -e '.s:BASH_Wrapper.' '.l:bashCmdLineArgs.tmpfile.l:arguments.' &' + else + silent exe '!xterm -title '.l:fullnameesc.' '.s:BASH_XtermDefaults + \ .' -e '.s:BASH_Wrapper.' '.l:bashCmdLineArgs.l:fullnameesc.l:arguments.' &' + endif + elseif a:mode=="v" + let titlestring = l:fullnameesc.'\ lines\ \ '.line("'<").'\ -\ '.line("'>") + silent exe ':!xterm -title '.titlestring.' '.s:BASH_XtermDefaults + \ .' -e '.s:BASH_Wrapper.' '.l:bashCmdLineArgs.tmpfile.l:arguments.' &' + endif + endif + " + endif + " + if !has("gui_running") && v:progname != 'vim' + redraw! + endif +endfunction " ---------- end of function BASH_Run ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_SyntaxCheck {{{1 +" DESCRIPTION: run syntax check +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_SyntaxCheck () + exe ":cclose" + let l:currentbuffer=bufname("%") + exe ":update" + call BASH_SaveOption( 'makeprg' ) + exe ":setlocal makeprg=".s:BASH_Executable + let l:fullname = expand("%:p") + " + " check global syntax check options / reset in case of an error + if BASH_SyntaxCheckOptions( s:BASH_SyntaxCheckOptionsGlob ) != 0 + let s:BASH_SyntaxCheckOptionsGlob = "" + endif + " + let options=s:BASH_SyntaxCheckOptionsGlob + if exists("b:BASH_SyntaxCheckOptionsLocal") + let options=options." ".b:BASH_SyntaxCheckOptionsLocal + endif + " + " match the Bash error messages (quickfix commands) + " errorformat will be reset by function BASH_Handle() + " ignore any lines that didn't match one of the patterns + " + exe ':setlocal errorformat='.s:BASH_Errorformat + silent exe ":make! -n ".options.' -- "'.l:fullname.'"' + exe ":botright cwindow" + exe ':setlocal errorformat=' + call BASH_RestoreOption('makeprg') + " + " message in case of success + " + redraw! + if l:currentbuffer == bufname("%") + echohl Search | echo l:currentbuffer." : Syntax is OK" | echohl None + nohlsearch " delete unwanted highlighting (Vim bug?) + endif +endfunction " ---------- end of function BASH_SyntaxCheck ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_Debugger {{{1 +" DESCRIPTION: run debugger +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_Debugger () + if !executable(s:BASH_bashdb) + echohl Search + echo s:BASH_bashdb.' is not executable or not installed! ' + echohl None + return + endif + " + silent exe ":update" + let l:arguments = exists("b:BASH_ScriptCmdLineArgs") ? " ".b:BASH_ScriptCmdLineArgs : "" + let Sou = fnameescape( expand("%:p") ) + " + " + if has("gui_running") || &term == "xterm" + " + " debugger is ' bashdb' + " + if s:BASH_Debugger == "term" + let dbcommand = "!xterm ".s:BASH_XtermDefaults.' -e '.s:BASH_bashdb.' -- '.Sou.l:arguments.' &' + silent exe dbcommand + endif + " + " debugger is 'ddd' + " + if s:BASH_Debugger == "ddd" + if !executable("ddd") + echohl WarningMsg + echo "The debugger 'ddd' does not exist or is not executable!" + echohl None + return + else + silent exe '!ddd --debugger '.s:BASH_bashdb.' '.Sou.l:arguments.' &' + endif + endif + else + " no GUI : debugger is ' bashdb' + silent exe '!'.s:BASH_bashdb.' -- '.Sou.l:arguments + endif +endfunction " ---------- end of function BASH_Debugger ---------- +" +"=== FUNCTION ================================================================ +" NAME: BASH_MakeScriptExecutable {{{1 +" DESCRIPTION: make script executable +" PARAMETERS: - +" RETURNS: +"=============================================================================== +function! BASH_MakeScriptExecutable () + let filename = expand("%:p") + if executable(filename) == 0 + " + " not executable -> executable + " + if BASH_Input( '"'.filename.'" NOT executable. Make it executable [y/n] : ', 'y' ) == 'y' + silent exe "!chmod u+x ".shellescape(filename) + if v:shell_error + echohl WarningMsg + echo 'Could not make "'.filename.'" executable!' + else + echohl Search + echo 'Made "'.filename.'" executable.' + endif + echohl None + endif + else + " + " executable -> not executable + " + if BASH_Input( '"'.filename.'" is executable. Make it NOT executable [y/n] : ', 'y' ) == 'y' + silent exe "!chmod u-x ".shellescape(filename) + if v:shell_error + echohl WarningMsg + echo 'Could not make "'.filename.'" not executable!' + else + echohl Search + echo 'Made "'.filename.'" not executable.' + endif + echohl None + endif + endif +endfunction " ---------- end of function BASH_MakeScriptExecutable ---------- + +"---------------------------------------------------------------------- +" *** SETUP PLUGIN *** {{{1 +"---------------------------------------------------------------------- + +call BASH_ToolMenu() + +if s:BASH_LoadMenus == 'yes' && s:BASH_CreateMenusDelayed == 'no' + call BASH_CreateGuiMenus() +endif +" +if has( 'autocmd' ) + " + "------------------------------------------------------------------------------- + " shell files with extensions other than 'sh' + "------------------------------------------------------------------------------- + if exists( 'g:BASH_AlsoBash' ) + for item in g:BASH_AlsoBash + exe "autocmd BufNewFile,BufRead ".item." set filetype=sh" + endfor + endif + " + "------------------------------------------------------------------------------- + " create menues and maps + "------------------------------------------------------------------------------- + autocmd FileType * + \ if &filetype == 'sh' | + \ if ! exists( 'g:BASH_Templates' ) | + \ if s:BASH_LoadMenus == 'yes' | call BASH_CreateGuiMenus () | + \ else | call g:BASH_RereadTemplates ('no') | + \ endif | + \ endif | + \ call s:CreateAdditionalMaps () | + \ call mmtemplates#core#CreateMaps ( 'g:BASH_Templates', g:BASH_MapLeader, 'do_special_maps' ) | + \ endif + + "------------------------------------------------------------------------------- + " insert file header + "------------------------------------------------------------------------------- + if s:BASH_InsertFileHeader == 'yes' + autocmd BufNewFile *.sh call mmtemplates#core#InsertTemplate(g:BASH_Templates, 'Comments.file header') + if exists( 'g:BASH_AlsoBash' ) + for item in g:BASH_AlsoBash + exe "autocmd BufNewFile ".item." call mmtemplates#core#InsertTemplate(g:BASH_Templates, 'Comments.file header')" + endfor + endif + endif + +endif +" }}}1 +" +" ===================================================================================== +" vim: tabstop=2 shiftwidth=2 foldmethod=marker diff --git a/.config/nvim/plugged/bash-support.vim/syntax/template.vim b/.config/nvim/plugged/bash-support.vim/syntax/template.vim new file mode 100644 index 0000000..76ddc9d --- /dev/null +++ b/.config/nvim/plugged/bash-support.vim/syntax/template.vim @@ -0,0 +1,94 @@ +" Vim syntax file +" Language: mm template engine : template library +" Maintainer: Wolfgang Mehner <wolfgang-mehner@web.de> +" Last Change: 12.08.2013 +" Version: 0.9.1-2 + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +"------------------------------------------------------------------------------- +" Syntax +"------------------------------------------------------------------------------- + +" comment +syn match Comment "^§.*$" +syn match Comment "\%(==\)\@<=[^=]*$" + +" templates, lists, ... +syn match Structure "^==\s*\%(TEMPLATE:\)\?[a-zA-Z0-9\-+.,_ ]\+==\%(.\+==\)\?" +syn match Structure "^==\s*ENDTEMPLATE\s*==" + +syn match Structure "^==\s*HELP:[a-zA-Z0-9\-+.,_ ]\+==\%(.\+==\)\?" + +syn match Structure "^==\s*SEP:[a-zA-Z0-9\-+.,_ ]\+==" + +syn match Structure "^==\s*LIST:\s*[a-zA-Z0-9_]\+\s*==\%(.\+==\)\?" +syn match Structure "^==\s*ENDLIST\s*==" + +" style sections +syn match Statement "^==\s*IF\s\+|STYLE|\s\+IS\s\+[a-zA-Z0-9_]\+\s*==" +syn match Statement "^==\s*ENDIF\s*==" + +syn match Statement "^==\s*USE\s\+STYLES\s*:[a-zA-Z0-9_, ]\+==" +syn match Statement "^==\s*ENDSTYLES\s*==" + +" functions: command mode +syn match Function "IncludeFile\ze\s*(" +syn match Function "SetFormat\ze\s*(" +syn match Function "SetMacro\ze\s*(" +syn match Function "SetStyle\ze\s*(" +syn match Function "SetSyntax\ze\s*(" +syn match Function "SetPath\ze\s*(" + +syn match Function "MenuShortcut\ze\s*(" +syn match Function "SetProperty\ze\s*(" +syn match Function "SetMap\ze\s*(" +syn match Function "SetShortcut\ze\s*(" + +" functions: standard template +syn match Function "|\zsDefaultMacro\ze(" +syn match Function "|\zsPrompt\ze(" +syn match Function "|\zsPickFile\ze(" +syn match Function "|\zsPickList\ze(" +syn match Function "|\zsSurroundWith\ze(" +syn match Function "|\zsInsert\ze(" +syn match Function "|\zsInsertLine\ze(" + +syn match Comment "|C(.\{-})|" +syn match Comment "|Comment(.\{-})|" + +" functions: picker +syn match Function "|\zsPath\ze(" " file +syn match Function "|\zsGetPath\ze(" " file +syn match Function "|\zsKeepPath\ze(" " file +syn match Function "|\zsRemovePath\ze(" " file +syn match Function "|\zsList\ze(" " list +syn match Function "|\zsGetList\ze(" " list + +" functions: help +syn match Function "|\zsPrompt\ze(" +syn match Function "|\zsWord\ze(" +syn match Function "|\zsPattern\ze(" +syn match Function "|\zsDefault\ze(" +syn match Function "|\zsSubstitute\ze(" +syn match Function "|\zsLiteralSub\ze(" +syn match Function "|\zsSystem\ze(" +syn match Function "|\zsVim\ze(" + +" strings, macros, tags, jump targets +syn match String "'\%([^']\|''\)*'" +syn match String "\"\%([^\\]\|\\.\)*\"" + +syn match Tag "|?\?[a-zA-Z][a-zA-Z0-9_:]*|" +syn match Tag "<CURSOR>\|{CURSOR}" +syn match Tag "<SPLIT>" +syn match Tag "<CONTENT>" + +syn match Search "<\([+-]\)\w*\1>" +syn match Search "{\([+-]\)\w*\1}" + +let b:current_syntax = "template"