jscheid / dtrt-indent

A minor mode that guesses the indentation offset originally used for creating source code files and transparently adjusts the corresponding settings in Emacs, making it more convenient to edit foreign files.
184 stars 31 forks source link

Overriding tab setting for hard tabbed file #46

Open ambihelical opened 5 years ago

ambihelical commented 5 years ago

I have a source tree which uses hard tabs for indentation and which assumes tab width is a value different than my default tab-width (as set up in init.el). I'd like to tell dtrt-indent via .dir-locals.el to set that tab-width and let it set any related variables (e.g. evil-shift-width). I've failed so far to do this.

If I set tab-width in .dir-locals.el, that sets only tab-width, dtrt-indent seems to use my default values for everything else.I get the same result by setting c-basic-offset. Here is the messages I get for dtrt-indent in both cases (I am trying to set tab width to 3 via .dir-locals.el, my init.el sets tab-width and evil-shift-width to 4, I don't set c-basic-offset at all):

Note: c-basic-offset, evil-shift-width adjusted to 4
Note: indent-tabs-mode adjusted to t

Is there a way to do this?

Here is my setup for dtrt-indent:

(use-package dtrt-indent
  :hook (( prog-mode text-mode ) . dtrt-indent-mode)
  :init
  (setq dtrt-indent-run-after-smie t)
  :config)
rrthomas commented 5 years ago

I'm sorry that despite being the current maintainer I don't know the code well enough to give a comprehensive answer.

I observe that tab-width is not used directly by dtrt-indent at all.

I wonder whether this is a matter of the order in which things happen when .dir-locals.el is read; that is, is dtrt-indent reading the global value of tab-width (indirectly) and overriding the dir-locals value? Is dtrt-indent's advicing of hack-one-local-variable in play here?

ambihelical commented 5 years ago

I think tab-width is a red-herring here. I should be using c-basic-offset. I did some experimentation. If I use c-basic-offset, the advice does correctly set dtrt-indent-explicit-offset, however the advice runs after the "Note: ..." logging, which I'm guessing means it happens too late.

Note: c-basic-offset, evil-shift-width adjusted to 4
Note: indent-tabs-mode adjusted to t
dtrt 2nd arg for c++-mode is c-basic-offset
ad-get-arg 0 c-basic-offset
explicit offset
dtrt 2nd arg for c++-mode is c-basic-offset
ad-get-arg 0 c-basic-offset
explicit offset
ambihelical commented 5 years ago

It looks like the processing that dtrt-indent is doing in define-minor-mode is too early, and probably should be done on a hook, maybe hack-local-variables-hook? Not sure.

ambihelical commented 5 years ago

I pushed a commit to my fork for you to look at that does fix the problem of overriding the variables by using hack-local-variables-hook to delay the initial dtrt-indent setup until the file local variables have been set. It doesn't do exactly what I want, as I really want dtrt-indent to set all related variables, but I guess I can make do without that.

ambihelical commented 5 years ago

I added some functionality to allow overriding the offset found without disabling any of the setting of related variables. Also added code to allow the related variables to apply to any derived major mode. I'll test these this week. Let me know if these seem reasonable or not.

rrthomas commented 5 years ago

Thanks, this all looks good. Let me know how you get on with testing!

ambihelical commented 5 years ago

Updated the code, moved to branch tab-override in my fork. Still trying it out. Fixed the explicit file variable setting of indent-tabs-mode as well, as it didn't work.

rrthomas commented 4 years ago

Any update on this?

ambihelical commented 4 years ago

No not really. I wasn't able to get it work correctly in all cases. I think it's probably doable, but I don't know enough about emacs internals to do it.

rrthomas commented 4 years ago

OK, thanks for getting back to me! I guess it's worth leaving this issue open in case anyone with enough time and/or expertise can solve it in future.

ambihelical commented 4 years ago

Yes please. I may revisit the problem again as well.