Zsh refer to last element of current argument list and expand it
up vote
3
down vote
favorite
Suppose I do something like:
ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/a_file_with_a_long_filename_slightly_modified.pdf
Is there a way to refer to and expand a_file_with_a_long_filename.pdf
if my cursor is at the end of the string ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/
in zsh?
If not, what would you suggest do reduce typing work?
zsh line-editor zle
add a comment |
up vote
3
down vote
favorite
Suppose I do something like:
ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/a_file_with_a_long_filename_slightly_modified.pdf
Is there a way to refer to and expand a_file_with_a_long_filename.pdf
if my cursor is at the end of the string ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/
in zsh?
If not, what would you suggest do reduce typing work?
zsh line-editor zle
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
Suppose I do something like:
ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/a_file_with_a_long_filename_slightly_modified.pdf
Is there a way to refer to and expand a_file_with_a_long_filename.pdf
if my cursor is at the end of the string ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/
in zsh?
If not, what would you suggest do reduce typing work?
zsh line-editor zle
Suppose I do something like:
ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/a_file_with_a_long_filename_slightly_modified.pdf
Is there a way to refer to and expand a_file_with_a_long_filename.pdf
if my cursor is at the end of the string ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/
in zsh?
If not, what would you suggest do reduce typing work?
zsh line-editor zle
zsh line-editor zle
edited Nov 19 at 20:32
Gilles
522k12610401570
522k12610401570
asked Nov 19 at 19:23
student
6,8681663119
6,8681663119
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
up vote
3
down vote
With the default Emacs bindings, it's just two keychords: ESC-2 ESC-^_
(i.e. Esc 2 Esc Ctrl+_ or Alt+2 Ctrl+Alt+_).
That's the command copy-prev-word
with the numeric argument 2 (the default argument 1 would copy ~/path/to/a/new/hardlink/
). If the file name contains (quoted) spaces, you would need ESC-2 ESC-x copy-prev-shell-word RET
. You may want to bind this command to more convenient key, especially if your keyboard layout requires Shift for _. You can use these commands in vi mode as well, but neither is bound to a key by default.
If you get the numeric argument wrong, press Ctrl+_ to undo then try again.
add a comment |
up vote
1
down vote
This sounds like a fun code golf challenge. Here's one option:
Run an innocuous command with the filename; enter enough of the filename to allow TAB-completion.
: a_file<TAB>
Use
!!$
to refer to the last argument of the previous command:
ln !!$ ~/path/to/a/new/hardlink/!!$
Thanks to zsh's helpful quoting, this is safe even in the face of IFS-containing filenames. You'll notice that as soon as you hit space after the first !!$
, zsh expands the filename; ditto if you add a gratuitous space at the end of the command.
Number of characters required is:
- 3 x 2 = 6 for the two
!!$
- 2 for the
:<SPACE>
8 + plus enough for the initial tab completion.
You can “golf”!!$
toESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.
– Gilles
Nov 19 at 20:34
add a comment |
up vote
0
down vote
In vi
mode this would be <esc>0wyt $p
which goes to command mode, 0
beginning of the line, w
to the next word (advance to the filename) yt
yank to space (to get the long filename, assuming no spaces in the filename) and then $p
to put what was just yanked at the end of the line. This is a lot quicker than describing it once you memorize the vi
motions.
You could also setup a bindkey
to yank-put the second argument though that's pretty specific code for such a use case, here bound to control+t but that could be whatever you want.
function yank-put {
local -a words
words=(${(z)LBUFFER})
if (( $#words > 1 )); then
BUFFER+=$words[2]
CURSOR+=${#words[2]}
fi
}
zle -N yank-put
autoload -U yank-put compinit
compinit
set -o vi
bindkey -M viins "^t" yank-put
add a comment |
up vote
0
down vote
There is copy-earlier-word
, you could bind it to your favorite keybinding before using it with appending these lines to ~/.zshrc
:
autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[," copy-earlier-word
So, you could use like this in the command line:
% ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/<Esc-,><Esc-,>
(The first keypress of Esc-,(or Alt+,) yields "~/path/to/new/hardlink/" like copy-prev-shell-word
, and the second time it replaces that newly inserted word with "a_file_with_a_long_filename.pdf").
Here is a copy of copy-earlier-word
document for a reference.
This widget works like a combination of
insert-last-word
andcopy-prev-shell-word
. Repeated invocations of the widget retrieve earlier words on the relevant history line. With a numeric argument N, insert the N th word from the history line; N may be negative to count from the end of the line.
If
insert-last-word
has been used to retrieve the last word on a previous history line, repeated invocations will replace that word with earlier words from the same line.
Otherwise, the widget applies to words on the line currently being edited. The widget style can be set to the name of another widget that should be called to retrieve words. This widget must accept the same three arguments as
insert-last-word
.
--
copy-earlier-word
ZLE Function, widgets, zshcontrib(1)
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
With the default Emacs bindings, it's just two keychords: ESC-2 ESC-^_
(i.e. Esc 2 Esc Ctrl+_ or Alt+2 Ctrl+Alt+_).
That's the command copy-prev-word
with the numeric argument 2 (the default argument 1 would copy ~/path/to/a/new/hardlink/
). If the file name contains (quoted) spaces, you would need ESC-2 ESC-x copy-prev-shell-word RET
. You may want to bind this command to more convenient key, especially if your keyboard layout requires Shift for _. You can use these commands in vi mode as well, but neither is bound to a key by default.
If you get the numeric argument wrong, press Ctrl+_ to undo then try again.
add a comment |
up vote
3
down vote
With the default Emacs bindings, it's just two keychords: ESC-2 ESC-^_
(i.e. Esc 2 Esc Ctrl+_ or Alt+2 Ctrl+Alt+_).
That's the command copy-prev-word
with the numeric argument 2 (the default argument 1 would copy ~/path/to/a/new/hardlink/
). If the file name contains (quoted) spaces, you would need ESC-2 ESC-x copy-prev-shell-word RET
. You may want to bind this command to more convenient key, especially if your keyboard layout requires Shift for _. You can use these commands in vi mode as well, but neither is bound to a key by default.
If you get the numeric argument wrong, press Ctrl+_ to undo then try again.
add a comment |
up vote
3
down vote
up vote
3
down vote
With the default Emacs bindings, it's just two keychords: ESC-2 ESC-^_
(i.e. Esc 2 Esc Ctrl+_ or Alt+2 Ctrl+Alt+_).
That's the command copy-prev-word
with the numeric argument 2 (the default argument 1 would copy ~/path/to/a/new/hardlink/
). If the file name contains (quoted) spaces, you would need ESC-2 ESC-x copy-prev-shell-word RET
. You may want to bind this command to more convenient key, especially if your keyboard layout requires Shift for _. You can use these commands in vi mode as well, but neither is bound to a key by default.
If you get the numeric argument wrong, press Ctrl+_ to undo then try again.
With the default Emacs bindings, it's just two keychords: ESC-2 ESC-^_
(i.e. Esc 2 Esc Ctrl+_ or Alt+2 Ctrl+Alt+_).
That's the command copy-prev-word
with the numeric argument 2 (the default argument 1 would copy ~/path/to/a/new/hardlink/
). If the file name contains (quoted) spaces, you would need ESC-2 ESC-x copy-prev-shell-word RET
. You may want to bind this command to more convenient key, especially if your keyboard layout requires Shift for _. You can use these commands in vi mode as well, but neither is bound to a key by default.
If you get the numeric argument wrong, press Ctrl+_ to undo then try again.
answered Nov 19 at 20:32
Gilles
522k12610401570
522k12610401570
add a comment |
add a comment |
up vote
1
down vote
This sounds like a fun code golf challenge. Here's one option:
Run an innocuous command with the filename; enter enough of the filename to allow TAB-completion.
: a_file<TAB>
Use
!!$
to refer to the last argument of the previous command:
ln !!$ ~/path/to/a/new/hardlink/!!$
Thanks to zsh's helpful quoting, this is safe even in the face of IFS-containing filenames. You'll notice that as soon as you hit space after the first !!$
, zsh expands the filename; ditto if you add a gratuitous space at the end of the command.
Number of characters required is:
- 3 x 2 = 6 for the two
!!$
- 2 for the
:<SPACE>
8 + plus enough for the initial tab completion.
You can “golf”!!$
toESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.
– Gilles
Nov 19 at 20:34
add a comment |
up vote
1
down vote
This sounds like a fun code golf challenge. Here's one option:
Run an innocuous command with the filename; enter enough of the filename to allow TAB-completion.
: a_file<TAB>
Use
!!$
to refer to the last argument of the previous command:
ln !!$ ~/path/to/a/new/hardlink/!!$
Thanks to zsh's helpful quoting, this is safe even in the face of IFS-containing filenames. You'll notice that as soon as you hit space after the first !!$
, zsh expands the filename; ditto if you add a gratuitous space at the end of the command.
Number of characters required is:
- 3 x 2 = 6 for the two
!!$
- 2 for the
:<SPACE>
8 + plus enough for the initial tab completion.
You can “golf”!!$
toESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.
– Gilles
Nov 19 at 20:34
add a comment |
up vote
1
down vote
up vote
1
down vote
This sounds like a fun code golf challenge. Here's one option:
Run an innocuous command with the filename; enter enough of the filename to allow TAB-completion.
: a_file<TAB>
Use
!!$
to refer to the last argument of the previous command:
ln !!$ ~/path/to/a/new/hardlink/!!$
Thanks to zsh's helpful quoting, this is safe even in the face of IFS-containing filenames. You'll notice that as soon as you hit space after the first !!$
, zsh expands the filename; ditto if you add a gratuitous space at the end of the command.
Number of characters required is:
- 3 x 2 = 6 for the two
!!$
- 2 for the
:<SPACE>
8 + plus enough for the initial tab completion.
This sounds like a fun code golf challenge. Here's one option:
Run an innocuous command with the filename; enter enough of the filename to allow TAB-completion.
: a_file<TAB>
Use
!!$
to refer to the last argument of the previous command:
ln !!$ ~/path/to/a/new/hardlink/!!$
Thanks to zsh's helpful quoting, this is safe even in the face of IFS-containing filenames. You'll notice that as soon as you hit space after the first !!$
, zsh expands the filename; ditto if you add a gratuitous space at the end of the command.
Number of characters required is:
- 3 x 2 = 6 for the two
!!$
- 2 for the
:<SPACE>
8 + plus enough for the initial tab completion.
answered Nov 19 at 19:53
Jeff Schaller
36.4k952120
36.4k952120
You can “golf”!!$
toESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.
– Gilles
Nov 19 at 20:34
add a comment |
You can “golf”!!$
toESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.
– Gilles
Nov 19 at 20:34
You can “golf”
!!$
to ESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.– Gilles
Nov 19 at 20:34
You can “golf”
!!$
to ESC-.
, but even so this is more complicated than it should be. This isn't the 1970s anymore, shells have a line editor.– Gilles
Nov 19 at 20:34
add a comment |
up vote
0
down vote
In vi
mode this would be <esc>0wyt $p
which goes to command mode, 0
beginning of the line, w
to the next word (advance to the filename) yt
yank to space (to get the long filename, assuming no spaces in the filename) and then $p
to put what was just yanked at the end of the line. This is a lot quicker than describing it once you memorize the vi
motions.
You could also setup a bindkey
to yank-put the second argument though that's pretty specific code for such a use case, here bound to control+t but that could be whatever you want.
function yank-put {
local -a words
words=(${(z)LBUFFER})
if (( $#words > 1 )); then
BUFFER+=$words[2]
CURSOR+=${#words[2]}
fi
}
zle -N yank-put
autoload -U yank-put compinit
compinit
set -o vi
bindkey -M viins "^t" yank-put
add a comment |
up vote
0
down vote
In vi
mode this would be <esc>0wyt $p
which goes to command mode, 0
beginning of the line, w
to the next word (advance to the filename) yt
yank to space (to get the long filename, assuming no spaces in the filename) and then $p
to put what was just yanked at the end of the line. This is a lot quicker than describing it once you memorize the vi
motions.
You could also setup a bindkey
to yank-put the second argument though that's pretty specific code for such a use case, here bound to control+t but that could be whatever you want.
function yank-put {
local -a words
words=(${(z)LBUFFER})
if (( $#words > 1 )); then
BUFFER+=$words[2]
CURSOR+=${#words[2]}
fi
}
zle -N yank-put
autoload -U yank-put compinit
compinit
set -o vi
bindkey -M viins "^t" yank-put
add a comment |
up vote
0
down vote
up vote
0
down vote
In vi
mode this would be <esc>0wyt $p
which goes to command mode, 0
beginning of the line, w
to the next word (advance to the filename) yt
yank to space (to get the long filename, assuming no spaces in the filename) and then $p
to put what was just yanked at the end of the line. This is a lot quicker than describing it once you memorize the vi
motions.
You could also setup a bindkey
to yank-put the second argument though that's pretty specific code for such a use case, here bound to control+t but that could be whatever you want.
function yank-put {
local -a words
words=(${(z)LBUFFER})
if (( $#words > 1 )); then
BUFFER+=$words[2]
CURSOR+=${#words[2]}
fi
}
zle -N yank-put
autoload -U yank-put compinit
compinit
set -o vi
bindkey -M viins "^t" yank-put
In vi
mode this would be <esc>0wyt $p
which goes to command mode, 0
beginning of the line, w
to the next word (advance to the filename) yt
yank to space (to get the long filename, assuming no spaces in the filename) and then $p
to put what was just yanked at the end of the line. This is a lot quicker than describing it once you memorize the vi
motions.
You could also setup a bindkey
to yank-put the second argument though that's pretty specific code for such a use case, here bound to control+t but that could be whatever you want.
function yank-put {
local -a words
words=(${(z)LBUFFER})
if (( $#words > 1 )); then
BUFFER+=$words[2]
CURSOR+=${#words[2]}
fi
}
zle -N yank-put
autoload -U yank-put compinit
compinit
set -o vi
bindkey -M viins "^t" yank-put
answered Nov 19 at 20:55
thrig
23.7k12955
23.7k12955
add a comment |
add a comment |
up vote
0
down vote
There is copy-earlier-word
, you could bind it to your favorite keybinding before using it with appending these lines to ~/.zshrc
:
autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[," copy-earlier-word
So, you could use like this in the command line:
% ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/<Esc-,><Esc-,>
(The first keypress of Esc-,(or Alt+,) yields "~/path/to/new/hardlink/" like copy-prev-shell-word
, and the second time it replaces that newly inserted word with "a_file_with_a_long_filename.pdf").
Here is a copy of copy-earlier-word
document for a reference.
This widget works like a combination of
insert-last-word
andcopy-prev-shell-word
. Repeated invocations of the widget retrieve earlier words on the relevant history line. With a numeric argument N, insert the N th word from the history line; N may be negative to count from the end of the line.
If
insert-last-word
has been used to retrieve the last word on a previous history line, repeated invocations will replace that word with earlier words from the same line.
Otherwise, the widget applies to words on the line currently being edited. The widget style can be set to the name of another widget that should be called to retrieve words. This widget must accept the same three arguments as
insert-last-word
.
--
copy-earlier-word
ZLE Function, widgets, zshcontrib(1)
add a comment |
up vote
0
down vote
There is copy-earlier-word
, you could bind it to your favorite keybinding before using it with appending these lines to ~/.zshrc
:
autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[," copy-earlier-word
So, you could use like this in the command line:
% ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/<Esc-,><Esc-,>
(The first keypress of Esc-,(or Alt+,) yields "~/path/to/new/hardlink/" like copy-prev-shell-word
, and the second time it replaces that newly inserted word with "a_file_with_a_long_filename.pdf").
Here is a copy of copy-earlier-word
document for a reference.
This widget works like a combination of
insert-last-word
andcopy-prev-shell-word
. Repeated invocations of the widget retrieve earlier words on the relevant history line. With a numeric argument N, insert the N th word from the history line; N may be negative to count from the end of the line.
If
insert-last-word
has been used to retrieve the last word on a previous history line, repeated invocations will replace that word with earlier words from the same line.
Otherwise, the widget applies to words on the line currently being edited. The widget style can be set to the name of another widget that should be called to retrieve words. This widget must accept the same three arguments as
insert-last-word
.
--
copy-earlier-word
ZLE Function, widgets, zshcontrib(1)
add a comment |
up vote
0
down vote
up vote
0
down vote
There is copy-earlier-word
, you could bind it to your favorite keybinding before using it with appending these lines to ~/.zshrc
:
autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[," copy-earlier-word
So, you could use like this in the command line:
% ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/<Esc-,><Esc-,>
(The first keypress of Esc-,(or Alt+,) yields "~/path/to/new/hardlink/" like copy-prev-shell-word
, and the second time it replaces that newly inserted word with "a_file_with_a_long_filename.pdf").
Here is a copy of copy-earlier-word
document for a reference.
This widget works like a combination of
insert-last-word
andcopy-prev-shell-word
. Repeated invocations of the widget retrieve earlier words on the relevant history line. With a numeric argument N, insert the N th word from the history line; N may be negative to count from the end of the line.
If
insert-last-word
has been used to retrieve the last word on a previous history line, repeated invocations will replace that word with earlier words from the same line.
Otherwise, the widget applies to words on the line currently being edited. The widget style can be set to the name of another widget that should be called to retrieve words. This widget must accept the same three arguments as
insert-last-word
.
--
copy-earlier-word
ZLE Function, widgets, zshcontrib(1)
There is copy-earlier-word
, you could bind it to your favorite keybinding before using it with appending these lines to ~/.zshrc
:
autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[," copy-earlier-word
So, you could use like this in the command line:
% ln a_file_with_a_long_filename.pdf ~/path/to/a/new/hardlink/<Esc-,><Esc-,>
(The first keypress of Esc-,(or Alt+,) yields "~/path/to/new/hardlink/" like copy-prev-shell-word
, and the second time it replaces that newly inserted word with "a_file_with_a_long_filename.pdf").
Here is a copy of copy-earlier-word
document for a reference.
This widget works like a combination of
insert-last-word
andcopy-prev-shell-word
. Repeated invocations of the widget retrieve earlier words on the relevant history line. With a numeric argument N, insert the N th word from the history line; N may be negative to count from the end of the line.
If
insert-last-word
has been used to retrieve the last word on a previous history line, repeated invocations will replace that word with earlier words from the same line.
Otherwise, the widget applies to words on the line currently being edited. The widget style can be set to the name of another widget that should be called to retrieve words. This widget must accept the same three arguments as
insert-last-word
.
--
copy-earlier-word
ZLE Function, widgets, zshcontrib(1)
edited Nov 20 at 2:12
answered Nov 19 at 23:36
hchbaw
3014
3014
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482827%2fzsh-refer-to-last-element-of-current-argument-list-and-expand-it%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown