Re: c-ts-mode: How to set indent-style in dir-locals

Stéphane Marks <[email protected]> Mon, 18 May 2026 18:38:16 -0400
Newsgroups gmane.emacs.help
Message-ID <CAN+1HbpjaL=qNCQSchSW+_Q8ipJYhzdFFsm3KajD8UPYZsnUng@mail.gmail.com>
On Mon, May 18, 2026 at 6:17 PM <[email protected]> wrote:

> समीर सिंह Sameer Singh <[email protected]> writes:
>
> > I have a .dir-locals.el file with the following content:
> >
> > ;;; Directory Local Variables            -*- no-byte-compile: t -*-
> > ;;; For more information see (info "(emacs) Directory Variables")
> >
> > ((c-ts-mode . ((c-ts-mode-indent-style . bsd))))
> >
> > but the c files in the project does not follow the specified style for
> > whatever reason. If I "describe-var" `c-ts-mode-indent-style' it says:
> >
> > c-ts-mode-indent-style is a variable defined in ‘c-ts-mode.el’.
> >
> > Its value is ‘bsd’
> > Original value was ‘gnu’
> > Local in buffer test.c; global value is gnu
> >
> > Style used for indentation.
> >
> > The selected style could be one of GNU, K&R, LINUX or BSD.  If the
> > supplied styles don’t suffice, the value could be a function instead.
> > This function takes no arguments and is expected to return a list of
> > indent RULEs as described in ‘treesit-simple-indent-rules’.  Note that
> > the list of RULEs doesn’t need to contain the language symbol.
> >
> >   This variable’s value is directory-local, set by the file
> >   ‘/home/ss141309/code/project-dir/.dir-locals.el’.
> >   This variable is safe as a file local variable if its value
> >   satisfies the predicate ‘c-ts-indent-style-safep’.
> >   This variable was introduced, or its default value was changed, in
> >   version 29.1 of Emacs.
> >   You can customize this variable.
> >   Setting this variable directly with ‘setq’ may not take effect;
> >   use either customize or ‘setopt’, or call
> ‘c-ts-mode--indent-style-setter’.
> >
>
> Note the last sentence in the docstring/help text, above:
>
> >   Setting this variable directly with ‘setq’ may not take effect;
> >   use either customize or ‘setopt’, or call
> ‘c-ts-mode--indent-style-setter’.
>
> There does not appear to be any way to customize a user
> option using a ‘.dir-locals.el’ file.  It only sets the
> values of variables, which is different from setting a user
> option (since Emacs 29).
>
> C-h f setopt
>
>    "This is like ‘setq’, but is meant for user options instead of
>     plain variables.  This means that ‘setopt’ will execute any
>     ‘custom-set’ form associated with VARIABLE."
>
> When the functions ‘c-ts-mode--indent-style-setter’ or
> ‘c-ts-mode-set-style’ are called, they set the value of
> ‘c-ts-mode-indent-style’ (as your ‘.dir-locals.el’ does,
> also), but also perform some other actions.  Because those
> other actions are not performed when your ‘.dir-locals.el’
> is read, the indentation is not working.
>
> Two alternatives that should work for you is:
>
>   1. Customize this option using ‘setopt’ by adding:
>
>        (setopt c-ts-mode-indent-style 'bsd)
>
>      to your Emacs initialization file.
>
> or,
>
>    2. Customize this option using the Easy Customization
>       interface in Emacs:
>
>       M-x customize-option RET
>       Customize variable: c-ts-mode-indent-style RET
>
>       After setting the value, click on the ‘Apply and Save’
>       button to save the new value to your customization file.
>
> This will make the indentation style always in effect,
> rather than only in effect for a specific directory.  You
> would need to change its value again if you do not want your
> setting in effect for specific files or directories.
>

It might be worth trying and adapting something like this in your
.dir-locals.el or .dir-locals-2.el file:

(
 (c-mode . ((eval . (setopt-local c-ts-mode-indent-style 'bsd))))
 )

'setopt-local' is new in Emacs 31.