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