How does `C-x z` work?
Specifically, the keyboard event C-x
, following by N z
characters, will repeat the previous command N times.
I do not understand how this can work. As far as I understand, after the input event C-x z
, for the behavior to be as specified, Emacs would need to somehow remap the z
character to the command repeat
in order for the next z
to actually again execute `repeat'. Is this correct? If so, I do not understand how Emacs can change the keymap immediately after executing a command. If not, what is going on?
keymap commands
New contributor
add a comment |
Specifically, the keyboard event C-x
, following by N z
characters, will repeat the previous command N times.
I do not understand how this can work. As far as I understand, after the input event C-x z
, for the behavior to be as specified, Emacs would need to somehow remap the z
character to the command repeat
in order for the next z
to actually again execute `repeat'. Is this correct? If so, I do not understand how Emacs can change the keymap immediately after executing a command. If not, what is going on?
keymap commands
New contributor
add a comment |
Specifically, the keyboard event C-x
, following by N z
characters, will repeat the previous command N times.
I do not understand how this can work. As far as I understand, after the input event C-x z
, for the behavior to be as specified, Emacs would need to somehow remap the z
character to the command repeat
in order for the next z
to actually again execute `repeat'. Is this correct? If so, I do not understand how Emacs can change the keymap immediately after executing a command. If not, what is going on?
keymap commands
New contributor
Specifically, the keyboard event C-x
, following by N z
characters, will repeat the previous command N times.
I do not understand how this can work. As far as I understand, after the input event C-x z
, for the behavior to be as specified, Emacs would need to somehow remap the z
character to the command repeat
in order for the next z
to actually again execute `repeat'. Is this correct? If so, I do not understand how Emacs can change the keymap immediately after executing a command. If not, what is going on?
keymap commands
keymap commands
New contributor
New contributor
edited 4 hours ago
Drew
47.1k462104
47.1k462104
New contributor
asked 4 hours ago
extremeaxe5
1111
1111
New contributor
New contributor
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
The code is in repeat.el
. See command repeat
, which is what C-x z
is bound to.
The code uses the fact that Emacs records the current command and the last command in variables. The repeat
code resets the variable this-command
to what it records as the command that was previous to command repeat
.
Note that you can define your own repeatable command by using code such as this:
(defun my-repeat-command (command)
"Repeat COMMAND."
(require 'repeat)
(let ((repeat-previous-repeated-command command)
(repeat-message-function #'ignore)
(last-repeatable-command 'repeat))
(repeat nil)))
(defun some-command (...)
(interactive...)
...)
(defun some-command-repeat ()
"Invoke `some-command' in a repeatable way."
(interactive)
(my-repeat-command 'some-command))
So it doesn't remap the key on the fly. Instead it just fools Emacs into thinking that the current command is whatever command was used last.
And yes, there are other ways of doing this kind of thing, such as using a transient keymap - that does more what you were guessing.
1
Looking at the repeat defun, it also usesset-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.
– glucas
3 hours ago
add a comment |
As you guessed, for this to work, the repeat
command needs to be able to "change the keymap" immediately after executing a command. And indeed, repeat
ends with a call to set-transient-map
which makes a new keymap active (rather than modify in-place one of the currently active keymaps, it works by changing the set of active keymaps) with a binding for z
which shadows the normal binding of z
. This keymap needs to be short-lived, so set-transient-map
internally uses pre-command-hook
to deactivate that special keymap as soon as you hit something else than z
.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "583"
};
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
});
}
});
extremeaxe5 is a new contributor. Be nice, and check out our Code of Conduct.
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%2femacs.stackexchange.com%2fquestions%2f46948%2fhow-does-c-x-z-work%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The code is in repeat.el
. See command repeat
, which is what C-x z
is bound to.
The code uses the fact that Emacs records the current command and the last command in variables. The repeat
code resets the variable this-command
to what it records as the command that was previous to command repeat
.
Note that you can define your own repeatable command by using code such as this:
(defun my-repeat-command (command)
"Repeat COMMAND."
(require 'repeat)
(let ((repeat-previous-repeated-command command)
(repeat-message-function #'ignore)
(last-repeatable-command 'repeat))
(repeat nil)))
(defun some-command (...)
(interactive...)
...)
(defun some-command-repeat ()
"Invoke `some-command' in a repeatable way."
(interactive)
(my-repeat-command 'some-command))
So it doesn't remap the key on the fly. Instead it just fools Emacs into thinking that the current command is whatever command was used last.
And yes, there are other ways of doing this kind of thing, such as using a transient keymap - that does more what you were guessing.
1
Looking at the repeat defun, it also usesset-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.
– glucas
3 hours ago
add a comment |
The code is in repeat.el
. See command repeat
, which is what C-x z
is bound to.
The code uses the fact that Emacs records the current command and the last command in variables. The repeat
code resets the variable this-command
to what it records as the command that was previous to command repeat
.
Note that you can define your own repeatable command by using code such as this:
(defun my-repeat-command (command)
"Repeat COMMAND."
(require 'repeat)
(let ((repeat-previous-repeated-command command)
(repeat-message-function #'ignore)
(last-repeatable-command 'repeat))
(repeat nil)))
(defun some-command (...)
(interactive...)
...)
(defun some-command-repeat ()
"Invoke `some-command' in a repeatable way."
(interactive)
(my-repeat-command 'some-command))
So it doesn't remap the key on the fly. Instead it just fools Emacs into thinking that the current command is whatever command was used last.
And yes, there are other ways of doing this kind of thing, such as using a transient keymap - that does more what you were guessing.
1
Looking at the repeat defun, it also usesset-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.
– glucas
3 hours ago
add a comment |
The code is in repeat.el
. See command repeat
, which is what C-x z
is bound to.
The code uses the fact that Emacs records the current command and the last command in variables. The repeat
code resets the variable this-command
to what it records as the command that was previous to command repeat
.
Note that you can define your own repeatable command by using code such as this:
(defun my-repeat-command (command)
"Repeat COMMAND."
(require 'repeat)
(let ((repeat-previous-repeated-command command)
(repeat-message-function #'ignore)
(last-repeatable-command 'repeat))
(repeat nil)))
(defun some-command (...)
(interactive...)
...)
(defun some-command-repeat ()
"Invoke `some-command' in a repeatable way."
(interactive)
(my-repeat-command 'some-command))
So it doesn't remap the key on the fly. Instead it just fools Emacs into thinking that the current command is whatever command was used last.
And yes, there are other ways of doing this kind of thing, such as using a transient keymap - that does more what you were guessing.
The code is in repeat.el
. See command repeat
, which is what C-x z
is bound to.
The code uses the fact that Emacs records the current command and the last command in variables. The repeat
code resets the variable this-command
to what it records as the command that was previous to command repeat
.
Note that you can define your own repeatable command by using code such as this:
(defun my-repeat-command (command)
"Repeat COMMAND."
(require 'repeat)
(let ((repeat-previous-repeated-command command)
(repeat-message-function #'ignore)
(last-repeatable-command 'repeat))
(repeat nil)))
(defun some-command (...)
(interactive...)
...)
(defun some-command-repeat ()
"Invoke `some-command' in a repeatable way."
(interactive)
(my-repeat-command 'some-command))
So it doesn't remap the key on the fly. Instead it just fools Emacs into thinking that the current command is whatever command was used last.
And yes, there are other ways of doing this kind of thing, such as using a transient keymap - that does more what you were guessing.
answered 4 hours ago
Drew
47.1k462104
47.1k462104
1
Looking at the repeat defun, it also usesset-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.
– glucas
3 hours ago
add a comment |
1
Looking at the repeat defun, it also usesset-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.
– glucas
3 hours ago
1
1
Looking at the repeat defun, it also uses
set-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.– glucas
3 hours ago
Looking at the repeat defun, it also uses
set-transient-map
to allow repeated taps of the last character in the binding to continue to repeat.– glucas
3 hours ago
add a comment |
As you guessed, for this to work, the repeat
command needs to be able to "change the keymap" immediately after executing a command. And indeed, repeat
ends with a call to set-transient-map
which makes a new keymap active (rather than modify in-place one of the currently active keymaps, it works by changing the set of active keymaps) with a binding for z
which shadows the normal binding of z
. This keymap needs to be short-lived, so set-transient-map
internally uses pre-command-hook
to deactivate that special keymap as soon as you hit something else than z
.
add a comment |
As you guessed, for this to work, the repeat
command needs to be able to "change the keymap" immediately after executing a command. And indeed, repeat
ends with a call to set-transient-map
which makes a new keymap active (rather than modify in-place one of the currently active keymaps, it works by changing the set of active keymaps) with a binding for z
which shadows the normal binding of z
. This keymap needs to be short-lived, so set-transient-map
internally uses pre-command-hook
to deactivate that special keymap as soon as you hit something else than z
.
add a comment |
As you guessed, for this to work, the repeat
command needs to be able to "change the keymap" immediately after executing a command. And indeed, repeat
ends with a call to set-transient-map
which makes a new keymap active (rather than modify in-place one of the currently active keymaps, it works by changing the set of active keymaps) with a binding for z
which shadows the normal binding of z
. This keymap needs to be short-lived, so set-transient-map
internally uses pre-command-hook
to deactivate that special keymap as soon as you hit something else than z
.
As you guessed, for this to work, the repeat
command needs to be able to "change the keymap" immediately after executing a command. And indeed, repeat
ends with a call to set-transient-map
which makes a new keymap active (rather than modify in-place one of the currently active keymaps, it works by changing the set of active keymaps) with a binding for z
which shadows the normal binding of z
. This keymap needs to be short-lived, so set-transient-map
internally uses pre-command-hook
to deactivate that special keymap as soon as you hit something else than z
.
answered 1 hour ago
Stefan
18.6k2461
18.6k2461
add a comment |
add a comment |
extremeaxe5 is a new contributor. Be nice, and check out our Code of Conduct.
extremeaxe5 is a new contributor. Be nice, and check out our Code of Conduct.
extremeaxe5 is a new contributor. Be nice, and check out our Code of Conduct.
extremeaxe5 is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Emacs 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%2femacs.stackexchange.com%2fquestions%2f46948%2fhow-does-c-x-z-work%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