1

emacs-w3m really likes to have its buffers have names like *w3m*<16> or *w3m* so when switching buffers, it's impossible to tell just from the names which buffer is displaying which web page.

I've tried renaming the w3m buffers to their web page titles -- which you can get with (w3m-current-title) -- but ran in to problems when I realized that internally emacs-w3m uses the original buffer titles to both do tab ordering and tab movement, so changing those names (even when leaving in the original w3m buffer names as prefixes) at the very least destroyed my ability to move tabs, so I reverted back to the original names.

Today I realized that for the most part it doesn't matter to me what the buffers are called, as long as when I use ivy-switch-buffer it shows the results of running (w3m-current-title) in place of the corresponding w3m buffer name.

Is there an easy way to accomplish this?

In short, I'm looking for a way for ivy-switch-buffer to filter buffer names through a user-given function before displaying them.

2 Answers 2

3

The ivy way

In short, I'm looking for a way for ivy-switch-buffer to filter buffer names through a user-given function before displaying them.

ivy calls such filters "display transformers" and stores them in the property list ivy--display-transformers-list. The intention is that the user or package author call ivy-set-display-transformer:

ivy-set-display-transformer is a compiled Lisp function in ivy.el.

(ivy-set-display-transformer CMD TRANSFORMER)

Set CMD a displayed candidate TRANSFORMER.

It’s a lambda that takes a string one of the candidates in the collection and returns a string for display, the same candidate plus some extra information.

This lambda is called only on the ivy-height candidates that are about to be displayed, not on the whole collection.

In fact, ivy-switch-buffer comes with a predefined display transformer, namely ivy-switch-buffer-transformer. You could copy / extend / advise / replace this function to achieve your purpose.

The w3m way

Having said all that, I believe w3m can already be configured to do what you want, via the user option w3m-use-title-buffer-name:

w3m-use-title-buffer-name is a variable defined in w3m.el.

Its value is t

Original value was nil

Documentation: Non-nil means use name of buffer included current title.

In other words, enabling this option results in all w3m buffers including the current page's title in their name.

2

The question asked for a solution specific to ivy, but it should be pointed out that emacs-w3m has its own superior solution, w3m-select-buffer. When one's focus / point is in an emacs-w3m buffer, one can use the function using its default keybinding C-c C-s, but one can also use it from any emacs buffer by evaluating it explicitly, eg. M-x w3m-select-buffer.

When a user runs that command, emacs-w3m pops-up a temporary buffer listing the titles of all emacs-w3m buffers, along with each's buffer number and an indication of whether the buffer has been "read", ie. displayed. Within that pop-up buffer, one can use the normal emacs search functions (eg. C-s, C-r) to select any particular buffer.

3
  • In the most recent version of w3m on MELPA of 2017-12-21, the command w3m-select-buffer is bound to C-c C-s, not M-t. It would be nice to point to C-h f w3m-select-buffer-mode RET for a listing of further actions provided in the selection buffer. Either way, +1 for pointing out this handy command.
    – Basil
    Commented Jan 10, 2018 at 17:17
  • Just noticed there's an even better command (w.r.t. ivy completion): C-c C-a (w3m-switch-buffer).
    – Basil
    Commented Jan 10, 2018 at 17:27
  • @Basil: Thanks for the correction, applied. Also, I corrected myself in that the command is available from any emacs buffer, not just emacs-w3m ones. The only difference is the lack of a default keybinding. Commented Jan 11, 2018 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.