Don't Indent After Two Newlines - emacs

I've got RET bound to newline-and-indent. Whenever I skip a line, it leaves a line with no indent and indents the current line, which is how it should be. In certain circumstances, I'd like it to not indent the current line after skipping. Some examples:
Default behavior
This is a test.
Line two.
How I'd like it:
This is a test.
Line two.
I'm not quite sure the best way to go about implementing this. One solution which just reeks of inelegance is to try to detect two presses of in a row and then outdent the current line. Any ideas?

This solution assumes you want the changes in text-mode, adjust the code appropriately if it's a different mode.
(add-hook 'text-mode-hook
(lambda () (setq indent-line-function 'indent-relative-only-when-previous-has-non-whitespace)))
(defun indent-relative-only-when-previous-has-non-whitespace ()
"Only call indent-relative when previous line has non whitespace"
(interactive)
(when (save-excursion
(beginning-of-line 0)
(looking-at "^\\s *\\S "))
(indent-relative)))

Related

How to get auto indent (not smart indent) in emacs in all modes

I'm new to emacs, and its indenting is driving me up the walls. It's too smart for its own good; it (incorrectly) thinks it knows how I want to format my source, but I don't have time to chase down every setting for every mode for every different language that I write code for; and many of those languages don't have any mode enabled at all.
Here's the behaviour I'd like:
TAB inserts indent
RET inserts a new line then copies the blank characters from the start of the previous line to the first non-blank character, or end of line, whichever comes sooner
DEL (backspace key) in the blank text between line start and first non-blank character / end of line deletes one indent if possible, otherwise single character like normal
No auto-indent on {
No auto-unindent on }
In fact, no smart-ass indenting behaviour anywhere anytime, just copy previous line's indent on RET.
Two variables to be configured per source file format: display tab width, and contents of indent. Preferably these can be configured for random source code formats without having to write a major mode for them, unless writing a major mode is a one-liner in .emacs, consisting of two setqs.
This would get me logical and consistent behaviour across all languages. It would leave the work of formatting the code to me, but that's OK, I've been doing that for 20 years, and I know how to make other macros that make it efficient. More importantly, it saves me from endless fiddling with configuration settings trying to get the automatic behaviour to suit my preferences. And my macros can rely on consistent behaviour so they work correctly in all modes.
Is the above possible? Surely someone else has done this before? Is there some minor mode out there that makes it so?
Here's the code:
(setq tab-width 4)
(defun plain-tab ()
(interactive)
(insert (make-string tab-width ?\ )))
(defun plain-ret ()
(interactive)
(looking-back "^\\( +\\).*")
(newline)
(insert (match-string 1)))
(defun plain-del ()
(interactive)
(backward-delete-char
(if (looking-back (format " \\{%d\\}" tab-width)) tab-width 1)))
(defvar all-the-mode-maps
'(c-mode-map c++-mode-map java-mode-map
js-mode-map emacs-lisp-mode-map
clojure-mode-map))
(require 'cc-mode)
(require 'js)
(require 'clojure-mode)
(eval `(mapc
(lambda(map)
(define-key map [tab] 'plain-tab)
(define-key map [return] 'plain-ret)
(define-key map [backspace] 'plain-del)
(define-key map "{" (lambda()(interactive)(insert "{")))
(define-key map "}" (lambda()(interactive)(insert "}"))))
(list ,#all-the-mode-maps)))

Elisp: Old variable values seem to stick

Beginner question for emacs lisp.
In my .emacs I have written the following:
(defun line-text-up-with-parentheses-above()
(interactive)
(line-text-up-with-char-above "("))
(defun line-text-up-with-char-above(charval)
(interactive)
(setq now-point (point))
(previous-line)
(setq above-point (point))
(forward-char)
(search-forward charval (line-end-position) nil)
(setq above-paren (point))
(goto-char now-point)
(insert (make-string (- above-paren above-point) ? )))
(global-set-key (kbd "\<C-S-iso-lefttab>") 'line-text-up-with-parentheses-above)
The function intends to line the text at the point up with the character after the "(" on the line above it.
Everything seem to work fine, unless the function is called twice in a row. In this case, the text before the point advances exactly the same amount as last time.
Seems like the variables aren't being set the second time around.
Does anyone know how to fix this?
Many thanks!
You calculate the intended indentation. However, you always insert it regardless of how many spaces the current line contains.
You could either simply delete the spaces on the current line before inserting the new spaces, or you could try to calculate the number of spaces needed and insert or delete, as needed.
Some hints:
By using setq you are using global variables, try to bind them using let.
Instead of recording where the point is before you move it around and restore it afterwards, you could use the special construct save-excursion.
I think the variables are being set correctly (although Lindydancer is correct to suggest let instead of setq). And your function works fine for me if I call it with point at the first non-whitespace character on the line you want to 'line up'. The only problem I see is that the function lines up with wherever point is when you call it, which is not correct if point is not at the first non-whitespace character.
You can fix this be adding (back-to-indentation) immediately after (interactive) in line-text-up-with-char-above. Actually, once you wrap everything in save-excursion you'll want to add back-to-indentation as the first function within the save-excursion form.
Protip: align and specifically align-regexp.

Scala mode indentation in Emacs

When writing Scala code in Emacs, I notice the following indentation issue:
List(1,2,3).foreach{ x =>
Then press enter.
Then close the bracket, and this is what ends up happening:
List(1,2,3).foreach{ x =>
}
Although this is one particular example, this issue appears in a variety of ways when auto-indenting in Emacs.
An answer to either of these two questions would be appreciated:
How can this issue be fixed so that the brace gets put in the proper place and anything within the braces is indented one level to the right?
Is it possible to disable this type of auto-indentation (i.e. like 'set noautoindent' in vi). I tried solutions like the ones suggested here: Disable auto indent globally in Emacs without success.
Thanks in advance!
I've coded up a simple piece of code - it makes emacs keep indent level for most time, and indents two spaces to the right when the previous non-empty line ends with "{", "(", ">", "=".
Add file besi.el to your load path.
(provide 'besi)
(defun besi-indent-line ()
"Indent current line"
(interactive)
(scala-indent-line-to (besi-indent)))
(defun besi-indent ()
(save-excursion
(forward-comment -100000)
(backward-char 1)
(if (or (looking-at "{") (looking-at "=") (looking-at ">") (looking-at "("))
(+ (current-indentation) 2)
(current-indentation))))
(defun besi-newline ()
(interactive)
(newline-and-indent))
Edit line in scala-mode.el
indent-line-function 'besi-indent-line
and line in scala-mode-ui.el
("\r" 'besi-newline)
Also add a line (require 'besi) to the start of scala-mode.el.
Uploaded it to github for easy reference - besi
I tried to solve this by editing scala-mode-indent.el file. It breaks indent in some of the other situations, but at least you will not have all those indents half-screen forward.
Comment out this line:
;; (scala-indentation-from-following)
And modify scala-indentation-from-preceding:
(defun scala-indentation-from-preceding ()
;; Return suggested indentation based on the preceding part of the
;; current expression. Return nil if indentation cannot be guessed.
(save-excursion
(scala-backward-spaces)
(and
(not (bobp))
(if (eq (char-syntax (char-before)) ?\()
(scala-block-indentation)
(progn
(when (eq (char-before) ?\))
(backward-sexp)
(scala-backward-spaces))
t
;;(scala-looking-at-backward scala-expr-start-re)
))
(if (scala-looking-at-backward scala-expr-start-re)
(+ (current-indentation) scala-mode-indent:step)
(current-indentation)
))))
As I said, it still remains broken after that. I plan to write a better support shortly, maybe in a week or two.
EDIT:
If you want to disable scala indentation completely, comment out the line in scala-mode.el
;; indent-line-function 'scala-indent-line

yasnippets with % ending the line after $0 acts strange when used with AUCTeX

Yasnippet snippets that has a percent sign, %, ending a line with the last point of the snippet, $0, before the percent sign acts strange in that the cursor gets placed after the percent sign and not before it. I wonder how I can avoid this strange behavior.
Consider the following snippet:
# -*- mode: snippet -*-
# name: test snippet
# key: ts
# --
{
$0%
}
I take it that as it's activated it should insert three lines where the first contains {, the last line } and the second line % and place the cursor before % on the second line as in the following example:
{
[cursor]%
}
But what happens is the following:
{
% [cursor]
}
How can I make it so that the snippet behaves as I think it should?
My guess is that this is due to something in AUCTeX because it happens with AUCTeX activated but not in the major mode Lisp Interaction.
It works right with my configuration, but I suspect it has to do with auto indenting (mine is heavily customized so that may be the difference). Do you still see the problem if you add
# expand-env: ((yas/indent-line 'fixed))
or
# expand-env: ((yas/indent-line t))
to the snippet's header? You can also try adding $> to the line(s) that you want indented to see if that makes a difference (if it does that would narrow things down a lot). There is a note in the yasnippet code about some problems with markers changing places, but that looks like it was fixed a few years ago.
You should also check that indent-line-function has the proper value namely LaTeX-indent-line.
You could add some sit-for's to the definition of yas/indent-according-to-mode to see where point is at different stages. For example put the following in a scratch buffer, position your cursor after the end of it and type C-x C-e. Then insert your snippet as usual and it will pause for 1 second every where in the code you see a (sit-for 1). So if the cursor starts out in the wrong place, then you know the problem is before indentation, etc. You will have to watch it for every line that is indented, so you may wish to turn off indentation except for the problematic line via $>. Adding or removing sit-for's will allow you to narrow it down.
(defun yas/indent-according-to-mode (snippet-markers)
"Indent current line according to mode, preserving
SNIPPET-MARKERS."
(sit-for 1)
(goto-char (yas/real-line-beginning))
(sit-for 1)
(let ((trouble-markers (remove-if-not #'(lambda (marker)
(= marker (point)))
snippet-markers)))
(save-restriction
(widen)
(sit-for 1)
(condition-case err
(indent-according-to-mode)
(error (message "[yas] warning: yas/indent-according-to-mode habing problems running %s" indent-line-function)
nil)))
(sit-for 1)
(mapc #'(lambda (marker)
(set-marker marker (point)))
trouble-markers)))

How to make emacs behave closer to the regular editors?

I'm using Emacs 23.1.1 on Ubuntu with Emacs starter kit. I primarily work in the lua-mode.
Is there a way to stop Emacs being so smart about indentation? I'm used to the dumb editors, and press all the required keys manually.
I want to use two spaces per indent, tabs-to-spaces.
When I press RETURN, the new line indentation must match the previous line.
When I press TAB on the leading whitespace, the line contents must be indented by one indentation unit.
When I press TAB on the beginning of empty line, the cursor must move one indentation unit to the right.
Oh, and I'd like to get soft word wrap on 80th column and trim-trailing-spaces on save as well.
Update:
(Would put this in a comment, but it needs formatting)
If I use Thomas's solution, auto-indent on RETURN is "fixed", but TAB still indents weirdly:
local run = function(...)
x
"x" marks the spot where cursor appears after I type the first line and hit RETURN, TAB.
Emacs has a concept of modes, which means that depending on what type of file you're editing it provides special functionality that is useful for that file. Every buffer has one major mode associated and optionally a number of minor modes.
Indentation is one of the things that is typically mode-dependent. That is, you may have to configure indentation separately for every major-mode, because otherwise when you load a new file, its associated major mode may override your indentation settings. It's possible though to write a function that configures indentation and set up Emacs in a way that the function is invoked whenever a new major-mode is started.
In order to realize the settings you want, you'll need to run a few lines of elisp code. (Unfortunately your description of what should happen when you hit TAB leaves out some details, I've implemented the simplest version I could think of below -- if it's not what you want, that can be changed, of course.)
Put the following code in the file named .emacs in your home directory (~):
(setq-default indent-tabs-mode nil) ; use spaces for indentation
(defvar my-indentation-width 2
"The number of spaces I prefer for line indentation.")
(defun my-enter ()
"Inserts a newline character then indents the new line just
like the previous line"
(interactive)
(newline)
(indent-relative-maybe))
(defun my-indent ()
"When point is on leading white-space of a non-empty line, the
line is indented `my-indentation-width' spaces. If point is at
the beginning of an empty line, inserts `my-indentation-width'
spaces."
(interactive)
(insert (make-string my-indentation-width ? )))
(defun my-indentation-setup ()
"Binds RETURN to the function `my-enter' and TAB to call
`my-indent'"
(local-set-key "\r" 'my-enter)
(setq indent-line-function 'my-indent))
(defun delete-trailing-whitespace-and-blank-lines ()
"Deletes all whitespace at the end of a buffer (or, rather, a
buffer's accessible portion, see `Narrowing'), including blank
lines."
(interactive)
(let ((point (point)))
(delete-trailing-whitespace)
(goto-char (point-max))
(delete-blank-lines)
(goto-char (min point (point-max)))))
;; make sure trailing whitespace is removed every time a buffer is saved.
(add-hook 'before-save-hook 'delete-trailing-whitespace-and-blank-lines)
;; globally install my indentation setup
(global-set-key "\r" 'my-enter)
(setq indent-line-function 'my-indent)
;; also override key setting of major-modes, if any
(add-hook 'after-change-major-mode-hook 'my-indentation-setup)
This works for me in Emacs 23, although I may have missed some edge cases. However, these changes are so fundamental that I predict you will run into incompatibilities sooner or later with some major-modes that expect indentation to work they set it up. If you really want to get into Emacs it's worthwhile adapting the habits you inherited from other editors to the way Emacs does things.
For soft word-wrap there is a minor-mode called "longlines" which you can download from here: http://www.emacswiki.org/cgi-bin/emacs/download/longlines.el I haven't used it so I can't tell you how well it works.
Fixing TAB and RETURN:
(global-set-key "\t" 'self-insert-command)
(global-set-key "\r" 'newline-and-indent)
Fill column (haven't tried): say ESC x customize-var, enter fill-column, set to 80.