How to insert new line (after cursor point) with indentation? - emacs

I works in programming mode such as javascript-mode and usually need to push some lines down for formatting purpose.
I find C-o convenient to insert a newline after cursor point. However the line pushed down loses its indentation.
I find RET convenient to insert newline. And the line pushed down is nicely indented. However, the inserted new-line comes after the current cursor point. (EDIT: ) I find it is convenient to keep the cursor position by inserting the newline after it, because sometimes I still need to modify the current line.

Probably something like this:
(defun open-line-and-indent ()
"Like `newline-and-indent', but do not move the point."
(interactive)
(save-excursion
(newline-and-indent)))
(global-set-key (kbd "C-o") #'open-line-and-indent)
;; (define-key javascript-mode-map (kbd "C-o") #'open-line-and-indent)

Related

How to set a keybinding to create and jump to the next line in emacs?

I have the following code that attempts to create a new line and then jump to it. The idea is that move-end-of-line will jump to the end of the current line, and ["C-m"] would act as return/enter. Yet executing this command gives the error: "wrong number of arguments". How do I fix this?
(global-set-key (kbd "C-.") 'new-line)
(defun new-line ()
(interactive)
(move-end-of-line)
["C-m"]
)
I think you need to read the Emacs & elisp manuals: these questions are pretty easy to answer. Here's one way to do it.
(defun insert-line-after-line (&optional n)
(interactive "p")
(end-of-line 1) ;end of current line
(open-line n) ;open n new lines
(forward-line 1)) ;go to start of first of them
But seriously: Emacs has very extensive self-documentation, it is easy to find out how to do these things.
An option is to record a macro and use that.
M-x kmacro-start-macro
C-e
C-m
M-x kmacro-end-macro
If you don't care about the macro persisting, just run it:
C-x e
But if you want it to persist you would save it:
M-x name-last-kbd-macro new-line
M-x insert-kbd-macro new-line
and paste the output into your initialisation file (with your shortcut definition):
(global-set-key (kbd "C-.") 'new-line)
(fset 'new-line
[end return])
["C-m"] is like the way you specify a key for doing a key binding, but this is not the same as how you programmatically tell Emacs to insert a character into a document. You could use (insert-char ?\^M) (see ref here), but that would result in a literal ^M character (try it; another way to do the same thing interactively is Ctrl-Q followed by Ctrl-M). (insert "\n") seems to be what you're looking for.
Also, the reason you're getting the message "wrong number of arguments" is because (move-end-of-line) requires an argument when called out of interactive context. (move-end-of-line 1) works.
That said, possibly an easier way to achieve the result you're looking for is with the following setting:
(setq next-line-add-newlines t)
This will allow you to just do C-n at the end of the file and not worry about the distinction between moving and inserting.

Setting arbitrary cursor positions with multiple cursors in Emacs?

I want to modify different parts of my file with the same string. So I installed multiple-cursors in emacs. But unfortunately, I cannot do the (simple?) thing of marking different parts of the text and start to edit.
Each command I have checked seems not useful to do what I want. For instance consider I need to edit the beginning of line 10 and a character in the middle of line 34. How do I do that?
It sounds like you are looking for the command mc/add-cursor-on-click, which I personally have bound to C-S-<mouse-1>. With this setup, I can hold Ctrl and Shift and click the beginning of line 10, and then click the middle of line 34, and I will have a cursor in both positions.
You can bind this command the way I have like this in your init:
(global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click)
You can replace the kbd with another combination too if you want.
The following is derived from https://github.com/magnars/multiple-cursors.el/issues/44 and seems like a reasonable keyboard-driven solution.
(require 'multiple-cursors)
(defun mc/toggle-cursor-at-point ()
"Add or remove a cursor at point."
(interactive)
(if multiple-cursors-mode
(message "Cannot toggle cursor at point while `multiple-cursors-mode' is active.")
(let ((existing (mc/fake-cursor-at-point)))
(if existing
(mc/remove-fake-cursor existing)
(mc/create-fake-cursor-at-point)))))
(add-to-list 'mc/cmds-to-run-once 'mc/toggle-cursor-at-point)
(add-to-list 'mc/cmds-to-run-once 'multiple-cursors-mode)
(global-set-key (kbd "C-S-SPC") 'mc/toggle-cursor-at-point)
(global-set-key (kbd "<C-S-return>") 'multiple-cursors-mode)
Firstly use mc/toggle-cursor-at-point to mark each position where you want a cursor, and then invoke multiple-cursors-mode to activate them.

How to insert space after cursor?

I am a new user of emacs.
I found some useful options that allows me to insert new line before or after cursor: C-j (before cursor), C-o (after cursor).
I found this very convenient in doing formatting text across lines.
Now, are there methods to insert space after cursor for in-line formatting?
Currently I have to insert space before cursor using Space then C-b multiple times just to return to the original position when doing formatting within one line.
I don't think there is such a function, but it is easy to write:
(defun my-insert-space-after-point ()
(interactive)
(save-excursion (insert " ")))
(global-set-key (kbd "C-.") 'my-insert-space-after-point)
This binds the function to C-.; adjust to preference.
Another way to do this is to record a macro, save it, and bind it to a key. The steps to do that are described in this answer.

How to select text between quotes, brackets... in Emacs?

In vim, you can do this by vi", vi[, vi( ...
For example, if you have a line like this:
x = "difference between vim and emacs"
and the cursor is anywhere between those quotes and you hit vi", then the string will be visually
selected.
The package expand-region is convenient for this. Calling er/expand-region with the point inside the quotes will mark the nearest word, and then calling it again will mark all the words inside the quotes. (Calling it a third time will expand the region to include the quotes.)
I have it bound to C-;.
(global-set-key (kbd "C-;") 'er/expand-region)
With this binding, pressng C-; C-; will highlight the text between the quotes.
From Emacs Documentation
Nearly all modes support “(,)” as parentheses, and most also support
square brackets “[,]” and curly brackets “{,}”. However, you can make
any pair of characters a parenthesis-pair, by using the following
command:
(modify-syntax-entry ?^ "($")
(modify-syntax-entry ?$ ")^")
Also, take a look at this post How to mark the text between the parentheses in Emacs?. key combination given per this post
Try the key sequence C-M-u C-M-SPC (i.e., while holding the Control and Meta keys, press u and Space in sequence), which executes the commands backward-up-sexp and mark-sexp
Late to the party, but you can also use Evil mode, which does a bang-up job of Vim emulation, including the motion commands you mentioned.
(defun select-text-in-delimiters ()
"Select text between the nearest left and right delimiters."
(interactive)
(let (start end)
(skip-chars-backward "^<>([{\"'")
(setq start (point))
(skip-chars-forward "^<>)]}\"'")
(setq end (point))
(set-mark start)))
On top of the toolkit
https://launchpad.net/s-x-emacs-werkstatt/+download
the following keys/commands are delivered:
(global-set-key [(super \))] 'ar-parentized-atpt)
(global-set-key [(super \])] 'ar-bracketed-atpt)
(global-set-key [(super \})] 'ar-braced-atpt)
(global-set-key [(super \")] 'ar-doublequoted-atpt)
(global-set-key [(super \')] 'ar-singlequoted-atpt)
That way with a couple of more chars known as delimiters will constitute commands.
ar-delimited-atpt will return the string around point found by nearest delimiter.
A group of more powerful commands allows re-using keys like that
(global-set-key [(control c)(\")] 'ar-doublequote-or-copy-atpt)
(global-set-key [(control c)(\')] 'ar-singlequote-or-copy-atpt)
(global-set-key [(control c)(<)] 'ar-lesser-angle-or-copy-atpt)
(global-set-key [(control c)(>)] 'ar-greater-angle-or-copy-atpt)
Here a doctring given as example:
ar-doublequote-or-copy-atpt is an interactive Lisp function in
`thing-at-point-utils.el'.
It is bound to C-c ".
(ar-doublequote-or-copy-atpt &optional NO-DELIMITERS)
If region is highlighted, provide THING at point with doublequote(s),
otherwise copy doublequote(ed) at point.
With C-u, copy doublequote(ed) without delimiters.
With negative argument kill doublequote(ed) at point.
Use libraries thingatpt+.el and thing-cmds.el.
You will find there commands such as thing-region, which selects a thing at point as the region. Since string-contents and list-contents are defined as things (in thingatpt+.el), these select the string/list contents as the region:
(thing-region "string-contents") ; Select the contents of the string at point.
(thing-region "list-contents") ; Select the contents of the list at point.
Or interactively:
M-x thing-region RET string-contents RET
Other, related commands include:
C-M-U (aka C-M-S-u) -- mark-enclosing-list: Select enclosing list. Repeat to expand list levels. Works with any balanced-parenthesis expressions (e.g., vectors): whatever the current syntax table defines as having balanced-delimiter syntax.
mark-thing -- Select successive things of a given kind (repeating).
next-visible-thing -- Move to the next visible thing of a given kind (repeating).

Emacs Command to Delete Up to Non-Whitespace Character

I often want to make a multiline function call and reduce it down to one line. For example, convert...
function_call(
'first_arg',
'second')
to
function_call('first_arg', 'second')
Does emacs have some commands to help with this. Specifically, is there a command that will delete all whitespace from the point to the first non-whitespace character?
You might try delete-indentation, my favorite command for joining multiple lines into one line. In your example, put the cursor on the line with "second" and hit M-^ twice. Here are the docs:
M-^ runs the command delete-indentation, which is an interactive compiled Lisp function in simple.el.
It is bound to M-^.
(delete-indentation &optional arg)
Join this line to previous and fix up whitespace at join. If there is a fill prefix, delete it from the beginning of this line. With argument, join this line to following line.
Take a look at the fixup-whitespace function. It comes with Emacs, in simple.el. Its docs are:
Fixup white space between objects around point.
Leave one space or none, according to the context.
A similar function, just-one-space, that
Deletes all spaces and tabs around point, leaving one space
is typically bound to M-SPC.
Specifically, is there a command that will delete all whitespace from the point to the first non-whitespace character?
There's a command that does almost that:
M-\ runs the command delete-horizontal-space
which is an interactive compiled Lisp function in `simple.el'.
It is bound to M-\.
(delete-horizontal-space &optional backward-only)
Delete all spaces and tabs around point.
If backward-only is non-nil, only delete them before point.
You can always use M-z to delete upto a character.
For eg in your case:
M-z ' to delete upto the single quote (unfortunately this will delete the single quote as well, but that is a minor inconvenience).
I use the following macro to "pull" the next line onto the end of the current line, compressing whitespace.
(defun pull-next-line()
(interactive)
(move-end-of-line 1)
(kill-line)
(just-one-space))
This is exactly the opposite of #jrockway's move-line-up and of delete-indentation, which I find more natural. The just-one-space command in the macro is exactly #Mike's M-SPACE.
I bind pull-next-line to M-J (in analogy with Vim's J, for "join", command) using the following in my .emacs.
(global-set-key (kbd "M-J") 'pull-next-line)
Example. Calling pull-next-line on the first line of
function_call(
'first_arg',
'second')
yields
function_call( 'first_arg',
'second')
Calling it a second time yields
function_call( 'first_arg', 'second')
Alt-space will reduce a string of whitespace to a single space character, but it won't delete the newline. Still, that should help a little.
To delete everything from point to the first non-whitespace (or newline), type a non-whitespace char, Alt-space, backspace (to remove final whitespace char), then backspace (to delete the char you added.
To turn the multi-line function declaration into a single-line declaration, use a combination of Alt-space, backspace, and Alt-E (goto-endofline) commands.
A rather drastic way of doing this is Hungry-Delete mode:
Hungry-Delete is a minor-mode that causes deletion to delete all whitespace in the direction you are deleting.
A slightly different approach would be creating a keyboard macro to do the job for you.
so, for creating the macro stage a general scenario like so:
foo
bar
[a line with "foo" then a couple of lines later and with some white spaces, write "bar"]
then standing anywhere between foo and bar, do the following:
C-x ( ; start recording macro
M-b ; move backwards to the beginning of foo
END ; move to the end of foo
C-space ; place mark
C-M-f ; move to the end of bar
HOME ; move to the beginning of the line
C-w ; yank out all the white space
M-SPACE ; leave only one space
C-x ) ; end recording the macro
M-x name-last-kbd-macro ; name it, call it jline or something
Now you can always remove all whitespace between two words with M-x one-line
Make sure you remember to save your keyboard macro by issuing M-x insert-kbd-macro somewhere in your .emacs file - this is how it looks:
(fset 'jline
[?\M-b end ?\C- ?\C-\M-f home ?\C-w escape ? ])
I do this:
(defun move-line-up ()
"Removes leading spaces from the current line, and then moves
the current line to the end of the previous line."
(interactive)
(let (start end)
(save-excursion
(beginning-of-line)
; get first non-space character, only look on this line
(let ((search-end (save-excursion (end-of-line) (point))))
(re-search-forward "[^[:space:]]" search-end))
(setq end (1- (point)))
(previous-line)
(end-of-line)
(setq start (point))
(delete-region start end))
(goto-char start)))
(defun move-next-line-up ()
"Moves the next line to the end of the current line"
(interactive)
(next-line)
(move-line-up))
And bind these as:
(global-set-key (kbd "C-x ,") 'move-line-up)
(global-set-key (kbd "C-x .") 'move-next-line-up)
So to solve your problem, on the line that says "second)", just run C-x , C-x ,
If you want all of your deletes to act that way, you might check out greedy-delete.