&optional BUFFER for other-buffer function does not work? - emacs

When I need to switch to another buffer I have a key binding that will create a buffer called "*Buffer List*" from which I select the new buffer.
I need a command to switch between current buffer and the previous one. Except I don't want "*Buffer List*". I looked up function definition for other-buffer:
(other-buffer &optional BUFFER VISIBLE-OK FRAME)
Return most recently selected buffer other than BUFFER...
so I tried using:
(other-buffer "*Buffer List*")
Now if in the new buffer I execute above code with C-x C-e it will echo "*Buffer List*", instead of the initial buffer that I called "*Buffer List*" from. So &optional BUFFER does not seem to work the way I do it. Can anyone explain why?

BUFFER must be a buffer object. To use the buffer name you would need to use:
(other-buffer (get-buffer "*Buffer List*"))
Notice that when you can use a buffer's name as the argument, the documentation tends to name that argument BUFFER-OR-NAME (e.g. see the docstring for get-buffer itself), and to be explicit about the fact in the text.
If you see BUFFER as an argument, it likely requires the actual buffer object (as in this instance).

Related

Get the content as string of a region in a buffer by elisp program

Here is the problem that I'm solving:
Convert a region of text into a string data structure for subsequent processing by elisp program. The challenge is that
I want to execute an elisp program interactively without affecting the selection of a region
store the string value into a variable so that I can further manipulate it.
By my understanding, a region is defined by a mark and the subsequent cursor position. And I usually execute elisp program in *scratch* buffer. Furthermore, the region is also in the *scratch* buffer.
But to write the function call and execute it in the buffer, I need to move the cursor away from the end of the text selection (region) in order to write the program of
(setq grabbed (buffer-substring-no-properties (region-beginning) (region-end)))
but then the region of selection would change due to the cursor movement.
So I wonder how I could execute the elisp program while keeping the selection intact and still can access the return value.
If you want to run the function from some Elisp code but as if the user had invoked it via a keybinding, you can use call-interactively:
(setq variable-to-keep-the-value (call-interactively 'lines-to-list))
But in most cases, what you want instead is to take yourself the responsibility to choose to which part of text the function should apply:
(setq variable-to-keep-the-value
(lines-to-list (region-beginning) (region-end)))
Notice that the region's boundaries are nothing magical, regardless if they've been set by the mouse or what.
Finally, I found a desirable solution! It's using ielm buffer, the real repl of elisp.
In the ielm buffer, I can set working buffer (by C-c C-b) to be a buffer where I have the text to be manipulated, for example, *scratch*.
I can then select a region of the working buffer to be processed, and in the ielm buffer then I can type and execute elisp code to extract the text in the selected region in the working buffer, for example,
ELISP> (setq grabbed (buffer-substring-no-properties (region-beginning) (region-end)))
"One\nTwo\nThre"
ELISP> grabbed
"One\nTwo\nThre"
ELISP> (split-string grabbed)
("One" "Two" "Thre")
I can then work with the value held by the set variable, grabbed.
Here is a very helpful description of ielm:
https://www.masteringemacs.org/article/evaluating-elisp-emacs

How to create a new, unnamed file in emacs?

This is a very simple request: I want to create a new, blank file without giving it a name (yet). I can use the scratch buffer but there's only one. I can C-x C-f and open a new file, but then I have to give it a name and path. If I'm just writing notes to myself or sketching out ideas, I don't want to have to give it a name. How do I create a new, empty, unnamed file?
You can create a new buffer with: C-xb and type in the buffer name and it will create a new buffer with a name that you choose.
If you want to save that buffer, just hit C-x w to create the file with its contents to a desired location.
My recommendation is that you give org-mode a try. It will do what want among a million other things.
Give it a name. Just don't save it.
Not what you wanted to hear, but this is the Emacs way.
Use C-x C-f, giving the (to-be-file-visiting) buffer a name. Edit the text. Do not use C-x C-s to save the buffer to the file (i.e., to disk).
Note that you can first put yourself in a directory whose contents you don't care about, so that if you accidentally do save the buffer there then you can easily find, recognize and toss the file. To change directories, you can use M-x cd. Or just do it by editing the directory part when you first use C-x C-f. Or use C-x d to put yourself in a Dired buffer for the directory.
If you don't want to take the chance of accidentally hitting C-x C-s and thus saving your edits, then use C-x b instead of C-x C-f. You are (even here) prompted for the buffer name. Giving it a new name (not the name of an existing buffer) creates a new buffer. In this case, if you use C-x C-s then Emacs prompts you for the file location to save the buffer in.
Why would you want to use C-x C-f instead of C-x b, if you might not want to save the buffer? Providing a file extension in the file name you give automatically puts the buffer in the proper major mode (typically). Otherwise (for C-x b) you need to put the buffer in the mode you want.
Buffer *scratch* is by default in Lisp-Interaction mode, which is similar to Emacs-Lisp mode (but not the same).
In every other text editor or word processor the intuition is to create a “new file” or a “new buffer”, not to switch to idiosyncratic *scratch* buffer. For example, you write quick notes or thoughts in several different buffers to keep trace of them—later you decide if you throw them away or save them. Or you manipulate a snippet of text or code, but you don't want to change the original buffer, so you just copypaste it to a new temporary buffer.
*scratch* is set to Lisp Interaction mode, but if I want to quickly evaluate some Elisp code, I could eval it running eval-expression (Alt+:) or in Elisp interpreter IELM (Alt+x Enter ielm). Also, if you close *scratch* buffer, it doesn't ask you to save it, so you can accidentally lose all your work. Drew's traditional solution seems too sub-optimal. And I don't buy the argument that “this is how you do it in Emacs”. Emacs is a customizable editor, so you can and should create whatever workflow is comfortable for you.
That's how ErgoEmacs solves it, buy creating a new-empty-buffer command. You can implemented like this:
(defun new-empty-buffer ()
"Opens a new empty buffer."
(interactive)
(switch-to-buffer (generate-new-buffer "untitled"))
(funcall initial-major-mode)
(put 'buffer-offer-save 'permanent-local t)
(setq buffer-offer-save t))
The variable buffer-offer-save resets every time you change a major mode, therefore you need to annotate it with permanent-local. It also prompts only when you exit Emacs. I think it is intuitive for it to also ask, when you close a modified untitled buffer, therefore see my solution on how to upgrade kill-buffer to prompt before closing a modified buffer.
ErgoEmacs revamps the default keybindings completely and has new-empty-buffer bound to Ctrl+N, like in almost all software. Change variable initial-major-mode if you want the new buffer to have another mode on start.
See also:
Emacs: Problems of the Scratch Buffer # Xah Lee
Emacs: New Empty Buffer # Xah Lee
You can try the following snippet, just add it to your .emacs
(defun new-file-tmp()
"Create a new empty file."
(interactive)
(let ((buf (generate-new-buffer "untitled")))
(switch-to-buffer buf)
(put 'buffer-offer-save 'permanent-local t)
(setq buffer-offer-save t)))
(defun tool-bar-local-item-pre (icon def key map after_item &rest props)
"Add an item to the tool bar in map MAP.
ICON names the image, DEF is the key definition and KEY is a symbol
for the fake function key in the menu keymap. Remaining arguments
PROPS are additional items to add to the menu item specification. See
Info node ‘(elisp)Tool Bar’. The item is added after AFTER_ITEM.
ICON is the base name of a file containing the image to use. The
function will first try to use low-color/ICON.xpm if ‘display-color-cells’
is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally
ICON.xbm, using ‘find-image’."
(let* ((image-exp (tool-bar--image-expression icon)))
(define-key-after map (vector key)
`(menu-item ,(symbol-name key) ,def :image ,image-exp ,#props) after_item)
(force-mode-line-update)))
(when (boundp 'tool-bar-map)
(tool-bar-local-item-pre "new" 'new-file-tmp 'new-file-tmp tool-bar-map
'new-file :label "" :help "New untitled File")
(define-key tool-bar-map (vector 'new-file) nil)
;; comment the above line if you want to keep the button for the default behavior
)
(global-set-key (kbd "C-n") 'new-file-tmp)
It defines a new command which creates new empty buffers
Then the code binds it to the top left button of the toolbar, if you are in gui mode, and to the Control-n shortcut.
You can check the post on my site about it.
disclaimer: it's my site
A buffer and a file are not the same thing.
terminology
Regarding buffers,
The text you are editing in Emacs resides in an object called a
buffer. Each time you visit a file, a buffer is used to hold the file's text.
Regarding files,
The operating system stores data permanently in named files, so most
of the text you edit with Emacs comes from a file and is ultimately
stored in a file.
Buffers and files are related through visiting,
Visiting a file means reading its contents into an Emacs buffer so you
can edit them. Emacs makes a new buffer for each file that you visit.
answering the question
Unless I'm mistaken, technically speaking, your question, as written, can't be answered. Pedantically speaking, there's no such thing as (or little practical use for) an unnamed file. A file is a handle for something stored on disk. If you have no handle, then why make a file?
The question can then be interpreted as having two possible meanings1.
1. Making a new buffer (without regard to name)
A new buffer must have a name. An unsaved buffer can be saved to file with a given name using write-file (C-x C-w). You will be prompted for a path/name. Once written, the buffer update to be visiting the file you just wrote.
Since the name of the buffer doesn't matter (until you write it to file), here's a function which creates buffers named *scratch1*, *scratch2*, ... .
(defun create-scratch-buffer ()
"Create a new numbered scratch buffer.
Taken from URL `https://stackoverflow.com/a/21058075/5065796' "
(interactive)
(let ((n 0)
bufname)
(while (progn
(setq bufname (concat "*scratch"
(if (= n 0) "" (int-to-string n))
"*"))
(setq n (1+ n))
(get-buffer bufname)))
(switch-to-buffer (get-buffer-create bufname))
(org-mode)
(if (= n 1) initial-major-mode)))
2. Making a new file (without regard to name)
As hinted at in the new buffer solution, new files can be created with write-file.
When called interactively (M-x make-random-file), this function prompts for a directory. It then writes an empty file named something random like tmp-17388716387615.txt.
(defun make-random-file (dir)
"Make a random file in DIR."
(interactive "DDir: ")
(let* ((filename (concat "tmp-" (int-to-string (random t)) ".txt"))
(filepath (concat dir filename)))
(write-region "" nil filepath nil 'silent nil 'excl)))
As always, if the code above doesn't make sense, look at the documentation for functions and variables with C-h f and C-h v, respectively. And/or read the Introduction to Programming in Emacs Lisp.
1 It was the second meaning which I was searching for solutions to when I found this as the top search engine hit. Apologies if this was a bit obtuse. Figured it was better to share my solutions with y'all than not. :)

Programmatically setting major mode of buffer with emacs lisp

I wish to programmatically set the major mode of a buffer. I have dug into the documentation, and the function set-buffer-major-mode only takes a buffer object. I am essentially looking for a function that takes a buffer object and a mode name.
Alternatively, I also tried using auto-mode-alist by forcing the buffer to have a file extension but that did not work even when I called the set-buffer-major-mode function.
Thanks for all the help!
The basics are that if you want to switch to my mode, all you have to do is to call my-mode, for example:
(with-current-buffer buffer
(my-mode))
If you have a buffer and a variable bound to the major mode, you could use the following:
(with-current-buffer buffer
(funcall the-mode-i-want))
Again, if you have a variable bound to a string, you have to convert it to a symbol using intern:
(with-current-buffer buffer
(funcall (intern the-name-of-the-mode-i-want)))

Emacs: How do I create a new "empty" buffer whenever creating a new frame?

My Emacs is on OS X system. Is there any way to make a new frame defaulted to an empty buffer whenever I use ⌘N (just like the way TextEdit works)? I prefer to write contents first and decide an appropriate filename later. However, Emacs wants me to decide the filename first and write contents later. I don't see any advantage for it. Does anyone know why Emacs works that way?
Basically, if I use C-x 5 2, Emacs always pops up a frame with whatever file I am currently working on. This is inconvenient. I also don't want my Emacs to pop up a new frame defaulted to *scratch* (many Google search results somehow suggest this approach). I prefer it to have a buffer temporarily called "Untitled" in the new frame, and if I use ⌘N again, Emacs pops up another temporarily "Untitled 2" buffer, and so on. In this way, I can decide the buffer filenames later.
You can create new buffers with switch-to-buffer. Type C-x b, enter a buffer name, and press RET. If no buffer with that name exists, Emacs creates a new one automatically in Fundamental Mode. You may switch to any other mode as usual with M-x, e.g. M-x python-mode. To change the default buffer, set the default value of major-mode to the desired buffer.
If you'd like to have a buffer name chosen automatically, and create a new frame, however, you need to write your own command:
(defun lunaryorn-new-buffer-frame ()
"Create a new frame with a new empty buffer."
(interactive)
(let ((buffer (generate-new-buffer "untitled")))
(set-buffer-major-mode buffer)
(display-buffer buffer '(display-buffer-pop-up-frame . nil))))
Bind this to C-c n:
(global-set-key (kbd "C-c n") #'lunaryorn-new-buffer-frame)
Now pressing C-c n creates a new frame with a new empty buffer named “untitled” where x is a consecutive number.
The following will create a buffer with a unique name. The buffer is not associated with any file, so if/when you ever C-x C-s save-buffer, you will be prompted to supply a filename.
(defun empty-frame ()
"Open a new frame with a buffer named Untitled<N>.
The buffer is not associated with a file."
(interactive)
(switch-to-buffer-other-frame (generate-new-buffer "Untitled")))
This might work for you, if I understand your request:
(defun empty-frame ()
(interactive)
(let ((fl (make-temp-file "Untitled")))
(switch-to-buffer-other-frame fl)))
This will open a new temporary file for each new buffer. If you'd rather not actually create the file, you can use this instead:
(defun empty-frame ()
(interactive)
(let ((bn "Untitled-")
(num 1))
(while
(get-buffer (concat bn (number-to-string num)))
(setq num (1+ num)))
(switch-to-buffer-other-frame
(concat bn (number-to-string num)))))
You've seen answers as to how to create new "Untitled" buffers, but as for why Emacs wants you to first choose a name, some of the reasons are:
Historical: that's just how it worked, and once you get used to it, it's no worse than the alternative.
Major modes and various other details are usually chosen based on the name of the file. So instead of creating an Untitled buffer and having to choose whether to put it into LaTeX mode or C mode, you just open a file with extension ".tex" or ".c".
Having a file name means that Emacs can use the standard auto-save procedure, whereas with the Untitled approach, applications need to have some special way to auto-save those Untitled documents at some "standard" place.
C-x b *untitled* will open new buffer if not exist. Also, see Emacs manual

How can I check if a current buffer exists in Emacs?

I would like to write a function which takes action if a give buffer name already exists. For example:
(if (buffer-exists "my-buffer-name")
; do something
)
Does elisp have a function that will check the for the existence of a buffer similar to how my made up "buffer-exists" function does?
Thanks
From the documentation:
(get-buffer name)
Return the buffer named name (a string).
If there is no live buffer named name, return nil.
name may also be a buffer; if so, the value is that buffer.
(get-buffer-create name)
Return the buffer named name, or create such a buffer and return it.
A new buffer is created if there is no live buffer named name.
If name starts with a space, the new buffer does not keep undo information.
If name is a buffer instead of a string, then it is the value returned.
The value is never nil.
This is what I did:
(when (get-buffer "*scratch*")
(kill-buffer "*scratch*"))
This checks for the buffer scratch. If there's such a thing, kill it.
If not, do nothing at all.
not sure about version this predicate appeared, but now Emacs has buffer-live-p:
buffer-live-p is a built-in function in `buffer.c'.
(buffer-live-p OBJECT)
Return non-nil if OBJECT is a buffer which has not been killed.
Value is nil if OBJECT is not a buffer or if it has been killed.
If you'd like to define your hypothetical function as above, this works:
(defun buffer-exists (bufname) (not (eq nil (get-buffer bufname))))
I use this to automatically close the *scratch* buffer on startup, so I don't have to cycle through it in my list of buffers, as follows:
(defun buffer-exists (bufname) (not (eq nil (get-buffer bufname))))
(if (buffer-exists "*scratch*") (kill-buffer "*scratch*"))