Emacs caps lock minor mode? - emacs

Is there a command in Emacs to turn on what might be described as "caps lock minor mode"? I'm looking to do something like M-x toggle-caps-mode, then every letter I type in the buffer is a capital letter until I do M-x toggle-caps-mode again.
Note: I'm NOT looking for directions on how to swap caps and control. In reality this is because I have already done that. I am generally quite happy with it, but occasionally I'm editing code where there are a bunch of constants that are in all caps, and it gets to be a strain holding down the shift key. I'm aware of the various upcase conversion functions; I'd rather not have to type the word, select it, then run upcase-region.
If it matters, I'm using Aquamacs 2.2 w/ Emacs 23.3.1.

You don't need to type the word then select it. If you want to upcase the last word, press M-b M-u or ESC b u. Ok, you'll need to press b several times if it's a word_with_underscores.
If you really want a caps lock minor mode, try John Paul Wallington's lockcaps.el.

You can try something like this:
(define-minor-mode caps-lock-mode
"caps-lock mode"
;; The initial value.
nil
;; The indicator for the mode line.
" CAPS-LOCK"
;; The minor mode bindings.
'(("a" . (lambda () (interactive) (insert-char ?A 1)))
("b" . (lambda () (interactive) (insert-char ?B 1)))
;;etc
("A" . (lambda () (interactive) (insert-char ?a 1)))
("B" . (lambda () (interactive) (insert-char ?b 1)))
;;etc
))

Related

How to delete(or kill) the current word in emacs?

For example, my cursor (point) is at an arbitrary letter in the word "cursor". I want to delete (kill) that word such that it is copied to kill-ring.
The Emacs way to remove the word one is inside of to press M-backspace followed by M-d. That will kill the word at point and save it to kill ring (as one unit).
If the cursor is at the beginning or after the end of the word, only one of the two is sufficient. An Emacs user will typically move between words using commands such as forward-word (M-f) and backward-word (M-b), so they will be at the word boundary to begin with and thus rarely need to kill the word from the inside.
You could use this as a framework for killing various kinds of things at point:
(defun my-kill-thing-at-point (thing)
"Kill the `thing-at-point' for the specified kind of THING."
(let ((bounds (bounds-of-thing-at-point thing)))
(if bounds
(kill-region (car bounds) (cdr bounds))
(error "No %s at point" thing))))
(defun my-kill-word-at-point ()
"Kill the word at point."
(interactive)
(my-kill-thing-at-point 'word))
(global-set-key (kbd "s-k w") 'my-kill-word-at-point)
You can do that by moving to the beginning of the word (if not standing there already) by M-b, then deleting it with M-d. You can then press C-y to put it back. If you want to automate it, you can create a short elisp function and assign it to a key:
(global-set-key [24 C-backspace] ; C-x C-backspace
(lambda () (interactive)
(save-excursion
(backward-word)
(kill-word 1)
(yank))))

How can I get `emacs -nw` to work with xterm using UTF-8 locale?

I'm using Emacs 23 with xterm and am trying to bring my Linux system into the 21st century by switching from a POSIX locale to en_US.utf8. Problem: when I use the Alt key on the keyboard in this locale, xterm sends a two-character sequence. I'd like to fix emacs so that it sees, e.g., Alt-f as meta-f rather than the two-character sequence "\303\246". I think this might be a job for an input coding, but from the emacs documentation I have not figured out how to write one.
As an alternative I would be willing to add octal '\303' to a keymap so that emacs would treat it as a prefix character to introduce a meta escape. The way I would prefer to do this would be to bind '\303' to a function that then takes the next key and adjusts it as a meta key. But I can't quite figure out that one either.
Worst case I guess I write a loop that binds the meta keys for 'a' through 'z' or something equally horrid.
I've messed around with the set-terminal-coding-system, but the crux of the matter is that in a UTF-8 locale, xterm uses the Alt key to send non-ascii characters—the Alt key no longer behaves like meta. So setting the terminal coding system to UTF-8 merely enables me to enter Latin characters with diacritical marks. Not the behavior I hoped for.
I found a really horrid answer that involves guessing what xterm is doing around the meta key. Suggestions for improvement are welcome—I'd like to find code that could do this job cleanly.
(And FYI, I'm not the only one with this problem.)
Here's a truly horrible hack:
(unless (display-graphic-p)
(defun make-meta-key ()
(interactive)
(let ((e (read-event)))
(if (numberp e)
(let ((keys (vector (event-convert-list (list 'meta
(+ (event-basic-type e) 64))))))
(let ((result (key-binding keys)))
(command-execute result)))
(error "this can't happen"))))
(global-set-key [?\M-C] 'make-meta-key))
This seems to work around what xterm is doing.
ETA: revision to handle more meta sequences:
(unless (display-graphic-p)
;; deal with the Unicode sequences that xterm sends when Alt (meta) keys
;; are used. N.B. Works with Alt-letter, Alt-\, Alt-space, and Alt-Shift-:
(defun make-meta-key ()
(interactive)
(let ((e (read-event)))
;; (message "Got event %s; basic event is %s" e (event-basic-type e))
(if (numberp e)
(let* ((basic (event-basic-type e))
(shifted (+ basic 64))
(basecode (if (<= shifted 127) shifted basic))
(keys (vector (event-convert-list (list 'meta basecode))))
(command (key-binding keys)))
;; (message "Result is %s; commandp says %s" command (commandp command))
(command-execute command))
(error "this can't happen"))))
(global-set-key [?\M-C] 'make-meta-key)
(defun do-nothing () (interactive) nil)
(global-set-key [?\M-B] 'do-nothing))

How to use vimpulse together with autopair.el

It seems that when vimpulse is running, autopair only works partially in the sense that pressing backspace in empty bracket pairs will no longer remove the closing bracket but only the opening one (which means backspace functions as normal backspace now). An example:
(When Vimpulse and autopair are both active, and current mode is INSERT mode, "|" denotes the cursor)
begin: (|)
Now press "backspace"
expected result: | (both opening and closing brackets are removed)
actual result: |) (only the opening bracket is removed)
I know this has to do with the fact that vimpulse (or rather viper-mode) remapped [backspace] from delete-backward-char to something else (viper-delete-backward-char I think). But I could not find a fix to it.
Could anybody find a solution to this? (so that backspace key will remove both opening and closing bracket when the bracket is empty and cursor is in between).
Thanks!
i think something like this in your init file would work:
(add-hook 'autopair-mode-hook
'(lambda ()
(define-key autopair-emulation-alist [remap viper-delete-backward-char] 'autopair-backspace)))
I will answer this question myself.
I could not figure out an "orthodoxy" way to solve the problem and I came up with a hack.
The function that is bound to in viper insert mode (viper-del-backward-char-in-insert) is adviced to check whether cursor is currently in a matched pair, if so, the character after the cursor is deleted before the actual function is called. This also takes into account possible problem caused by prefix character (backslash).
Just copy the code below into your .emacs file after viper-mode or vimpulse is loaded.
(defun not-escaped (escape-char)
"Character immediately before cursor is not prefixed by escape-char"
(let ((count 0))
(save-excursion
(if (char-before)
(backward-char))
(while (and (char-before)
(= (char-before) escape-char))
(setq count (+ count 1))
(backward-char))
(if (= 0
(% count 2))
t
nil))))
(defun in-matched-empty-pair (pair-list)
"tell if cursor is in an empty pair in pair-list"
(let ((next-char (char-after))
(prev-char (char-before))
(matched nil)
(pair)
(pair-left)
(pair-right))
(if (and next-char
prev-char)
(while (and (setq pair
(pop pair-list))
(not matched))
(setq pair-left (pop pair)
pair-right (pop pair))
(if (= next-char pair-right)
(if (and
(= prev-char pair-left)
(not-escaped ?\\))
(setq matched t)))))
(if matched
t
nil)))
(defvar viper-workaround-pairs
'(
(?\" ?\")
(?\' ?\')
(?\` ?\`)
(?\( ?\))
(?\[ ?\])
(?\{ ?\})
))
;; Workaround for integration problem with autopair
(defadvice viper-del-backward-char-in-insert (before viper-auto-delete-pair-backward())
(if (in-matched-empty-pair viper-workaround-pairs)
(delete-char 1)))
;; Activate advice
(ad-activate 'viper-del-backward-char-in-insert)
This is a hack but it is probably the best I could do now.
Here is my updated solution. Put the following in your .emacs file after the code that loads autopair and vimpulse:
(add-to-ordered-list 'emulation-mode-map-alists (car (last emulation-mode-map-alists)) 400)
It moves autopair's keymap in front of viper's one, giving it higher priority.
Maybe you have to adept the order number (here 400), depending on whether you are using additional emulation-modes.
The result can be checked with C-x v emulation-mode-map-alists. In my case:
(viper--intercept-key-maps cua--keymap-alist autopair-emulation-alist viper--key-maps)
Now, autopair-emulation-alist should be listed before viper--key-maps.
baumichel found the trick. I just add a quick snippet to help :
First, as autopair-mode simply appends autopair-emulation-alist, evaluate:
(defadvice viper-change-state-to-insert (after autopair nil activate)
(add-to-ordered-list 'emulation-mode-map-alists 'autopair-emulation-alist 300))
Then, remember that vimpulse-normalize-minor-mode-map-alist removes all viper keymaps in front of the alist, so execute:
(defadvice vimpulse-normalize-minor-mode-map-alist (after order-viper--key-maps nil activate)
(add-to-ordered-list 'emulation-mode-map-alists 'viper--key-maps 500))
That works for me! I evaluate these snippets in an embedded eval-after-load for both vimpulse and autopair.
My idea is that Emacs dev should rethink the emulation-mode-map-alists and use a property list indexing priority order like this: ((:name viper--key-maps :after (cua--keymap-alist autopair-emulation-alist)) (:name viper--intercept-key-maps :before (cua--keymap-alist autopair-emulation-alist))). Old packages like viper, CUA and so on should be better maintained because our setup becomes ugly after years with Emacs.

In Emacs can you evaluate an Emacs Lisp expression and replace it with the result?

For example if I have the text:
Sum of items is (+ 1 2 3)
I want to move to the end of the line, evaluate the expression and replace it with the result, so that it reads:
Sum of items is 6
With the cursor at the end of the line, C-u C-x C-e will insert the value of the preceding parenthesized expression into the buffer. You could do that, then manually back up and delete the original expression. If that's too much work, here's a command that evaluates the preceding expression and replaces it with its value:
(defun replace-last-sexp ()
(interactive)
(let ((value (eval (preceding-sexp))))
(kill-sexp -1)
(insert (format "%S" value))))
Related to this, you might like Luke Gorrie's "lively.el", which provides live replacement of emacs lisp expressions within a text buffer. It's a neat hack.
I was having a go at a solution for this when I came across one in a Google search result.
(defun fc-eval-and-replace ()
"Replace the preceding sexp with its value."
(interactive)
(backward-kill-sexp)
(prin1 (eval (read (current-kill 0)))
(current-buffer)))
http://emacs.wordpress.com/2007/01/17/eval-and-replace-anywhere/
replace-regex functions can execute lisp to generate the replacements.
In the trivial instance where the sexp in question is on a single line, and is the only thing containing parenthesis, then you could match "(.+)" and replace with "\,(eval (read \&))".
If you are using emacs starter kit by technomancy there is "esk-eval-and-replace" function which evaluates the elisp sexp and replace them. Its bind to C-c e by default.
look to the function eval-print-last-sexp, you can build something using it
My emacs-fu isn't so strong, so I don't know if there's a single command to do this, but you can make yourself a (somewhat fragile) macro for it ... drop these lines in your .emacs:
(fset 'eval-sexp-in-place
[?\M-x ?e ?v ?a ?l ?- ?p ?r ?i ?n tab return ?\M-^ ?\M-^ ?\C-\M-b ?\C-\M-k ?\C-d])
(global-set-key [(control x) (control a)] 'eval-sexp-in-place)
This works fine, but there's one issue with it: you need to be at the end of the sexp (i.e. after the last right paren) to get it to work.
Also, I picked a random unbound key (C-x C-a) -- feel free to change that to something more to your liking.

About the forward and backward a word behaviour in Emacs

I don't know if there's something wrong with my settings but when I press M-f (forward a word)
it doesn't matter where I am, it never place the cursor in the next word (just between words). This doesn't happen with M-b which place my cursor in the beginning of the previous word.
Is this a normal behavior? How do I place my cursor at the beginning of the following word?
The macro solution described is a great way to get this behavior in a session, but it's a little inconvenient if that's the default behavior you want, since you have to define it every time you start emacs. If you want M-f to work like this all the time, you can define an elisp function and bind it to the key. Put this in your .emacs file:
(defun next-word (p)
"Move point to the beginning of the next word, past any spaces"
(interactive "d")
(forward-word)
(forward-word)
(backward-word))
(global-set-key "\M-f" 'next-word)
Ok, just so we're clear, Im going to assume you are talking about the commands forward-word and backward-word these are bound by default to Alt+f and Alt+b
eg string: "Hello dolly I am here"
If your cursor is on the "H" of "Hello", and you do forward-word the cursor will move to the space between "Hello" and "dolly", but it sounds like you want the cursor to be on the letter "d" of "dolly" instead of in-front of it.
So, do forward-word twice, then backward-word once.
That will put your cursor on the "d" of "dolly".
This can be automated with a macro.
;; = comments, do not type them
Ctrl+x ( ;;start macro
Alt+f Alt+f Alt+b
Ctrl+x ) ;;end macro
Then to run last defined macro do this:
Ctrl+x e
EDIT: as pascal mentioned in a comment, this can also just be done with
Alt+f Ctrl+f
You could put that into a macro as well, either way the result is the same.
That is correct behavior. According to the Emacs manual, "[f]orward motion stops right after the last letter of the word, while backward motion stops right before the first letter."
Why is it this way? Perhaps to be consistent with kill-word (M-d).
Moving forward twice and backwards once is fine unless you are at the beginning of a line with spaces in the front. Then going forward twice and back once will move you to the next word not the first word. The code below will mimic vi's "w" command perfectly. I've written this quite fast so this code can be cleaned up further.
(defun forward-word-to-beginning (&optional n)
"Move point forward n words and place cursor at the beginning."
(interactive "p")
(let (myword)
(setq myword
(if (and transient-mark-mode mark-active)
(buffer-substring-no-properties (region-beginning) (region-end))
(thing-at-point 'symbol)))
(if (not (eq myword nil))
(forward-word n))
(forward-word n)
(backward-word n)))
(global-set-key (kbd "M-C-f") 'forward-word-to-beginning)
Try something like following:
;; replace common word-operations on same-syntax-operations
(require 'thingatpt)
(global-set-key "\M-f" 'forward-same-syntax)
(global-set-key "\M-b" (lambda()
(interactive)
(forward-same-syntax -1)))
(defun kill-syntax (&optional arg)
"Kill ARG sets of syntax characters after point."
(interactive "p")
(let ((opoint (point)))
(forward-same-syntax arg)
(kill-region opoint (point))))
(global-set-key "\M-d" 'kill-syntax)
(global-set-key [(meta backspace)] (lambda()
(interactive)
(kill-syntax -1)))
You can achieve this behavior by using the forward-to-word and backward-to-word found in misc.el. I have these bound to Meta-F/Meta-B (i.e. with Shift pressed). These are equivalent to Meta-f/Meta-b for forward-word/backward-word
My .emacs has the following bindings
(global-set-key (kbd "M-F") #'forward-to-word)
(global-set-key (kbd "M-B") #'backward-to-word)