How to make emacs behave closer to the regular editors? - emacs

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.

Related

Emacs lisp code indentation

In emacs-lisp mode whenever i insert a closing brace i prefer to have indented to the same column like the corresponding opening brace. How is that possible? If i have eg in my init.el
(defadvice isearch-forward-regexp (before kill-ring-save-before-search activate)
"Save region (if active) to kill-ring before starting isearch. So that region
can be inserted into isearch easily with C-y."
(when (region-active-p)
(kill-ring-save (region-beginning) (region-end))
) ;; this should be under (when
) ;; this should be under (defadvice
It seems that you want to align the close parens to be able to
visually match them to the opening ones. You can do that with
show-paren-mode instead - it's much better at that job.
As pointed out by others, and I fully agree, the hanging parens are
very annoying and painful to look at - don't make a habit out of using
them. I've authored a minor mode for editing Elisp which might be
interesting for you - lispy-mode:
Pressing i will auto-indent an s-expression, eliminating
the hanging parens.
Pressing d will switch from one side of s-expression to
the other: a quick way to see what the current list contains.
Pressing m will toggle the region selection on the
current list: you can see what it contains even more clearly.

Emacs version 24.4: New obnoxious loss of indentation on hitting RETURN

Starting with Emacs 24.4, when I type a line beginning with white space (a typical way to
denote a new paragraph) and at the end of it I hit RETURN, the white space disappears.
This problem appears also with 'emacs -Q'.
My .emacs file uses a rather plain text-mode paragraphing scheme, namely,
(setq default-major-mode 'text-mode)
(add-hook 'text-mode-hook 'paragraph-indent-minor-mode)
which has been working without problems for a dozen years. The bug appeared when I installed the current (24.4) version.
Basically, I type:
This is a line beginning with four spaces
and as soon as I type RETURN my line immediately becomes
This is a line beginning with four spaces
That is, the indentation vanishes. I'd much appreciate some advice.
Should I post a bug?
In Emacs 24.4, electric-indent-mode is enabled by default. It seems like that's what's causing this problem in combination with paragraph-indent-minor-mode. You can avoid that by turning off Electric Indent mode everywhere (M-x electric-indent-mode) or just in the local buffer (M-x electric-indent-local-mode).
The following will try to keep electric-indent-mode from stepping on the toes of paragraph-indent-minor-mode. It doesn't attempt to be robust in all situations, but I suspect it's entirely sufficient in your situation.
(defvar-local my-local-electric-indent-status :unknown)
(defun my-local-electric-indent-disable ()
"Make `electric-indent-mode' ineffective in the current buffer."
(setq my-local-electric-indent-status electric-indent-mode)
(electric-indent-local-mode -1))
(defun my-local-electric-indent-restore ()
"Restore original status of `electric-indent-mode' in the current buffer."
(unless (eq my-local-electric-indent-status :unknown)
(electric-indent-local-mode my-local-electric-indent-status)))
(add-hook 'paragraph-indent-minor-mode-on-hook #'my-local-electric-indent-disable)
(add-hook 'paragraph-indent-minor-mode-off-hook #'my-local-electric-indent-restore)
If you're not running at least Emacs 24.3, replace the defvar-local with:
(defvar my-local-electric-indent-status :unknown)
(make-variable-buffer-local 'my-local-electric-indent-status)
;;(global-set-key "\em" 'newline) ;;for emacs 23
global-set-key "\em" 'electric-newline-and-maybe-indent) ;;for emacs 24

Repeating TABs on subsequent lines in text files (but keeping TABs disabled for code)

I am editing a text file foo.txt using emacs.
I press C-q TAB to insert a TAB character at the beginning of a line and then follow with a few characters.
Once I press ENTER, emacs inserts eight spaces on the following line.
How do I specify in my .emacs that I would like TABs to be repeated on subsequent lines with TABs?
Importantly, I dislike TAB characters in program code, and so I have (setq-default indent-tabs-mode nil) to make sure that TABs are inserted only when I explicitly ask for them.
Emacs inserts SPC chars because you told it to, by setting indent-tabs-mode to nil (my preference too, BTW).
If you want Emacs to indent using TAB chars in a particular mode (buffer), but you want it to use SPC chars in general (i.e., in other modes), then set indent-tabs-mode to t in those modes where you want TABs. Just use setq when you are in the mode, since it is a buffer-local variable. For example:
(add-hook MY-mode-hook (lambda () (setq indent-tabs-mode t)))
The real answer is: No, there is no way to do this by some simple configuration setting in emacs. indent-tabs-mode is either on or off, and indentation will behave according to that.
But, just because this feature is not there, doesn't mean you can't add it!
This is actually not a simple problem from what I found. Whether or not to use tabs or spaces is determined by indent-tabs-mode in C mostly. Assuming that you are running a recent version of emacs, the auto indentation is coming from electric-indent-mode which uses indent-according-to-mode in a post-self-insert-hook to do the indentation.
What I did for this was define a buffer local minor mode, when this mode is active indent-tabs-mode will be temporarily set depending on the first character in the last line while running indent-according-to-mode.
So when smart-electric-indent-tabs-mode is active, and your last line started with the tab, the next line will indent with a tab too, else it will just use whatever indent-tabs-mode would normally be set to.
You could add the following to your config to activate it. The add-hook clause is put in there for your convenience, you can activate it on the fly like a normal minor mode if you'd like.
(define-minor-mode smart-electric-indent-tabs-mode
"When on, indenting will use tabs if the current line does,
else it will indent according to `indent-tabs-mode'."
:init-value nil
:lighter " smart-tabs"
:keymap nil
:global nil)
(defadvice indent-according-to-mode (around maybe-use-tabs activate)
"Follow `smart-electric-indent-tabs-mode'."
(let ((indent-tabs-mode
(or (and smart-electric-indent-tabs-mode
(save-excursion
(save-restriction
(widen)
(beginning-of-line 0)
(looking-at "\t"))))
indent-tabs-mode)))
ad-do-it))
;; if you want, add a text mode hook
(add-hook 'text-mode-hook 'smart-electric-indent-tabs-mode)
This has only been tested to work during electric indentation

Emacs Whitespace Mode ignores whitespace-line-column and fill-column

I have an issue using Emacs 24.1.1 on Mac OS X. I'm editing Jade and CoffeeScript files, so I've turned on whitespace-mode for those file types.
What I'm seeing is that lines longer than 70 characters are highlighted with the whitespace-line font face, regardless of the setting of whitespace-line-column.
In this shot, it is clear that I've customized whitespace-line-column to track fill-column, and I've set fill-column to 120, but much shorter lines are being highlighted.
I've glanced over the code for the Jade mode and don't see anything that would explain the behavior, but I have only a passing understanding of Emacs Lisp.
Thanks in advance for any pointers!
You have to set whitespace-line-column before you activate whitespace-mode. That is, if you want to change its value it does not take effect unless you turn whitespace-mode off and on again. Ironically, that variable is not available for M-x customize until you have activated the mode once :-(
However, you can customize the global value of this variable by putting the following line in your .emacs file:
(setq whitespace-line-column 120)
Since your .emacs is evaluated when you start Emacs, the setting will take effect before you invoke whitespace-mode for the first time and should thus do what you want. If you don't want to set the value globally, but only for Jade files, put the following in your .emacs file instead:
(set (make-local-variable 'whitespace-line-column) 80)
(add-hook 'after-change-major-mode-hook
'(lambda () (when (eq major-mode 'jade-mode)
(setq whitespace-line-column 120))))
If you never want long lines to be highlighted specially at all, there is a third option you might want to consider. You could customize the variable whitespace-style (by typing M-x customize-variable ENTER whitespace-style ENTER) and in the value list remove the entries:
lines
lines-tail
(if any). This should turn off highlighting of long lines globally independent of the value of whitespace-line-column (again, only after you de- and re-activate whitespace mode).

Emacs global configuration of tabs

I'm attempting to switch from Vim to Emacs, but I'm tearing my hair out trying to configure it to treat tabs how I wish. I require:
Inserted "tabs" to be expanded into two spaces. Emacs stubbornly sticks to eight, no matter what I do.
Tabs (i.e. real \t characters) to be represented on screen by two spaces.
Pressing TAB should insert a tab at the cursor rather than indent the entire line. Currently, I press TAB anywhere and Emacs destroys all whitespace at the start of the line; this is the most infuriating thing so far.
My current ~/.emacs reads
(setq standard-indent 2)
(setq-default indent-tabs-mode nil)
but I have tried no end of suggested configurations from the web, none of which have done what they said they would. (Does the API constantly change? I'm using GNU Emacs 23.1.1, apparently.)
Emacs has extremely flexible support for handling indentation. Generally the mode that you are in dictates how they work - so if you're working on a C file then the way that pressing tab works will be different than if you're working on a Python file.
So it does depend which mode you're working in, which will limit the answers you get. In most cases I would recommend that you don't fight against it - for me the indentation behaviour is one of the best features of emacs. However, you do need to spend the time to customize it for yourself.
To change the way that tabs are displayed you need to set tab-width to 2. If you're editing Java or C style code then it sounds like you want to turn off all the nice indentation features by these to NIL:
c-tab-always-indent
c-syntactic-indentation
indent-tabs-mode
I suggest you set these through the customization interface. If you use "M-x customize-group RET C" then you can see the various settings for C mode.
If you're editting different types of files then the instructions will be different.
Perhaps emacs is in the wrong mode for your file. You could try doing "M-x fundamental-mode" to see if you prefer the behaviour there.
;; * Inserted "tabs" to be expanded into two spaces. Emacs stubbornly
;; sticks to eight, no matter what I do.
;; * Tabs (i.e. real \t characters) to be represented on screen by two
;; spaces.
(setq-default tab-width 2)
;; * Pressing TAB should insert a tab at the cursor rather than indent
;; the entire line. Currently, I press TAB anywhere and Emacs
;; destroys all whitespace at the start of the line; this is the
;; most infuriating thing so far.
(setq-default indent-tabs-mode t)
(mapcar (lambda (hooksym)
(add-hook hooksym
(lambda ()
(kill-local-variable 'indent-tabs-mode)
(kill-local-variable 'tab-width)
(local-set-key (kbd "TAB") 'self-insert-command))))
'(
c-mode-common-hook
;; add other hook functions here, one for each mode you use :-(
))
;; How to know the name of the hook function? Well ... visit a file
;; in that mode, and then type C-h v major-mode RET. You'll see the
;; mode's name in the *Help* buffer (probably on the second line).
;; Then type (e.g.) C-h f python-mode; you'll see blather about the
;; mode, and (hopefully) somewhere in there you'll see (again e.g.)
;; "This mode runs the hook `python-mode-hook', as the final step
;; during initialization."
This should get you most of what you want. You'll probably have to customize some other programming modes you commonly use.
(defun insert-tab ()
"self-insert-command doesn't seem to work for tab"
(interactive)
(insert "\t"))
(setq indent-line-function 'insert-tab) ;# for many modes
(define-key c-mode-base-map [tab] 'insert-tab) ;# for c/c++/java/etc.
(setq-default tab-width 2)