0

Is there a way to select a buffer by part of its name using elisp?

For instance, the ag package may create a buffer called

*ag search text:MyPtyhonClass dir:c:/projects/my_module/*

or the realgud package may create a buffer called

*ipdb my_program.py shell*

My usual approach is to select a buffer by name with switch-to-buffer-other-window. Here is how I might do it for a buffer called *Occur*:

(switch-to-buffer-other-window "*Occur*")

When I try the same pattern using only part of a buffer name, such as ag search text: or ipdb, a new buffer called ag search text: or ipdb is created rather than selecting the buffer whose name contains that substring. That is, supposing there exists a buffer called *ag search text:MyPtyhonClass dir:c:/projects/my_module/*, calling

(switch-to-buffer-other-window "*ag search text:")

creates a new buffer called *ag search text:.

  • 1
    Please consider explaining what you mean by your "For instance". Should readers need to go read about ag or ipbb to understand what you're saying? – Drew Feb 5 at 15:00
  • 1
    It's not clear (to me at least) why you can't just choose the buffer based on part of its name. Is there no part of the name that you know and that is specific/unique? Or are you thinking that choosing needs to be based on a unique prefix? – Drew Feb 5 at 15:01
  • 1
    Do you mean how to do that from a program? You can always use completion when switching to a buffer interactively. But if you want to do it from a program, it's probably better to use the full name: it's too unpredictable to do anything else, particularly if you are doing something destructive with the result. – NickD Feb 5 at 16:25
  • 1
    @NickD, I mean using elisp. Thank you for asking for clarification. I would use the fullname, however, that changes depending on the context. – Lorem Ipsum Feb 5 at 16:33
  • You can use completion functions non-interactively, to get a set of pattern matches. See the functions described in Elisp manual node Basic Completion, such as all-completions. – Drew Feb 5 at 19:46
1

One can easily define a new command that displays a buffer with a given substring in its name.

There are some conceptional things to consider:

  • It may be that none of the living buffers has the substring in its name. The example code bails out in that case.
  • There may be multiple buffers with that substring in their name. The example code selects one of those where the substring is found at the lowest index in the name.
(defun switch-to-existing-buffer-other-window (part)
  "Switch to buffer with PART in its name."
  (interactive
   (list (read-buffer-to-switch "Switch to buffer in other window: ")))
  (let ((candidates
     (cl-remove
      nil
      (mapcar (lambda (buf)
            (let ((pos (string-match part (buffer-name buf))))
              (when pos
            (cons pos buf))))
          (buffer-list)))))
    (unless candidates
      (user-error "There is no buffers with %S in its name." part))
    (setq candidates (cl-sort candidates #'< :key 'car))
    (switch-to-buffer-other-window (cdr (car candidates)))))

If you do not like the regexp-match you can wrap part in string-match by regexp-quote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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