Zsh refer to last element of current argument list and expand it
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 |
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 |
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 '18 at 20:32
Gilles
528k12810581583
528k12810581583
asked Nov 19 '18 at 19:23
student
6,9631763120
6,9631763120
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
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 |
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.
1
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 '18 at 20:34
add a comment |
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 |
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 |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 |
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 |
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 '18 at 20:32
Gilles
528k12810581583
528k12810581583
add a comment |
add a comment |
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.
1
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 '18 at 20:34
add a comment |
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.
1
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 '18 at 20:34
add a comment |
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 '18 at 19:53
Jeff Schaller
38.7k1053125
38.7k1053125
1
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 '18 at 20:34
add a comment |
1
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 '18 at 20:34
1
1
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 '18 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 '18 at 20:34
add a comment |
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 |
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 |
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 '18 at 2:12
answered Nov 19 '18 at 23:36
hchbaw
3114
3114
add a comment |
add a comment |
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 |
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 |
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 '18 at 20:55
thrig
24.2k23056
24.2k23056
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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