My RSI is acting up, and I am trying to remap some keys in Emacs to help. Here's what I want to do:
Be able to type the { character with the sequence M-j.
Remove the ability to type the { character with the { key.
I've gotten 1 working by myself but not 2. Point 2 is important for me because the habit is pretty deeply ingrained in me, and I need a reminder to help me switch.
Is this possible? Thank you!
-Patrick
The original poster indicated that he remapped { to M-j, which caused Emacs to treat the latter as the former. In other words, the behavior for { was the same as M-j.
The following is a means of separating the two, and will serve to help remind the original poster that he wishes to train himself not to press the { key:
(global-set-key [?\M-j] (lambda () (interactive) (insert "{")))
(global-set-key "{" (lambda () (interactive) (message "Bad boy!")))
;;; OR use the following instead:
;; (global-set-key "{" nil)
Related
I've just started using emacs, and there's one feature I'd really like, and searching around a bit was fruitless. I hope someone else has done this because I don't want to learn elisp just yet.
void foo()<cursor>
I would like typing an "{" to cause this to happen
void foo(){
<cursor>
}
I would like this to only happen in cc-mode, and only at the end of a line when not in a string/comment/etc
The first thing that came to mind was rebinding "{" to do this always(I could figure out how to do this myself), but it would be hard to make it only happen at the right time.
any hints would be appreciated.
on latest emacs you can use :
electric-pair-mode is an interactive compiled Lisp function.
(electric-pair-mode &optional ARG)
Automatically pair-up parens when inserting an open paren.
this is integrated in Emacs 24.1 (actually CVS)
This will do it:
(defun my-c-mode-insert-lcurly ()
(interactive)
(insert "{")
(let ((pps (syntax-ppss)))
(when (and (eolp) (not (or (nth 3 pps) (nth 4 pps)))) ;; EOL and not in string or comment
(c-indent-line)
(insert "\n\n}")
(c-indent-line)
(forward-line -1)
(c-indent-line))))
(define-key c-mode-base-map "{" 'my-c-mode-insert-lcurly)
turn on electric-pair-mode in emacs 24 or newer version.
(electric-pair-mode 1)
I heartily recommend you to try out the excellent autopair minor mode - it does a lot more than simply inserting braces and makes Emacs a lot more IDE like in that area. I guess combining it with the electric braces setting in cc-mode will give you more or less the behavior you seek.
Try yasnippet (or on the Emacs Wiki page yasnippet). There are many packages for Emacs which support doing this kind of thing, but yasnippet seems to have momentum currently and is very extensible. Check out the videos.
You will need to delve into emacs-lisp to do this exactly as you wish, since YASnippet will do something nice for you but not exactly what you're asking for.
I think the simplest way to do this would be to bind a function to the RET key, in the cc-mode key-map.
The function should check to that the previous character is an { and if so, perform the required RET, RET, TAB, }, Up, TAB to get the cursor where you want and the closing } inserted.
You can make the feature more robust by having it check for a balanced closing } but this would be more complicated, and I'd recommend seeing how it feels without this additional polishing feature.
If you like I can write the function and the key-map binding for you, but since you asked for an idea of how it's done, I'll leave it up to you to ask for more assistance if you need it.
Alternatively, I find that autopair.el does this nicely enough for me, and I do the newlines myself ;)
You might want to keep the option of an empty function body, in which case you would want the closing brace to stay on the same line. If that is the case, then you can try this alternative solution:
Rely on the packages mentioned in the previous replies to automatically add the closing brace.
When you want to add statements to the function body, you press the Return key (while the automatically added closing brace is still under the cursor). The 'Return' key is bound as follows:
;; automatic first line in function
(defun my-c-mode-insert-funline ()
(interactive)
(newline-and-indent)
(when (looking-at "}")
(newline-and-indent)
(forward-line -1)
(c-indent-line)))
(global-set-key (kbd "RET") 'my-c-mode-insert-funline)
Here's the bigger picture of what I'm trying to do:
With a keypress, it will insert an opening and closing parenthesis right after/before the innermost closing/opening delimiter (bracket, brace, parenthesis, whatever).
But if it is pressed immediately after, it will undo the last insertions, seek out the next closing delimiter, and put it after that, and so on.
I have a working version of the first part, but am looking for "best practices" for the second part (where it undoes and moves outwards)
As a motivator and concrete example, this is a typical scenario when coding in Python. I work with list comprehensions a lot, and often I construct the list, and then decide I want to sum all elements, etc. So I would first type:
[x*x for x in some_lst if is_prime(x)]
and then I'll want to encapsulate this list with a "sum" command:
sum([x*x for x in some_lst if is_prime(x)])
I don't want to have to keep moving the cursor to both the beginning and the end just to insert the parentheses. I'd rather have the point in the list, press a keystroke, have it figure out the delimiters, and place the mark just before the opening inserted parenthesis so that I can type "sum". My function below seems to work (piggybacking on the "expand-region" package):
(defun add-paren ()
(interactive)
(er/mark-outside-pairs)
(exchange-point-and-mark)
(insert-string ")")
(exchange-point-and-mark)
(insert-string "(")
(left-char 1)
)
What's the best practice for the 2nd step?
(Any suggestions/improvements to the above would also be appreciated. This is my first "real" function in Elisp.)
Thanks.
Update: Thanks everyone for the tips. I'll probably use some of them in my final solution. My original question still stands: Is there a standard pattern of "undoing and redoing at a larger scale", or will each problem have its own custom solution? Suppose I use smartparens as suggested to do it all in one keystroke, but I want it to occur on the 3rd level out. What I want is to press the keystroke 3 times and have it place the parentheses there.
So after the first keystroke, it places the parentheses at the innermost level. Pressing it again should remove the inserted parentheses, and place them in the next level up, and so on...
(BTW, not trying to reinvent the wheel. I suspect some of the packages listed may have exactly what I need - I just want practice coding in Elisp).
Update 2:
I guess there is no best practice for this? Anyway, I solved the problem using both expand-region and smartparens:
(defun add-paren ()
(interactive)
(if (eq last-command 'add-paren)
;; (message "AAAA")
(delete-paren)
)
(setq currpoint (point))
(er/mark-outside-pairs)
(if (eq currpoint (point))
(er/mark-outside-pairs)
)
(sp-wrap-with-pair "(")
(left-char 1)
)
(global-set-key (kbd "<f5>") 'add-paren)
(defun delete-paren ()
(interactive)
(setq currloc (point))
(sp-unwrap-sexp)
(goto-char currloc)
(left-char 1)
)
You're already using expand-region. Why not combine that with one of the many "surround region with..." modes?
I personally like smartparens (available via Marmalade or MELPA), but there are many other similar tools.
Use er/expand-region until you've got an appropriate selection, then
( to wrap in parentheses.
When programming, there are several hundred slightly different edit-tasks of this kind. Therefor created a toolkit for it.
In example given, the form might be described as delimited, more precisely bracketed.
ar-bracketed-atpt would mark it.
It's set here like this:
(global-set-key [(super \])] 'ar-bracketed-atpt)
Then comes in another class of commands which do several things on active region. In this case:
M-x ar-parentize-or-copy-atpt RET
It is bound to C-c )
A tarball for all this stuff is available here:
https://launchpad.net/s-x-emacs-werkstatt/
FWIW, I'd do it as follows:
go before the open bracket.
type sum C-M-SPC (
The C-M-SPC selects the parenthesized (well, "bracketized") expression, and the subsequent ( wraps it in parens (because of electric-pair-mode).
I guess there is no best practice for this? Anyway, I solved the problem using both expand-region and smartparens:
(defun add-paren ()
(interactive)
(if (eq last-command 'add-paren)
;; (message "AAAA")
(delete-paren)
)
(setq currpoint (point))
(er/mark-outside-pairs)
(if (eq currpoint (point))
(er/mark-outside-pairs)
)
(sp-wrap-with-pair "(")
(left-char 1)
)
(global-set-key (kbd "<f5>") 'add-paren)
(defun delete-paren ()
(interactive)
(setq currloc (point))
(sp-unwrap-sexp)
(goto-char currloc)
(left-char 1)
)
I have a function in my emacs dot file to insert a date in my journal. After adding it, I would like to jump back a couple of lines and place the cursor below the date. How do I do that in the function?
(defun ddd ()
"Insert date at point journal style."
(interactive)
(insert (format-time-string "[%Y-%m-%d %a]"))
(insert "\n")
(insert "\n")
(insert "\n")
(insert "** end\n")
(gobacktwolineshere))
Any ideas?
You want the function forward-line, specifically
(forward-line -2)
goes backward two lines. For more information, type C-h f forward-line RET inside emacs. Depending on where you've left point, you might not end up at the beginning of the line. If you want this, add a call to beginning-of-line.
Remember that if you can tell Emacs to do it interactively (e.g. with <up> or C-p in this instance) then you can ask Emacs what it does when you type that, by prefixing C-hk.
In this case, Emacs tells you that those keys run the command previous-line, and also:
If you are thinking of using this in a Lisp program, consider using
forward-line with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.).
You might want to use save-excursion to make it more robust:
(defun ddd ()
"Insert date at point journal style."
(interactive)
(insert (format-time-string "[%Y-%m-%d %a]\n"))
(save-excursion (insert "\n\n** end\n")))
If you know how many characters you want to go back, you can use (backward-char 9).
I use Emacs to write research papers (which include a lot of text .. duh). I always want to move from a period (.) to another period - basically, move from beginning of a sentence to the end (and vice-versa). I have not found any key map that does this (M-a, M-e, C-x C-t are not what I require). I don't have much experience with elisp. If someone can point to me and existing key-map or a function, I would be very grateful.
TIA
S.
M-e (forward-sentence) is the right way to go. It would take care of going to the end of the next sentence (although I think it relies on there being two spaces after the period to decide that it's a sentence end rather than an abbreviation point).
If you just want to jump to the next ., you can use this (I presume you're editing your files in text-mode).
(add-hook 'text-mode-hook (lambda ()
(local-set-key (kbd "C-c .")
(lambda () (interactive) (search-forward "." nil t)))))
and use C-c . to jump to the next period.
I've just started using emacs, and there's one feature I'd really like, and searching around a bit was fruitless. I hope someone else has done this because I don't want to learn elisp just yet.
void foo()<cursor>
I would like typing an "{" to cause this to happen
void foo(){
<cursor>
}
I would like this to only happen in cc-mode, and only at the end of a line when not in a string/comment/etc
The first thing that came to mind was rebinding "{" to do this always(I could figure out how to do this myself), but it would be hard to make it only happen at the right time.
any hints would be appreciated.
on latest emacs you can use :
electric-pair-mode is an interactive compiled Lisp function.
(electric-pair-mode &optional ARG)
Automatically pair-up parens when inserting an open paren.
this is integrated in Emacs 24.1 (actually CVS)
This will do it:
(defun my-c-mode-insert-lcurly ()
(interactive)
(insert "{")
(let ((pps (syntax-ppss)))
(when (and (eolp) (not (or (nth 3 pps) (nth 4 pps)))) ;; EOL and not in string or comment
(c-indent-line)
(insert "\n\n}")
(c-indent-line)
(forward-line -1)
(c-indent-line))))
(define-key c-mode-base-map "{" 'my-c-mode-insert-lcurly)
turn on electric-pair-mode in emacs 24 or newer version.
(electric-pair-mode 1)
I heartily recommend you to try out the excellent autopair minor mode - it does a lot more than simply inserting braces and makes Emacs a lot more IDE like in that area. I guess combining it with the electric braces setting in cc-mode will give you more or less the behavior you seek.
Try yasnippet (or on the Emacs Wiki page yasnippet). There are many packages for Emacs which support doing this kind of thing, but yasnippet seems to have momentum currently and is very extensible. Check out the videos.
You will need to delve into emacs-lisp to do this exactly as you wish, since YASnippet will do something nice for you but not exactly what you're asking for.
I think the simplest way to do this would be to bind a function to the RET key, in the cc-mode key-map.
The function should check to that the previous character is an { and if so, perform the required RET, RET, TAB, }, Up, TAB to get the cursor where you want and the closing } inserted.
You can make the feature more robust by having it check for a balanced closing } but this would be more complicated, and I'd recommend seeing how it feels without this additional polishing feature.
If you like I can write the function and the key-map binding for you, but since you asked for an idea of how it's done, I'll leave it up to you to ask for more assistance if you need it.
Alternatively, I find that autopair.el does this nicely enough for me, and I do the newlines myself ;)
You might want to keep the option of an empty function body, in which case you would want the closing brace to stay on the same line. If that is the case, then you can try this alternative solution:
Rely on the packages mentioned in the previous replies to automatically add the closing brace.
When you want to add statements to the function body, you press the Return key (while the automatically added closing brace is still under the cursor). The 'Return' key is bound as follows:
;; automatic first line in function
(defun my-c-mode-insert-funline ()
(interactive)
(newline-and-indent)
(when (looking-at "}")
(newline-and-indent)
(forward-line -1)
(c-indent-line)))
(global-set-key (kbd "RET") 'my-c-mode-insert-funline)