Timer on modeline: how to update modeline every second?
As part of my custom mode-line, I've included a feature that displays a countdown timer (timers are created using the chronos package) when it recognises that there is one running.
Works great, but the problem I have is that the mode-line only refreshes when I enter keypresses into emacs. It will not update in the background (say I work in the browser for a bit but emacs is still visible).
Is there any good way to force the mode-line to redisplay each second, so that the timer display stays up to date?
Screenshot of mode-line
Relevant code
This is appended to the format-mode-line
list:
(if (>= (length chronos--timers-list) 2)
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| ")
"")
The my-timer-display
decides whether or not to show the timer. I think this might be the best place to get emacs to start forcing redisplays.
(defun my-timer-display ()
"Return the lowest timer, avoiding the --now-- time, in the chronos timers list"
(if (string= (chronos--message (nth 0 (chronos--sort-by-expiry))) chronos-now-message)
(my-print-timer 1)
(my-print-timer 0)))
The my-print-timer
function referenced just returns the xth timer in the chronos timers list. I won't include it as I don't think it's relevant to the question.
Any help or ideas would be much appreciated, thanks :)
mode-line timers
add a comment |
As part of my custom mode-line, I've included a feature that displays a countdown timer (timers are created using the chronos package) when it recognises that there is one running.
Works great, but the problem I have is that the mode-line only refreshes when I enter keypresses into emacs. It will not update in the background (say I work in the browser for a bit but emacs is still visible).
Is there any good way to force the mode-line to redisplay each second, so that the timer display stays up to date?
Screenshot of mode-line
Relevant code
This is appended to the format-mode-line
list:
(if (>= (length chronos--timers-list) 2)
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| ")
"")
The my-timer-display
decides whether or not to show the timer. I think this might be the best place to get emacs to start forcing redisplays.
(defun my-timer-display ()
"Return the lowest timer, avoiding the --now-- time, in the chronos timers list"
(if (string= (chronos--message (nth 0 (chronos--sort-by-expiry))) chronos-now-message)
(my-print-timer 1)
(my-print-timer 0)))
The my-print-timer
function referenced just returns the xth timer in the chronos timers list. I won't include it as I don't think it's relevant to the question.
Any help or ideas would be much appreciated, thanks :)
mode-line timers
add a comment |
As part of my custom mode-line, I've included a feature that displays a countdown timer (timers are created using the chronos package) when it recognises that there is one running.
Works great, but the problem I have is that the mode-line only refreshes when I enter keypresses into emacs. It will not update in the background (say I work in the browser for a bit but emacs is still visible).
Is there any good way to force the mode-line to redisplay each second, so that the timer display stays up to date?
Screenshot of mode-line
Relevant code
This is appended to the format-mode-line
list:
(if (>= (length chronos--timers-list) 2)
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| ")
"")
The my-timer-display
decides whether or not to show the timer. I think this might be the best place to get emacs to start forcing redisplays.
(defun my-timer-display ()
"Return the lowest timer, avoiding the --now-- time, in the chronos timers list"
(if (string= (chronos--message (nth 0 (chronos--sort-by-expiry))) chronos-now-message)
(my-print-timer 1)
(my-print-timer 0)))
The my-print-timer
function referenced just returns the xth timer in the chronos timers list. I won't include it as I don't think it's relevant to the question.
Any help or ideas would be much appreciated, thanks :)
mode-line timers
As part of my custom mode-line, I've included a feature that displays a countdown timer (timers are created using the chronos package) when it recognises that there is one running.
Works great, but the problem I have is that the mode-line only refreshes when I enter keypresses into emacs. It will not update in the background (say I work in the browser for a bit but emacs is still visible).
Is there any good way to force the mode-line to redisplay each second, so that the timer display stays up to date?
Screenshot of mode-line
Relevant code
This is appended to the format-mode-line
list:
(if (>= (length chronos--timers-list) 2)
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| ")
"")
The my-timer-display
decides whether or not to show the timer. I think this might be the best place to get emacs to start forcing redisplays.
(defun my-timer-display ()
"Return the lowest timer, avoiding the --now-- time, in the chronos timers list"
(if (string= (chronos--message (nth 0 (chronos--sort-by-expiry))) chronos-now-message)
(my-print-timer 1)
(my-print-timer 0)))
The my-print-timer
function referenced just returns the xth timer in the chronos timers list. I won't include it as I don't think it's relevant to the question.
Any help or ideas would be much appreciated, thanks :)
mode-line timers
mode-line timers
edited 2 hours ago
asked 6 hours ago
jamesmaj
335
335
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I try not to use standard timers that repeat because they can affect performance while typing or scrolling. An idle-timer only fires once each time an idle occurs. Therefore, I would suggest setting up a system that runs an idle timer while Emacs has focus and a standard timer when Emacs loses focus. Since that is outside the scope of the question, I will leave that to the O.P. to investigate ...
To try out the following example, start with emacs -Q
, open two or more windows and evaluate the following two lines of code. E.g., place both lines of code in the *scratch*
buffer and type M-x eval-buffer
.
The extra set of parentheses used in the example as part of the mode-line-format
is not necessary for this example, but is helpful to remind us that we can include additional components of the mode-line (as elements of the list) if so desired.
Note that this example uses the optional argument for force-mode-line-update
to operate on all visible windows.
(setq-default mode-line-format '((:eval (format-time-string "%m/%d/%Y @ %1I:%M:%S %p"))))
(run-with-timer 0 1 #'(lambda () (force-mode-line-update t)))
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for themode-line-format
list.
– jamesmaj
3 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
add a comment |
Thanks to @lawlist for directing me to timer.el
. A solution I implemented uses timer.el
's run-at-time
.
I replaced the format-line-list
item with:
(if (>= (length chronos--timers-list) 2)
(progn
(cancel-function-timers 'force-mode-line-update)
(run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))
"")
This means that if a timer is running, I ask emacs to update the mode-line in another 0.5s. This sets a timer. To prevent timers building up if I trigger multiple mode-line refreshes within the 0.5s interval I delete any previous timers first (cancel-function-timers
).
I found that if I used a 1s interval, it would sometimes skip a second if I was typing in emacs. Reducing to 0.5s makes it act/feel smoother.
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
});
}
});
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%2f46846%2ftimer-on-modeline-how-to-update-modeline-every-second%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
I try not to use standard timers that repeat because they can affect performance while typing or scrolling. An idle-timer only fires once each time an idle occurs. Therefore, I would suggest setting up a system that runs an idle timer while Emacs has focus and a standard timer when Emacs loses focus. Since that is outside the scope of the question, I will leave that to the O.P. to investigate ...
To try out the following example, start with emacs -Q
, open two or more windows and evaluate the following two lines of code. E.g., place both lines of code in the *scratch*
buffer and type M-x eval-buffer
.
The extra set of parentheses used in the example as part of the mode-line-format
is not necessary for this example, but is helpful to remind us that we can include additional components of the mode-line (as elements of the list) if so desired.
Note that this example uses the optional argument for force-mode-line-update
to operate on all visible windows.
(setq-default mode-line-format '((:eval (format-time-string "%m/%d/%Y @ %1I:%M:%S %p"))))
(run-with-timer 0 1 #'(lambda () (force-mode-line-update t)))
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for themode-line-format
list.
– jamesmaj
3 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
add a comment |
I try not to use standard timers that repeat because they can affect performance while typing or scrolling. An idle-timer only fires once each time an idle occurs. Therefore, I would suggest setting up a system that runs an idle timer while Emacs has focus and a standard timer when Emacs loses focus. Since that is outside the scope of the question, I will leave that to the O.P. to investigate ...
To try out the following example, start with emacs -Q
, open two or more windows and evaluate the following two lines of code. E.g., place both lines of code in the *scratch*
buffer and type M-x eval-buffer
.
The extra set of parentheses used in the example as part of the mode-line-format
is not necessary for this example, but is helpful to remind us that we can include additional components of the mode-line (as elements of the list) if so desired.
Note that this example uses the optional argument for force-mode-line-update
to operate on all visible windows.
(setq-default mode-line-format '((:eval (format-time-string "%m/%d/%Y @ %1I:%M:%S %p"))))
(run-with-timer 0 1 #'(lambda () (force-mode-line-update t)))
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for themode-line-format
list.
– jamesmaj
3 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
add a comment |
I try not to use standard timers that repeat because they can affect performance while typing or scrolling. An idle-timer only fires once each time an idle occurs. Therefore, I would suggest setting up a system that runs an idle timer while Emacs has focus and a standard timer when Emacs loses focus. Since that is outside the scope of the question, I will leave that to the O.P. to investigate ...
To try out the following example, start with emacs -Q
, open two or more windows and evaluate the following two lines of code. E.g., place both lines of code in the *scratch*
buffer and type M-x eval-buffer
.
The extra set of parentheses used in the example as part of the mode-line-format
is not necessary for this example, but is helpful to remind us that we can include additional components of the mode-line (as elements of the list) if so desired.
Note that this example uses the optional argument for force-mode-line-update
to operate on all visible windows.
(setq-default mode-line-format '((:eval (format-time-string "%m/%d/%Y @ %1I:%M:%S %p"))))
(run-with-timer 0 1 #'(lambda () (force-mode-line-update t)))
I try not to use standard timers that repeat because they can affect performance while typing or scrolling. An idle-timer only fires once each time an idle occurs. Therefore, I would suggest setting up a system that runs an idle timer while Emacs has focus and a standard timer when Emacs loses focus. Since that is outside the scope of the question, I will leave that to the O.P. to investigate ...
To try out the following example, start with emacs -Q
, open two or more windows and evaluate the following two lines of code. E.g., place both lines of code in the *scratch*
buffer and type M-x eval-buffer
.
The extra set of parentheses used in the example as part of the mode-line-format
is not necessary for this example, but is helpful to remind us that we can include additional components of the mode-line (as elements of the list) if so desired.
Note that this example uses the optional argument for force-mode-line-update
to operate on all visible windows.
(setq-default mode-line-format '((:eval (format-time-string "%m/%d/%Y @ %1I:%M:%S %p"))))
(run-with-timer 0 1 #'(lambda () (force-mode-line-update t)))
answered 5 hours ago
lawlist
10.4k11062
10.4k11062
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for themode-line-format
list.
– jamesmaj
3 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
add a comment |
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for themode-line-format
list.
– jamesmaj
3 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for the
mode-line-format
list.– jamesmaj
3 hours ago
After learning about timer.el from this answer decided to implement a solution like so: ` (progn` ` (cancel-function-timers 'force-mode-line-update)` ` (run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))` ` (list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))` This fits in the true condition for the
mode-line-format
list.– jamesmaj
3 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
Unsure on stackoverflow ettiquite. Should I mark this as the answer, or should I create my own detailed answer and give credit to this answer?
– jamesmaj
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
I will not be saddened if you write-up your own alternative answer. If you think that the question title and/or body need to be clarified so that this thread helps future forum searches, then please feel free to do so.
– lawlist
2 hours ago
add a comment |
Thanks to @lawlist for directing me to timer.el
. A solution I implemented uses timer.el
's run-at-time
.
I replaced the format-line-list
item with:
(if (>= (length chronos--timers-list) 2)
(progn
(cancel-function-timers 'force-mode-line-update)
(run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))
"")
This means that if a timer is running, I ask emacs to update the mode-line in another 0.5s. This sets a timer. To prevent timers building up if I trigger multiple mode-line refreshes within the 0.5s interval I delete any previous timers first (cancel-function-timers
).
I found that if I used a 1s interval, it would sometimes skip a second if I was typing in emacs. Reducing to 0.5s makes it act/feel smoother.
add a comment |
Thanks to @lawlist for directing me to timer.el
. A solution I implemented uses timer.el
's run-at-time
.
I replaced the format-line-list
item with:
(if (>= (length chronos--timers-list) 2)
(progn
(cancel-function-timers 'force-mode-line-update)
(run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))
"")
This means that if a timer is running, I ask emacs to update the mode-line in another 0.5s. This sets a timer. To prevent timers building up if I trigger multiple mode-line refreshes within the 0.5s interval I delete any previous timers first (cancel-function-timers
).
I found that if I used a 1s interval, it would sometimes skip a second if I was typing in emacs. Reducing to 0.5s makes it act/feel smoother.
add a comment |
Thanks to @lawlist for directing me to timer.el
. A solution I implemented uses timer.el
's run-at-time
.
I replaced the format-line-list
item with:
(if (>= (length chronos--timers-list) 2)
(progn
(cancel-function-timers 'force-mode-line-update)
(run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))
"")
This means that if a timer is running, I ask emacs to update the mode-line in another 0.5s. This sets a timer. To prevent timers building up if I trigger multiple mode-line refreshes within the 0.5s interval I delete any previous timers first (cancel-function-timers
).
I found that if I used a 1s interval, it would sometimes skip a second if I was typing in emacs. Reducing to 0.5s makes it act/feel smoother.
Thanks to @lawlist for directing me to timer.el
. A solution I implemented uses timer.el
's run-at-time
.
I replaced the format-line-list
item with:
(if (>= (length chronos--timers-list) 2)
(progn
(cancel-function-timers 'force-mode-line-update)
(run-at-time 0.5 nil '(lambda () (force-mode-line-update t)))
(list " timer|" (propertize (my-timer-display) 'face 'my-red-face) "| "))
"")
This means that if a timer is running, I ask emacs to update the mode-line in another 0.5s. This sets a timer. To prevent timers building up if I trigger multiple mode-line refreshes within the 0.5s interval I delete any previous timers first (cancel-function-timers
).
I found that if I used a 1s interval, it would sometimes skip a second if I was typing in emacs. Reducing to 0.5s makes it act/feel smoother.
answered 2 hours ago
jamesmaj
335
335
add a comment |
add a comment |
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%2f46846%2ftimer-on-modeline-how-to-update-modeline-every-second%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