I am trying to customize my Emacs init file in such a way that Emacs opens with two windows split and the ansi-term opened in one side and my init file on the other side. Now, the function I wrote (switch-to-next-window) works perfectly if Emacs is open already.
I was hoping to make the cursor switch to the other window and then open my init file there. However, if I try to run this upon start-up (actually after start up, at least this is what I am thinking) I get the following error: window-live-p, nil
I am gessing that there is no "next window". But I just don't know a work around here since I do think that I am only calling my function after Emacs has fully started up? If anyone could point me to where I am going wrong in my logic, that would be great!
(split-window-horizontally)
(setq initial-buffer-choice "*ansi-term*")
(defun switch-to-next-window ()
(interactive)
(let* ((next-window (get-buffer-window (other-buffer (current-buffer) t))))
(select-window next-window)))
(add-hook 'emacs-startup-hook (lambda ()(ansi-term "/bin/bash")))
(with-eval-after-load "~/.emacs.d/init.el"
(switch-to-next-window)
(setq initial-buffer-choice "~/.emacs.d/init.el"))
Changing initial-buffer-choice after the initial buffer has been opened won't have any effect.
What helps is putting everything into the emacs-startup-hook and using the find-file-other-window function:
(add-hook 'emacs-startup-hook
(lambda ()
(ansi-term "/bin/bash")
(split-window-horizontally)
(find-file-other-window "~/.emacs.d/init.el")))
Related
In Emacs org-mode, how do I get org-capture to open in a full-sized window, rather than first splitting the window ?
You can add (add-hook 'org-capture-mode-hook 'delete-other-windows) or (add-hook 'org-capture-mode-hook 'make-frame) to your .emacs. (To test, you can eval these with M-:). The first should delete the other windows, the second opens the window in a new frame. However these work after you select the capture template.
The accepted answer doesn't seem to work for me in emacs 24. The only solution I was able to find involves using emacs-noflet and (thanks Alex Vorobiev) in your emacs file:
(defun make-capture-frame ()
"Create a new frame and run org-capture."
(interactive)
(make-frame '((name . "capture")))
(select-frame-by-name "capture")
(delete-other-windows)
(noflet ((switch-to-buffer-other-window (buf) (switch-to-buffer buf)))
(org-capture)))
and bind make-capture-frame to a shortcut.
For me, I needed to ensure that org-capture opened in a new frame, and that the frame was closed when finished. The following worked well for this:
; close capture frames when finished capturing
(add-hook 'org-capture-after-finalize-hook (lambda () (delete-frame)))
; make org-capture open up as sole window in a new frame
(defadvice org-capture (around my-org-capture activate)
(progn
(select-frame (make-frame))
(delete-other-windows)
(noflet
((switch-to-buffer-other-window (buf) (switch-to-buffer buf)))
ad-do-it)))
I am involved in python project where tabs are used, however i am not using them in every other code i write, it is vital to use them in that particular project. Projects are located in one directory under specific directories. I.E:
\main_folder
\project1
\project2
\project3
...etc
I have couple functions/hooks on file open and save that untabify and tabify whole buffer i work on.
;; My Functions
(defun untabify-buffer ()
"Untabify current buffer"
(interactive)
(untabify (point-min) (point-max)))
(defun tabify-buffer ()
"Tabify current buffer"
(interactive)
(tabify (point-min) (point-max)))
;; HOOKS
; untabify buffer on open
(add-hook 'find-file-hook 'untabify-buffer)
; tabify on save
(add-hook 'before-save-hook 'tabify-buffer)
If i put it in .emacs file it is run on every .py file i open which is not what i want. What i`d like to have is to have these hooks used only in one particular folder with respective subfolders. Tried .dir_locals but it works only for properties not hooks. I can not use hooks in specific modes (i.e. python-mode) as almost all projects are written in python. To be honest i tried writing elisp conditional save but failed.
A very easy solution is to just add a configuration variable that can be used to disable the hooks. For example:
(defvar tweak-tabs t)
(add-hook 'find-file-hook
(lambda () (when tweak-tabs (untabify (point-min) (point-max)))))
(add-hook 'before-save-hook
(lambda () (when tweak-tabs (tabify (point-min) (point-max)))))
Now you can add a .dir-locals.el file in the relevant directories, setting tweak-tabs to nil, disabling this feature there.
(But another problem is that this is a pretty bad way to deal with tabs. For example, after you save a file you do see the tabs in it.)
Just for the record, to answer the literal question in the title (as I reached this question via a web search): one way to add a hook that depends on file location is to make it a function that checks for buffer-file-name. (Idea from this answer.)
For example, for the exact same problem (turn on tabs only in a particular directory, and leave tabs turned off elsewhere), I'm currently doing something like (after having installed the package smart-tabs-mode with M-x package-install):
(smart-tabs-insinuate 'python) ; This screws up all Python files (inserts tabs)
(add-hook 'python-mode-hook ; So we need to un-screw most of them
(lambda ()
(unless (and (stringp buffer-file-name)
(string-match "specialproject" buffer-file-name))
(setq smart-tabs-mode nil)))
t) ; Add this hook to end of the list
(This is a bit inverted, as smart-tabs-insinuate itself modifies python-mode-hook and then we're modifying it back, but it should do as an example.)
How to kill the buffer in emacs without being questioned.
This will kill the current visible buffer without confirmation unless the buffer has been modified. In this last case, you have to answer y/n.
(global-set-key [(control x) (k)] 'kill-this-buffer)
I use this
(defun volatile-kill-buffer ()
"Kill current buffer unconditionally."
(interactive)
(let ((buffer-modified-p nil))
(kill-buffer (current-buffer))))
(global-set-key (kbd "C-x k") 'volatile-kill-buffer) ;; Unconditionally kill unmodified buffers.
It will kill the buffer unless it's modified.
OK, I've done some poking around in the Emacs manual and found a working solution (as of Emacs 23.4.1). It's almost identical to Noufal's solution:
(defun kill-this-buffer-volatile ()
"Kill current buffer, even if it has been modified."
(interactive)
(set-buffer-modified-p nil)
(kill-this-buffer))
I've renamed the function a bit to make it a closer cousin to kill-this-buffer.
Apparently, the EmacsWiki has a page on this topic at http://www.emacswiki.org/emacs/KillBufferUnconditionally (modified in 2007), but the code is just a copy of Noufal's.
Use (kill-current-buffer) instead of (kill-this-buffer) if you want to bind it to some key. See the docs for (kill-this-buffer)
...
This command can be reliably invoked only from the menu bar,
otherwise it could decide to silently do nothing.
and (kill-current-buffer)
...
This is like ‘kill-this-buffer’, but it doesn’t have to be invoked
via the menu bar, and pays no attention to the menu-bar’s frame.
So I would put the following in my init.el:
(global-set-key (kbd "C-x k") 'kill-current-buffer)
This works at least in emacs 26.1.
I use the following piece of code -- unlike Noufal's solution of ignoring the buffer being modified or not, this will save the buffer and then kill it. It also deletes the window which makes a difference when you have several sub-windows showing -- by default it will remove the window instead of switching to some other buffer. (To use this conveniently, you need to bind some key to it, of course.)
;; Kill the current buffer immediatly, saving it if needed.
(defvar kill-save-buffer-delete-windows t
"*Delete windows when `kill-save-buffer' is used.
If this is non-nil, then `kill-save-buffer' will also delete the corresponding
windows. This is inverted by `kill-save-buffer' when called with a prefix.")
(defun kill-save-buffer (arg)
"Save the current buffer (if needed) and then kill it.
Also, delete its windows according to `kill-save-buffer-delete-windows'.
A prefix argument ARG reverses this behavior."
(interactive "P")
(let ((del kill-save-buffer-delete-windows))
(when arg (setq del (not del)))
(when (and (buffer-file-name) (not (file-directory-p (buffer-file-name))))
(save-buffer))
(let ((buf (current-buffer)))
(when del (delete-windows-on buf))
(kill-buffer buf))))
I very often open a lot of file system explorer windows (either under linux or windows). Then I make a big cleanup and close everything. Often, I also close Emacs by mistake.
I'd like to change the behaviour of the 'X' button to minimize instead of closing (leave closing to C-x C-c only). I'm almost sure it's possible, but I don't know how. Anyone to help?
One possible way to achieve this is to (ab-)use the confirm-kill-emacs mechanism: this is meant to be a function that asks the user for confirmation about killing emacs. However, instead of using an interactive function, you could introduce a special variable that is true only if the kill command has been invoked through C-x C-c, and the confirm function simple returns the value of that variable.
Put the following in your .emacs file:
(defvar killed-from-keyboard nil)
(setq confirm-kill-emacs '(lambda (prompt) killed-from-keyboard))
(defun save-buffers-kill-emacs-from-keyboard (&optional arg)
(interactive)
(condition-case nil
(progn (setq killed-from-keyboard t)
(save-buffers-kill-terminal arg))
((quit error)
(setq killed-from-keyboard nil))))
(global-set-key [(control x) (control c)] 'save-buffers-kill-emacs-from-keyboard)
If you advise the kill-emacs function, then you can get the functionality that you desire. I have code that makes my emacs frame invisible (hidden), but you can iconify it instead with code similar to the following.
(defvar bnb/really-kill-emacs nil)
(defadvice kill-emacs (around bnb/really-exit activate)
"Only kill emacs if a prefix is set"
(if bnb/really-kill-emacs
ad-do-it)
(iconify-frame))
(defun bnb/really-kill-emacs ()
(interactive)
(setq bnb/really-kill-emacs t)
(kill-emacs))
The bnb/really-kill-emacs function is defined so that you can actually kill emacs when necessary.
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)
)