5
votes

I was wondering if anyone can provide me with some help on minifying my .emacs file.

Currently I have it set up where each language I use have a custom tab, for example, if I have a hook for Java, it would look like this.

;; Java Hook
(defun e-java-mode-hook ()
    (setq tab-width 4)
    (setq indent-tabs-mode t)
    (define-key java-mode-map (kbd "") 'java-insert-tab))
(defun java-insert-tab (&optional arg)
    (interactive "P")
    (insert-tab arg))
(add-hook 'java-mode-hook 'e-java-mode-hook)

And if I were to add another language like CSS or JavaScript, I would add another hook for CSS and another hook for JavaScript. So I was wondering if there's a global way of setting it so it would apply to any and all language?

I am currently running GNU Emacs 23.2.1 on Windows 7.

3

3 Answers

5
votes

I agree with Tyler; although it's a bit complicated, you would be better off in the long run if you try to understand and customize the default indentation features. The Emacs Wiki has good resources, and there are other relevant Q&As here on Stack Overflow.

Binding the tab key to insert-tab means you completely lose the benefit of the likes of indent-region, and any other intelligent behaviour that a major mode might offer.

To address your specific questions regardless, however:

1) If you are defining (java-insert-tab) and (css-insert-tab) and (javascript-insert-tab) etc, and they all do exactly the same thing... well, hopefully you can see that you don't actually need more than one of those functions. Just give it a more generic name, and re-use it.

2) (local-set-key ...) does the same thing as (define-key (current-local-map) ...), which means you can also have a single generic function to override the tab keybinding, regardless of the major mode.

(defun my-coding-config ()
    (setq tab-width 4)
    (setq indent-tabs-mode t)
    (local-set-key (kbd "<tab>") 'my-insert-tab))

(defun my-insert-tab (&optional arg)
    (interactive "P")
    (insert-tab arg))

Then you just need to add my-coding-config to each applicable mode hook variable. If there are a lot of them, you might wrap it up in a list like this:

;; Use my coding hook for all programming modes
(mapcar
 (lambda (language-mode-hook)
   (add-hook language-mode-hook 'my-coding-config))
 '(java-mode-hook
   javascript-mode-hook
   css-mode-hook
   ...))

3) If you look at C-h v tab-width RET and likewise for indent-tabs-mode, you'll notice that they both say "Automatically becomes buffer-local when set in any fashion."

As an alternative to the customize interface already mentioned, you can use (set-default 'indent-tabs-mode t) to establish the default value for such variables. In the absence of code which sets a buffer-local value, all of your buffers will use the default, which might help you to avoid writing unnecessary mode hooks.

2
votes

I'm not sure what you're trying to do. If you want to set the tab-width to 4 spaces globally, then you can do that using the customize command:

M-x customize-variable tab-width <ret>

Any changes you make to tab-width in customize will be applied globally. So you won't need to set it individually for each mode with hooks.

If you have different settings you want to apply to different modes, you will necessarily have to have code specific for each mode in your .emacs.

More generally, it looks like you're trying to build your own custom tab insertion commands - does the built-in indentation not do what you need? I think it will be easier to customize the indentation settings in Emacs than to manually insert tabs where you want them.

If you haven't already, take a look at the manual section on indentation and see if you might be able to do what you need without a lot of extra hooks:

C-h r m Indentation

(that is: h-elp, r-ead the manual, m-enu item Indentation)

or:

(info "(emacs)Indentation")
1
votes

espect.el is doing exactly what you want.

From the docs: