Emacs: reload from file for all buffers - emacs

If I want to reload from disk a file that is in a buffer, I can do M-x revert-buffer. Is there an equivalent command that will do this for all open buffers at once?

You could use the following simple function,
(defun my-revert-all ()
(interactive)
(dolist (buff (buffer-list))
(ignore-errors ; ignore errors from buffers w/ no files
(revert-buffer buff))))
which could be modified further to pass all the arguments similar to revert-buffer.

Related

Forbid buffer content to save to old file when buffer file name is changed

I have follow use case annoying me a lot.
Open file foo.rb in emacs buffer.
rename foo.rb to bar.rb use external tool.(e.g. rename from terminal)
Select foo.rb buffer in Emacs, edit it, when C-x s to save, this buffer
save as old file name (foo.rb), not expected bar.rb.
Is there any emacs config to prevent this??
What i expect is some like:
open file foo.rb in Emacs buffer.
rename foo.rb to bar.rb use external tool
edit foo.rb buffer, when save, told me: file is removed, or prompt,
save as a new file name.
Here's the beginning of a solution. The devil's in the details; there are probably a lot of corner cases that this code doesn't deal with.
(defvar do-not-save-list ())
(defun do-not-save-add-to-list (event)
(when (eq 'renamed (cadr event))
(add-to-list 'do-not-save-list
(caddr event))))
(defun do-not-save-add-watcher ()
(setq do-not-save-list (remove (buffer-file-name) do-not-save-list))
(file-notify-add-watch (buffer-file-name)
'(change)
#'do-not-save-add-to-list))
(add-hook 'find-file-hook #'do-not-save-add-watcher)
(defun do-not-save-check ()
(let ((filename (buffer-file-name)))
(when (member filename do-not-save-list)
(message "not saving %s" filename)
t ;; returns non-nil to prevent write
)))
(add-hook 'write-file-functions #'do-not-save-check)
(defun do-not-save-kill-hook ()
(setq do-not-save-list (remove (buffer-file-name) do-not-save-list)))
(add-hook 'kill-buffer-hook #'do-not-save-kill-hook)

Executing shell command on emacs file opening

I'm currently using the terminal Terminator,
and i got a bash function
set_title() { printf '\e]2;%s\a' "$*"; }
wich permit me to set the terminator window title
So I would want to know if it's possible to execute this specific shell command (like this):
set_title ##filename
on each opening (or re-opening) of the said file in emacs?
(btw english is not my native language, please be indulgent!)
If you mean that you're running the non-GUI Emacs inside bash inside Terminator and you want Terminator's title to reflect the current file in Emacs, then the fact that bash sits in between is of no use to you: Emacs is in control here.
But you can define an Elisp function that will do the same job as your set_title:
(defun my-set-title (title)
(send-string-to-terminal (format "\e]2;%s\a" title)))
And then you could use it via find-file-hook:
(add-hook 'find-file-hook (lambda () (my-set-title buffer-file-name)))
Note that this will set the terminal's title to the last file Emacs visits, so if you switch back to a previous file-buffer via C-x C-b, the title won't be updated to reflect the current buffer's file name. If you want to do that, you'd need something more like:
(defvar my-last-file nil)
(defun my-keep-file-title ()
(when (and buffer-file-name
(not (equal buffer-file-name my-last-file)))
(setq my-last-file buffer-file-name)
(my-set-title buffer-file-name)))
(add-hook 'post-command-hook #'my-keep-file-title)
As suggested by #Dan, you can do
(add-hook find-file-hook
(lambda ()
(when (string= buffer-file-name "my-file")
(shell-command "printf ...."))))
to call printf when you open "my-file".
However, if what you want is to set the frame title (emacs calls "frame" what window managers call "window"),
you should be setting frame-title-format, e.g.:
(setq frame-title-format
'(buffer-file-name "%b - %f" ; File buffer
(dired-directory dired-directory ; Dired buffer
(revert-buffer-function "%b" ; Buffer Menu
("%b - Dir: " default-directory)))) ; Plain buffer
icon-title-format "%b")

Emacs: how to load an ansi-term buffer at startup?

I have figured how to close the scratch buffer and the GNU Emacs buffer, and I would now like to have a terminal started automatically within emacs, instead of having to type manually M-x ansi-term. I saw a couple posts explaining how to load a file at startup, but I believe the ansi-term buffer is a bit different.
I'd rather modify my .emacs than create an alias for emacs.
(add-hook 'emacs-startup-hook
(lambda ()
(kill-buffer "*scratch*")
(ansi-term "/bin/bash")
))

Automatically closing the scratch buffer

What I must write in my .emacs file so that the *scratch* buffer is closed when I open Emacs?
(kill-buffer "*scratch*")
Not exactly the answer to your question, but you might like to know that you can choose to have a different buffer open on startup, or change the contents of the *scratch* buffer. For example:
;; Make *scratch* buffer blank.
(setq initial-scratch-message nil)
;; Make the buffer that opens on startup your init file ("~/.emacs" or
;; "~/.emacs.d/init.el").
(setq initial-buffer-choice user-init-file)
In the first example, the *scratch* buffer will be empty. In the second example, the *scratch* buffer will still exist, but user-init-file will be focused.
You can customize:
initial-buffer-choice
I set it to my homedir: "~/" to start in Dired mode.
I suspect from your question that you probably start emacs fairly often, perhaps even once for each file you want to edit. (If I'm wrong in this assumption, then the following comments don't apply to you.)
Emacs is designed to be started and then left running for weeks or months while you visit various files as you need to edit them. Emacs handles multiple files very well, so it's hardly even necessary to kill the associated buffers until you get 50 or 100 of them hanging around. I start emacs just after my window system starts, and it runs until my system shuts down or crashes. The initial scratch buffer is a non-problem in this mode, because I see it so infrequently.
I use this to kill the scratch buffer and open a new buffer in text mode called Untitled.
Found it on a newsgroup and modified it slightly.
(defun my-close-scratch ()
(kill-buffer "*scratch*")
(if (not (delq nil (mapcar 'buffer-file-name (buffer-list))))
(new-untitled-buffer)
))
(defun my-emacs-startup-hook ()
(my-close-scratch))
(add-hook 'emacs-startup-hook 'my-emacs-startup-hook)
(defun new-untitled-buffer ()
"Opens a new empty buffer."
(interactive)
(let ((buf (generate-new-buffer "Untitled")))
(switch-to-buffer buf)
(normal-mode)
(setq buffer-offer-save t))
(add-hook 'kill-buffer-query-functions
'ask-to-save-modified nil t)
)
To close Untitled when opening files from filemanager when emacs is not open I use this:
(defun my-close-untitled ()
(if (get-buffer "Untitled")
(kill-buffers-by-name "Untitled")))
(add-hook 'find-file-hook 'my-close-untitled)
The proper way is to add inhibit-startup-screen to the custom-set-variables section of your .emacs file.
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(inhibit-startup-screen t)
)

How do I get a warning before killing a temporary buffer in Emacs?

More than once I've lost work by accidentally killing a temporary buffer in Emacs. Can I set up Emacs to give me a warning when I kill a buffer not associated with a file?
Make a function that will ask you whether you're sure when the buffer has been edited and is not associated with a file. Then add that function to the list kill-buffer-query-functions.
Looking at the documentation for Buffer File Name you understand:
a buffer is not visiting a file if and only if the variable buffer-file-name is nil
Use that insight to write the function:
(defun maybe-kill-buffer ()
(if (and (not buffer-file-name)
(buffer-modified-p))
;; buffer is not visiting a file
(y-or-n-p "This buffer is not visiting a file but has been edited. Kill it anyway? ")
t))
And then add the function to the hook like so:
(add-to-list 'kill-buffer-query-functions 'maybe-kill-buffer)
(defun maybe-kill-buffer ()
(if (and (not buffer-file-name)
(buffer-modified-p))
;; buffer is not visiting a file
(y-or-n-p (format "Buffer %s has been edited. Kill it anyway? "
(buffer-name)))
t))
(add-to-list 'kill-buffer-query-functions 'maybe-kill-buffer)