0

Having the following function, I would like to use the default name "arktika-N" where N is a number which makes the name unique. Currently it is using the name of the recently used buffer other than the current buffer.

(defun arktika-workspace (name)
  "Make a new uniquely named buffer."
  (interactive "B Buffer-Name: ")
  (let ( ($buf (generate-new-buffer name)) )
    (switch-to-buffer $buf)))

2 Answers 2

0

It's not clear to me exactly what you want.


If you want a command that never prompts the user, and always uses artika as the "base" name, then I think you simply need:

(defun artika-workspace ()
  (interactive)
  (switch-to-buffer (generate-new-buffer "artika")))

This will produce buffers named artika, artika<2>, artika<3>, and so on.

(If you dislike that standard Emacs naming convention, and you really want it to be artika-1, artika-2, artika-3, and so on? Then you'll need to write your own equivalent of generate-new-buffer and generate-new-buffer-name.)


Otherwise, the answer by Tobias might be closer to what you want?

EDIT

Based on your comment, I think you want something like:

(defun artika-workspace (&optional base)
  (interactive "sBuffer name: ")
  (switch-to-buffer
   (generate-new-buffer
    (if (string-blank-p base) "artika" base))))

The equivalent, using more named intermediate variables, in case you prefer that style:

(defun artika-workspace (&optional base)
  (interactive "sBuffer name: ")
  (let* ((name   (if (string-blank-p base) "artika" base))
         (buffer (generate-new-buffer name)))
    (switch-to-buffer buffer)))
2
  • I wanted the user to enter a name, but also to default it when the user just hits return. Am happy with artika<N>. Just wanted to avoid using a recently used buffer that happens to be some programming language buffer that a user might be working on.
    – Dilna
    Commented Jun 27, 2022 at 18:29
  • Works well as intended. The first edit version is straightforward and understandable. Shall stick with that one.
    – Dilna
    Commented Jun 27, 2022 at 20:26
0

The argument of the interactive form can also be a sexp that evaluates to a list of argument values. In your case that list contains only the value of the NAME argument.

With this form of interactive you are completely free in the programming of the prompting for interactive arguments.

The following code is very close to what you want. If you accept unique buffer names with the format NAME<%d> instead of NAME-%d you can replace arktika-generate-new-buffer-name with the built-in generate-new-buffer-name.

The function arktika-workspace offers a not yet used buffer name as default but it does not enforce the input of non-used buffer names in general.

In theory there could be a racing condition if you have multiple minibuffers. It could be that you start arktika-workspace twice and wait for input. In that case the same name is offered in both calls as default.

(cl-defun arktika-generate-new-buffer-name (&optional (name "arktika"))
  "Return a new buffer name based on NAME."
  (if (get-buffer name)
      (let ((n 1)
        real-name)
    (while (get-buffer (setq real-name (format "%s-%d" name n)))
      (cl-incf n))
    real-name)
    name))

(defun arktika-workspace (name)
  "Get buffer NAME.
By default, propose a new uniquely named buffer."
  (interactive (let ((name (arktika-generate-new-buffer-name "arktika")))
         (list
          (read-buffer (format "Buffer name " name) name))))
  (let (($buf (get-buffer-create name)))
    (switch-to-buffer $buf)))

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.