andreyorst / smarttab.kak

Automatic handling different styles of indentation and alignment.
MIT License
62 stars 4 forks source link

Add autoconfigtab command to use existing settings #12

Closed clarfonthey closed 2 years ago

clarfonthey commented 3 years ago

This essentially provides "use what I have in editorconfig" behaviour.

Updated the readme as well to explain how users can take advantage of this. This is actually the biggest part of this PR, as the actual code is rather small.

0phoff commented 2 years ago

Small sidenote, smart_tabs seems to be coming to editorconfig, so it might be interesting to support that as well ? I added support for this in my setup by duplicating the editorconfig-load command and adding support for this extra property.

code Implementation: ```kak declare-option -docstring "Default to smarttab or noexpandtab when editorconfig sets indent_style to tabs without smart_tabs" \ bool smarttab_default false define-command smarttab-editorconfig -params 1..2 \ -docstring "smarttab-editorconfig [file]: Set formatting and tabbing behaviour according to editorconfig, but default to a certain tab-mode if there is no editorconfig / those settings are not set" \ %{ require-module smarttab evaluate-commands %sh{ command -v editorconfig >/dev/null 2>&1 || { echo "fail editorconfig could not be found"; exit 1; } default_mode="${1}" file="${2:-$kak_buffile}" case $file in /*) # $kak_buffile is a full path that starts with a '/' printf %s\\n "remove-hooks buffer editorconfig-hooks" editorconfig "$file" | awk -v file="$file" -v default_mode="$default_mode" -v smarttab_default="${kak_opt_smarttab_default}" -F= -- ' $1 == "indent_style" { indent_style = $2 } $1 == "smart_tabs" { smart_tabs = $2 } $1 == "indent_size" { indent_size = $2 == "tab" ? 4 : $2 } $1 == "tab_width" { tab_width = $2 } $1 == "end_of_line" { end_of_line = $2 } $1 == "charset" { charset = $2 } $1 == "trim_trailing_whitespace" { trim_trailing_whitespace = $2 } $1 == "max_line_length" { max_line_length = $2 } END { if (indent_style == "tab") { if (smart_tabs == "true" || (smart_tabs == "" && smarttab_default == "true")) { print "smarttab" } else { print "noexpandtab" } } else if (indent_style == "space") { print "set-option buffer indentwidth " indent_size print "expandtab" } else { print default_mode } if (indent_size || tab_width) { print "set-option buffer tabstop " (tab_width ? tab_width : indent_size) } if (end_of_line == "lf" || end_of_line == "crlf") { print "set-option buffer eolformat " end_of_line } if (charset == "utf-8-bom") { print "set-option buffer BOM utf8" } if (trim_trailing_whitespace == "true") { print "hook buffer BufWritePre \"" file "\" -group editorconfig-hooks %{ try %{ execute-keys -draft %{ %s\\h+$|\\n+\\zd } } }" } if (max_line_length && max_line_length != "off") { print "set window autowrap_column " max_line_length print "autowrap-enable" print "add-highlighter -override window/ column %sh{ echo $((" max_line_length "+1)) } default,bright-black" } } ' ;; esac } } ``` Configuration in kakrc (Note that I explicitely source my custom script files, but this should not be necessary if implemented in this plugin): ```kak plug "andreyorst/smarttab.kak" config %{ source "%val{config}/scripts/smarttab-editorconfig.kak" # Default to editorconfig or expandtab hook global WinSetOption filetype=.* %{ smarttab-editorconfig expandtab } # Force specific modes hook global WinSetOption filetype=(makefile) noexpandtab # Force specific mode unless editorconfig hook global WinSetOption filetype=(c|cpp|typescript|javascript) %{ smarttab-editorconfig smarttab } } defer smarttab %{ set-option global softtabstop 4 set-option global smarttab_default true } ```
clarfonthey commented 2 years ago

I'm sorry for taking so long to get to this; I've been going through my old PRs on GitHub and this one got left behind.

Another thing I'm thinking of, is that the name autotab may be a bit misleading into thinking that this enables automatic indentation, which it really doesn't. Maybe we could use something like econftab or something like that? I'm not strictly opposed to autotab though, as the readme clarifies it's use. Just thinking maybe it can be named more related to editorconfig somehow. Ideas?

In terms of the name, I think autoconfigtab is a good compromise. I want to avoid specifically referencing editorconfig since technically this is just using existing settings that kakoune has, although editorconfig is the main use case.

Can you explain me how user would configure this feature to work for specific languages, defined in their .editorconfig?

For example, I have this in my .editorconfig file:

root = true

[*.{c,cc,cpp,h,hpp,hh}]
indent_style = tab

[*.{rs,toml}]
indent_style = space
indent_size = 4

And in my kakrc I use these hooks:

hook global WinSetOption filetype=rust expandtab
hook global WinSetOption filetype=(c|cpp) smarttab

AFAIU, instead of specifying different hooks for rust and c/cpp filetypes, I would need to specify one that loads .editorconfig and calls autotab, right?

So, in this specific case, you'd choose:

hook global BufCreate .* {
    editorconfig-load
    set global aligntab false
    autoconfigtab
}

I tried to modify the docs to be a bit clearer, specifically clarifying that you can replace noexpandtab with smarttab if you go with this option. expandtab will always remain the same, however. As I mention in the last point in the README, having alignment with tabs and indenting with spaces didn't really make sense to me, so, that use case just forces everything to spaces.

clarfonthey commented 2 years ago

Small sidenote, smart_tabs seems to be coming to editorconfig, so it might be interesting to support that as well ? I added support for this in my setup by duplicating the editorconfig-load command and adding support for this extra property.

For right now at least, I don't want to cover this case, but it could definitely be added in the future. Although maybe in the future this would provide justification for including smarttab.kak's code in the main kakoune repo.

andreyorst commented 2 years ago

LGTM! Thanks!