GNU Emacs 24.3.1
Hello,
I am doing some coding in Java using emacs. Just to make my coding easier I want to auto indent each time I insert a semi-colon or curly brace {
;; Auto indent for java mode
(add-hook 'java-mode-hook '(lambda ()
(local-set-key (kbd "RET") 'newline-and-indent)))
(add-hook 'java-mode-hook '(lambda ()
(local-set-key (kbd "{") 'newline-and-indent)))
(add-hook 'java-mode-hook '(lambda ()
(local-set-key (kbd ";") 'newline-and-indent)))
The return works as expected. However, the curly brace and semi-colon just returns without entering the the ; or {.
Is this possible?
many thanks for any suggestions,
It's possible. Here is one way of doing it (replace the second and third call to add-hook with this):
(defun java-autoindent ()
(when (and (eq major-mode 'java-mode) (looking-back "[{;]"))
(newline-and-indent)))
(add-hook 'post-self-insert-hook 'java-autoindent)
The way this works is that every time you type a character in a java-mode buffer, Emacs will
check if that character is { or ;, and if that's the case
run newline-and-indent.
Related
I know this type of question have been asked by many people,
but I have read many similar posts and still have no idea
what to do. So here is the elisp code in .emacs:
;; send line to python console
(require 'python-mode)
(defun py-execute-line-down ()
"execute python line and move cursor down"
(progn
(py-execute-line)
(evil-next-line)))
(add-hook 'python-mode-hook
(lambda () (define-key python-mode-map (kbd "C-c C-j") 'py-execute-line-down)))
I also tried to add (interactive) into the function, it didn't work.
Just to keep the record here, this seemed to do the trick, not sure if it's optimal though:
;; send line to python console
(require 'python-mode)
(defun py-execute-line-down ()
"execute python line and move cursor down"
(interactive)
(py-execute-line)
(evil-next-line 1))
(defun kaiyin-pykeys ()
"python mode custome keys"
(local-set-key (kbd "C-c j") 'py-execute-line-down)
)
(add-hook 'python-mode-hook 'kaiyin-pykeys)
Taking Dan's advice, I changed the above into:
;; send line to python console
(require 'python-mode)
(defun py-execute-line-down ()
"execute python line and move cursor down"
(interactive)
(py-execute-line)
(forward-line 1))
(define-key python-mode-map (kbd "C-c j") 'py-execute-line-down)
I'm completely new to both Lisp and Emacs. In Emacs, when coding in Java for example, I want to be able to type "{" then hit "ENTER" and have the next line be ready for whatever is nested in the braces. For example, if I have the following line:
public void method()
and I type "{" then hit return I should get this:
public void method() {
// indentation applied, no additional tabbing necessary
}
I'm already able to insert by pairs, for example, typing "{" gives "{}" with my cursor between the braces. I did this by adding these lines to the emacs init file:
;; insert by pairs (parens, quotes, brackets, braces)
(defun insert-pair (leftChar rightChar)
(if (region-active-p)
(let (
(p1 (region-beginning))
(p2 (region-end))
)
(goto-char p2)
(insert rightChar)
(goto-char p1)
(insert leftChar)
(goto-char (+ p2 2))
)
(progn
(insert leftChar rightChar)
(backward-char 1) ) )
)
(defun insert-pair-brace () (interactive) (insert-pair "{" "}") )
(global-set-key (kbd "{") 'insert-pair-brace)
To get the auto-nesting I described above, I added these lines:
;; automatically nest next line
(defun auto-nest ()
(insert "\n\n")
(backward-char 1)
(insert "\t")
)
(defun auto-nest-brace () (interactive) (auto-nest) )
(global-set-key (kbd "{ RET") 'auto-nest-brace)
When I start up Emacs, however, I get this message:
error: Key sequence { RET starts with non-prefix key {
What am I doing wrong, and what can I do to fix it? I don't want to use a different key combination to do this. There are a lot of text editors in which this auto-nesting is standard, and it should be easy enough to code up in ELisp.
It's great that you are trying to add this functionality to Emacs yourself, but there's no need to reinvent the wheel here. Emacs already has a command for the purpose of auto-indenting; it's called newline-and-indent. It is bound to C-j by default, but you can rebind it to RET
globally:
(global-set-key (kbd "RET") 'newline-and-indent)
for a specific mode only:
(require 'cc-mode)
(define-key java-mode-map (kbd "RET") 'newline-and-indent)
java-mode-map is defined in cc-mode.el and not available by default, that's why you have to require cc-mode before you can modify java-mode-map.
Note that newline-and-indent indents according to major mode. That is, if you're e.g. in java-mode and press RET in some random location that's not meaningful w/r/t Java syntax, it won't insert additional whitespace at the beginning of the new line.
To read all there is to know about newline-and-indent do
C-h f newline-and-indent RET
I have something similar in my emacs config which I have been using for a while. It calls 'newline-and-indent twice then moves the point one line up before indenting correctly. Here is the snippet of code to do this from my config file:
;; auto indent on opening brace
(require 'cc-mode)
(defun av/auto-indent-method ()
"Automatically indent a method by adding two newlines.
Puts point in the middle line as well as indent it by correct amount."
(interactive)
(newline-and-indent)
(newline-and-indent)
(forward-line -1)
(c-indent-line-or-region))
(defun av/auto-indent-method-maybe ()
"Check if point is at a closing brace then auto indent."
(interactive)
(let ((char-at-point (char-after (point))))
(if (char-equal ?} char-at-point)
(av/auto-indent-method)
(newline-and-indent))))
(define-key java-mode-map (kbd "RET") 'av/auto-indent-method-maybe)
Pretty straightforward as you can see. Hopefully it will work for you. I have not used it in any other modes except java.
You want a combination of auto pairs (or alternatives) plus auto indentation. Check out the emacswiki on the former: http://www.emacswiki.org/emacs/AutoPairs
And on the latter:
http://www.emacswiki.org/emacs/AutoIndentation
I wrote this below to get to search for the next period in tex mode. It works fine except trying to get it to move forward a char after it finds the period. I am not sure how to do this but here was my attempt.
(add-hook 'text-mode-hook (lambda ()
(local-set-key (kbd "s-p")
(lambda () (interactive) ((search-backward "." nil t) (forward-char))))))
Final solution I combined the functions from ajk solution. I couldn't get the other one working without the add-hook. Someone might know how to get the second one working. The below completely works and searches backward for the previous period unless it is currently at a period.
(add-hook 'text-mode-hook
(lambda ()
(local-set-key (kbd "s-p")
(lambda ()
(interactive)
(if (looking-back "\.")
(backward-char))
(search-backward "." nil t)
(forward-char)))))
Thanks for the help.
You have parentheses around the last two function calls in the anonymous function you're assigning to the key, causing Emacs Lisp to think you want to call a function named (search-backward "." nil t). Try
(add-hook 'text-mode-hook
(lambda ()
(local-set-key (kbd "s-p")
(lambda ()
(interactive)
(search-backward "." nil t)
(forward-char)))))
The problem I would have with this binding is it's not repeatable. If you run it a second time, it finds the same period you just found. You might want to check to see if the previous character is a period and if so, skip it. Also, you can simplify it a bit by using define-key to add the binding explicitly to the text-mode keymap:
(define-key text-mode-map (kbd "s-p")
(lambda ()
(interactive)
(if (looking-back "\.")
(backward-char))
(search-backward "." nil t)
(forward-char)))
I don't know elisp, but I'm trying to do something like the following:
(add-hook
'scala-mode-hook
(lambda ()
(define-key scala-mode-map (kbd "RET") (lambda ()
(scala-newline)
(scala-indent-line)))))
Goal is to call the two functions each time I hit the ENTER key. How do I actually do this?
I do essentially this in so many modes that I've squashed them all together:
(mapcar (lambda (hooksym)
(add-hook hooksym
(lambda ()
(local-set-key (kbd "C-m") 'newline-and-indent)
)))
'(
clojure-mode-hook
emacs-lisp-mode-hook
erlang-mode-hook
java-mode-hook
js-mode-hook
lisp-interaction-mode-hook
lisp-mode-hook
makefile-mode-hook
nxml-mode-hook
python-mode-hook
ruby-mode-hook
scheme-mode-hook
sh-mode-hook
))
Just stick scala-mode-hook in there somewhere and it'll work for you too :)
You need an (interactive) form after the lambda in your define-key.
EDIT:
To be clear, the inner form should look like:
(lambda ()
(interactive)
(scala-newline)
(scala-indent-line))
In hook you can use local-set-key, for example
(add-hook 'scala-mode-hook
(lambda ()
(local-set-key [return]
(lambda ()
(scala-newline)
(scala-indent-line)))))
although, maybe it will be easier to use something like standard newline-and-indent?
(add-hook 'scala-mode-hook
(lambda ()
(local-set-key [return] 'newline-and-indent)))
Just type C-j it will call the newline-and-indent command and do exactly what you ask.
I have (global-set-key (kbd "RET") 'newline-and-indent) in my .emacs which works fine in all modes but scala-mode(the newest, revision 19295 from svn).
What do I need to change to get it working?
(add-hook 'scala-mode-hook
(lambda () (local-set-key (kbd "RET") 'reindent-then-newline-and-indent)))
The above somewhat fixes the problem. It now indents the line correctly after pressing Enter once, but still doesn't work if there is a blank line above the newline.
In scala-mode, "RET" is bound to scala-newline by default, and this overrides the global key binding set with global-set-key, hence the need for the hook specific to scala-mode. Consider using:
(add-hook 'scala-mode-hook
(lambda () (local-set-key (kbd "RET") 'newline-and-indent)))
instead of:
(add-hook 'scala-mode-hook
(lambda () (local-set-key (kbd "RET") 'reindent-then-newline-and-indent)))
If you don't want Emacs to change your indentation after leaving a line.