I'm trying to create "smart" abbreviations that expand to some text and then move the cursor. E.g., in C mode I'd like INC to expand to #include <> with the cursor between the <> signs. Or, in HTML mode: BF expanded to <b></b> with the cursor at the right spot.
What's a smart way of going about this (short of defining functions for all this and binding them to a key, which I don't want to do, because I'd prefer abbreviations)?
I would heartily recommend Yasnippets. It seems to be designed to do exactly what you want.
EmacsWiki: Yasnippet
ErgoEmacs summary of Yasnippet
Yasnippet on GitHub
You can install it through Elpa as well.
I think what you are looking for is this:
hippie-expand is an interactive compiled Lisp function in
`hippie-exp.el'. It is bound to M-pause. (hippie-expand arg)
Try to expand text before point, using multiple methods. The expansion
functions in hippie-expand-try-functions-list' are tried in order,
until a possible expansion is found. Repeated application of
hippie-expand' inserts successively possible expansions. With a
positive numeric argument, jumps directly to the arg next function in
this list. With a negative argument or just C-u, undoes the
expansion.
[back]
It is bound to M-pause on my system, probably not on yours yet.
Define abbrev. Than
M-x edit-abbrevs RET
Fourth slot receives a function. For example write:
(lambda nil (forward-char -1))
in order to move backwards one char after expansion.
Related
Since I don't want underline char _ to break a word, I put the script:
(modify-syntax-entry ?_ "w")
in the Emacs init file. The purpose is that for words like test_test, to double click the word will select the whole word before and after _.
But for some reason, the script is not working in initialization.
If I run
M-x eval-buffer
Then it will start to be effective. Why is that?
BTW, all other setups in init are working well, it is only the modify-syntax-entry that requires an additional evaluation after the initial launch.
See the Elisp manual, node Syntax Basics. There you will see this:
Typically, each major mode has its own syntax table, which
it installs in all buffers that use that mode. For example, the
variable emacs-lisp-mode-syntax-table holds the syntax table used by
Emacs Lisp mode, and c-mode-syntax-table holds the syntax table used
by C mode. Changing a major mode’s syntax table alters the syntax in
all of that mode’s buffers, as well as in any buffers subsequently put
in that mode.
You need to change the syntax table of the current buffer (which will
typically make the change for all buffers in the same mode).
The current syntax table, that is, the syntax table of the current buffer, is returned by function syntax-table. So that is what you pass to modify-syntax:
;; Modify the CURRENT syntax table (not `standard-syntax-table').
(modify-syntax-entry ?_ "w" (syntax-table))
Function syntax-table is described in the Elisp manual, node Syntax Table Functions.
However, you seem to want to make this change for all buffers, whatever the mode. Is that right? That's probably a mistake.
What you should probably do is this:
Decide which modes you want to modify this way.
For those modes, put the call to modify-syntax-entry in a function that you add to the mode hook of each of those modes (using add-hook).
For example, to modify the syntax of, say, foo-mode:
(defun my-syntax () (modify-syntax-entry ?_ "w" (syntax-table)))
(add-hook 'foo-mode-hook 'my-syntax)
A sideways solution: replace your problematic line of code with
(global-superword-mode 1)
This will tell Emacs that you like your "word movements" to actually operate on identifiers rather than what Emacs traditionally defines as words. The advantage is that it keeps the normal definition of words for internal use, so it should in theory break less code than your approach.
Every buffer has its own syntax table, which is usually dependent on the major mode of the buffer. When you run your code in the Emacs init file, it just modifies the syntax table of the temporary buffer that's used while loading the file, not your regular buffers.
Most syntax tables inherit from the standard syntax table, so you can make your change to that table by giving another argument to modify-syntax-entry:
(modify-syntax-entry ?_ "w" (standard-syntax-table))
On Emacs, while editing a text document of notes for myself (a .txt document, not a .tex document), I am using M-x set-input-method Ret TeX, in order to get easy access to various Unicode characters. So for example, typing \tospace causes a "→" to be inserted into the text, and typing x^2 causes "x2" to be inserted, because the font I am using has support for Unicode codepoints 0x2192 and 0x00B2, respectively.
One of the specially handled characters in the method is for the underscore key, _. However, the font I am using for Emacs does not appear to have support for the codepoints for the various subscript characters, such as subscript zero (codepoint 0x2080), and so when I type _0, I get something rendered as a thin blank in my output. I would prefer to just have the two characters _0 in this case.
I can get _0 by the awkward keystroke sequence _spacedel0, since the space keystroke in the middle of the sequence causes Emacs to abort the TeX input method. But this is awkward.
So, my question: How can I locally customize my Emacs to not remap the _ key at all when I am in the TeX input method? Or how can I create a modified clone (or extension, etc) of the TeX input method that leaves out underscore from its magic?
Things I have tried so far:
I have already done M-xdescribe-key on _; but it is just bound to self-insert-command, like many other text characters. I did see a post-self-insert-hook there, but I have not explored trying to use that to subvert the TeX input method.
Things I have not tried so far:
I have not tried learning anything about the input method architecture or its source code. From my quick purview of the code and methods. it did not seem like something I could quickly jump into.
So here is the solution I just found: Make a personalized copy of the TeX input method, with all of the undesirable entries removed. Then when using M-x set-input-method, select the personalized version instead of TeX.
I would have tried this earlier, but the built-in documentation for set-input-mode and its ilk does not provide sufficient guidance to the actual source for the input-methods for me to find it. It was only after doing another search on SO and finding this: Emacs: Can't activate input method that I was able to get enough information to do this on my own.
Details:
In Emacs, open /usr/share/emacs/22.1/leim/leim-list.el and find the entry for the input method you want to customize. The entry will be something like the following form:
(register-input-method
"TeX" "UTF-8" 'quail-use-package
"\\" "LaTeX-like input method for many characters."
"quail/latin-ltx")
Note the file name prefix referenced in the last element in the form above. Find the corresponding Elisp source file; in this case, it is a relative path to the file quail/latin-ltx.el[.gz]. Open that file in Emacs, and check it out; it should have the entries for the method remappings, both desired and undesired.
Make a user-local copy of that Elisp source file amongst your other Emacs customizations. Open that local copy in Emacs.
In your local copy, find the (quail-define-package ...) form in the file, and change the name of the package; I used FSK-TeX as my new name, like so:
(quail-define-package
"FSK-TeX" "UTF-8" "\\" t ;; <-- The first argument here is the important bit to change.
"LaTeX-like input method for many characters but not as many as you might think.
...)
Go through your local copy, and delete all the S-expressions for mappings that you don't want.
In your .emacs configuration file, register your customized input method, using a form analogous to the one you saw when you looked at leim-list.el in step 1:
(register-input-method
"FSK-TeX" "UTF-8" 'quail-use-package
"\\" "FSK-customized LaTeX-like input method for many characters."
"~/ConfigFiles/Elisp/leim/latin-ltx")
Restart Emacs and test your new input-method; in my case, by doing M-x set-input-method FSK-TeX, typing a_0, and confirming that a_0 shows up in the buffer.
So, there's at least one answer that is less awkward once you have it installed than some of the workarounds listed in the question (and as it turns out, are also officially documented in the Emacs 22 manual as a way to cut off input method processing).
However, I am not really happy with this solution, since I would prefer to inherit future changes to TeX mode, and just have my .emacs remove the undesirable entries on startup.
So I will wait to see if anyone else comes up with a better answer than this.
I did not test this myself, but this seems to be the exact thing you are looking for:
"How to disable underscore subscript in TeX mode in emacs" - source
Two solutions are given in this blogpot:
By the author of the blogpost: (setq font-lock-maximum-decoration nil) (from maximum)
Mentioned as comment:
(eval-after-load "tex-mode" '(fset 'tex-font-lock-subscript 'ignore))
The evil plugin for vim-like modal keybinding allows to map two subsequent presses of the _ key to the insertion of a single _ character:
(set-input-method 'TeX)
(define-key evil-insert-state-local-map (kbd "_ _")
(lambda () (interactive) (insert "_")))
(define-key evil-insert-state-local-map (kbd "^ ^")
(lambda () (interactive) (insert "^")))
When _ and then 1 is pressed, we get ₁ as before, but
when _ and then _ is pressed, we get _.
Analogous for ^.
As already explained in pnkfelix answer, it seems we have to make a personalized copy of the TeX input method. But here comes a lighter way to do that, without any file tweaking. Simply put the following in your .emacs :
(eval-after-load "quail/latin-ltx"
'(let ((pkg (copy-tree (quail-package "TeX"))))
(setcar pkg "MyTeX")
(assq-delete-all ?_ (nth 2 pkg))
(quail-add-package pkg)))
(set-input-method 'TeX)
(register-input-method "MyTeX" "UTF-8" 'quail-use-package "\\")
(set-input-method 'MyTeX)
The important part is the assq-delete-all line in the middle that remove all shortcut entries starting with _. It's a bit of a lisp hack but it seems to work. Since I'm also annoyed by the shortcuts starting with - and ^, I also use the following two lines to disable them :
(assq-delete-all ?- (nth 2 pkg))
(assq-delete-all ?^ (nth 2 pkg))
Note that afterwards you can M-x set-input-method at any time and indicate TeX or MyTeX to switch between the pristine TeX input method or the customized one.
There's a phenomenally useful feature of emacs lisp where you can evaluate the result of an expression and paste the result directly into a buffer.
Say I want to check addition works. Then I type:
(* 3 2)
and I define the keyboard macro:
(setq last-kbd-macro
[down ?\( ?i ?s ?= ? ?\C-\M-f ? ?\C-u ?\C-x ?\C-e ?\) home])
If I then place point above the expression, and press F4 to execute the macro, the expression turns into:
(is= (* 3 2) 6)
Which makes a nice regression test.
Unfortunately the same keyboard macro executed in a clojure/nrepl buffer results in:
(* 8 9)(is= )
and an error from clojure about not being able to resolve the symbol is=
So I think that something weird is happening to the ordering of things, and the macro is trying to evaluate the wrong thing.
Can anyone get this to work with clojure? (And in fact solve the general problem so that arbitrary keyboard macros work OK with C-u C-x C-e like they do with emacs lisp)
Edit since people seem to be misunderstanding:
Doing the keypresses by hand works fine in either an elisp or a clojure buffer. In one C-u C-x C-e evals with emacs lisp and in the other evals in the external clojure process.
The problem comes when trying to run a keyboard macro (recorded in a clojure buffer) which contains C-u C-x C-e
Running the macro in the clojure buffer, things get re-ordered somehow. It looks like the macro may be carrying on executing even though the eval-paste has not completed yet.
I was wondering if there was a way of forcing the keyboard macro (or corresponding function) to execute in the same order as it would by hand.
I'm quite happy to turn the keyboard macro into a proper elisp function if necessary.
Keyboard macros are a quick and dirty way to repeat a certain sequence of actions. They are very fragile because they remember the keys pressed, not the functions they invoke, so they may produce wildly different results depending on the buffer they are invoked in, the current command history, window configuration and what not.
In your case, chances are that one of the keys in the macro invoke a different command in the clojure/nrepl buffer than in the buffer in which you tested the macro. You really need to define the macro in the buffer in which it will be used.
If you are going to re-use the macro, I suggest that you write a emacs
lisp function which does what you want instead of messing with macros.
You might find the output of (format-kbd-macro nil t) useful, but note that you should not use the commands like eval-last-sexp in your function, use a lower-level function which returns the evaluation result instead of inserting it into the current buffer.
Addressing a problem you haven't had yet, but will soon: don't forget to insert a ' character before the result of evaluating the expression: you want (= (cons 1 nil) '(1)), not (= (cons 1 nil) (1)).
M-x < TAB > prints all the defined functions.
To check a variable is defined or not evaluating the following expression,
(boundp 'variable-name) C-x C-e will print t if the variable-name is defined else nill.
How to print all the defined variables in emacs.
It's unclear exactly what you want to do with a full list of symbols, since the way in which M-x displays function names is somewhat specialized.
Assuming that you want to programmatically obtain a list of all defined symbols, here's how auto-complete.el does it:
(loop for x being the symbols
if (boundp x)
collect (symbol-name x))
Note that you can also enter M-x describe-var RET, and then press TAB to get a sorted completion list of all symbols.
I presume (apropos-variable "." t) would show you all the variables defined at that point in time.
edit: I presumed wrongly, it would seem.
Interestingly, this actually shows me significantly fewer results than the auto-completions from describe-var.
Can anyone shed light on that?
e.g. the differences between these, when winner-mode has been enabled:
C-uM-x apropos-variable RET winner- RET
C-hv winner- TAB
edit 2: Ah... it looks like apropos may ignore any symbol which lacks a documentation string.
If it's possible, I suggest reassigning the accepted answer.
Extrapolating (heavily!) what is being asked for, here is a way to get a pretty-printed alist of all buffer-local variables with their values. This is very convenient for finding out why for instance a mode isn't behaving the way one expects.
To get this listing, do:
M-x pp-eval-expression RET (buffer-local-variables) RET
Relevant portions from this list can be added almost verbatim to a .dir-locals.el file for use with multiple files.
Vim completes words and lines with CTRL-X P and CTRL-L. There's a Emacs plugin called Company mode but this plugin interfere and cause conflicts with lots of things within Emacs (with global linum and yasnippets). I know that I can complete words with CTRL-/ in Emacs. But it is possible to take previously written lines to complete code?
Maybe you're looking for hippie-expand? From that web page (as of this writing, anyway):
HippieExpand looks at the word before
point and tries to expand it in
various ways including expanding from
a fixed list (like expand-abbrev),
expanding from matching text found in
a buffer (like dabbrev-expand) or
expanding in ways defined by your own
functions. Which of these it tries and
in what order is controlled by a
configurable list of functions.
For a comprehensive list of completion options visit the emacs wiki page on completion.
There are a gazillion ways to do completion in Emacs. Some are mode specific, some inline, some configurable and what not. Here is a list of modes that might help you.
Use numberic argument to complete by line, say M-5 M-/ will complete by line, while M-/ alone still complete the normal way.
hippe-expend function has a very useful feature which is :
With a positive numeric argument, jumps directly to the ARG next function in this list. With a negative argument or just C-u, undoes the expansion.
Customize the expansion functions in hippie-expand-try-functions-list and put the function try-expand-line as 5th list element, then you could use M-5 M-/ to complete by line.
This tip is very handy and useful and I highly recommend it.
Also worth noting: if your window manager does not steal Alt-tab, emacs will auto-complete with Alt-tab (I set up my window manager to user the "windows key" instead of alt for this very reason).
If you are using evil, this is the most vim-like solution I use:
(defun my-expand-lines ()
(interactive)
(let ((hippie-expand-try-functions-list
'(try-expand-line-all-buffers)))
(call-interactively 'hippie-expand)))
(define-key evil-insert-state-map (kbd "C-x C-l") 'my-expand-lines)
This way you can use our old friend C-x C-l in insert mode for whole line all buffers completion.
Thanks #ymln for the suggestion of using try-expand-line-all-buffers.