Run function before exit emacs - emacs

I want such feature in org-mode: before exiting emacs (while org-mode is running) it asks me: "Do you want to run function vc-dir before exit?"
I tried this:
(add-hook 'kill-emacs-hook 'vc-dir)
But it errors: "wrong number of arguments"
also tried as found here:
(defadvice save-buffers-kill-emacs (before update-mod-flag activate)
(vc-dir))
The same error.
So how to make it work in easy way: vc-dir runs always on exit.
Or how to make it work with warning message (the best way)?
Thanks!

vc-dir takes an argument (the "dir").
So you can do:
(add-hook 'kill-emacs-hook (lambda () (vc-dir "your-dir-here")))
Of course this won't stop emacs from exiting: vc-dir opens a buffer but does not "wait" for user input. For the interactive approach you want you can do this:
(add-hook 'kill-emacs-query-functions
(lambda ()
(if (y-or-n-p "Do you want to run function vc-dir before exit?")
(progn
(vc-dir "your-directory")
nil)
t)))
Change "your-directory" by default-directory if you want to use the last visited buffer as vc-directory.

How about trying that function, which asks for confirmation before running vc-dir:
(defun my-vc-check-onexit ()
(interactive)
(let ((doquit (read-from-minibuffer "Do you want to run vcs? ")))
(if (string-equal doquit "y") (vc-dir "~/my/dir"))
))
and bound it to the hook.
note: it may not be good elisp ;)

Related

emacs init - splitting window and opening files next to each other

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")))

How to auto say Yes when run a command in Emacs?

I had to run the command revert-buffer many times recently and really frustrated to say yes whenever emacs prompts this message Revert buffer from file abc.txt? (yes or no).
Is there anyway to auto say yes in this case?
If it's just for interactive usage, I'd define an alternative function:
(defun my-revert-buffer-noconfirm ()
"Call `revert-buffer' with the NOCONFIRM argument set."
(interactive)
(revert-buffer nil t))
Alternatively, as the revert-buffer docstring tells you, take a look at the revert-without-query variable, in case that's a nicer solution for you.
On a related side note, many people have the following line in their .emacs that will make confirmations just a single keypress (just y or n):
(defalias 'yes-or-no-p 'y-or-n-p)
I use this, similar to what #phils proposed, but with non-nil IGNORE-AUTO arg:
(defun revert-buffer-no-confirm ()
"Revert buffer without confirmation."
(interactive) (revert-buffer t t))
And I bind it to <f5>, since that's what that key does generally, in MS Windows.
In any case, I agree (strongly) with those who have advised to define a separate command for this. I would not bother with revert-without-query, unless you are very sure wrt certain files (always) etc. It's best to let revert-buffer continue to act normally, and provide (and perhaps bind) your own command for interactive use. You know best when to not be bothered by a confirmation prompt.
Customizing revert-without-query might be an option.
While it is, as pointed out by other answers, preferred to redefine the revert-buffer function or the key binding, it is possible to auto-reply "yes" to any function using yes-or-no-p or for that matter y-or-n-p by something like the following:
(defalias 'yes-or-no-p '(lambda (a &rest b) t))
This may be very destructive to your data, so use at your own discretion.
I use the following to turn all ‘yes/no’ confirmations to ‘y/n’ confirmations,
and default to yes for certain prompts. i add prompts to default-yes-sometimes as needed. note i don’t have to list the entire prompt, just a regexp that matches it.
(setq original-y-or-n-p 'y-or-n-p)
(defalias 'original-y-or-n-p (symbol-function 'y-or-n-p))
(defun default-yes-sometimes (prompt)
(if (or
(string-match "has a running process" prompt)
(string-match "does not exist; create" prompt)
(string-match "modified; kill anyway" prompt)
(string-match "Delete buffer using" prompt)
(string-match "Kill buffer of" prompt)
(string-match "Kill Dired buffer of" prompt)
(string-match "delete buffer using" prompt))
t
(original-y-or-n-p prompt)))
(defalias 'yes-or-no-p 'default-yes-sometimes)
(defalias 'y-or-n-p 'default-yes-sometimes)

how to jump to the newly created buffer/window automatically in Emacs

In compilation, occur search, grep search, etc., Emacs will create a new buffer in a separate window to show the results, is there anyway to jump to that window automatically? It is useful because then I can use n and p instead of M-g n and M-g p to move to next and previous items; plus, the buffer can be quit quickly with q. Currently I manually switch to the new buffer every time I run those commands, which is just annoying. Thanks.
You can use advice.
For example to jump to the grep buffer use the following advice:
(defadvice compilation-start (after compilation-start-maximize activate)
(when (equal mode 'grep-mode)
(switch-to-buffer "*grep*")
;; you may want to maximize the buffer
(delete-other-windows)))
For occur you can use the following advice
(defadvice occur-1 (after occur-maximize activate)
(other-window 1))
After some search, I came up with this solution without advising the built-in functions:
(add-hook 'occur-hook (lambda () (pop-to-buffer occur-buf)))
(add-hook 'grep-mode-hook (lambda () (pop-to-buffer (get-buffer "*grep*"))))
(setq help-window-select t)
(add-hook 'compilation-mode-hook (lambda () (pop-to-buffer (get-buffer "*compilation*"))))
It works for *Occur*, *grep*, *compilation* and *Help*.

How do I bind latexmk to one key in Emacs and have it show errors if there are any

I'm using AUCTeX and I would like to bind a key, e.g. C-0, that does the following:
Saves the active file without prompting me.
Runs latexmk on the active file without prompting me.
Shows me errors if latexmk encounters any by .
My problem is not how to bind a key (for which Tyler posted a link in a comment below) but how to come up with a function that accomplishes item 1–3.
I call Latexmk by
(add-hook 'LaTeX-mode-hook (lambda ()
(push
'("Latexmk" "latexmk %s" TeX-run-TeX nil t
:help "Run Latexmk on file")
TeX-command-list)))
This is my .latexmkrc
$pdf_mode = 1;
$recorder = 1;
$latex = 'latex -recorder -halt-on-error -interaction=nonstopmode -shell-escape';
$pdflatex = 'pdflatex -recorder -halt-on-error -interaction=nonstopmode -shell-escape';
I'm using Emacs 23.3 and AUCTeX 11.86.
Something like this?
(require 'tex-buf)
(defun run-latexmk ()
(interactive)
(let ((TeX-save-query nil)
(TeX-process-asynchronous nil)
(master-file (TeX-master-file)))
(TeX-save-document "")
(TeX-run-TeX "latexmk" "latexmk" master-file)
(if (plist-get TeX-error-report-switches (intern master-file))
(TeX-next-error t)
(minibuffer-message "latexmk done"))))
(add-hook 'LaTeX-mode-hook
(lambda () (local-set-key (kbd "C-0") #'run-latexmk)))
Edit:
TeX-save-document saves your master file and any sub-files (if you just have one file, it's your master file), and when TeX-save-query is nil, it doesn't ask you for confirmation. Then TeX-run-TeX runs latexmk using the mechanism usually used for running TeX, which includes error message parsing, but because it usually starts an asynchronous process, we set TeX-process-asynchronous to nil to wait for it to end. The odd-looking plist-get form is the documented way to check for errors from TeX-run-TeX (see comments in tex-buf.el), and if there are errors, we jump to the first one; if there are no errors, we show a message in the minibuffer just for fun.
Finally, the local-set-key is one way to bind a key to the function.
Does this do what you want?
(defun my-tex ()
"Saves the current buffer and runs LaTeX, all with no prompts or further interaction."
(interactive)
(save-buffer)
(TeX-command "LaTeX" 'TeX-master-file -1))
I don't use latexmk, but to make that work all you need to do is switch the string "LaTeX" for the name string you use for latexmk in TeX-command-list (which is probably just "latexmk" or "Latexmk").
I'm glad you asked, as this will be useful for me now!
Assuming you've already used the answer in How to call latexmk in emacs, and jump to next-error to add latexmk to the command list for AUCTeX, you can use the following function:
(defun run-latexmk ()
(interactive)
(save-buffer)
(TeX-command "Latexmk" 'TeX-master-file 0)
(if (plist-get TeX-error-report-switches (intern (TeX-master-file)))
(next-error))) ;; 0 -> suppress confirmation
And use any of the key-binding techniques to bind it to C-0; here's one that's local to the TeX mode:
(define-key TeX-mode-map (kbd "C-0") 'run-latexmk)
The run-latexmk function is based on digging through TeX-command-master, and simplifying it to your needs. Note that the call to (next-error) may not always happen, because LaTeX may get confused by your error and pause waiting for input

Emacs : prevent from closing from window manager button

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.