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

समीर सिंह Sameer Singh <[email protected]> Mon, 18 May 2026 18:26:31 -0700
Newsgroups gmane.emacs.help
Message-ID <CAOR1sLz4p8VQFYq29XqzAOUOQTuge7v_-5pFU67mUTqu6BFxBw@mail.gmail.com>
Stéphane Marks <[email protected]> writes:

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


Even after reading the documentation, somehow I did not seem to put two
and two together and figure out what I was doing wrong 🫠

Thanks everyone!

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

`setopt-local' does not work with c-ts-mode-indent-style it complains:

File local-variables error: (error The setter of
c-ts-mode-indent-style does not support setopt-local)

`setopt' works fine though.

-- 
समीरसिंह