Wednesday, January 18, 2012

Re: Retrieve the argument of a prior Ex mode command (back on-list)

[Bringing back on-list, as others might have better suggestions
for my mapping/function down further]

On 01/18/12 14:27, Chris Jones wrote:
> Note that, there are two separate factors here: speed within
> the limited context of a bash session and _overall_ speed
> when you are switching back and forth between bash and Vim.
[snip]
> What I notice happens is that I issue a few bash commands in
> a terminal and then go back to editing in Vim and sooner
> rather than later, my fingers will be tempted to take the
> [Alt+.] route and of course.. since Vim does not allow this, I
> have to stop right there in my tracks.

I think the biggest impediment to making a simple mapping to do
this would be that in bash, commands are almost always of the
form "<command> [optional args]". In Vim, you have a variety of
patterns, so extracting the "args" portion or the "last arg"
portion becomes more complex. Not that it can't be done. In at
least an xterm, Vim can see alt+period for the purposes of
mapping. So this can easily be exploited to do *some* form of
last-command-expansion.

> As to the workarounds you suggest, I'll take a look at the
> cmdline register, but I am skeptical I could integrate this
> particular strategy to my workflow.

So I'd exploit it something like

=================================================
function! PreviousTail()
let item = histget(getcmdtype(), -1)
let patterns = [
\
'^\%([GvV]\|g\%[lobal]\|s\%[ubstitute]\)\(\W\)\%(\1\@!.\|\\\1\)\1\(.*\)',
\ '^.* \(.*\)',
\ ]
for pat in patterns
let matches = matchlist(@:, pat)
if len(matches)
for i in range(1,9)
if len(matches[-i])
return matches[-i]
endif
endfor
endif
endfor
return item
endfunction

cnoremap <expr> <m-.> PreviousTail()
=================================================

You can add patterns to find particular subsets of the last
command. This should work (mostly) for both Ex and search
command-lines. You can tweak the logic accordingly, adding other
patterns, or having different pattern-sets based on getcmdtype().

One might have to work up smart quoting/parsing (perhaps using
something like Python's "shlex" module if your Vim is built with
Python support) to handle cases like

:echo "hello world"
:let greeting = <m-.>

With the current code, it would just pull in

:let greeting = world"

but with proper quoting-smarts applied in certain contexts, it
would correctly give you

:let greeting = "hello world"

I'll leave such adventures as an exercise for the reader

> As regards the command-window, I investigated this particular
> feature of Vim& tried to force myself to use it (for over a
> week or so.. not too long ago) but I found it was not only
> slow in essence (much typing) but that it required too many
> successive individual actions (worst of all actions that
> required at least part of my attention.. now... where is that
> command... page up.. page down.. oh here it is.. etc. and
> therefore conflicted with what I was doing..)

remember that it's (mostly) just another Vim window, so you can
perform :s/foo/bar/g on commands, you can search using "/" and
"?", and all the other power of Vim. I can't help with the
mental context-switch, but there are certain type of changes (or
searches for previous commands) that I find far easier in the
command-line window. YMMV.

> Hope you won't mind the rant, folks are so much into plugins
> these days, that I did not see this as having any relevance
> to the doings of the 'vim_use' list.

I tend to run a pretty stripped-down vimrc, and don't do much
with plugins, so I don't mind at all.

-tim


--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: