Opening emacs without the scratch buffer when opening a file - emacs

I've changed a setting in Emacs. Now, whenever I try to open a file from the command line, it opens a *scratch* buffer on top of the file. Is there a way to get rid of this? Or a way to reset my emacs startup settings?

M-x customize-group
initialization
Then, on Initial Buffer Choice, you can select among:
Startup Screen
Directory
File
scratch buffer
Finally, click on save for future sessions.
You can also toggle it on/off.
See if this can help.
(The other thing you probably want to do is to open just a single buffer at start-up. I can't remember by heart how this is done. I'll post an update if I find it out).

You can reload your .emacs file with M-x load-file ~/.emacs. There are also other ways to do it, check out the question How can I load changes to my .emacs without rebooting Emacs?.
If you think you have a problem with your .emacs file, try opening using the -q option:
emacs -q somefile
If that works as expected, you probably have an error in your .emacs, and a good way to debug your .emacs is to use the option --debug-init:
emacs --debug-init
Which will tell Emacs to provide a stack trace of any error it encounters while loading your .emacs, something like:
Debugger entered--Lisp error: (wrong-type-argument symbolp (car n))
(setq (car n) 3)
(let ((n ...)) (setq (car n) 3))
eval-buffer(#<buffer *load*<2>> nil "/home/tjackson/.emacs.tjackson.el" nil t) ; Reading at buffer position 161460
load-with-code-conversion("/home/tjackson/.emacs.tjackson.el" "/home/tjackson/.emacs.tjackson.el" nil nil)
load("/home/tjackson/.emacs.tjackson.el")
(let ((debug-on-error t)) (load user-init-file))
(if init-file-debug (let (...) (load user-init-file)) (error (format "Problems while loading the file %s: %s" user-init-file ...)))
(condition-case err (load user-init-file) (error (if init-file-debug ... ...)))
(if (file-exists-p user-init-file) (condition-case err (load user-init-file) (error ...)))
eval-buffer(#<buffer *load*> nil "/home/tjackson/.emacs" nil t) ; Reading at buffer position 12150
load-with-code-conversion("/home/tjackson/.emacs" "/home/tjackson/.emacs" t t)
load("~/.emacs" t t)
#[nil "....."]
command-line()
normal-top-level()
And that generally can point you to what might be wrong. In my case above, I'm using setq improperly, and it looks like it's inside a let statement, which is inside the file /home/tjackson/.emacs.tjackson.el. A quick search in that file leads me to the error and I can fix it.

If you want to reset emacs settings, you could rename your current .emacs file to something else to have a backup - then relaunch Emacs.

My ~/.emacs.d folder was owned by root with restrictive r/w/x privileges, so I was unable to access as any non-root user.
Make sure your current user has read privileges for the emacs config files/directories.
This fixed it for me:
sudo chown -R user:group ~/.emacs.d/
The -R works recursively in the directory.

I removed my ~/.emacs.d directory and that fixed the situation for me.

Related

Can I stop Emacs from resetting default-directory every time I open a file?

I've already asked the same question on Emacs. If it's not permitted, I'm sorry and I will delete the question.
If I:
Start Emacs in my home directory (~)
Find a file in the ~/Projects/ruby-play directory with C-x C-f
Try to find another file with C-x C-f
The default directory in the file finder will be ~/Projects/ruby-play.
What I'd like to see is the default directory being ~ still.
Is there a package/hook/Elisp function I should use to make this happen?
Thank you very much!
One way would be to set initial-default-directory to nil, but then you won't have a default directory at all, not even your home-directory:
(setq insert-default-directory nil)
If you want your home directory to show up as the default, this cannot be done so easily. When interactively calling find-file, this results in a call to read-file-name which has a rather complicated default behavior.
Using setq-default on default-directory doesn't help, as it's value is set when the file of the buffer you're currently seeing is visited.
The only option I see is using your own version of find-file like this:
(defun my-find-file-read-args (prompt mustmatch)
(list (read-file-name prompt "~/" nil mustmatch)
t))
(defun my-find-file (filename &optional wildcards)
"Edit file FILENAME.
Like `find-file` but always uses ~ as the default directory"
(interactive
(my-find-file-read-args "Find file: "
(confirm-nonexistent-file-or-buffer)))
(let ((value (find-file-noselect filename nil nil wildcards)))
(if (listp value)
(mapcar 'switch-to-buffer (nreverse value))
(switch-to-buffer value))))
(global-set-key (kbd "C-x C-f") 'my-find-file)

Elisp: possible to automatically open Emacs init file if error at start-up?

Here's the idea: if I restart Emacs after making a change to my Emacs init file, it would be very convenient if, in the event of an error at start-up, Emacs automatically opened my init file for editing
For example, if there's an error at start-up, Emacs could show the error/debug message in one window and my init file in the other window.
I'm new to Emacs Lisp and am not familiar with error-handling procedures. Are there any error-handling mechanisms/settings that could be useful? (Am honestly not sure where to even start with this one, hence the lack of any experimental code in this post...)
If you really want to do that, you can try this:
Wrap the contents of your init file in this, where CONTENTS is your originaly init file, and FILE is the absolute name (i.e., location) of your init file:
(condition-case err
(progn
(setq debug-on-error t)
CONTENTS
)
(error (find-file FILE)
(error "*INIT ERROR*: %s" (error-message-string err))))
Or perhaps a little better: Put what is in your init file now in another file - called ORIG-INIT here (again, an absolute file name), and use this as the (only) content of your init file:
(condition-case err
(progn (setq debug-on-error t)
(load-file ORIG-INIT))
(error (find-file ORIG-INIT)
(error "*INIT ERROR*: %s" (error-message-string err))))
Actually, I normally have one emacs open with the .emacs file. Then I open and close a new emacs every time I've made changes. Not as cool, I know, but then even your cursor will be where you were working.
Another thing I do is just edit a piece of code in a scrap buffer (scratch or a newly made temporary file) and execute it using C-x C-e (while standing at the end of the expression).

How do I get emacs to write to read-only files automatically?

I am finding myself editing a lot of files that are read-only. I usually hit C-x C-q to call toggle-read-only. Then I hit C-x C-s to save and get,
File foo.txt is write-protected; try to save anyway? (y or n)
After hitting y, the file is saved and the permissions on the file remain read-only.
Is there a way to shorten this process and make it so that simply saving a file with C-x C-s does the whole thing without prompting? Should I look into inserting chmod in before-save-hook and after-save-hook or is there a better way?
Adding a call to chmod in before-save-hook would be clean way to accomplish this. There isn't any setting you can change to avoid the permissions check.
Based on the follow-up question, it sounds like you'd like the files to be changed to writable by you automatically upon opening. This code does the trick:
(defun change-file-permissions-to-writable ()
"to be run from find-file-hook, change write permissions"
(when (not (file-writable-p buffer-file-name))
(chmod buffer-file-name (file-modes-symbolic-to-number "u+w" (nth 8 (file-attributes buffer-file-name))))
(if (not (file-writable-p buffer-file-name))
(message "Unable to make file writable."))))
(add-hook 'find-file-hook 'change-file-permissions-to-writable)
Note: When I tested it on my Windows machine, the file permissions didn't show up until I tried to save the buffer, but it worked as expected. I personally feel uneasy about this customization, but it's your Emacs. :)
I agree with Trey that universally doing a chmod on write is risky -- read-only files are read-only for a reason, IMHO. Here's a way to specifically override things on a per-buffer basis. It's not ideal in that it overrides file-writable-p for the life of the buffer (or at least until you toggle my-override-mode-on-save back to nil), but it makes you make a conscious decision on a file-by-file basis (sort-of; it's really a buffer-by-buffer basis, which is fairly similar). Of course since you're looking to automatically toggle the read-only flag when the file is visited, you might not be interested in this distinction. Still, here it is; enjoy it or ignore it as you will.
(make-variable-buffer-local
(defvar my-override-mode-on-save nil
"Can be set to automatically ignore read-only mode of a file when saving."))
(defadvice file-writable-p (around my-overide-file-writeable-p act)
"override file-writable-p if `my-override-mode-on-save' is set."
(setq ad-return-value (or
my-override-mode-on-save
ad-do-it)))
(defun my-override-toggle-read-only ()
"Toggle buffer's read-only status, keeping `my-override-mode-on-save' in sync."
(interactive)
(setq my-override-mode-on-save (not my-override-mode-on-save))
(toggle-read-only))
P.S. Thanks to Trey for the ad-return-value pointer in the other SO question.
Since I find it useful to be constantly reminded that I am about to edit a file I do not have permissions to, when I open a file in a buffer I want to force myself to proactively make the buffer writable wit C-x q. Opening it with tramp by hand however is quite tedious so I advise save-buffer to prompt me for password if it fails to write. I totally recommend you put this snippet in your .emacs
(defadvice save-buffer (around save-buffer-as-root-around activate)
"Use sudo to save the current buffer."
(interactive "p")
(if (and (buffer-file-name) (not (file-writable-p (buffer-file-name))))
(let ((buffer-file-name (format "/sudo::%s" buffer-file-name)))
ad-do-it)
ad-do-it))
For a reason I could no determine the Trey Jackson solution does not work on my gnu emacs 25.2 under windows: the file-modes-rights-to-number called from file-modes-rights-to-number fails.
If someone is stuck with the same problem he could use a less elegant but working solution replace block :
(chmod buffer-file-name (file-modes-symbolic-to-number "u+w" (nth 8 (file-attributes buffer-file-name))))
with block :
(cond ((or (eq system-type 'ms-dos) (eq system-type 'windows-nt))
(progn
(shell-command-to-string (concat "attrib -R " (buffer-file-name (current-buffer))))
(message "Setting file and buffer to writeable (%s style)" system-type)
))
((eq system-type 'gnu/linux)
(progn
(shell-command-to-string (concat "chmod u+w " (buffer-file-name (current-buffer))))
(message "Setting file and buffer to writeable (%s style)" system-type)
))
(t (message "file permission change not handle for OS %s" system-type))
)

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 change read/write mode for a file using Emacs?

If a file is set to read only mode, how do I change it to write mode and vice versa from within Emacs?
M-x read-only-mode
in very old versions of Emacs, the command was:
M-x toggle-read-only
On my Windows box, that amounts to Alt-x to bring up the meta prompt and typing "read-only-mode" to call the correct elisp function.
If you are using the default keyboard bindings,
C-x C-q
(which you read aloud as "Control-X Control-Q") will have the same effect. Remember, however, given that emacs is essentially infinitely re-configurable, your mileage may vary.
Following up from the commentary: you should note that the writeable status of the buffer does not change the writeable permission of the file. If you try to write out to a read only file, you'll see a confirmation message. However, if you own the file, you can write out your changes without changing the permissions on the file.
This is very convenient if you'd like to make a quick change to a file without having to go through the multiple steps of add write permission, write out changes, remove write permission. I tend to forget that last step, leaving potentially critical files open for accidental changes later on.
Be sure you're not confusing 'file' with 'buffer'. You can set buffers to read-only and back again with C-x C-q (toggle-read-only). If you have permission to read, but not write, a file, the buffer you get when you visit the file (C-x C-f or find-file) will be put in read-only mode automatically. If you want to change the permissions on a file in the file system, perhaps start with dired on the directory that contains the file. Documentation for dired can be found in info; C-h i (emacs)dired RET.
What I found is M-x set-file-modes filename mode
It worked at my Windows Vista box.
For example: M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666
As mentioned up there by somebody else: M-x toggle-read-only would work.
However, this is now deprecated and M-x read-only-mode is the current way to do it, that it is set to C-x C-q keybinding.
CTRL + X + CTRL + Q
If only the buffer (and not the file) is read-only, you can use toggle-read-only, which is usually bound to C-x C-q.
If the file itself is read-only, however, you may find the following function useful:
(defun set-buffer-file-writable ()
"Make the file shown in the current buffer writable.
Make the buffer writable as well."
(interactive)
(unix-output "chmod" "+w" (buffer-file-name))
(toggle-read-only nil)
(message (trim-right '(?\n) (unix-output "ls" "-l" (buffer-file-name)))))
The function depends on unix-output and trim-right:
(defun unix-output (command &rest args)
"Run a unix command and, if it returns 0, return the output as a string.
Otherwise, signal an error. The error message is the first line of the output."
(let ((output-buffer (generate-new-buffer "*stdout*")))
(unwind-protect
(let ((return-value (apply 'call-process command nil
output-buffer nil args)))
(set-buffer output-buffer)
(save-excursion
(unless (= return-value 0)
(goto-char (point-min))
(end-of-line)
(if (= (point-min) (point))
(error "Command failed: %s%s" command
(with-output-to-string
(dolist (arg args)
(princ " ")
(princ arg))))
(error "%s" (buffer-substring-no-properties (point-min)
(point)))))
(buffer-substring-no-properties (point-min) (point-max))))
(kill-buffer output-buffer))))
(defun trim-right (bag string &optional start end)
(setq bag (if (eq bag t) '(?\ ?\n ?\t ?\v ?\r ?\f) bag)
start (or start 0)
end (or end (length string)))
(while (and (> end 0)
(member (aref string (1- end)) bag))
(decf end))
(substring string start end))
Place the functions in your ~/.emacs.el, evaluate them (or restart emacs). You can then make the file in the current buffer writable with M-x set-buffer-file-writable.
If you are looking at a directory of files (dired), then you can use Shift + M on a filename and enter the modespec, the same attributes used in the chmod command.
M modespec <RET>
See the other useful commands on files in a directory listing at
http://www.gnu.org/s/libtool/manual/emacs/Operating-on-Files.html
I tried out Vebjorn Ljosa's solution, and it turned out that at least in my Emacs (22.3.1) there isn't such function as 'trim-right', which is used for removing an useless newline at the end of chmod output.
Removing the call to 'trim-right' helped, but made the status row "bounce" because of the extra newline.
C-x C-q is useless. Because your also need the permission to save a file.
I use Spacemacs. It gives me a convenient function to solve this question. The code is following.
(defun spacemacs/sudo-edit (&optional arg)
(interactive "p")
(if (or arg (not buffer-file-name))
(find-file (concat "/sudo:root#localhost:" (ido-read-file-name "File: ")))
(find-alternate-file (concat "/sudo:root#localhost:" buffer-file-name))))
I call spacemacs/sudo-edit to open a file in emacs and input my password, I can change the file without read-only mode.
You can write a new function like spacemacs/sudo-edit.