Opening a new line in evil-mode - emacs

Consider the following piece of code:
(goto-char (point-max))
(insert "\n")
In normal state of evil-mode goto-char moves the cursor to the end of line visually, but it points before the last symbol, not after. Although the example above works just fine — it works as if the cursor is pointing after the last symbol so the last symbol is not carried to the next line which is a correct behavior. I wonder how evil determines that it needs to insert after the last symbol, not before.
The reason I ask about this is because I am trying to understand why hitting enter in haskell-mode repl in normal state in evil-mode puts the last symbol of the current line on the next line. It looks like (insert "\n") is invoked in a callback and evil doesn't know that it needs to maintain the compatibility.

It's not entirely clear what the question is, but I presume you want to avoid moving the last character to the next line upon hitting enter.
To mimic Vim's behavior, the cursor moves back a point after exiting insert state. As a by-product, (insert "\n") at the end of the line occurs just before the character on which the cursor is sitting, which puts it before the newline.
To disable this compatibility feature, do (setq evil-move-cursor-back nil) (or use setq-local if you only want to disable in the REPL) and you should be able to avoid putting the last symbol on the next line.

Related

Emacs macro that only fires on non-empty lines

Generally, I find myself writing short macros that, e.g. add or remove line comments or correct indentation on a line.
However, with whitespace-mode enabled, I will still have to look out not to fire these macros on blank lines; if the macro tries to delete a character on an empty line, generally it will mess up the entire document.
Is there any solution to this problem which does not involve having some amount of spaces on blank lines, or otherwise altering my document structure?
You could use C-M-s ^. at the beginning of the macro. That is, search for a line that contains at least one character.
Expanding on the legoscia's answer -- here's a version which also notifies if there's no previous line at all:
(defun goto-first-previous-non-empty-line ()
(interactive)
(if (re-search-backward "^." nil t)
(message "First previous non-empty line")
(message "Beginning of buffer")
)
)

Insert complete lines with Emacs + Evil

In Vim, I often move lines by deleting them (either with dd or visual line mode), moving my cursor to the new position, then p to put them in:
first
second
third
And if my cursor is on the line second, I can use ddp to move it down:
first
third
second
But with Emacs + Evil mode, putting the line back doesn't work as expected: if, for example, my cursor is on the i in third when I hit p, I end up with:
first
thisecondrd
How can I make Emacs + Evil mode insert new lines when putting entire yanked lines?
I use C-a to go to the beginning of the line (^ in evil-mode, probably) before yanking, if I want that behaviour. If you do this often, you can probably come up with your own thing for yank, although you have to figure out during the kill part if you're doing that. (Or you can check if the yanked thing has newlines, I guess?)
There's a transpose-lines command, by the way (C-x C-t in regular Emacs binding - someone suggested binding this to xtl - https://github.com/syl20bnr/spacemacs/blob/master/my-keybindings.el).
If I find my cursor on a line that I want to move, my natural response is to first delete the line into the kill ring with either C-a C-k C-k or C-a C-space C-n C-w (either of which can also grab several-line sequences by duplicating either the C-k or C-n or prefixing the C-n with a numeric argument) and then travel to the beginning of the line where I want to paste and doing a C-y yank.
Note that Emacs considers a file to be a steam of characters, in which newline or carriage return is not special. Unlike in vi, you can C-f forward right over a newline exactly as though it is a normal character; backspace over it; or include it in a deleted and yanked buffer. It is exactly like any other character. Perhaps Emacs is for people who think of files as sequences of characters — some of which happen to be newlines — and vi is for people who think of their file as lines, that are magically separated by who-knows-what but it certainly is not like any other character.
If the main use case you are trying to address is moving lines up or down (as opposed to the more general question of how to "make Emacs + Evil mode insert new lines when putting entire yanked lines"), I suggest you try out move-text.
It is a very small add-on package that provides two commands (move-text-up and move-text-down) for moving lines up and down, respectively. You can be anywhere on a line and call these; there is no need to kill or yank anything, and they work for regions as well.
For example, calling move-line-down in this situation (point right after second):
first line
second| line
third line
will produce
first line
third line
second| line
As you would expect, moving the current line (or region) up or down n lines works by calling the appropriate command with a numeric prefix.
The commands are bound to M-up and M-down by default but you should be able to rebind them to key sequences of your liking via
(define-key evil-normal-state-map "mu" 'move-line-up)
(define-key evil-normal-state-map "md" 'move-line-down)
move-text is package-installable from MELPA.

Have emacs incremental search place the cursor at the beginning of the match

I am trying to get out of evil mode, but one thing that is causing problems is that the forward incremental search places my cursor at the end of the match instead of the beginning. I very rarely want to have my cursor in the middle of the match which results in unnecessary keypresses to reposition the cursor. Is there a way to make the forward incremental search place the cursor at the beginning of the match instead of the end?
You question is addressed specifically in the Position of the Cursor after Searching
section of the IncrementalSearch page on Emacs Wiki. In particular, it shows you how to use isearch-mode-end-hook to get the behavior you want.
I suppose you can use defadvice to isearch-exit.
(defadvice isearch-exit (after move-to-match-beginning activate)
(when (and isearch-forward isearch-success)
(goto-char (match-beginning 0))))

How to prevent Emacs from setting an undo boundary?

I've written an Emacs Lisp function which calls a shell command to
process a given string and return the resulting string. Here is a
simplified example which just calls tr to convert text to uppercase:
(defun test-shell-command (str)
"Apply tr to STR to convert lowercase letters to uppercase."
(let ((buffer (generate-new-buffer "*temp*")))
(with-current-buffer buffer
(insert str)
(call-process-region (point-min) (point-max) "tr" t t nil "'a-z'" "'A-Z'")
(buffer-string))))
This function creates a temporary buffer, inserts the text, calls
tr, replaces the text with the result, and returns the result.
The above function works as expected, however, when I write a wrapper
around this function to apply the command to the region, two steps are
being added to the undo history. Here's another example:
(defun test-shell-command-region (begin end)
"Apply tr to region from BEGIN to END."
(interactive "*r")
(insert (test-shell-command (delete-and-extract-region begin end))))
When I call M-x test-shell-command-on-region, the region is replaced
with the uppercase text, but when I press C-_ (undo), the first
step in the undo history is the state with the text deleted. Going
two steps back, the original text is restored.
My question is, how does one prevent the intermediate step from being
added to the undo history? I've read the Emacs documentation on undo,
but it doesn't seem to address this as far as I can tell.
Here's a function which accomplishes the same thing by calling the
built-in Emacs function upcase, just as before: on the result of
delete-and-extract-region with the result being handed off to
insert:
(defun test-upcase-region (begin end)
"Apply upcase to region from BEGIN to END."
(interactive "*r")
(insert (upcase (delete-and-extract-region begin end))))
When calling M-x test-upcase-region, there is only one step in the
undo history, as expected. So, it seems to be the case that calling
test-shell-command creates an undo boundary. Can that be avoided
somehow?
The key is the buffer name. See Maintaining Undo:
Recording of undo information in a newly created buffer is normally enabled to start with; but if the buffer name starts with a space, the undo recording is initially disabled. You can explicitly enable or disable undo recording with the following two functions, or by setting buffer-undo-list yourself.
with-temp-buffer creates a buffer named ␣*temp* (note the leading whitespace), whereas your function uses *temp*.
To remove the undo boundary in your code, either use a buffer name with a leading space, or explicitly disable undo recoding in the temporary buffer with buffer-disable-undo.
But generally, use with-temp-buffer, really. It's the standard way for such things in Emacs, making your intention clear to anyone who reads your code. Also, with-temp-buffer tries hard to clean up the temporary buffer properly.
As for why undo in the temporary buffer creates an undo boundary in the current one: If the previous change was undoable and made in some other buffer (the temporary one in this case), an implicit boundary is created. From undo-boundary:
All buffer modifications add a boundary whenever the previous undoable change was made in some other buffer. This is to ensure that each command makes a boundary in each buffer where it makes changes.
Hence, inhibiting undo in the temporary buffer removes the undo boundary in the current buffer, too: The previous change is simply not undoable anymore, and thus no implicit boundary is created.
There are many situations where using a temporary buffer is not practical. It's hard to debug what's going on for example.
In these cases you can let-bind undo-inhibit-record-point to prevent Emacs from deciding where to put boundaries:
(let ((undo-inhibit-record-point t))
;; Then record boundaries manually
(undo-boundary)
(do-lots-of-stuff)
(undo-boundary))
The solution in this case was to create the temporary output buffer
using with-temp-buffer, rather than explicitly creating one with
generate-new-buffer. The following alternative version of the
first function does not create an undo boundary:
(defun test-shell-command (str)
"Apply tr to STR to convert lowercase letters to uppercase."
(with-temp-buffer
(insert str)
(call-process-region (point-min) (point-max) "tr" t t nil "'a-z'" "'A-Z'")
(buffer-string)))
I was not able to determine whether generate-new-buffer is indeed
creating the undo boundary, but this fixed the problem.
generate-new-buffer calls get-buffer-create, which is defined in
the C source code, but I could not quickly determine what was
happening in terms of the undo history.
I suspect that the issue may be related to the following passage in
the Emacs Lisp Manual entry for undo-boundary:
All buffer modifications add a boundary whenever the previous
undoable change was made in some other buffer. This is to ensure
that each command makes a boundary in each buffer where it makes
changes.
Even though the with-temp-buffer macro calls generate-new-buffer
much as in the original function, the documentation for
with-temp-buffer states that no undo information is saved (even
though there is nothing in the Emacs Lisp source that suggests this
would be the case):
By default, undo (see Undo) is not recorded in the buffer created by
this macro (but body can enable that, if needed).

Emacs scala-mode newline-and-indent weirdness

I have the following code in Emacs under scala-mode (from the Scala 2.8 package):
object t1 {
def main (args: List[String]) = {
println("Hello")
}
}
I also have my return key set to newline-and-indent. When I repeatedly hit return after the last brace, it goes to the leftmost column for one blank line. When I press return again, it indents two spaces. Then it stays at this indentation thereafter. Obviously it shouldn't do this.
However, when I repeatedly run newline-and-indent by the M-x and typing newline-and-indent, I don't get the two-space indentation. The same goes for reindent-then-newline-and-indent.
Why is there this difference?
Your problem is stemming from the fact that you rebound enter to newline-and-indent, which doesn't seem to be idiomatic when using scala-mode. newline-and-indent ends up calling indent-according-to-mode, which checks for some undesirable settings, works around them if necessary, and if everything is OK, ends up calling indent-line-function, which is a buffer local variable.
Since this is mode-specific, modes define their own indent-line-function. Most have pretty consistent behavior, but Scala's function is scala-indent-line, seen here:
(defun scala-indent-line ()
"Indent current line as smartly as possible.
When called repeatedly, indent each time one stop further on the right."
(interactive)
(if (or (eq last-command this-command)
(eq last-command 'scala-undent-line))
(scala-indent-line-to (+ (current-indentation) scala-mode-indent:step))
(let
((indentation (scala-indentation)))
(scala-indent-line-to indentation))))
The funny thing about this is that it detects repeated calls and indents further over each time. When using M-x, last-command is not scala-indent-line, it's execute-extended-command. So, when using M-x, it continues to indent at the correct indentation level. When bound to a key, however, it notices it was executed immediately previously and indents an extra level.
The effect isn't cumulative...I think this is because of the odd command set at the end of the function, which initially indents the line, but then checks for the correct indentation with (scala-indentation) and indents accordingly.
I'm not 100% on this, but at first glance that's what seems to be going on.