Yes, one can get as far as
$ emacs -Q
C-x C-b C-h k C-x C-b C-x o <tab> <tab> <return> C-x 1
However the following requires a jump in logic, as the user cannot know it.
mr> Customizing the group `buffer-menu' gives you a buffer including the
mr> option `Buffer-menu-buffer+size-width' which is probably the one you
mr> want to tweak here.
maybe there should be "you can customize this group" visible to the user so
he can learn that.
(By the way, I prefer to use setq and hate using the customization
interface.)
OK, now reading about the variable you told me about,
Buffer-menu-buffer+size-width is a variable defined in `buff-menu.el'.
Its value is 26
Documentation:
How wide to jointly make the buffer name and size columns.
But I want to use the same .emacs file with many different terminal
sizes. Why can't there be a setting 'maximum or 'current-window-width or
something?
Hmmm, it shows the name if it is long. If it is not long, one instead
sees mouse instructions.
Some users encountering one might never guess the other would be shown
if over the other... Hmmm.
Why complicate things so much? If users knowing about this option is truly a
problem, then just mention the option in `C-h m'.
It also wouldn't be a bad idea, IMO, to change the default binding of `C-x C-b'
from `list-buffers' to `buffer-menu'. (I do that in my .emacs.)
> > Buffer-menu-buffer+size-width is a variable defined in
> > `buff-menu.el'. Its value is 26
> >
> > Documentation:
> > How wide to jointly make the buffer name and size columns.
> >
> > But I want to use the same .emacs file with many different terminal
> > sizes. Why can't there be a setting 'maximum or
> > 'current-window-width or something?
FWIW, the code from buff-menu+.el could be integrated. It lets you change the
value of option `Buffer-menu-buffer+size-width' incrementally, on the fly, using
keys `+' and `-'. When limited window space makes it impossible to see
everything, you control how much of which fields you see.
They always have produced the same display, since Day 1. Only the features (e.g.
keys/actions) are different. Personally, I have always set `C-x C-b' to
buffer-menu.
The main point here is to just mention the option in the mode help, rather than
introduce Customize buttons and other silliness into the buffer menu.
> A> FWIW, the code from buff-menu+.el could be integrated.
>
> Too many 'other leading brands' of C-x C-b... good thing I'm using the
> official supported version, else you guys would never know
> there was bugs:-)
This isn't a bug. Your report is an enhancement request.
My point was that the vanilla code could do what buff-menu+ does in this regard.
It is a hell of a lot easier to hit `+' to change the value of an option than it
is to use Customize or `set-variable'. It lets you adjust the display on the fly
to compensate for differing buffer names.
A> FWIW, the code from buff-menu+.el could be integrated.
That's what I had in mind - some construct which has the Help system add
a link to the custom group automatically (just like customization links
for options).
> Maybe this is not very reliable for the case when a package has more
> than one group.
Many packages have a root group which should be sufficient for this
purpose.
> Then a solution would be to not deduce information,
> but to add more reliable links: from every command add a link to the
> information about the package it belongs to, and on the page with the
> package information list all groups with customizable variables.
I'm afraid this might be confusing. But for a a minor mode like
`show-paren-mode' a clickable link from the command to its major
customization group (whose name is not easily deducible in this
particular case) should be mandatory.
> I propose to add the same options to `Buffer-menu-buffer+size-width' as
> `Man-width' currently has. It fits the output width to the window width,
> and `list-buffers' could do the same.
Does `Man-width' trigger a refit when the window gets resized?
> Displaying the buffer list in a table would be an ideal solution.
That would require substantial work.
> I think it's better to implement that by allowing dragging a handle
> in the header line, and redrawing the buffer accordingly.
Agreed. We should also give the header line items the standard button
appearance so it's easy to see (1) which sorting method is currently
selected, (2) where and what I have to click, and (3) the position of
the handle for dragging.
martin
A pushable button similar to the one you can find for customizable
options. That would be reasonable I think. Juri, what do you think?
> (By the way, I prefer to use setq and hate using the customization
> interface.)
It's one of the basic problems of the customization interface that many
people hate it and so we don't get many suggestions how to improve it.
> Buffer-menu-buffer+size-width is a variable defined in `buff-menu.el'.
> Its value is 26
>
> Documentation:
> How wide to jointly make the buffer name and size columns.
>
> But I want to use the same .emacs file with many different terminal
> sizes. Why can't there be a setting 'maximum or 'current-window-width or
> something?
'maximum should be possible without greater problems.
'current-window-width is a wishlist item: We could reserve float values
between 0 and 1 for specifying an appropriate fraction of the window
width for the width of name+size fields. The program would have to
recalculate the new actual width (in `window-configuration-change-hook')
every time the size of the Buffer Menu window changes.
We could also show the full name of the current entry in a tooltip (when
the mouse is over it) and/or in the echo area.
And finally we could split a window like the Buffer Menu's one into as
many subwindows as there are fields and allow the use to drag vertical
dividers between the various fields in order to reveal hidden
information. Currently such an approach would work iff all fields used
the same font size.
martin
Here is one for those who prefer editing custom-file or .emacs instead:
We can teach `lisp-complete-symbol' how to behave inside a
(custom-set-variables ...)
form. Would that be terribly difficult?
I think that instead of manually adding a button, we should improve
the Help system to automatically deduce additional useful information.
For example, `list-buffers' is a command from the package `buff-menu'
that contains the group `Buffer-menu', so we could automatically
add information about this to the help output of `list-buffers'.
Maybe this is not very reliable for the case when a package has more
than one group. Then a solution would be to not deduce information,
but to add more reliable links: from every command add a link to the
information about the package it belongs to, and on the page with the
package information list all groups with customizable variables.
>> But I want to use the same .emacs file with many different terminal
>> sizes. Why can't there be a setting 'maximum or 'current-window-width or
>> something?
>
> 'maximum should be possible without greater problems.
>
> 'current-window-width is a wishlist item: We could reserve float values
> between 0 and 1 for specifying an appropriate fraction of the window
> width for the width of name+size fields. The program would have to
> recalculate the new actual width (in `window-configuration-change-hook')
> every time the size of the Buffer Menu window changes.
I propose to add the same options to `Buffer-menu-buffer+size-width' as
`Man-width' currently has. It fits the output width to the window width,
and `list-buffers' could do the same.
> We could also show the full name of the current entry in a tooltip (when
> the mouse is over it) and/or in the echo area.
This is already implemented. There is a tooltip for long names.
> And finally we could split a window like the Buffer Menu's one into as
> many subwindows as there are fields and allow the use to drag vertical
> dividers between the various fields in order to reveal hidden
> information. Currently such an approach would work iff all fields used
> the same font size.
Displaying the buffer list in a table would be an ideal solution.
I think it's better to implement that by allowing dragging a handle
in the header line, and redrawing the buffer accordingly.
--
Juri Linkov
http://www.jurta.org/emacs/
Dunno what your "standard button appearance" means here, but see the code in
buff-menu+.el. Users can see not only which column is the sort column, but what
the sorting direction (ascending/descending) is. A simple underline/overline is
used in the column header to indicate the direction.
Wrt resizing by dragging a column divider: there's nothing wrong with that idea.
However, IMO:
1. Key bindings (e.g. +/-) should also be provided.
2. It is a good idea for such resizing to update the value of option
`Buffer-menu-buffer+size-width'.
3. Besides resizing column widths, it should be easy to remove given columns
from the display. (In buff-menu+, there are toggle commands for this.)
buff-menu+.el is essentially a patch to buff-menu.el. Consequently, any of its
features should be trivial to integrate.
They are the same except where they display the buffer:
in the same window or in another window.
I blur their distinctions with:
(add-to-list 'same-window-buffer-names "*Buffer List*")
Do you think it should? Maybe. So when a window is split horizontally,
it would refit. But this requires re-running the man command with the
new value of the environment variable COLUMNS.
>> I think it's better to implement that by allowing dragging a handle
>> in the header line, and redrawing the buffer accordingly.
>
> Agreed. We should also give the header line items the standard button
> appearance so it's easy to see (1) which sorting method is currently
> selected, (2) where and what I have to click, and (3) the position of
> the handle for dragging.
I think that ruler-mode has a good UI where it's easy to see
the position of the handle for dragging.
--
Juri Linkov
http://www.jurta.org/emacs/
It probably should refit at least when run in a standalone frame and the
user maximizes the frame or sizes it back to normal.
> I think that ruler-mode has a good UI where it's easy to see
> the position of the handle for dragging.
The header line of ruler-mode looks good indeed. Remains the question
whether we want a generic interface, so `list-processes' can use it as
well, and maybe also `dired', the various message modes, file managers,
table headers ...
martin
I see there is more serious problem. With `emacs -Q' in a wide frame,
`M-x man' displays the truncated page, because the default value of
`Man-notify-method' is "friendly" (this is a subjective name and I think
actually this option is not friendly at all!), and `man' runs the
formatting command with the value of `COLUMNS' equal to the frame's width,
but later `man' splits the frame horizontally and displays in a half-width
window the manual formatted to the full frame width. Perhaps `man' should
be able to predict the window's width for `COLUMNS' before running the
formatting command. Do you know a function in window.el that would
predict the width that the current window will have after splitting
horizontally?
>> I think that ruler-mode has a good UI where it's easy to see
>> the position of the handle for dragging.
>
> The header line of ruler-mode looks good indeed. Remains the question
> whether we want a generic interface, so `list-processes' can use it as
> well, and maybe also `dired', the various message modes, file managers,
> table headers ...
A generic interface would be a big plus.
Conceptually `split-window-horizontally' when called with a non-nil SIZE
argument should either (1) produce two windows such that either the old
or the new one has this many columns, or (2) fail to split the window.
So all you have to do is to divide the current width of the window by 2
and eventually call `split-window-horizontally' with first argument (or
`split-window' with second argument) assigned the negative of the value
you calculated here. Meanwhile you can use that precalculated value as
argument for the formatting process.
Does the weird behavior of `man' result from the fact that it doesn't
know what to display in the new window until formatting completes?
martin
Yes, and the only reasonable way to fix this weirdness is to do what
other similar Emacs commands do (e.g. `compile' and `grep'): first display
the output buffer, and later when the formatted output is ready, put it
to this buffer. Just imagine how unfriendly it would be if `compile'/`grep'
worked like `man' currently works by waiting while the shell command is
finished, and then suddenly popping up the output buffer!
I've been using a local hack which causes the *man...* buffers to be
displayed early rather than late. The main reason was to avoid
interrupting me with a new frame at some random time in the future.
So I'd welcome such a change. My local hack isn't installable as is:
the output shown temporarily in the buffer is rather ugly (because the
buffer first gets an unprocessed output and then cleans it up and adds
faces. Usually the intermediate ugly states are not shown, but after my
change, they are).
Stefan
Using a separate buffer for the process output (a hidden buffer with
a leading space in its name) where `man' collects and formats the output
and later copies to the displayed main buffer is implemented in the
following patch.
One remaining problem: when `man' can't find a manpage, it signals
the error "Can't find the manpage". But what to do with the displayed
empty window that waits for the formatted output? Maybe to undo
the window configuration to its original state? And what to do
with the created frame? To leave it displaying an empty buffer?
=== modified file 'lisp/man.el'
--- lisp/man.el 2010-01-09 23:53:06 +0000
+++ lisp/man.el 2010-01-11 00:47:07 +0000
@@ -880,13 +880,25 @@
"Use TOPIC to build and fire off the manpage and cleaning command."
(let* ((man-args topic)
(bufname (concat "*Man " man-args "*"))
- (buffer (get-buffer bufname)))
+ (buffer (get-buffer bufname))
+ (procbufname (concat " " bufname))
+ procbuffer)
(if buffer
(Man-notify-when-ready buffer)
(require 'env)
(message "Invoking %s %s in the background" manual-program man-args)
(setq buffer (generate-new-buffer bufname))
+ (setq procbuffer (generate-new-buffer procbufname))
+ ;; Display empty output buffer.
+ (unless (memq Man-notify-method '(polite quiet meek))
+ (Man-notify-when-ready buffer))
(with-current-buffer buffer
+ (insert (format "Invoking %s %s in the background\n"
+ manual-program man-args))
+ (setq buffer-undo-list t)
+ (setq Man-original-frame (selected-frame))
+ (setq Man-arguments man-args))
+ (with-current-buffer procbuffer
(setq buffer-undo-list t)
(setq Man-original-frame (selected-frame))
(setq Man-arguments man-args))
@@ -927,8 +939,14 @@
(cond
((and (integerp Man-width) (> Man-width 0))
Man-width)
- (Man-width (frame-width))
- ((window-width))))))
+ (Man-width
+ (with-selected-window (get-buffer-window
+ buffer t)
+ (frame-width)))
+ (t
+ (with-selected-window (get-buffer-window
+ buffer t)
+ (window-width)))))))
(setenv "GROFF_NO_SGR" "1")
;; Since man-db 2.4.3-1, man writes plain text with no escape
;; sequences when stdout is not a tty. In 2.5.0, the following
@@ -936,7 +954,7 @@
(setenv "MAN_KEEP_FORMATTING" "1")
(if (fboundp 'start-process)
(set-process-sentinel
- (start-process manual-program buffer
+ (start-process manual-program procbuffer
(if (memq system-type '(cygwin windows-nt))
shell-file-name
"sh")
@@ -944,7 +962,7 @@
(format (Man-build-man-command) man-args))
'Man-bgproc-sentinel)
(let ((exit-status
- (call-process shell-file-name nil (list buffer nil) nil
+ (call-process shell-file-name nil (list procbuffer nil) nil
shell-command-switch
(format (Man-build-man-command) man-args)))
(msg ""))
@@ -955,7 +973,7 @@
(format "exited abnormally with code %d"
exit-status)))
(setq msg exit-status))
- (Man-bgproc-sentinel bufname msg)))))))
+ (Man-bgproc-sentinel procbufname msg)))))))
(defun Man-notify-when-ready (man-buffer)
"Notify the user when MAN-BUFFER is ready.
@@ -1179,16 +1197,18 @@
synchronously, PROCESS is the name of the buffer where the manpage
command is run. Second argument MSG is the exit message of the
manpage command."
- (let ((Man-buffer (if (stringp process) (get-buffer process)
- (process-buffer process)))
- (delete-buff nil)
- (err-mess nil))
+ (let* ((Man-procbuffer (if (stringp process) (get-buffer process)
+ (process-buffer process)))
+ (Man-buffer (get-buffer (replace-regexp-in-string
+ "\\` " "" (buffer-name Man-procbuffer))))
+ (delete-buff nil)
+ (err-mess nil))
(if (null (buffer-name Man-buffer)) ;; deleted buffer
(or (stringp process)
(set-process-buffer process nil))
- (with-current-buffer Man-buffer
+ (with-current-buffer Man-procbuffer
(let ((case-fold-search nil))
(goto-char (point-min))
(cond ((or (looking-at "No \\(manual \\)*entry for")
@@ -1224,11 +1244,18 @@
(insert (format "\nprocess %s" msg))))
))
(if delete-buff
+ ;; FIXME: also undo window configuration?
(kill-buffer Man-buffer)
(if Man-fontify-manpage-flag
(Man-fontify-manpage)
(Man-cleanup-manpage))
+ (copy-to-buffer Man-buffer (point-min) (point-max)))))
+
+ (kill-buffer Man-procbuffer)
+
+ (unless delete-buff
+ (with-current-buffer Man-buffer
(run-hooks 'Man-cooked-hook)
(Man-mode)
@@ -1243,11 +1270,12 @@
;; Man-notify-when-ready because it may switch buffers.
(if (not delete-buff)
- (Man-notify-when-ready Man-buffer))
+ (when (memq Man-notify-method '(polite quiet meek))
+ (Man-notify-when-ready Man-buffer)))
(if err-mess
(error "%s" err-mess))
- ))))
+ )))
;; ======================================================================
Hmm... that's not the solution I was looking for, but I guess yours is
a lot simpler, indeed. So it's probably good, while we keep waiting for
someone to implement the formatting on the fly from the process-fiter.
> One remaining problem: when `man' can't find a manpage, it signals
> the error "Can't find the manpage". But what to do with the displayed
> empty window that waits for the formatted output?
Good question. If the buffer is new, it could/should be deleted, and
similarly for the window.
> Maybe to undo the window configuration to its original state?
window-configurations are never a good answer to those problems.
Stefan
Conceptually, that would be just as disturbing as popping up a window
after formatting completes. The user might have already altered the
window configuration in some other respect since formatting started.
> And what to do
> with the created frame? To leave it displaying an empty buffer?
The window (which probably should be dedicated initially to avoid that
some other action steals it before formatting is complete) could first
display some text about the formatting process in progress and a more
detailed text when formatting fails telling the user what the potential
reasons of the failure were and how to get rid of the window or frame
(and implicitly the temporary buffer).
But maybe this part should be written separately so that other packages
waiting for the completion of asynchronous processes could use it too.
martin
My patch already inserts a line "Invoking manual-program man-args
in the background" in the displayed buffer until formatting is complete.
> and a more detailed text when formatting fails telling the user what
> the potential reasons of the failure were and how to get rid of the
> window or frame (and implicitly the temporary buffer).
I think you are right. Exactly like e.g. `grep' displays the output
*grep* buffer with the text "Grep finished with no matches found",
so when `man' can't find a manpage, it should display a similar
error message in the man output buffer.
It seems the bzr vc backend needs the same treatment.
When `vc-diff' reports that there are no differences, then vc
displays the *vc-diff* buffer with a single line in it:
No changes between working revision and workfile.
bzr's behavior differs from the git backend that doesn't display the
*vc-diff* buffer. It displays this line only in the echo area.
I understand that there is such a difference between bzr and git
vc backends because bzr is slower than git and so needs man.el-like
behavior that waits for the completion of the asynchronous process.
> > But maybe this part should be written separately so that other packages
> > waiting for the completion of asynchronous processes could use it too.
>
> It seems the bzr vc backend needs the same treatment.
>
> When `vc-diff' reports that there are no differences, then vc
> displays the *vc-diff* buffer with a single line in it:
>
> No changes between working revision and workfile.
>
This is due to this code in vc.el:vc-diff-internal
(if (and (zerop (buffer-size))
(not (get-buffer-process (current-buffer))))
;; Treat this case specially so as not to pop the buffer.
(progn
(message "%s" (cdr messages))
nil)
> bzr's behavior differs from the git backend that doesn't display the
> *vc-diff* buffer. It displays this line only in the echo area.
vc-git-diff does not call the diff command asynchronously (probably
because nobody had a problem with it being synchronous), but vc-bzr-diff
is asynchronous.
I see that the difference is at `(get-buffer-process (current-buffer))'.
When the process is slow, it is still running at the time when execution
arrives to this condition.
> > bzr's behavior differs from the git backend that doesn't display the
> > *vc-diff* buffer. It displays this line only in the echo area.
>
> vc-git-diff does not call the diff command asynchronously (probably
> because nobody had a problem with it being synchronous), but vc-bzr-diff
> is asynchronous.
I too see no problem with git being synchronous.
Maybe a new window parameter `quit-restore-window' could take care
about deleting the created window/frame when the man's formatting fails.