3

According to indent-tabs-mode,

Indentation can insert tabs if this is non-nil.

nil means indentation cannot use tabs. I need the opposite of this option, prevent indentation from using spaces as tabs.

I need this to match a formatting convention (eclipse) where tabs are mandatory.

What is the simplest way to achieve this? I'm using plain java-mode, whose tab is bound to (c-indent-line-or-region &optional ARG REGION), which seems to use (symbol-function 'indent-according-to-mode), which eventually uses c-shift-line-indentation, but I don't see any options to configure using tabs only. Am I looking in the wrong place?

2 Answers 2

4

Ultimately it's up to the individual mode to decide how it indents things, but indent-tabs-mode is generally respected, and all you need do is set it to a non-nil value.

The canonical non-nil value is t when no other value is more appropriate.

indent-tabs-mode is automatically buffer-local, and you can use the mode hook for java-mode to set it in any buffer using that mode.

(add-hook 'java-mode-hook 'my-java-mode-hook)

(defun my-java-mode-hook ()
  "Custom behaviours for `java-mode-hook'."
  (setq indent-tabs-mode t))

Provided java-mode only ever indents to multiples of tab-width, this ought to give you tab-only indentation.

If not, you would need to determine how to control the level of indentation in java-mode so that you can set that (and/or tab-width -- another buffer-local value) to coincide, so that only tabs will be required.

Naturally if there are circumstances when java-mode needs to indent to a column which is not an exact tab-width multiple, it won't be possible for it to use only tabs.

1
  • in this case, java-mode just resorts to c-indent-line-or-region. although your answer is helpful in giving some insight into how indentation works, I'd like to accept my own answer since it fixes my problem and has a little bit more "research" (basically, (setq indent-tabs-mode t) alone did not work for me)
    – erjoalgo
    Commented May 29, 2016 at 6:09
0

TLDR: (setf tab-width 4)

I was seeing the unwanted behavior of 4 spaces being inserted despite indent-tabs-mode being t. Thankfully, emacs is free software, so I was able to follow my TAB key press all the way down to the C source:

`TAB->c-indent-line-or-region->(symbol-function 'indent-according-to-mode)->c-shift-line-indentation->indent-to`

indent-to is defined in C source. the relevant portion is:

if (indent_tabs_mode)
{
  Lisp_Object n;
  XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
  if (XFASTINT (n) != 0)
{
  Finsert_char (make_number ('\t'), n, Qt);

  fromcol = (mincol / tab_width) * tab_width;
}
}

clearly n was being 0. This is because mincol / tab_width was 4 / 8, because tab-width was too big. Setting (setf tab-width 4) allows the function to indent using a tab, and no spaces are needed.

Finally:

(add-hook 'java-mode-hook (lambda () (setf tab-width 4)))

Your Answer

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

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