Emacs/Auctex: Automatically enabling/disabling LaTeX-Math-mode - emacs

I'm using Emacs in conjunction with AucTeX (running Ubuntu 10.04, if that matters).
Does anyone know if there is a way to automatically enable LaTeX-math-mode (a minor mode of AucTeX) if the point is in any maths environment (i.e. in a $...$, a $$...$$, begin{equation}...\end{equation}, and so on)?
I suppose there is a relatively easy answer, since syntax highlighting uses the same criterion for coloring math stuff, but I could not find anything.

If andre-r's answer doesn't satisfy you, here's some code that sets up ` to self-insert in text mode and act as a math mode prefix in math mode. LaTeX-math-mode must be off.
(defun LaTeX-maybe-math ()
"If in math mode, act as a prefix key for `LaTeX-math-keymap'.
Otherwise act as `self-insert-command'."
(interactive)
(if (texmathp)
(let* ((events (let ((overriding-local-map LaTeX-math-keymap))
(read-key-sequence "math: ")))
(binding (lookup-key LaTeX-math-keymap events)))
(call-interactively binding))
(call-interactively 'self-insert-command)))
(define-key LaTeX-mode-map "`" 'LaTeX-maybe-math)
The following improvements are left as exercises:
Make it a minor mode.
Make it more robust towards unexpected input (I've only tested basic operation).
Show a better error message if the user presses an unbound key sequence.
Show help if the user presses C-h or f1.

LaTeX-math-mode is "a special minor mode for entering text with many mathematical symbols." (For those who don't know how, you press e.g. `A and get \forall.) So I guess it doesn't hurt to leave it on, also if you're not entering maths.
The info page therefore suggests:
(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
IMHO the only downside would be that you have to press the prefix twice: `` to get `, at least that works with the standard prefix ` customized in LaTeX-math-abbrev-prefix.

Related

Emacs 25 yank from x windows PRIMARY clipboard buffer with keyboard

Using Emacs 25 in a linux environment, I often copy text with the mouse and wish that I could paste the copied text with some command in Emacs, but currently the only way I know of is via the mouse middle click which is bound to mouse-yank-primary.
I've attempted to bind this to a key command, along with setting mouse-yank-at-point set true, but this (as I suspected) requires a mouse event to work correctly and I'm not sure how to get Emacs into believing that a mouse event went off due to a keystroke.
Anyone have any ideas? Or simply know the correct way to yank with the keyboard from the PRIMARY selection?
After looking around thanks to Christian's answer, I found select.el and came up with the following to stick into my .emacs
;; Pull from PRIMARY (same as middle mouse click)
(defun get-primary ()
(interactive)
(insert
(gui-get-primary-selection)))
(global-set-key "\C-c\C-y" 'get-primary)
Edit: As noted by Stefan, gui-get-primary-selection (and more generically, gui-get-selection) are only available in Emacs 25 and up. In Emacs 25.1 x-get-selection was made obsolete.
I just got annoyed by emacs default behavior of inserting the secondary X-selection on S-insert and found this thread. I tried to use the code from Silfheed but emacs 24 has no function like 'gui-get-primary-selection'. So I browsed the source for 'mouse-yank-primary' and came up with this alternative solution:
;; Pull from PRIMARY (same as middle mouse click)
(defun paste-primary-selection ()
(interactive)
(insert
(x-get-selection 'PRIMARY)))
(global-set-key (kbd "S-<insert>") 'paste-primary-selection)
So s-insert will insert the primary X-selection on the cursor position - just as in xterm...
Try setting this:
(setq select-enable-clipboard t)
this way the normal kill/yank commands (eg C-w and C-y) will work with the clipboard. Works both on X11 and OSX (and, I believe, Windows as well).
If you consult the documentation for that variable (for instance via C-h v) you should a sentence like this:
You can customize this variable.
where "customize" is a link you can click. This will bring you to Emacs' customaization system which provides an easier and more guided way of configuring Emacs. In particular, it will show you at lot about the controls that may be relevant to tweak. Even you do not want to control your confuguration that way, you can use it as guide to important variables to set and what they can be set to.
Hopefully this helps. It is shamelessly copied from above, but works both on 24 and 25. I have not tested in in other versions.
(if (< emacs-major-version 25)This w
;; in emacs 24 or previous
(defun paste-primary-selection ()
(interactive)
(insert (x-get-selection 'PRIMARY))
)
;; in emacs 25 and above
(defun paste-primary-selection ()
(interactive)
(insert (gui-get-primary-selection)))
)
(global-set-key (kbd "S-<insert>") 'paste-primary-selection)

Emacs evil-mode and ensime

I am a VIM guy - but evil-mode allowed me to productively use Emacs for my Scala development, and it did it so well that I am sort of hooked... I want to customize the environment to my liking, so I e.g. added these to my .emacs:
(define-key evil-normal-state-map (kbd "<f7>") 'ensime-typecheck-all)
(define-key evil-normal-state-map (kbd "C-]") 'ensime-edit-definition)
While in evil-normal-mode, the first line allows me to do a typecheck of my Scala code by just hitting F7, while the second one navigates me to a type/val definition via the muscle-memoried Ctrl-] (used for tags-based navigation in VIM).
My only problem is that what I've done so far is a "global" assignment - if I open a Python file, I'd want F7 to do a different thing (pyflakes or pylint). How can I assign different actions to the same key based on what kind of file is currently open in the buffer I am viewing?
In case it helps, in my .vimrc, I've done this via sections like these:
au BufNewFile,BufRead *.ml call SetupOCamlEnviron()
function! SetupOCamlEnviron()
se shiftwidth=2
"
" Remap F7 to make if the file is an .ml one
"
noremap <buffer> <special> <F7> :make<CR>
noremap! <buffer> <special> <F7> <ESC>:make<CR>
"
" Thanks to Merlin
"
noremap <buffer> <silent> <F6> :SyntasticCheck<CR>
noremap! <buffer> <silent> <F6> <ESC>:SyntasticCheck<CR>
inoremap <buffer> <C-Space> <C-x><C-o>
noremap <buffer> <C-]> :Locate<CR>
inoremap <buffer> <C-]> <ESC>:Locate<CR>
endfunction
How do I do this kind of thing in Emacs/evil?
EDIT: In search of a way to do this, I realized I can dispatch on different code when F7 is pressed in normal mode - so I wrote this Emacs lisp:
(defun current-buffer-extension ()
(if (stringp (buffer-file-name))
(file-name-extension buffer-file-name)
"Unknown"))
(defun handle-f7 ()
(interactive)
(if (string= (current-buffer-extension) "scala")
(ensime-typecheck-all)))
(define-key evil-normal-state-map (kbd "<f7>") 'handle-f7)
...which can be extended with other tool invocations as I learn more about Emacs, by adding actions based on the file extension.
Being completely new to Emacs, I am open to suggestions...
Am I on the right track here? Is there a better way to do what I want? Have I violated some principle by hooking evil-normal-mode keystrokes?
The thing you are looking for is called hook. There are plenty of hooks that emacs runs is specifics moments, and are fully customizable by user.
For instance, whenever entering a mode, a "mode-hook" is run. So you could do:
(add-hook 'python-mode-hook (lambda ()
(setq fill-column 79)
(local-set-key [(f3)] 'run-flake8)))
Hooks are the canonical way of customizing a lot of things in emacs, and there is plenty of examples around about those. In the example above, I define the key F3 to do something whenever I am in python mode.
Note that the example does not cope with evil keymap, but uses a local key that should have preference. If you want to assign a key to do different things depending on the evil state, you should either add some additional logic or make the evil-X-state-map buffer local and then change it the way you want (you could do that in the hook)
Edit: Regarding your question about if you have "violated some principle"... lets say that because of the hooks and the ability to set local variables, checking file extensions to customize behaviour is never (afaik) done other than for setting the mode (and that is done internally). Even checking the major-mode (that would be preferred to checking extension) is not done, as it is less scalable than just hooking preferences and functionality into modes.
Evil has a useful facility for mode-specific keybindings: evil-define-key. As arguments, it takes:
the state (as a quoted symbol, in your case, 'normal),
an unquoted keymap (I don't use ensime, but it's probably something like ensime-mode-map),
the key sequence, and
the command to bind.
So, to make your bindings ensime-specific (again, fiddle with the specific map name to make sure it's correct):
(evil-define-key 'normal ensime-mode-map (kbd "<f7>") #'ensime-typecheck-all)
(evil-define-key 'normal ensime-mode-map (kbd "C-]") #'ensime-edit-definition)
You can also bind f7 to something else for use with python (again, tinker with the map names and commands accordingly):
(evil-define-key 'normal python-mode-map (kbd "<f7>") #'run-flake8)
(Aside: I'm using the sharp-quote (#', which is lisp-shorthand for "function") in front of command names rather than the plain quote ('). For your purposes the two are basically equivalent, but it's good to get in the habit of the former in case you start byte-compiling your setup files, as the byte-compiler will warn you if the function in question is undefined when you sharp-quote but not if you simple-quote. See a related discussion on the Emacs Stack Exchange site.)

Different results when elisp function is run different ways; why?

EDIT: Perhaps (in original post) I used the term "transient" incorrectly (I'm not familiar enough with the jargon yet). What I really mean is that the highlighted region will disappear immediately when the user presses a navigation keys eg. arrow-keys... (2nd EDIT: I've removed the word "transient")
The particular issue of selecting a region so the user gets "cursor-key movement will make highlighting disappear" has been the bane of my existance recently. I get differnt results depending on how I run the following script.
Why does it give different results, and more specifically, is there a way to make it produce "cursor-keys make highlighting disappear" regardless of which mode is running, or whether it is being evaluated while testing? .. CUA mode has this behaviour, but I really need that non CUA mode does it too (and eval, if possible)...
Here are the results, followed by the code. (GNU Emacs 23.1.1)
CUA mode enabled
Evaluate via C-x C-e — both (call-trans-hi) and (trans-hi)
NO-GO: Both set mark and move point to EOL, but nothing is highlighted.
Execute M-x call-trans-hi
ok: Works fine; the region is highlighted and then disappears the first time a key is pressed.
Via key binding C-f1
ok: Works fine; the region is highlighted and then disappears the first time a key is pressed.
no CUA mode (pretty much std emacs)
Evaluate via C-x C-e
NO-GO: Same as 1. when CUA is enabled.
Execute M-x call-trans-hi
NO-GO: The line is highlighted, but it is sticky! and requires C-g (keyboard-quit) to clear it.
Via key binding C-f1
NO-GO: The line is highlighted, but it is sticky! and requires C-g (keyboard-quit) to clear it.
;test (trans-hi) EOL
(defun trans-hi ()
"transient highlight"
(beginning-of-line)
(push-mark (point))
(end-of-line)
(activate-mark))
;test (call-trans-hi) EOL
(defun call-trans-hi ()
"call transient highlight"
(interactive)
(trans-hi))
(global-set-key [C-f1] 'call-trans-hi)
When you look at the source of activate-mark, you can see that it's just setting some variables. I suppose that's why you don't see the mark in both 1., because the actual highlighting happens in some stuff that's done when executing functions interactively instead of just calling them.
In the other cases of no CUA-mode, that just how transient highlighting works outside of CUA-mode. If you want the CUA-mode behaviour, use CUA-mode resp. that part of it.
EDIT:
Does this change (the addition of the setq line) to trans-hi make the highlighting work the way you want?
(defun trans-hi ()
"transient highlight"
(beginning-of-line)
(push-mark (point))
(end-of-line)
(setq transient-mark-mode (cons 'only transient-mark-mode))
(activate-mark))
If you want to see the region highlighted when you mark it, you need
to activate the minor mode transient-mark-mode.
When a region is highlighted and a character insterted the default is
to disable the highlighting and insert the character at the cursor.
If you wish you can delete the selected region by activating the minor
mode delete-selection-mode.

First elisp attempt - minor mode for tab key not being invoked on tab?

I've decided to get my toes wet with a bit of lisp, since I want to make emacs behave a little better when I hit TAB. My command works fine. It just performs indent-for-tab-command and if nothing happens, it performs tab-to-tab-stop, on the assumption that it's unlikely I was hitting TAB just to have the point refuse to budge when I'm inside a multi-line string or some such. After the first TAB press, it continues to do tab-to-tab-stop until either editing resumes, or the point is moved elsewhere. AFAIK, my logic is ok, though my lisp code probably isn't!
Originally I just hacked this into my emacs dot files by doing (local-set-key (kbd "TAB") 'tab-dwim) for major modes where I wanted this behaviour. That worked as expected.
Then I decided that what I was doing was basically a minor mode, so I tried to move the key-binding into a minor-mode. For some reason, even though the minor mode is enabled (as indicated in the mode line, and just from toggling it on and off), my tab-dwim function isn't being invoked when I hit the TAB key. I can still invoke it with M-x as expected.
What am I doing wrong with my minor mode's :keymap?
;;;
;; TAB DWIM
; buffer-local before/after point tracking
(setq point-before-tab nil)
(setq point-after-tab nil)
(make-local-variable 'point-before-tab)
(make-local-variable 'point-after-tab)
(defun tab-dwim ()
"Indents normally once, then switches to tab-to-tab-stop if invoked again.
tab-dwim will always perform tab-to-tab-stop if the first TAB press does not
cause the point to move."
(interactive)
(print "in tab-dwim now") ; THIS LINE IS NEVER INVOKED ON TAB?
(setq point-before-tab (point))
(if (eq point-before-tab point-after-tab) ; pressed TAB again
(tab-to-tab-stop)
(indent-for-tab-command))
(if (eq (point) point-before-tab) ; point didn't move
(tab-to-tab-stop))
(setq point-after-tab (point)))
(define-minor-mode tab-dwim-mode
"Toggle tab-dwim-mode.
With a non-nil argument, turns on tab-dwim-mode. With a nil argument, turns it
off.
When tab-dwim-mode is enabled, pressing the TAB key once will behave as normal,
but pressing it subsequent times, will continue to indent, using
tab-to-tab-stop.
If tab-dwim determines that the first TAB key press resulted in no movement of
the point, it will indent according to tab-to-tab-stop instead."
:init-value nil
:lighter " DWIM"
:keymap
'(([TAB] . tab-dwim)))
(provide 'tab-dwim)
Cheers,
Chris
I think you are very close.
Try this for your keymap:
'(("\t" . tab-dwim)))
Yes, use "\t" or the vector format "[(tab)]".
Some additional notes for your elisp development:
Avoid making global variables as much as possible. In this case, I think dynamically binding with let is appropriate. Also have a look at let*.
Understand the difference between make-local-variable and make-variable-buffer-local. The way you've written your code, the buffer-local variable would only exist in the buffer that loads your package.
As Nemo mentioned, it's extemely extremely extremely recommended that you use a common prefix for all variables/functions related to each package. Emacs has only one namespace, this is the "hacky" way to keep it somewhat organized.

viper-auto-indent breaks inferior modes

As a vim convert, I've gotten fairly used to viper mode. One issue that I've discovered, however, is that viper-auto-indent breaks all inferior modes. What happens is when I enter any sort of inferior mode (sql-mode, ess-mode, etc.) and hit Enter, the Enter key doesn't actually send the command off to the inferior process and gives the appearance of the process just hanging.
Without setting viper-auto-indent I have the problem that the Enter key doesn't automatically indent when writing code, meaning that I need to always hit tab after entering a new line, which is annoying. The workaround I've been using is to have viper-auto-indent enabled by default (since I spend most of my time programming), and then disabling it when I enter an inferior-mode buffer.
Does anyone know how to fix this problem? Alternatively, can anyone help supply me with the elisp to disable viper-auto-indent when switching to an interior mode buffer, and enabling it when in a non-inferior mode buffer? Thanks.
I think Emacs' intent is to have you use "C-j" for newline-and-indent, and let Enter be left alone.
If that is not yet acceptable to you, then this untested code may work:
(add-hook 'inferior-ess-mode-hook
'(lambda () (set (make-local-variable 'viper-auto-indent) nil))
I'm not able to reproduce your problem. I tried every level of viper-mode (1-5), and a number of inferior processes. That said, from your actual question, this code appears like it should fit the bill. If/when 'viper-autoindent is called, if the current buffer has a process, it calls the original binding for the keys just pressed. If there's no process, the original viper-autoindent is called.
(defadvice viper-autoindent (around viper-autoindent-but-not-when-buffer-has-process activate)
"work around reported user problem"
(if (and (this-command-keys)
(get-buffer-process (current-buffer)))
(let* ((viper-mode nil)
(thiskey (key-binding (this-command-keys))))
(when thiskey
(call-interactively thiskey)))
ad-do-it))