I have this code:
(defun do-repeated-work (args)
"some work that need executed repeatedly"
(message nil)
(message "doing some repeated work, arg = %s, current time = %s" args (format-time-string "%H:%M:%S")))
(setq timer (run-with-idle-timer 3 t 'do-repeated-work (list "arg1" "arg2" "arg3")))
The purpose of the code above is: print a line of message in minibuffer repeatedly every three seconds. But I found that, when the function do-repeated-work works again, the old message in emacs minibuffer cannot be cleared, so the new message cannot be displayed. I have already tried the way mentioned in this question: how to empty or clear the emacs minibuffer?, but it doesn't work.
My Emacs version is 25.3
How to cope with this problem?
You've made an incorrect assumption, and consequently your problem isn't what you think it is.
The purpose of the code above is: print a line of message in minibuffer repeatedly every three seconds.
That's not what it does.
You've used run-with-idle-timer which will run one time once Emacs has been idle for 3 (in this case) seconds, and will not repeat until some non-idle activity has taken place -- after which it will again run once Emacs has become idle for 3 seconds.
See C-hf run-with-idle-timer
If you want something which repeats at a consistent interval, use run-with-timer.
Related
I have not been able to get the minibuffer-exit-hook to play nice with read-string. As far as I can tell, I should no longer be in the minibuffer after finishing up with read-string. However, the condition (minibufferp) says I'm still in the minibuffer even though read-string finished. read-string is written in C, so I can't add the hook there (i.e., at the tail end of the read-string function).
"Documentation [minibuffer-exit-hook]: Normal hook run just after exit from minibuffer.
[After thinking a little more about this, I'm pretty sure it's a bug -- so I filed a bug report: bug#16524. As I learn more, I'll update this thread.
(defun test ()
(interactive)
(read-string "Prompt: " "testing"))
(add-hook 'minibuffer-exit-hook (lambda ()
(cond
((minibufferp)
(message "Focus is still in the minibuffer: %s" (buffer-name)))
(t (message "Contragulations -- focus is now in: %s." (buffer-name))))))
The doc string is not exact; that's all. The hook is run when inputting text in the minibuffer is done (no longer possible). The buffer that is current when it is run is still the minibuffer. (And that's the way it should be, FWIW.)
Note that the Elisp manual puts it slightly differently (but again, not very precisely):
This is a normal hook that is run whenever the minibuffer is
entered.
("Whenever", meaning about the same time as, not necessarily after.)
If you want to do something after every use of read-string in your code, then define a function that does the following: first (read-string...), then whatever you want done next. And use that function.
If you need to affect also other invocations of read-string, besides those you write in your code, then advise function read-string to perform whatever action after the vanilla code finishes.
For example:
(defadvice read-string (after fooness activate)
(message "buffer: %S" (current-buffer)))
[Note: Yes, you can advise primitives (functions written in C). You used to even be able to advise special forms, but they regressively took away that feature.]
Running a hook after you truly exited the minibuffer is rather pointless: you could be in any kind of buffer (since minibuffer use can be triggered from anywhere) and you hence know very little about the current context (unless you use a buffer-local exit-hook, I guess).
If you want to run a hook when the selected window changes, then your best option is probably to use a post-command-hook that stores the current selected-window in an auxiliary variable and uses it to compare to the previous selected-window.
I'm trying to write an emacs function that executes a shell command every 5 seconds. However, I can't get the pause to work. Here's what I have:
(while '(test)
(insert (format "echo hello"))
(comint-send-input))
(sleep-for 0 5000)
I suspect that the sleep is ignored for reasons related to functional evaluation of Lisp. Any advice on how to get the pause to occur after each command evaluation?
As mentioned in the comment, the issue is with a paren.
Also, I've just tried sit-for in *scratch* and it performs smoother compared to sleep-for.
(while 1
(insert "hello")
(sit-for 1))
But both lock up Emacs, since it's single threaded, so you should be careful with this sort of activity.
Consider using async package or something similar instead.
it is said in the manual that if you use kill-region sequentially, the texts you kill will be concatenated into one in the kill-ring.
I'm just confused how this works. So I tried to eval this in the scratch buffer:
(progn
(kill-region 1 5) ; this kills ";; T"
(kill-region 1 5)); this kills "his "
what I expect is that, since I use kill-region 2 times, the killed texts should be concatenated as one in the kill-ring.
but when I use C-y, I get only "his ".
So I have 2 questions here:
in lisp, how to invoke kill-region several times so that the killed texts are concatenated?
using keyboard C-w, how to invoke kill-region several times so that the killed texts are concatenated? since the typical workflow is kill-region(C-w), then move-cursor, then kill-region again.
here is the doc string of kill region. isn't the 2nd paragraph and the last paragraph contradictory?
"Kill (\"cut\") text between point and mark.
This deletes the text from the buffer and saves it in the kill ring.
The command \\[yank] can retrieve it from there.
\(If you want to save the region without killing it, use \\[kill-ring-save].)
If you want to append the killed region to the last killed text,
use \\[append-next-kill] before \\[kill-region].
If the buffer is read-only, Emacs will beep and refrain from deleting
the text, but put the text in the kill ring anyway. This means that
you can use the killing commands to copy text from a read-only buffer.
Lisp programs should use this function for killing text.
(To delete text, use `delete-region'.)
Supply two arguments, character positions indicating the stretch of text
to be killed.
Any command that calls this function is a \"kill command\".
If the previous command was also a kill command,
the text killed this time appends to the text killed last time
to make one entry in the kill ring."
The documentation refers to commands, not functions. A command is a function
that initiates the command loop.
Any command that calls this function is a \"kill command\".
If the previous command was also a kill command,
the text killed this time appends to the text killed last time
to make one entry in the kill ring.
This does not mean kill-region per se. It's saying any command that calls the
kill-region function becomes a "kill command" (including kill-region
itself). E.g. kill-line kill-word, etc
in lisp, how to invoke kill-region several times so that the killed texts
are concatenated?
Use kill-append.
(progn
(kill-region 1 5) ; this kills ";; T"
(kill-region 1 5)); this kills "his "
what I expect is that, since I use kill-region 2 times, the killed texts
should be concatenated as one in the kill-ring.
You called kill-region twice but not as commands. Both these calls happen
within the same command loop run.
I would like some copycat function, that takes the previous input and repeats it (like repeat), but does not get written over when something else is done, and thus remains repeatable. Anyone has any ideas?
EDIT: The way I intend this is to have some mode in which D keypress will act exactly like repeat (if some other input has been done, repeat that), while d will repeat the last thing assigned to the last D key press.
EDIT2: If I would yank, and then press C-x z (in my mode also bound to D), then it will repeat the yank. However, when I would move the cursor down, and I try to press D, it then repeats the down cursor. In this case, I would like the small d to do the behavior of the last repeat (that is, yank) while D would repeat the down cursor command. So, d would store the last repeated command, while D would repeat the last command.
This was just too long for a comment:
It feels like you essentially want a shorter version of keyboard macros? I'll try to explain briefly, and see if it is close:
C-x ( - start recording the macro.
Do whatever you want (may be just a single command). For example, yank something, i.e. M-d
C-x ) - finish recording the macro.
Now you can C-x e to replay the macro (you can do other stuff after you've recorded the macro, C-x e will do what you have previously recorded (i.e. M-d in this case).
Maybe you can create a shorthand version of start-macro end-macro recording, if you are sure there will be only one command, but these are really minor improvements. Once you get used to macros, you'll do it unconsciously, so that one keystroke saved won't matter really.
Also, if I didn't guess what you were after, this may prove to be interesting to you: http://www.gnu.org/software/emacs/manual/html_node/elisp/Command-History.html
My best attempt. It works, though it didn't incorporate all the error handling that repeat has.
(defun Navi-repeat ()
;; Checks whether the last repeatable command is the same as repeat var.
;; If yes, set repeat-navi to that command, and call it.
;; If no, check whether the Navi-repeat variable has been set before:
;; If bound, call it.
;; If not bound,
;; give it the value of the last-repeatable command, and call it.
(interactive)
(if (eq last-repeatable-command 'repeat)
(progn (setq repeat-navi repeat-previous-repeated-command)
(call-interactively repeat-navi))
(if (boundp 'repeat-navi)
(call-interactively repeat-navi)
(progn (setq repeat-navi last-repeatable-command)
(call-interactively repeat-navi))
)
)
)
Well. When I type some first keys of the key series, emacs write those keys in minibuffer after some interval of time. Like that: Typing C-x 4 will make C-x 4- visible in minibuffer.
The question is: can this be modified? I was thinking about making something like combining part of key-help (generated by C-h when type some keys) with this string.
Can interval for waiting this message be shorten too?
Is it subroutine?
Edited, new question
There is a message when I quit emacs with C-x C-c and have modified buffers, that ask me if I want to save them. How can I know that this message is here? I tried to look in (minibuffer-prompt) (minibuffer-contents) (buffer-substring (point-min) (point-max)), selecting (select-window (minibuffer-window)). Nothing gives me results.
Yes, the user option echo-keystrokes controls how much time elapses before the prefix key is shown in the minibuffer. From (emacs) Echo Area Customization:
User Option: echo-keystrokes
This variable determines how much time should elapse before command
characters echo. Its value must be an integer or floating point
number, which specifies the number of seconds to wait before
echoing. If the user types a prefix key (such as `C-x') and then
delays this many seconds before continuing, the prefix key is
echoed in the echo area. (Once echoing begins in a key sequence,
all subsequent characters in the same key sequence are echoed
immediately.)
If the value is zero, then command input is not echoed.
You can control the timing of this help message by setting suggest-key-bindings to a larger/smaller number.
(setq suggest-key-bindings 5) ; wait 5 seconds
There is no easy way to customize the behavior, you'd have to edit the C code for execute-extended-command, or use a replacement for it which also provides the help. One possibility for a replacement is the anything-complete library which has a replacement for execute-extended-command (note: I haven't tried it). It builds on top of the package anything, which is a different experience than the standard Emacs.
I wrote working version of what I wanted to implement.
To use, (require 'keylist), copy one or two last lines to .emacs and uncomment them.
As you can see through this code, I used this
(not cursor-in-echo-area)
(not (minibufferp))
(not (= 13 (aref (this-command-keys-vector) 0)))
to find out, if my minibuffer, or echo area is in use.
The difference between them is that minibuffer is used to read, and echo area is used to message something.
When you type C-x C-c cursor is placed in echo area, and value of cursor-in-echo-area is changed.
The last string (= 13 (aref (this-command-keys-vector) 0)) is the most funny. It is used to catch things like query-replace. When making raplacements, (this-command-keys-vector) shows that RET is the first key pressed, then keys of your choise(y,n). As far as I don't have key-sequences starting with RET, i am okay with this.