indent-tabs-mode is still using spaces - emacs

Below is my init.el script. It is loading because the column-indicator is visible. However editing any C file, the tab key still produces 4 spaces when I want only tabs (\t). I have never used lisp and I'm new to emacs, what's wrong?
(setq-default indent-tabs-mode t)
(require 'fill-column-indicator)
(defun my-c-mode-hook ()
(setq-default c-default-style "bsd"
c-basic-offset 4
tab-width 4
indent-tabs-mode t)
(c-set-offset 'substatement-open 0)
(fci-mode))
(add-hook 'c-mode-hook 'my-c-mode-hook)

Try this:
(setq c-default-style "bsd")
(defun my-c-mode-hook ()
(setq c-basic-offset 4
tab-width 4
indent-tabs-mode t)
(c-set-offset 'substatement-open 0)
(fci-mode))
(add-hook 'c-mode-hook 'my-c-mode-hook)
Variables have a global value and, potentially, a buffer-local value.
Furthermore certain variables will automatically use a buffer-local value when you set them. Such variables include c-basic-offset, tab-width, and indent-tabs-mode (as you can see for yourself if you describe them via C-hv)
setq-default sets the global value of a variable, but by the time that c-mode-hook runs the buffer-local values have already been established, so setting the default value at that point isn't really what you want, as it doesn't affect the existing local values (although depending on how the mode works, doing so may cause future buffers to have the desired values).
setq sets the buffer-local value when one exists (and the global value otherwise), so this is what you want to use for most of those variables.
c-default-style conversely is not automatically buffer-local, so there should be no purpose in setting that with c-mode-hook. We can just set its (global) value once.

Related

Why is my newline taking 4 spaces by default?

I have set c-basic-offset & c-basic-indent to 4 expecting it to indent newlines after brackets only in C/C++ files. But the issue I'm facing is every newline in ".txt" document is taking 4 spaces by default which I don't want.
Here is my init.el file
(global-display-line-numbers-mode 1)
(set-frame-font "JetBrains Mono-11" nil t)
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq indent-line-function 'insert-tab)
(setq c-basic-offset 4)
(setq c-basic-indent 4)
;(setq-default c-basic-offset 4)
;(c-set-offset 'substatement-open 0)
; stop creating backup files
(setq make-backup-files nil)
(recentf-mode 1)
(setq recentf-max-menu-items 25)
(setq recentf-max-saved-items 25)
(global-set-key "\C-x\ \C-r" 'recentf-open-files)
;; start the initial frame maximized
(add-to-list 'initial-frame-alist '(fullscreen . maximized))
;; start every frame maximized
(add-to-list 'default-frame-alist '(fullscreen . maximized))
Please help me get rid of 4 space characters in a normal text file.
You can make your settings specific for mode. In your case if you want indentation settings to apply only for C/C++ files, you need to apply these settings for that mode hook. There are various ways of doing it, one of them is using defining those settings in a defun and add that defun to appropriate hook.
Example below shows to setup c-basic-offset and c-basic-indent to 4.
(defun my-c-mode-common-hook ()
;; my customizations for all of c-mode and related modes
(setq c-basic-offset 4)
(setq c-basic-indent 4)
)
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

Set variable under specific mode emacs

Looking to set a variable under latex mode. The idea is that the value set under latex mode will override the value of the same variable set in the customise section. I am very new to emacs so these are my attempts:
(add-hook 'LaTeX-mode-hook '(setq line-move-visual t))
(add-hook 'latex-mode-hook (lambda () (setq line-move-visual t)))
Why do these not work? What should I do instead?
Clarification: looking to set the variable (setq line-move-visual t) as I have it as (setq line-move-visual nil) for all other files
If you just setq the variable in your LaTeX-mode-hook it will also have an effect on any other open buffer. It is possible to make the change only effect the current buffer:
(add-hook 'LaTeX-mode-hook
(lambda ()
(make-local-variable 'line-move-visual)
(setq line-move-visual nil)))
Also, please note that the hook for the default mode for LaTeX in Emacs is called latex-mode-hook but the hook when you are using the (far superior) AUCTeX is called LaTeX-mode-hook
EDIT: Changed make-variable-buffer-local to make-local-variable. See comments to this answer.

How to revert indent-tabs-mode when editing makefiles in emacs?

I've got the following in my .emacs since for most source code I use spaces only:
(add-hook 'prog-mode-hook
(lambda ()
(setq indent-tabs-mode nil)))
This messes up my makefiles though since they require tabs. How do I work around this so that I get spaces by default for all source code, but makefiles retain tabs?
You can always add an add-hook for makefile-mode to change it back.
(add-hook 'makefile-mode-hook
(lambda ()
(setq indent-tabs-mode t)))

major-mode hook configuration affects other buffers

Let me start by saying I'm very new to emacs.
I'm attempting to create customizations for major-modes. While my settings are functioning correctly, I'm observing that when I open a new buffer, that buffers major-mode customization is being applied to other buffers of a different type.
For instance, if I open a file named 'Makefile', makefile-mode is used and my customizations are applied. If I then open another file such as 'test.c', c-mode is used but customizations from makefile-mode are merged with customizations from c-mode.
The relevant portions of my .emacs file can be seen below:
(defun c-mode-settings ()
(c-set-style "bsd")
(set-buffer-file-coding-system 'utf-8-unix)
(show-paren-mode 1)
(setq c-basic-offset 4)
(setq tab-width 4)
(setq indent-tabs-mode nil)
(setq c-tab-always-indent t)
(setq require-final-newline t)
)
(defun makefile-mode-settings ()
(setq whitespace-style '(tabs spaces space-mark tab-mark face lines-tail))
(whitespace-mode t)
(show-paren-mode 1)
(setq tab-width 4)
(setq require-final-newline t)
)
(add-hook 'c-mode-hook 'c-mode-settings)
(add-hook 'makefile-mode-hook 'makefile-mode-settings)
How can I keep these mode hooks from affecting other buffers in different modes?
Thanks!
Andrew
You need to take into account, that some variables are becoming local to buffer when set, while some are global. Usually they have corresponding comment in their description (use C-h v var-name to get this description.
In some cases, you can force that any variable become local to buffer, using the
(set (make-local-variable 'var-name) var-value)
but you need to be careful with this.

Emacs Lisp function to toggle variable 'tab-width' between 4 & 8

The source tree that I work on has files indented with different tab values, (not to mention spaces) and the best I can do is to set emacs to use the style found in the region of code I am modifying. Instead of doing M-x set-variable tab-width to 4 or 8, a key binding to toggle the tab-width among these two value would help immensely.
Thanks.
;; Obviously substitute your preferred key for <f8>
(global-set-key (kbd "<f8>") 'tf-toggle-tab-width-setting) ; ' "fix" highlighting
(defun tf-toggle-tab-width-setting ()
"Toggle setting tab widths between 4 and 8"
(interactive)
(setq tab-width (if (= tab-width 8) 4 8))
(redraw-display))
Edited to add redraw-display as per comment suggested
Not quite answering the question (the answers given are good enough), but you might want to consider setting a per-file local variable. For example, assuming that "//" means comment in your language, you would put the following in the first line of the file:
// -*- tab-width: 4 -*-
And emacs will set the variable for you whenever you visit the file. See http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html for more information on file-based variables.
Of course this might not be a choice if the file is shared among a group - unless you can convince your colleges that this first line comment is completely harmless and extremely useful!
Thanks for all the answers. I added a redraw-display call so that the change is reflected immediately. (Tried posting this as a comment, but can't.)
(global-set-key (kbd "<f8>") 'tf-toggle-tab-width-setting)
(defun tf-toggle-tab-width-setting () "toggle setting tab widths between 4 and 8"
(interactive)
(setq tab-width (if (= tab-width 8) 4 8))
(message "set tab-width to %d." tab-width)
(redraw-display)
)
And along the same lines. :(
(global-set-key (kbd "<f7>") 'tf-toggle-indent-mode-setting)
(defun tf-toggle-indent-mode-setting ()
"toggle indenting modes"
(interactive)
(setq indent-tabs-mode (if (eq indent-tabs-mode t) nil t))
(message "Indenting using %s." (if (eq indent-tabs-mode t) "tabs" "spaces"))
)
Throw this in your .emacs or .emacs.d/init.el file:
(defun toggle-spaces ()
"Toggle tab-width between 4 and 8"
(interactive)
(if (eq tab-width 4)
(setq tab-width 8)
(setq tab-width 4)))
;; This will set Ctrl-g to toggle but you can set it to anything
;; you want.
(global-set-key "\C-g" 'toggle-spaces)