1

When I open a config file that has been indented with tabs, the mode shows as (Conf[Space] WS) and pressing Tab indents with spaces, even though the rest of the file is using tabs.

How can I change this mode to indent with tab characters instead?

I thought [Space] might have meant it was a minor mode, so I looked into changing the minor mode but the list of minor modes in the manual doesn't mention anything about a tab mode.

The EmacsWiki mentions an indent-tabs-mode however this does not appear to be in version 25.1.1 that I am using.

I looked into customize-mode however I can't find anything in there about indenting.

Is there a setting to change conf-mode to indent with tabs instead?

Update with suggestions from @Basil:

(setq indent-tabs-mode t) has no effect. After running it with M-:, pressing the tab key is the same as pressing the spacebar multiple times (enough to match the first non-leading space character on the previous line.)

Putting the add-hook code suggested by @Basil in my init.el, closing the buffer, reloading Emacs, then reopening the file, also has no effect. Pressing the tab key is the same as pressing the spacebar multiple times.

(setq tab-width N) immediately changes the width of the existing tabs in the file. On a line with no spaces on the line above it, setting tab-width to 2 makes the tab key insert two spaces, setting it to 8 makes the tab key equivalent to pressing the spacebar eight times.

1 Answer 1

3

I thought [Space] might have meant it was a minor mode

The mode line lighter Conf[Space] corresponds to conf-space-mode, which is a major mode derived from conf-mode for editing space-separated configuration files (i.e. ones where key-value pairs are separated by arbitrary-length whitespace), such as ~/.ssh/config under Unices. conf-space-mode has nothing to do with tabs vs spaces.

By the way, in graphical Emacs instances you can click on components of the mode line to get more information about them. There's probably a simple way to inspect this under a textual environment as well which eludes me.

conf-mode is interesting in that it is not actually a major mode. What it does is a pretty decent job of detecting the type of configuration syntax used in the current buffer before selecting a more specialised mode accordingly, such as conf-unix-mode or conf-space-mode in your case. See its documentation C-h f conf-mode RET or M-x describe-function RET conf-mode RET for more information.

indent-tabs-mode [...] does not appear to be in version 25.1.1 that I am using

It most certainly does exist in your version, you are probably just looking in the wrong place because of its misleading name. If you were to type M-x apropos RET indent-tabs-mode RET or C-h o indent-tabs-mode RET or M-x describe-symbol RET indent-tabs-mode RET you would see that it is, in fact, a variable and not a major/minor mode.

How can I change this mode to indent with tab characters instead?

You can usually toggle space/tab indentation in any normal/well-behaved mode via the buffer-local variable indent-tabs-mode. In order to enable tab indentation, set it to a non-nil value:

(setq indent-tabs-mode t)

If, for example, you would like to default to tab indentation in conf-mode, you can set this in a corresponding mode hook:

(add-hook 'conf-mode-hook
          (lambda ()
            (setq indent-tabs-mode t)))

You can replace conf-mode-hook with any other mode's hook, e.g. conf-space-mode-hook.

Update

As mentioned in the comments, another variable to play around with in combination with indent-tabs-mode is indent-line-function, which is the function called to actually perform the indentation. This variable is often set by the corresponding major-mode, but this is not the case in the conf-mode family. It defaults to indent-relative, which indents relative to the previous line, but a possibly more suitable value in this case would be insert-tab, which inserts either a literal tab character or tab-width many spaces, depending on the value of indent-tabs-mode. I recommend reading the documentation (and even viewing the source, if practical) for all aforementioned variables and functions. Here is a sample hook which performs the described change:

(add-hook 'conf-mode-hook
          (lambda ()
            (setq indent-line-function #'insert-tab
                  indent-tabs-mode     t)))

See also the last parts of this answer of mine for some tab/space auto-detection pointers.

10
  • Thanks for such a detailed helpful reply! I had no idea I could click on the mode to see more options - never occurred to me to do so! Unfortunately however, setting indent-tabs-mode seems to have no effect (with either M-: or putting the hook in my init.el) so does that mean conf-mode is not well-behaved?
    – Malvineous
    Jun 22, 2017 at 8:54
  • @Malvineous Could you please update your answer to describe the expected and actual behaviour after setting indent-tabs-mode? My first guess would be that the setting is working, but spaces are being inserted instead of a tab character because the indentation offset is smaller than tab-width. What happens if you also (setq tab-width N), where N is the number of spaces that constitute an indentation level?
    – Basil
    Jun 22, 2017 at 9:33
  • @Malvineous I wrote "update your answer" but meant to say "update your question". In addition, I don't think there is anything specific to conf-mode that is not well-behaved.
    – Basil
    Jun 22, 2017 at 9:39
  • Updated question with the result, thanks! I take it conf-mode is inserting tabs for you when you press the tab key?
    – Malvineous
    Jun 23, 2017 at 6:25
  • @Malvineous Indeed, enabling indent-tabs-mode and setting tab-width to a number less than or equal to the column of the next indent point on the last nonblank line (see documentation for function indent-relative) results in the TAB key inserting literal tab characters on my end. Have you tried starting emacs with the -Q option (which forgoes reading your user-init-file), adding the conf-mode-hook and then opening the file in question? If this works, it means a setting in your user-init-file is to blame for the undesired behaviour.
    – Basil
    Jun 23, 2017 at 8:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.