Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[emacs] tabs, spaces, and indentation

88 views
Skip to first unread message

Nerius Landys

unread,
Oct 6, 2010, 4:06:05 PM10/6/10
to help-gn...@gnu.org
Hi.  I use emacs all the time for programming and shell scripting.  Now I'm dabbling in an open source project that is written in C, and the entire code base uses tabs extensively (instead of spaces for indentation).  I very much prefer to use spaces for indentation; however I must use tabs for this project in order to make the code consistent.  I am looking for some quick command or something that will place my emacs into a special mode that is suitable for working with tabbed C code.  Then of course I'd like a command that puts me back into the regular settings that I have and am used to.  (In other words, a toggle on and off.)

Here are some details.

I am running FreeBSD 8.0 and I have emacs installed with no X11, from the port editors/emacs-nox11.  The version of emacs is 23.2_4,2.  I have no additional bells and whistles installed for emacs other than what comes with this FreeBSD port and my .emacs config, which is more or less like so:

(setq transient-mark-mode t)
(setq make-backup-files nil)
;(setq-default indent-tabs-mode nil) [ commented out ]
(setq-default c-basic-offset 2)

I tried searching on Google for commands that may help me, but most of what I found explained how to enable the kind of behavior that I'm NOT looking (I'm going in the opposite direction unfortunately).

The current default behavior that I am experiencing is as follows:

1. When I hit the Tab key, it indents the current line at the correct indentation level.  Existing Tabs are preserved but spaces might be added.
2. When I complete some syntax on a line, such as adding a semicolon or closing a paren, it indents the line for me automatically.

The behavior for this particular mode of operation that would be nice is as follows:

1. Hitting the Tab key places a literal Tab character in my file.  That is all.
2. I notice that sometimes when I complete a like (e.g. adding a semicolon or adding a paren) it auto-indents for me.  I want to turn this off completely.

Is it possible to toggle the mode consisting of #1 and #2 on and off?  Please help, and thank you very much!

des...@verizon.net

unread,
Oct 6, 2010, 6:05:06 PM10/6/10
to
Nerius Landys <nla...@gmail.com> writes:

> Hi. I use emacs all the time for programming and shell scripting. Now
> I'm dabbling in an open source project that is written in C, and the
> entire code base uses tabs extensively (instead of spaces for
> indentation). I very much prefer to use spaces for indentation; however I
> must use tabs for this project in order to make the code consistent. I am
> looking for some quick command or something that will place my emacs into
> a special mode that is suitable for working with tabbed C code. Then of
> course I'd like a command that puts me back into the regular settings that
> I have and am used to. (In other words, a toggle on and off.)
>
> Here are some details.
>
> I am running FreeBSD 8.0 and I have emacs installed with no X11, from the
> port editors/emacs-nox11. The version of emacs is 23.2_4,2. I have no
> additional bells and whistles installed for emacs other than what comes
> with this FreeBSD port and my .emacs config, which is more or less like
> so:
>
> (setq transient-mark-mode t)
> (setq make-backup-files nil)
> ;(setq-default indent-tabs-mode nil) [ commented out ]
> (setq-default c-basic-offset 2)
>
> I tried searching on Google for commands that may help me, but most of
> what I found explained how to enable the kind of behavior that I'm NOT
> looking (I'm going in the opposite direction unfortunately).

Check here:

http://www.mail-archive.com/fvwm-w...@lists.math.uh.edu/msg08136.html

PJ Weisberg

unread,
Oct 7, 2010, 12:22:34 AM10/7/10
to Nerius Landys, help-gn...@gnu.org
On Wed, Oct 6, 2010 at 1:06 PM, Nerius Landys <nla...@gmail.com> wrote:

> The behavior for this particular mode of operation that would be nice is as
> follows:
>
> 1. Hitting the Tab key places a literal Tab character in my file.  That is
> all.
> 2. I notice that sometimes when I complete a like (e.g. adding a semicolon
> or adding a paren) it auto-indents for me.  I want to turn this off
> completely.

Setting indent-line-function and indent-region-function doesn't seem
to do a damn thing, but (local-set-key "\t" 'self-insert-command)
works for #1 when it's called after you've switched to the major mode
you're using.

Also, if you configure tab-always-indent to nil Tab will only indent
if the cursor is at the start of the line. You can always insert a
literal tab with C-q Tab.

Dunno what to do about #2. The help docs lead me to believe setting
indent-line-function and indent-region-function is the answer, but
like I said those don't seem to do anything.

Jonathan Groll

unread,
Oct 7, 2010, 2:26:27 AM10/7/10
to Nerius Landys, help-gn...@gnu.org
On Wed, 6 Oct 2010 13:06:05 -0700,Nerius Landys wrote:
>I tried searching on Google for commands that may help me, but most of what I found
>explained how to enable the kind of behavior that I'm NOT looking (I'm going in the
>opposite direction unfortunately).

>The current default behavior that I am experiencing is as follows:

>1. When I hit the Tab key, it indents the current line at the correct indentation
>level.  Existing Tabs are preserved but spaces might be added.
>2. When I complete some syntax on a line, such as adding a semicolon or closing a
>paren, it indents the line for me automatically.

>The behavior for this particular mode of operation that would be nice is as follows:

>1. Hitting the Tab key places a literal Tab character in my file.  That is all.
>2. I notice that sometimes when I complete a like (e.g. adding a semicolon or adding
>a paren) it auto-indents for me.  I want to turn this off completely.

>Is it possible to toggle the mode consisting of #1 and #2 on and off?  Please help,


>and thank you very much!

Here is a good resource: http://cscs.umich.edu/lr/Misc/emacs_tabs.htm
As the above guide says:

;;force TAB to insert just one TAB:
(global-set-key (kbd "TAB") 'self-insert-command)

(This would be for every mode - but it may be best to just set it for
your C mode)

It is worth reading up on the eternal debate of tabs vs spaces. Here
is Jamie Zawinski's take:
http://www.jwz.org/doc/tabs-vs-spaces.html

Cheers,
JJG


Stefan Monnier

unread,
Oct 7, 2010, 5:30:43 AM10/7/10
to
> ;;force TAB to insert just one TAB:
> (global-set-key (kbd "TAB") 'self-insert-command)
> (This would be for every mode - but it may be best to just set it for
> your C mode)

Note also that it may fail to work for some major modes, in which case
it's normally a bug in that major mode.

For the problem of having auto-indentation take place while inserting
some other character, this is usually considered a feature, named
"electric keys" or something like that. Until now this has been
implemented in ad-hoc ways, separately in each major mode, so the way to
turn it off is different for each and every major mode.

Emacs-24 will introduce a standard way to provide this feature, with
a corresponding standard way (called electric-indent-mode) to turn it on
or off globally (tho it will only work with those major modes which use
this new standard implementation rather than doing it their own way).


Stefan

PJ Weisberg

unread,
Oct 8, 2010, 5:44:22 PM10/8/10
to help-gnu-emacs
On Wed, Oct 6, 2010 at 9:22 PM, PJ Weisberg <p...@irregularexpressions.net> wrote:

> Setting indent-line-function and indent-region-function doesn't seem
> to do a damn thing, but (local-set-key "\t" 'self-insert-command)
> works for #1 when it's called after you've switched to the major mode
> you're using.
>
> Also, if you configure tab-always-indent to nil Tab will only indent
> if the cursor is at the start of the line.  You can always insert a
> literal tab with C-q Tab.
>
> Dunno what to do about #2.  The help docs lead me to believe setting
> indent-line-function and indent-region-function is the answer, but
> like I said those don't seem to do anything.

I guess there isn't an easier way to do it, because a few hours after
I wrote this somebody posted a proposal on emacs-devel for making #2
easier to turn on and off, because right now every major mode does it
it's own way. (Personally, I'd also prefer it to be off. I can press
TAB when I want the line indented in the standard way. If I indented
it differently I don't want it changed because I fixed some
punctuation.)

Anyway, I've discovered that c-mode binds certain keys (semicolor,
comma, etc) to functions that indent the line in addition to inserting
a character. You can "fix" those by rebinding them to
'self-insert-command, just like you can with TAB.

-PJ

Nerius Landys

unread,
Oct 8, 2010, 6:12:05 PM10/8/10
to PJ Weisberg, help-gnu-emacs

Wow sounds like Emacs is becoming too intelligent.  Kind of like that old version of Microsoft Word.

Steve Revilak

unread,
Oct 8, 2010, 10:08:01 PM10/8/10
to help-gn...@gnu.org
>From: Nerius Landys

>The current default behavior that I am experiencing is as follows:
>
>1. When I hit the Tab key, it indents the current line at the correct
>indentation level. Existing Tabs are preserved but spaces might be added.
>2. When I complete some syntax on a line, such as adding a semicolon or
>closing a paren, it indents the line for me automatically.
>
>The behavior for this particular mode of operation that would be nice is as
>follows:
>
>1. Hitting the Tab key places a literal Tab character in my file. That is
>all.
>2. I notice that sometimes when I complete a like (e.g. adding a semicolon
>or adding a paren) it auto-indents for me. I want to turn this off
>completely.

CC-mode gives you a lot of options for controlling indentation.

M-x Info-goto-node RET (ccmode)Commands RET

The subsections "Indentation commands", "Minor Modes" and "Electric
keys" will probably be the most relevant for what you're trying to
accomplish.

For (1) something like

(setq c-basic-offset 8
indent-tabs-mode t
c-insert-tab-function 'tab-to-tab-stop)

(setq c-syntactic-indentation nil) ; maybe, or maybe not this one

should be close to the behavior you're looking for.


For (2), try

(c-toggle-electric-state -1)


Steve

Nerius Landys

unread,
Oct 11, 2010, 4:19:40 PM10/11/10
to Steve Revilak, help-gn...@gnu.org
CC-mode gives you a lot of options for controlling indentation.

 M-x Info-goto-node RET (ccmode)Commands RET

The subsections "Indentation commands", "Minor Modes" and "Electric
keys" will probably be the most relevant for what you're trying to
accomplish.

For (1) something like

 (setq c-basic-offset 8
      indent-tabs-mode t
      c-insert-tab-function 'tab-to-tab-stop)

 (setq c-syntactic-indentation nil) ; maybe, or maybe not this one

should be close to the behavior you're looking for.

For (2), try

 (c-toggle-electric-state -1)



Thanks a lot for this information.  I have taken your tips and done additional online research.  I came up with the following .emacs file for this project that has absolutely horrid indentation and use of tabs:

  (defun my-c-mode-common-hook ()
    (c-toggle-electric-state -1)
    (define-key c-mode-base-map (kbd "TAB") 'self-insert-command))
  (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)


It almost behaves how I want now.  I hit Tab, it creates a tab.  It does not start indenting stuff when I type a special character such as a paren or a semicolon.  However, there is still one thing needed to make it behave just like Notepad.  Let's say my cursor is positioned immediately following a tab character.  When I hit Backspace (I believe that causes a function "backward-delete-char" to be called), it converts that tab character into a bunch of spaces, then deletes the last space.  I would really like Backspace to just delete the tab character.  Is there any way to do this?  I suppose I'd have to rebind Backspace to a function other than backward-delete-char, but I'm not sure which function.

PJ Weisberg

unread,
Oct 11, 2010, 5:43:35 PM10/11/10
to Nerius Landys, help-gn...@gnu.org
On Mon, Oct 11, 2010 at 1:19 PM, Nerius Landys <nla...@gmail.com> wrote:

> However, there is still one thing needed to make it behave just
> like Notepad.  Let's say my cursor is positioned immediately following a tab
> character.  When I hit Backspace (I believe that causes a function
> "backward-delete-char" to be called), it converts that tab character into a
> bunch of spaces, then deletes the last space.  I would really like Backspace
> to just delete the tab character.  Is there any way to do this?  I suppose
> I'd have to rebind Backspace to a function other than backward-delete-char,
> but I'm not sure which function.

Is it bound to backward-delete-char? Or is it bound to
backward-delete-char-untabify? I believe the former does what you
want.

Pascal J. Bourguignon

unread,
Oct 11, 2010, 5:58:33 PM10/11/10
to
Nerius Landys <nla...@gmail.com> writes:

> Is there any way to do this? I suppose I'd have to rebind
> Backspace to a function other than backward-delete-char, but I'm not
> sure which function.

Try with delete-backward-char instead.

--
__Pascal Bourguignon__ http://www.informatimago.com/

Nerius Landys

unread,
Oct 11, 2010, 6:14:53 PM10/11/10
to PJ Weisberg, help-gn...@gnu.org

> However, there is still one thing needed to make it behave just
> like Notepad.  Let's say my cursor is positioned immediately following a tab
> character.  When I hit Backspace (I believe that causes a function
> "backward-delete-char" to be called), it converts that tab character into a
> bunch of spaces, then deletes the last space.  I would really like Backspace
> to just delete the tab character.  Is there any way to do this?  I suppose

> I'd have to rebind Backspace to a function other than backward-delete-char,
> but I'm not sure which function.

Is it bound to backward-delete-char?  Or is it bound to
backward-delete-char-untabify?  I believe the former does what you
want.

Woohoo!  My final .emacs file does just what I want.


(defun my-c-mode-common-hook ()
  (c-toggle-electric-state -1)
  (setq tab-width 8
        c-basic-offset 8
        indent-tabs-mode t
        backward-delete-char-untabify-method nil)

Steve Revilak

unread,
Oct 11, 2010, 9:42:56 PM10/11/10
to help-gn...@gnu.org
>From: Nerius Landys <nla...@gmail.com>

>> For (1) something like
>>
>> (setq c-basic-offset 8
>> indent-tabs-mode t
>> c-insert-tab-function 'tab-to-tab-stop)
>>
>> (setq c-syntactic-indentation nil) ; maybe, or maybe not this one
>>
>> should be close to the behavior you're looking for.
>>
>> For (2), try
>>
>> (c-toggle-electric-state -1)

>Thanks a lot for this information. I have taken your tips and done
>additional online research. I came up with the following .emacs file for
>this project that has absolutely horrid indentation and use of tabs:
>

> (defun my-c-mode-common-hook ()
> (c-toggle-electric-state -1)

> (define-key c-mode-base-map (kbd "TAB") 'self-insert-command))
> (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

Nerius,

That's great. I'm glad I was able to give you a starting point.

>It almost behaves how I want now. I hit Tab, it creates a tab. It does not
>start indenting stuff when I type a special character such as a paren or a

>semicolon. However, there is still one thing needed to make it behave just


>like Notepad. Let's say my cursor is positioned immediately following a tab
>character. When I hit Backspace (I believe that causes a function
>"backward-delete-char" to be called), it converts that tab character into a
>bunch of spaces, then deletes the last space. I would really like Backspace
>to just delete the tab character. Is there any way to do this? I suppose
>I'd have to rebind Backspace to a function other than backward-delete-char,
>but I'm not sure which function.

In C-mode, "C-h k DEL" tells me that DEL calls c-electric-backspace,
which in turn calls the function bound to c-backspace-function.

For me, c-backspace-function is bound to
backward-delete-char-untabify, which will convert a tab into a series
of spaces.

Maybe

(setq c-backspace-function 'backward-delete-char)

is what you're looking for.

Steve

0 new messages