emacs call-interactively and key simulation - emacs

I want to write a small function that saves the cursor's current position, mark the whole buffer, indents it and then goes back to the previous cursor position. I understand there might be easier way to achieve the same result but I'd like to understand how these principles work in Elisp.
Here's what I tried to do :
(defun indent-whole-buffer () (interactive)
(call-interactively 'point-to-register)
(call-interactively (kbd "RET"))
(mark-whole-buffer)
(call-interactively 'indent-region)
(call-interactively 'jump-to-register)
(call-interactively (kbd "RET"))
)
The blocking point here is the (call-interactively (kbd "RET")) how can I simulate the RET key, just as if I was doing
M-x point-to-register RET

Just use save-excursion. That's what it's for. It saves point and mark and which buffer is current, and then restores them for you.
(And if you did decide to roll your own, and you did decide to do it in the way you planned, then just call the functions you need directly - no need to use call-interactively. Use C-h f to see how each function is called. For example (point-to-register ?a) captures point in register a, and (indent-region (point-min) (point-max)) indents the whole buffer.)

Emacs Lisp is not just the macro language used by Emacs — it's the implementation language. Many Emacs functions have more functionality than what is exposed through the UI, and it is often possible to write more compact and elegant code by using this functionality.
In particular, if your goal is to indent the whole buffer, then there is no need to move point and mark around — the function indent-region is able to indent an arbitrary region:
(defun indent-whole-buffer ()
(interactive)
(indent-region (point-min) (point-max)))

Related

Undo buffer-search in Emacs

After doing a (re-search-forward str) in the current buffer, it would be nice in some cases to have an easy method to return to the previous buffer position. The behavior should be like (undo) for buffer changes. So if I do two searches forward, first from position A to B, and then from B to C, I would like to press a key to go back one step (from C to B), and pressing the key again would leave me at A..
If you are using re-search-forward in Lisp code (and you probably should be, if you are using it at all, even though it is a command), then do not set the mark in order to be able to return to your starting point.
Instead, simply save the starting position ((point)) as, say, variable beg, and then use goto-char beg.
See this paragraph in (elisp) The Mark:
Novice Emacs Lisp programmers often try to use the mark for the
wrong purposes. The mark saves a location for the user's
convenience. An editing command should not alter the mark unless
altering the mark is part of the user-level functionality of the
command. (And, in that case, this effect should be documented.)
To remember a location for internal use in the Lisp program, store
it in a Lisp variable. For example:
(let ((beg (point)))
(forward-line 1)
(delete-region beg (point))).
With this
(global-set-key
(kbd "M-p")
(lambda()(interactive) (set-mark-command 4)))
I can jump backwards one by one through a few C-M-s.
Note that this works for isearch-forward-regexp, not for plain
re-search-forward (this one doesn't set the mark).
But with elisp it's no problem - just call push-mark before
re-search-forward.
To sum up, the following seems to work:
(defun my-search-fun (str)
(interactive)
(push-mark)
(beginning-of-buffer)
(re-search-forward str))
(defun my-undo-search ()
(interactive)
(pop-mark)
(goto-char (mark))

how to emulate a specific key press in Emacs Lisp

Context: I want to make a minor mode where pressing f twice fast results in whatever the pressing of ( should do at that time. This doesn't always mean just insertion of (. For example, in buffers where paredit mode or autopair mode is enabled, pressing of ( usually results in insertion of (). In a paredit mode buffer, that sometimes results in wrapping the selected text: for example, if I select a b and press (, that should result in replacing the selection with (a b).
For detection of f being pressed twice, I just need to take the logic in the short code in http://www.emacswiki.org/emacs/electric-dot-and-dash.el
So the only missing piece is a Lisp code snippet that tells Emacs "Trigger pressing of ( now!"
The first thing that came to my mind was that the snippet should do
find the command bound to the key (
and then call call-interactively on that command.
but that breaks down if the auto pairing package (autopair or paredit or other similar package) binds ( to a command that has a logic that looks up what key was used to call the command, or if the package simply relies on post-self-insert-hook or post-command-hook instead of binding (.
update
I've looked up Key Chord documentation and it turns out what I am trying to do with answers to this question has a simpler solution:
(require 'key-chord)
(key-chord-mode 1)
(defvar my-easy-open-paren-mode-map
(let ((map (make-sparse-keymap)))
(key-chord-define map ",." (kbd "("))
map))
(define-minor-mode my-easy-open-paren-mode
"In this mode, pressing . and , together is another way of pressing the open paren.")
(defvar my-easy-semicolon-mode-map
(let ((map (make-sparse-keymap)))
(key-chord-define map ";;" (kbd "C-e ;"))
map))
(define-minor-mode my-easy-semicolon-mode
"In this mode, pressing semicolon twice fast is another way of pressing C-e and semicolon.")
(add-hook 'prog-mode-hook 'my-easy-open-paren-mode)
(add-hook 'c-mode-common-hook 'my-easy-semicolon-mode)
Triggering key press may still be useful in other contexts though.
You might appreciate the Key Chord library for binding functions to a double key-press. (I wouldn't recommend using f if you'll be writing in English, mind you; but YMMV.)
post-self-insert-hook would still run if the binding was self-insert-command. post-command-hook will run in any case, but if you're worried about it seeing an incorrect function and/or input event, you can manipulate those...
After looking up the binding, your function can set this-command to the function you're about to call-interactively, and last-command-event to the required key. e.g.:
(defun my-fake-paren ()
(interactive)
(let ((command (key-binding "(")))
(setq last-command-event ?\()
(setq this-command command)
(call-interactively command)))
I use Key Chord for this sort of thing, although the page you link appears to do the same thing. The trick is getting the call to call-interactively to work correctly. I wrapped it in a let that reset the variable last-command-event, such that call-interactively thinks it was a "(". This works for me in paredit and fundamental modes.
(require 'key-chord)
(key-chord-mode 1)
(defun my-paren-call ()
(interactive)
(let ((last-command-event ?\())
(call-interactively (key-binding "("))))
(key-chord-define-global "ff" 'my-paren-call)

emacs - set shortcut key only in major mode?

I would like to override C-l and use it to do M-x erase-buffer followed by simulating hitting RET, only when I am in m-shell-mode. C-l should be its default, recenter-top-bottom, otherwise. How do I do so?
Not sure what m-shell-mode is, but if it's a well-defined major mode, then the following should do the trick:
(require 'm-shell-mode)
(define-key m-shell-mode-map (kbd "C-l") 'erase-buffer)
Might I suggest an alternative binding, which has the same visual effect, but keeps the buffer contents around (which can be handy).
(defun shell-clear-command (&optional a)
"\"clear\" the screen"
(interactive "P")
(recenter (or a 0)))
(define-key m-shell-mode-map (kbd "C-l") 'shell-clear-command)
If m-shell-mode is based on comint-mode, which is true of many modes that provide a shell to interact with another process, then you can pass the return keypress to matlab with the function comint-send-input. In that case the following code should do what you want:
(defun clear-and-return ()
"Erases the buffer, and then passes a return to the buffer process.
Assumes the buffer is attached to a comint process."
(interactive)
(erase-buffer)
(comint-send-input))
(defun my-m-shell-mode-hook ()
(local-set-key (kbd "C-l") 'clear-and-return))
(add-hook 'm-shell-mode-hook 'my-m-shell-mode-hook)
The first defun makes a function that does what you want. The second is a hook function that will bind C-l to that function for the buffer that is active when the function is called. The add-hook tells emacs to run the second function whenever you start m-shell-mode. You can add further m-shell-mode customizations inside the body of my-m-shell-mode, and Emacs will run all of them each time you start the mode.
If m-shell-mode is not based on comint-mode, you need to find out what happens when you press return. From a buffer that is running the mode, type C-h k RET to find the function bound to the return key. Use that function instead of comint-send-input in the code above.
You can add to your m-shell-mode hook the following code:
(local-set-key (kbd "C-l") 'erase-buffer)

Stopping tex-shell from opening when compiling Latex from Emacs

How can I prevent the *tex-shell* buffer from opening when I compile Latex from Emacs? It splits the window in half, and I always just use C-x 1 to get rid of it immediately.
The solution is possibly related to
(setq special-display-buffer-names ("*tex-shell*"))
which makes the new buffer take up the whole frame instead of just half (not what I want).
I tried the following, but it has no effect for Latex:
(defadvice compilation-start
(around inhidbit-display (command &optional mode name-function highlight-regexp))
(flet (display-buffer) (fset 'display-buffer 'ignore) ad-do-it))
(ad-activate 'compilation-start)
(ad-deactivate 'compilation-start)
Well, you really should be using AUCTeX since it's much better. Nevertheless if you type C-hk and then a key sequence Emacs will tell you what would be run. In this case, for C-cC-f, it's tex-file so you will have to advise tex-file, or maybe (digging down into the source a little bit) tex-start-shell.
I use the following defun:
(defun tex-without-changing-windows ()
(interactive)
(save-buffer)
(save-window-excursion (tex-file)))
I bind it to C-c C-f to replace tex-file.

Emacs: Insert word at point into replace string query

Is there an analogue to inserting the word after point into the isearch query by hitting C-w after C-s but for the replace string (and replace regexp) queries?
I also enjoy Sacha Chua's modification of C-x inserting whole word around point into isearch:
http://sachachua.com/blog/2008/07/emacs-keyboard-shortcuts-for-navigating-code/
This too would be really useful in some cases if it could be used in replace string.
I'd be very thankful for any tips!
Thank you!
This will do it, although it isn't as fancy as C-w in isearch because you can't keep hitting that key to extend the selection:
(defun my-minibuffer-insert-word-at-point ()
"Get word at point in original buffer and insert it to minibuffer."
(interactive)
(let (word beg)
(with-current-buffer (window-buffer (minibuffer-selected-window))
(save-excursion
(skip-syntax-backward "w_")
(setq beg (point))
(skip-syntax-forward "w_")
(setq word (buffer-substring-no-properties beg (point)))))
(when word
(insert word))))
(defun my-minibuffer-setup-hook ()
(local-set-key (kbd "C-w") 'my-minibuffer-insert-word-at-point))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
EDIT:
Note that this is in the standard minibuffer, so you can use it use it anywhere you have a minibuffer prompt, for example in grep, occur, etc.
Two answers:
Replace+ automatically picks up text at point as the default value when you invoke replace commands.
More generally, Icicles does something similar to what scottfrazer's code (above) does, but it is more general. At any time, in any minibuffer, you can hit M-. (by default) to pick up text ("things") at point and insert it in the minibuffer. You can repeat this, to either (a) pick up successive things (e.g. words) of the same kind, accumulating them like C-w does for Isearch, or (b) pick up alternative, different things at point. More explanation here.
I think this exists in Emacs already - you just start replace with M-S-% and then press M-n (while the minibuffer is empty), this fills in the word under cursor, there are more useful things you can do with this, check http://endlessparentheses.com/predicting-the-future-with-the-m-n-key.html?source=rss#disqus_thread.