restart process executed in eshell in emacs - emacs

i have started a python process in eshell:
python app.py
i want to restart this with a elisp function, i think comint-quit-subjob when executed with C-c C-\ kills the process but all my attempts to execute comint-quit-subjob have failed
This is what i have so far:
(defun restart-app()
(with-current-buffer "*eshell*"
(interactive)
(comint-quit-subjob)
(eshell-return-to-prompt)
(insert "python app.py")
(eshell-send-input))
)
Hopefully it gives the jist of what i am trying, but it fails. Any ideas?

I would suggest looking for a eshell-ish way of killing a process (I am not a eshell user myself). Comint tries to search something in the buffer. You can workaround that doing something like this (but it is brittle and unelegant):
(defun restart-app()
(with-current-buffer "*eshell*"
(interactive)
(kill-process nil comint-ptyp)
(run-with-timer 0.5 nil
(lambda ()
(with-current-buffer "*eshell*"
(goto-char (point-max))
(insert "python app.py")
(eshell-send-input)))))

Related

Kill Emacs's Async Shell Command buffer if command is terminated

Emacs does not kill the *Async Shell Command* buffer if the async command terminates. How can I force this behavior?
What you are looking for is Process Sentinels.
The sentinel for *Async Shell Command* is shell-command-sentinel.
You can advise it:
(defun my-kill-buffer-when-done (process signal)
(when (and (process-buffer process)
(memq (process-status process) '(exit signal)))
(kill-buffer (process-buffer process))))
(defun my-kill-async-buffer-when-done ()
(let ((process (get-buffer-process "*Async Shell Command*")))
(add-function :after (process-sentinel process) #'kill-buffer-when-done)))
(add-function :after #'async-shell-command #'my-kill-async-buffer-when-done)
PS. I did not test the above code, mostly because I think it is a horrible idea: you want to examine the content of *Async Shell Command* before killing it.
However, I hope reading the code and links above will help you become a more proficient Emacs user.

Launching shell command in Eshell without prompt interfence

I'm trying to customize my eshell to intercept python to do two things:
Open a new window and run python if no arguments are given (e.g., $ python)
Run the command "per usual" if arguments are given (e.g., $ python foobar.py)
So far I have something like this
(defun eshell/python (&rest cmd-args)
(if (not cmd-args)
(progn (run-python "python")
(select-window (split-window-below))
(switch-to-buffer "*Python*")
(balance-windows)
nil)
(message "Use '*python' to call python directly")))
I've tried replacing (message ...) with a few different things:
Based on the ouput of eshell-parse-command "python test.py" I tried
(progn (eshell-trap-errors
(eshell-named-command "python" cmd-args)))
but it hits a recursion limit.
Since *python test.py does what I want, I then tried
(progn (eshell-trap-errors
(eshell-named-command (concat "*" "python") cmd-args)))
but that puts the python process in the background and interrupts stdout with the output of my eshell-prompt-function.
Finally, I've fiddled with shell-command but I can't get it to write to the eshell buffer. In particular,
(progn (eshell-trap-errors
(shell-command (mapconcat (lambda(x) x) cmd-args " ")
(get-buffer "*eshell*") (get-buffer "*eshell*"))))
gives me a Text is read only message and moves point to start of the eshell buffer.
Is what I'm looking for possible?
Edit 1
Running without eshell/python defined, I've instead tried to avoid alias problems:
(defun eshell/gvr (&rest cmd-args)
(if (not cmd-args)
(progn (run-python "python")
(select-window (split-window-below))
(switch-to-buffer "*Python*")
(balance-windows)
nil)
(progn (eshell-trap-errors
(eshell-named-command "python" cmd-args)))))
If test.py is
print "Hello World"
x = raw_input("What should I repeat? ")
print x
running gvr test.py in eshell fails when I reply to the prompt because eshell tries to execute the input instead of handing it to python, but running python test.py goes off without a hitch.
How can I get run my own subprocesses in eshell the same way that they happen by default?

Why is my term-mode-hook not selecting line mode?

I wrote this elisp function:
(defun run (command)
"Open a terminal running a command."
(interactive "sCommand: ")
(if (buffer-exists (concat "*" command "*" )) (kill-buffer (concat "*" command "*")))
(let ((term-mode-hook (cons (lambda () (term-line-mode)) term-mode-hook)))
(ansi-term (cons "sh" (cons "-i" (list "-c" command))) command)))
This works nicely except that the new ansi-term buffers remains in char mode (which is the default), so as far as I can tell the term-line-mode call is not doing anything. If I replace (term-line-mode) with (message "foo") I do see the message in the messages buffer.
The definition of term-line-mode in lisp/term.el is:
(defun term-line-mode ()
"Switch to line (\"cooked\") sub-mode of term mode.
This means that Emacs editing commands work as normally, until
you type \\[term-send-input] which sends the current line to the inferior."
(interactive)
(when (term-in-char-mode)
(use-local-map term-old-mode-map)
(term-update-mode-line)))
What am I doing wrong?
I wasn't able to get "term-line-mode" to work as you want in any of the term hooks; however, it does work if you advise the "ansi-term" function:
(defadvice ansi-term (after advice-term-line-mode activate)
(term-line-mode))

How to (automatically) remove or prevent popping up *Async Shell Command* in emacs?

As is asked in here. I could run vi or mate within emacs.
The problem is that after running (async-shell-command "vi"), I always have the *Async Shell Command" popped up as a window.
Can I prevent popping up this windows? Or, can I modify the emacs code to remove the window as soon as it pops up?
(defun runvi ()
(interactive)
(let (filename (file-truename buffer-file-name))
(setq cmd (format "/Users/smcho/bin/mvim %s" (file-truename buffer-file-name)))
(async-shell-command cmd)))
This will work (assuming cmd is bound to the command you want, like you have above):
(save-window-excursion
(async-shell-command cmd))

emacs sqlplus disconnected

I started using sqlplus for emacs. It works fine except one thing - very often I get a message "Buffer ... is not talking to anybody". In a file sqlplus.el there is the following code which verifies (get-buffer-process process-buffer-name). How can I keep alive the sql process?
(defun sqlplus-verify-buffer (connect-string)
(let ((output-buffer-name (sqlplus-get-output-buffer-name connect-string))
(process-buffer-name (sqlplus-get-process-buffer-name connect-string)))
(when (not (get-buffer process-buffer-name))
(sqlplus-shutdown connect-string)
(error "No SQL*Plus session! Use 'M-x sqlplus' to start the SQL*Plus interpreter"))
(unless (get-buffer-process process-buffer-name)
(sqlplus-shutdown connect-string)
(error "Buffer '%s' is not talking to anybody!" output-buffer-name)))
t)
One possible solution is the following
(defadvice sqlplus-verify-buffer (before sqlplus-verify-buffer-and-reconnect activate)
(unless (get-buffer-process (sqlplus-get-process-buffer-name connect-string))
(sqlplus connect-string)))