I use emacs' inferior shells, or just the shell frequently. Since I work mostly on ML algos my commands sometime take a long time. I would like to enable auto-timing of all commands run in emacs shells, so that I don't have to add extra/ugly glue code and I don't have to "pre-think" about timing a run. When I run a command its run time should automatically get logged (printing to a separate buffer would be best) so that if some parameters suddenly take a long time I can note its run-time later. All ideas are welcome, thanks.
3 Answers
One way to take care of this with a workaround is to set your shell prompt to display time, then each time you execute, you will have the previous time stamp and the new time stamp as soon as the job is finished. This will likely require you to press before runnign any command to get a new prompt and renew the dsiplayed time, but this is not a big problem when you want a quick imprecise timer once in a while.
To get a prompt like 15:01:54 MyPath/MyDir>
in bash, use
export PS1='\t \[\033[01;32m\]\w>\[\033[00m\] '
EDIT For windows, try
PROMPT $T $P$G
to get something like 17:07:34.60 C:\Programs\Console2>
-
would you know how I can change the shell prompt of shells in emacs? I mainly use the python shell and the normal shell (M-x shell) and I tried to use your command but it failed with error "The system cannot find the path specified." It might be because I am on windows. Mar 19, 2013 at 12:24
-
-
Thanks gt6989b. You fixed my shell :) If only there was a way to do this for emacs python shell as well. Anyway I am marking you correct. Mar 21, 2013 at 6:45
Inspired by gt's answer I found a way to do this in python. For python interpreter,
add following code to usercustomize.py
inside your site-packages
directory.
import time, sys
class ShowTime(object):
def __str__(self):
return time.strftime("%c", time.localtime())+" >>> "
sys.ps1=ShowTime()
This will add a prompt that looks like 03/21/13 13:10:42 >>>
EDIT
doing only the above would break useful features in python mode like send-region and send-buffer. Basically python mode expects that the prompt would match a particular regexp. (aside: it also means that there is no point in changing the lower, more basic, comint-mode.) Anyway, we change the variable python-shell-prompt-alist in python.el so that it matches the prompt that we have set, then delete python.elc and then restart.
Earlier:
(defcustom python-shell-prompt-alist
'(("ipython" . "^In \\[[0-9]+\\]: *")
(t . "^>>> "))
Now:
(defcustom python-shell-prompt-alist
'(("ipython" . "^In \\[[0-9]+\\]: *")
(t . "^[0-9][0-9]_[0-9][0-9]:[0-9][0-9]:[0-9][0-9]>>> "))
This will match a prompt of type time.strftime("%d_%H:%M:%S", time.localtime())+">>> "
I have a method that works for me under linux. It depends on the function time
. Maybe there is a similar function under windows.
This method is not good if you want to use a program inside the shell it does not work, lets say python
interactively. Just see this as an idea on how to implement it but it really isn't anything I recommend unless you only perform shell/cmd functions inside the *shell*-buffer.
Here it goes:
In your .emacs file add this.
(defun my-send (proc cmd)
(comint-simple-send proc (concat "time " cmd)))
(setq comint-input-sender 'my-send)
Whenever I run a command in it looks like this (this example: sleep for 1 second)
$ sleep 1
real 0m1.132s
user 0m0.000s
sys 0m0.000s
-
This question has really annoyed me. I just had to find a solution :)– McNisseMar 21, 2013 at 9:26
-
got this SO answer which can make it work on windows. Would your solution affect all repls in emacs like ruby, lisp etc? that would be cool Mar 21, 2013 at 14:24
-
I haven't tried it in other modes than shell-mode. When I think of it I believable it would ruin other interpreters because it inputs an other command before the one you want. This solution affects all that uses comint-mode. Think that you somehow need to reset
comint-input-sender
tocomint-simple-send
to make them work at all. I'll need to test it and update my answer.– McNisseMar 21, 2013 at 15:31 -
oh yeah, well thankfully i found a way to do it on python, bash and cmd and your answer can be tweaked with appropriate if else conditions. Though I think if we are handling it in emacs we should do it in the function that receives the output from the subprocess. then we could just call some sort of emacs native time function and prepend it. Would you know what function received the output? Mar 21, 2013 at 17:53
-
My first attempt was to use
comint-output-filter-functions
andcomint-input-filter-functions
to fix calculate the time but I failed.– McNisseMar 21, 2013 at 20:58