4

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 3

0

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>

3
  • 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.
    – Pushpendre
    Mar 19, 2013 at 12:24
  • @pushpen I edited the Windows option into the answer.
    – gt6989b
    Mar 19, 2013 at 21:09
  • 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.
    – Pushpendre
    Mar 21, 2013 at 6:45
1

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())+">>> "

0

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
5
  • This question has really annoyed me. I just had to find a solution :)
    – McNisse
    Mar 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
    – Pushpendre
    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 to comint-simple-sendto make them work at all. I'll need to test it and update my answer.
    – McNisse
    Mar 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?
    – Pushpendre
    Mar 21, 2013 at 17:53
  • My first attempt was to use comint-output-filter-functions and comint-input-filter-functions to fix calculate the time but I failed.
    – McNisse
    Mar 21, 2013 at 20:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .