Tab indentation in CoffeeScript using Emacs - emacs

I hope this is within the reasonable scope of this site and not too trivial, this is my first post. I am new to Emacs and am trying to set up the environment so that when I start a new line in coffee-mode the automatic indentation is in the form of tabs. As I understood the documentation of coffee-mode all I need to do is set coffee-indent-tabs-mode to t. I've appended my init file with the code below:
(custom-set-variables
'(coffee-tab-width 2)
'(coffee-indent-tabs-mode t))
However when I start Emacs and open a .coffee file, though it gets the tab width right, when I press enter it indents with spaces. Quibbles about whether I need to indent with tabs aside, what am I doing wrong?

In the coffee-mode I find in GNU ELPA, there is no coffee-indent-tabs-mode. I recommend you simply do:
(add-hook 'coffee-mode-hook
(lambda ()
(set (make-local-variable 'tab-width) 2)
(set (make-local-variable 'indent-tabs-mode) t)))
This should work for pretty much any major mode.

Related

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).

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.

How can I set Emacs tab settings by file type?

I need to be able to set the tab settings for the following file types:
.rb: 2 soft spaces
.css, .html.erb: 4 space tabs
I have tried the following, but none of it seems to alter my default tab settings for each of the file types.
;; js-mode-hook has also been tried
(add-hook 'javascript-mode-hook
'(lambda()
(setq tab-width 4)))
(add-hook 'css-mode-hook
'(lambda()
(setq tab-width 4)))
(add-hook 'html-mode-hook
'(lambda()
(setq tab-width 8)))
I am pretty new to emacs so my knowledge of configuration is pretty low.
In emacs each mode has it's own indentation style. The main command to indent (bound to TAB) is indent-for-tab-command.
This command calls mode specific indentation function found in the variable indent-line-function. So each mode has it's own way of doing it.
For Ruby (for my emacs 2 is a default):
(setq ruby-indent-level 2)
For CSS (again, default is 4 for me):
(setq css-indent-offset 4)
Unfortunately SGML mode (on which HTML mode is based) has a very simple indentation mechanism and apparently the level is not configurable.
See the source code of sgml-calculate-indent function.
I personally find it weird. I am not writing HTML, but you can try to modify the sgml-calculate-indent function yourself :). Learn some lisp.
I am using js2 mode, and it indents perfectly by default. For js you have to search for js-indent-level or something similar.
Cheers.
Theres a number of aspects to how Emacs does indentation. Setting the tab-width only specifics how big a tab is if a literal tab is inserted. If you don't wish to use literal tabs for indentation, then you should first disable their insertion (from the manual
):
Emacs normally uses both tabs and
spaces to indent lines. If you prefer,
all indentation can be made from
spaces only. To request this, set
indent-tabs-mode to nil. This is a
per-buffer variable, so altering the
variable affects only the current
buffer, but there is a default value
which you can change as well.which you can change as well.
However, to specify the indentation levels, you'll also need to set the c-basic-offset value variable as well:
(add-hook 'html-mode-hook
'(lambda()
(setq c-basic-offset 4)
(setq indent-tabs-mode nil))
In your case, you may only need the c-basic-offset but try a few combinations and see what works best.
js-mode uses js-indent-level so put (setq js-indent-level 4) into your ~/.emacs (shouldn't have to be in a hook, even, but if you're wondering, it's js-mode-hook, not javascript-mode-hook).
If setting tab-width doesn't change your indentation level for a certain mode, it's often simplest to just open the source for that mode. I found this variable by doing C-h f js-mode, clicking the link "js.el", then searching for "indent", second hit from the top.
However, if you collaborate a lot with other people, it's often better to put a cookie at the top of the file. I typically do // -*- tab-width: 8 -*- in the file, and then I have stuff like this in my ~/.emacs:
(defvaralias 'c-basic-offset 'tab-width)
(defvaralias 'cperl-indent-level 'tab-width)
(defvaralias 'perl-indent-level 'tab-width)
(defvaralias 'js-indent-level 'tab-width)
so that I have less variables to deal with (and don't have to get warnings about the file-local variable being unsafe or whatever if the mode-writer forgot to declare it as safe)
If you are using ELPA's css-mode.el with emacs 23.1.1, you can parametrize the global setting for tab width for CSS files for the tab width by doing the following:
1) Type M-x customize-variable ,
2) Then type css-indent-level,
3) Then after you change the variable to your liking, you do "Save for future sessions".
For HTML and erb: if you are using web-mode (the mode provided by Spacemacs) it can be as simple as:
(setq-default
web-mode-code-indent-offset 2
web-mode-markup-indent-offset 2)
where markup-indent-offset refers to the actual tags and code-indent-offset refers to embedded Ruby in ERB, etc.

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)