Skip to content

Commit

Permalink
Version 2
Browse files Browse the repository at this point in the history
Note: the interface has changed slightly (in version 2): buflocal aliases
added. To redefine default range add it to the cmd rather than to the alias
(this seems to be more intuitive).
  • Loading branch information
Marcin Szamotulski authored and vim-scripts committed Oct 7, 2012
1 parent 8ff4b97 commit 5e56667
Showing 1 changed file with 146 additions and 73 deletions.
219 changes: 146 additions & 73 deletions plugin/cmd_alias.vim
Expand Up @@ -3,106 +3,152 @@
" Copyright: © Marcin Szamotulski, 2012
" License: vim-license, see :help license
"
" Description
" ===========
"
" Note: the interface has changed slightly (in version 2): buflocal aliases
" added. To redefine default range add it to the cmd rather than to the alias
" (this seems to be more intuitive).
"
"
" This plugin implements aliases for command names, wihtout vim restriction:
" user defined commands via |:command| must begin with a captial letter. Using
" user defined commands via :command must begin with a captial letter. Using
" this plugin you make an alias to a command where the alias, is any sequence.
" You can also register a defult range or count with the alias. In this way
" you can change the default range or count of vim commands.
" To define alias use the command:
" :CmdAlias {alias} {command} [history] [match_end]
" where {alias} is the alias name (you might pretend to it the default range
" or count), {command} is the command that should be executed. The {alias} is
" any vim pattern that will be used to match what you are entering in the ':'
" command line (the pattern will have pretended '\C^' and appended '\>' - the
" later one unless [match_end] is specified and equal 0). For commands which
" do not run external programs you can also set [history]=1 (default is 0),
" then the command history will remember what you have typped rather than what
" was executed. But usage of it is limited, for example you can use with
" ```
" :CmdAlias {alias} [range]{command} [history] [buflocal] [match_end]
" ```
" where {alias} is the alias name, {command} is the command that should be
" executed. You might pretend new default [range] or count to the command. The
" {alias} is any vim pattern that will be used to match what you are entering in
" the ':' command line (the pattern will have pretended '\C^' and appended '\\>'
" - the later one unless [match_end] is specified and equal 0). For commands
" which do not run external programs you can also set [history]=1 (default is
" 0), then the command history will remember what you have typped rather than
" what was executed. But usage of it is limited, for example you can use with
" commands that echo some output because it will be hidden by next call to
" histdel() vim function.
" histdel() vim function. If [buflocal] has true value (1 for example) then the
" alias will be only valid in the current buffer (it will be denotes with @ when
" listing the aliases as Vim does for maps).
"
" Note: If you define [match_end] = 0 you might fall into troubles, simply
" because a the plugin might substitute part of a command name. So don't use
" it unless you really want to experiment - you've been warned ;).
"
" Fork me on GitHub:
" https://github.com/coot/cmdalias_vim
"
" If you don't provide any argument to the :CmdAlias command it will list all
" aliases.
"
" ---------------------------------------------------------------------------
" Examples:
" :CmdAlias ali\%[as] CmdAlias
" ---------
" ```
" :CmdAlias ali\%[as] CmdAlias
" ```
" Note: this alias would not work if we defined it with [history]=1.
" :CmdAlias %s s
" Change the default range of |:s| command from the current line to whole
" ```
" :CmdAlias s %s
" ```
" Change the default range of :s command from the current line to whole
" buffer. Note that :su will act with vim default range (the current line).
"
" :CmdAlias a\%[ppend] Append
" ```
" :CmdAlias a\%[ppend] Append
" ```
" define alias to the user command Append which will overwrite the vim command
" |:append|. The \%[...] allows that if you type: 'a' or 'ap' or 'app', ...
" :append. The \%[...] allows that if you type: 'a' or 'ap' or 'app', ...
" or 'append' then the Append command will be used (as with vim many commands)
"
" :CmdAlias bc\%[lose] BufClose
" ```
" :CmdAlias bc\%[lose] BufClose
" ```
" You will find the handy BufClose command in BufClose plugin by Christian
" Robinson.
"
" Tip: to find if an alias is not coliding type ':<alias><C-d>'.
" Tip: to find if an alias is not coliding type ':\<alias\>\<C-d\>'.
" See ':help c^D'.
"
" VIMRC:
" ```
" :CmdAlias SP 1,/\\\\begin{document}/-1s
" ```
" The :SP command will substitute in the LaTeX preambule (which starts in the
" first line and ends before `\begin{document}`). Note that the Vim pattern to
" find `\begin...` is `\\begin...` and each backslash needs to be escaped onece
" more. Thus we have four slashes (like in *Python* :).
"
" VIMRC
" -----
"
" To configure aliases on startup you haveto add the following lines to your
" vimrc file:
"
" ```
" augroup VIMRC_aliases
" au!
" au VimEnter * CmdAlias ...
" ...
" au!
" au VimEnter * CmdAlias ...
" ...
" augroup END
" ```
"
" ---------------------------------------------------------------------------
"
" :CmdAliasToggle
" toggles on/of the aliases. Since the plugin remaps <CR> in the command line
" this just delets/sets up the <CR> map. When you want to type a function:
" ':fun! X()' or use the expression register |@=| you need to switch aliases
" off. The plugin also defines <C-M> map to <CR> which doesn't trigger
" aliasing mechanism. So you can type ':fun! X()<C-M>' on the command line.
" Other Commands and Maps:
" ------------------------
"
" :CmdAlias! {alias}
" ```
" :CmdAliasToggle
" ```
" toggles on/of the aliases. Since the plugin remaps \<CR\> in the command line
" this just delets/sets up the \<CR\> map. When you want to type a function:
" ```
" :fun! X()
" ```
" or use the expression register @= you need to switch aliases
" off. The plugin also defines \<C-M\> map to \<CR\> which doesn't trigger
" aliasing mechanism. So you can type ':fun! X()\<C-M\>' on the command line.
" ```
" :CmdAlias! {alias}
" ```
" removes {alias}, this command has a nice completion.
"
" Note: If you have installed system.vim plugin (script id 4224) you need to
" update to version 3 (otherwise you will get an error).
" Note: If you have installed my [system plugin](http://www.vim.org/scripts/script.php?script_id=4224)
" you need to update it to version 3 (otherwise you will get an error).
"
" There is another plugin with the same functionality, but different
" implementation and thus a different limitations.
" http://www.vim.org/scripts/script.php?script_id=746 It uses cabbreviations.
" The problem with them is that it is more difficult to get the command bang
" working (what was the purpose of implementing this plugin). The range and
" the count probably could be implemented using the same range parser used by
" this plugin. The advantage of the cabbreviations approach is that after
" hitting the ' ' you get the real command together with its completion.
" Implementing completion for aliases within this approach would be quite
" tedious.
" There is another [plugin](http://www.vim.org/scripts/script.php?script_id=746)
" with the same functionality, but different implementation and thus a different
" limitations. It uses cabbreviations. The problem with them is that it is
" more difficult to get the command bang working (what was the purpose of
" implementing this plugin). The range and the count probably could be
" implemented using the same range parser used by this plugin. The advantage of
" the cabbreviations approach is that after hitting the ' ' you get the real
" command together with its completion. Implementing completion for aliases
" within this approach would be quite tedious.
"
" The aliasing works also when joining commands on the command line with "|",
" for example with a dummy alias:
" Alias S %s
" ```
" Alias S %s
" ```
" you can run:
" ```
" :S/aaa/yyy/|S/bbb/xxx
" ```
" Note: the first command has to end with / (to use |, this is a vim
" requirement.)
"
"
" Note: using the expression register:
" Since <C-R> is remapped in command line, you can not use it when you enter
" Since \<C-R\> is remapped in command line, you can not use it when you enter
" the expression register (:help ^R=). There is a patch on the way which fixes
" this disabling maps in expression register. Before it get accepted the
" plugin defies a map:
" ```
" cnoremap <C-M> <CR>
" ```
" It will not trigger aliases, any way it might be a good idea to have such
" a map in case you want to avoid aliases.
"
" If you want to debug define a list
" let g:cmd_alias_debug = []
" ```
" let g:cmd_alias_debug = []
" ```
" and for all calls an entry to this list will be appended.
" (except command lines which matches cmd_alias_debug since we don't want to
" record accessing to this variable)
Expand All @@ -111,7 +157,14 @@
if !exists("s:aliases")
let s:aliases = {}
" entries are dictionaries:
" { 'alias': alias, 'cmd': cmd, 'history': 1/0, 'default_range': range, 'match_end': 1/0}
" {
" 'alias': alias,
" 'cmd': cmd,
" 'history': 1/0,
" 'buflocal': ['list of buffer numbers, include 0 for global'],
" 'default_range': range,
" 'match_end': 1/0
" }
endif
let s:system = !empty(globpath(&rtp, 'plugin/system.vim'))
fun! ParseRange(cmdline) " {{{
Expand All @@ -126,37 +179,37 @@ fun! ParseRange(cmdline) " {{{
let add = matchstr(cmdline, '^\s*\d\+')
let range .= add
let cmdline = cmdline[len(add):]
echom range
" echom range
elseif cmdline =~ '^\.\s*'
let add = matchstr(cmdline, '^\s*\.\%([+-]\d*\)\=')
let range .= add
let cmdline = cmdline[len(add):]
echom range
" echom range
elseif cmdline =~ '^\s*\/'
let add = matchstr(cmdline, '^\s*\/\%([^/]\|\\\@<=\/\)*\/\%([-+]\d*\)\=')
let range .= add
let cmdline = cmdline[len(add):]
echom range . "<F>".cmdline."<"
" echom range . "<F>".cmdline."<"
elseif cmdline =~ '^\s*?'
let add = matchstr(cmdline, '^\s*?\%([^?]\|\\\@<=?\)*?\%([-+]\d*\)\=')
let range .= add
let cmdline = cmdline[len(add):]
echom range . "<?>".cmdline."<"
" echom range . "<?>".cmdline."<"
elseif cmdline =~ '^\s*\$'
let add = matchstr(cmdline, '^\s*\$\%(-\d*\)\=')
let range .= add
let cmdline = cmdline[len(add):]
echom range
" echom range
elseif cmdline =~ '^\s*\\\%(\/\|?\|&\)'
let add = matchstr(cmdline, '^\s*\\\%(\/\|?\|&\)')
let range .== add
let cmdine = cmdline[add:]
echom range
" echom range
elseif cmdline =~ '^\s*[;,]'
let add = matchstr(cmdline, '^\s*[;,]')
let range .= add
let cmdline = cmdline[len(add):]
echom range . "<;>".cmdline
" echom range . "<;>".cmdline
elseif cmdline =~ '^\s*\w'
return [ range, cmdline, 0]
endif
Expand Down Expand Up @@ -196,7 +249,8 @@ fun! ReWriteCmdLine() " {{{
let test=0
let [range, cmdline, error] = ParseRange(cmdline)
for alias in values(s:aliases)
if cmdline =~# '^\s*'.alias['alias'].(alias['match_end'] ? '\>' : '')
if cmdline =~# '^\s*'.alias['alias'].(alias['match_end'] ? '\>' : '') &&
\ (index(alias['buflocal'], 0) != -1 || index(alias['buflocal'], bufnr('%')) != -1)
let test=1
break
endif
Expand Down Expand Up @@ -236,18 +290,41 @@ fun! Cmd_Alias(alias, cmd, ...) " {{{
" The reason for this function is that for users with aliases within the
" cmdlias.vim plugin it is just to copy past the old config and add one
" underscore.
let [default_range, alias, error] = ParseRange(a:alias)
let [default_range, cmd, error] = ParseRange(a:cmd)
let hist = (a:0 >= 1 ? a:1 : 0)
let match_end = (a:0 >= 2 ? a:2 : 1)
let s:aliases[alias] = { 'alias': alias, 'cmd': a:cmd, 'history': hist, 'default_range': default_range, 'match_end': match_end, }
let buflocal = (a:0 >= 2 && a:2 ? bufnr("%") : 0 )
let match_end = (a:0 >= 3 ? a:3 : 1)
if !has_key(s:aliases, a:alias)
let s:aliases[a:alias] = {
\ 'alias': a:alias,
\ 'cmd': cmd,
\ 'history': hist,
\ 'buflocal':[buflocal],
\ 'default_range': default_range,
\ 'match_end': match_end,
\ }
else
if index(s:aliases[a:alias]['buflocal'], buflocal) == -1
call add(s:aliases[a:alias]['buflocal'], buflocal)
endif
endif
endfun " }}}
fun! <SID>RegAlias(bang,...) " {{{
if a:0 == 0
let lmax = max(map(values(s:aliases), "len(v:val['alias'])+len(v:val['default_range'])"))
let rmax = max(map(values(s:aliases), "len(v:val['cmd'])"))
echo "ALIAS".repeat(" ", lmax)."CMD".repeat(" ", 5+rmax-3)."HIS"
let lmax = max(map(values(s:aliases), "len(v:val['alias'])"))
let rmax = max(map(values(s:aliases), "len(v:val['cmd'])+len(v:val['default_range'])"))
let g:lmax = lmax
let g:rmax = rmax
echohl Title
echo " alias".repeat(" ", lmax)."cmd".repeat(" ", 5+rmax-3)."his"
echohl Normal
for alias in sort(values(s:aliases), "<SID>Compare")
echo alias['default_range'].alias['alias'].repeat(" ", (5+lmax-len(alias['default_range'])-len(alias['alias']))).alias['cmd'].repeat(" ", (5+rmax-len(alias['cmd']))).( alias['history'] ? 'yes' : '' )
if index(alias['buflocal'], 0) != -1 || index(alias['buflocal'], bufnr('%')) != -1
echo (index(alias['buflocal'], 0) == -1 ? '@' : ' ').
\ alias['alias'].repeat(" ", (5+lmax-len(alias['alias']))).
\ alias['default_range'].alias['cmd'].repeat(" ", (5+rmax-len(alias['default_range'].alias['cmd']))).
\ (alias['history'] ? 'yes' : ' ' ).repeat(" ", 4)
endif
endfor
else
if a:bang == "!"
Expand All @@ -261,12 +338,7 @@ fun! <SID>RegAlias(bang,...) " {{{
echoerr 'you have to specify the alias and the command'
return
endif
let [range, alias, error] = ParseRange(a:1)
let s:aliases[a:1]= {
\ 'alias': alias, 'cmd': a:2,
\ 'history': (a:0 >=3 ? a:3 : 0), 'default_range': (a:0>=4 ? a:4 : ""),
\ 'match_end': (a:0>=5 ? a:5 : 1),
\ }
call Cmd_Alias(a:1, a:2, (a:0 >=3 ? a:3 : 0), (a:0 >=4 && a:4 ? bufnr('%') : 0), (a:0>=5 ? a:5 : 1))
endif
endfun " }}}
fun! <SID>CompleteAliases(A,B,C) " {{{
Expand All @@ -283,4 +355,5 @@ fun! <SID>AliasToggle() " {{{
endif
endfun " }}}
com! -nargs=0 CmdAliasToggle :call <SID>AliasToggle()
nnoremap <F12> :CmdAliasToggle<CR>
" }}}

0 comments on commit 5e56667

Please sign in to comment.