Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Distinguishing between interactive and asynchronous shell buffers

5 views
Skip to first unread message

Sean McAfee

unread,
Feb 20, 2011, 7:02:39 PM2/20/11
to
I find that dired is a much better way of navigating around a large
directory hierarchy than staying in my shell buffer and issuing lots of
cd/ls commands. To bring my shell buffer to a directory I've located
with dired, I wrote an interactive command
bring-last-shell-buffer-to-this-directory (aliased to "c'mere") which
locates the most-recently-used shell buffer like this:

(let ((buffer (or (loop for buffer being the buffers
if (with-current-buffer buffer
(eq major-mode 'shell-mode))
return buffer)
(error "No shell buffers!"))))
;; Issue a "cd" command in buffer that sends that shell
;; to the starting buffer's default-directory

This works great most of the time, but once I started an asynchronous
shell command after moving around in dired, and when I did M-x c'mere,
my routine tried to send a cd to the *Async Shell Command* buffer.

What's the best way to distinguish asynchronous shell command buffers
from interactive shell buffers?

Barry Margolin

unread,
Feb 20, 2011, 9:43:45 PM2/20/11
to
In article <m2y65aj...@gmail.com>, Sean McAfee <eef...@gmail.com>
wrote:

Why not just look for the buffer named "*shell*"?

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***

Sean McAfee

unread,
Feb 21, 2011, 7:24:01 PM2/21/11
to
Barry Margolin <bar...@alum.mit.edu> writes:
> In article <m2y65aj...@gmail.com>, Sean McAfee <eef...@gmail.com>
> wrote:
>> What's the best way to distinguish asynchronous shell command buffers
>> from interactive shell buffers?

> Why not just look for the buffer named "*shell*"?

Because I often have multiple shell buffers open--none of which are
necessarily named "*shell*"--and I only want to target the
most-recently-accessed one.

Perry Smith

unread,
Feb 21, 2011, 7:50:39 PM2/21/11
to GNU Emacs List

mode-name ?

It would be "Shell" for things started with "shell" and "Fundamental" for things done with shell-command

Sean McAfee

unread,
Feb 22, 2011, 1:48:37 PM2/22/11
to
Perry Smith <ped...@gmail.com> writes:
>>> In article <m2y65aj...@gmail.com>, Sean McAfee <eef...@gmail.com>
>>> wrote:
>>>> What's the best way to distinguish asynchronous shell command buffers
>>>> from interactive shell buffers?

> mode-name ?


>
> It would be "Shell" for things started with "shell" and "Fundamental" for things done with shell-command

I hadn't known of that variable, but a quick test shows that its value
is also "Shell" in the buffer *Async Shell Command* after a
shell-command of "ls &".

Perry Smith

unread,
Feb 22, 2011, 2:59:41 PM2/22/11
to GNU Emacs List
Hmm... your are right:

If COMMAND ends in ampersand, execute it asynchronously.
The output appears in the buffer `*Async Shell Command*'.
That buffer is in shell mode.

bummer.

So, my (oh dear, I just walked into an awful pun) advice at this point
is to look at "advice" in the lisp manual.  I've never used it but
it seems to allow you to wrap a function with some extra code.  In
that code, maybe set a buffer local variable that you could later test.

The other alternatives would be not to use & for shell-commands or look
at mode-name first.  If it is shell then look at the buffers name and
if it isn't "Async ... whatever", then its an interactive shell buffer.

Sorry to be so vague.
pedz

Sean McAfee

unread,
Feb 22, 2011, 4:18:25 PM2/22/11
to
Following myself up...

Sean McAfee <eef...@gmail.com> writes:
> What's the best way to distinguish asynchronous shell command buffers
> from interactive shell buffers?

Digging into simple.el, the only difference I could find between
asynchronous and interactive shell buffers is that the former have
process sentinels associated with them when they're running; after they
finish, they of course have no process at all. That led me to write:

(defun is-interactive-shell-buffer (buffer)
(and (with-current-buffer buffer
(eq major-mode 'shell-mode))
(let ((proc (get-buffer-process buffer)))
(and proc (not (process-sentinel proc))))))

I guess this solution could fail if an interactive shell buffer ever had
a process sentinel for some reason, but it seems OK for now.

Stefan Monnier

unread,
Feb 23, 2011, 11:03:57 AM2/23/11
to
> Digging into simple.el, the only difference I could find between
> asynchronous and interactive shell buffers is that the former have
> process sentinels associated with them when they're running; after they
> finish, they of course have no process at all. That led me to write:

Indeed, there are very few differences between them. Another way to
distinguish them is to look at the buffer's history: if you never type
in async-shell-command buffers, then the input history should be empty
in those buffers. E.g. maybe checking (eq (point-min)
comint-last-input-start) will do the trick.
Another way is to check (string-match "Async" (buffer-name)).


Stefan

Deniz Dogan

unread,
Feb 23, 2011, 1:28:03 PM2/23/11
to Stefan Monnier, help-gn...@gnu.org
2011/2/23 Stefan Monnier <mon...@iro.umontreal.ca>:

Aren't those methods a bit tacky? I feel like there should be a
better way.

I barely know anything about comint/shell-mode but how about a
buffer-local variable which indicates whether or not the process is
running asynchronously?

0 new messages