mpeterv / luacheck

A tool for linting and static analysis of Lua code.
MIT License
1.92k stars 322 forks source link

Allow tab size to be configurable #140

Open nvs opened 7 years ago

nvs commented 7 years ago

As it stands, each tab is counted as a single character. However, in most cases, a tab's width is often greater. This discrepancy causes Luacheck to not warn on lines that would otherwise be considered too long.

It would be nice if a tab size could be specified, as this would ensure that the line length checks remain accurate when using tabs for indentation.

A visual example, with GitHub using a tab size of 8.

    -- 1 tab // 1 character
                                -- 8 tabs // 8 characters
        -- 8 spaces // 8 characters
kevans91 commented 6 years ago

Hi,

I started working on this, then I found this issue. =-) We use tabs for indentation in our lua bootloader with a tabstop of 8, so this would be most handy (even if our standard might be considered Lua heresy =D).

Here's my first cut at a patch: https://people.freebsd.org/~kevans/luacheck-tabstop.diff

I'm kind of stuck from here, though, and I think I need some input from @mpeterv -- I started from the bottom up and changed the line_lengths counter to expand tabs based on a local 'tabstop', but I'm floundering a little bit in adding a --tabstop option for it.

I -think- I'm on the right path, though. I've added it to the option parser in main.lua, and I've added it to options.all_options to validate as a number (or false, which I guess means to default to 1). I'm not 100% sure how to make that option available in check_or_throw over in the check module , or if that's even possible with the current setup.

mpeterv commented 6 years ago

Expanding tabs typically means extending a tab into spaces until it reaches a multiple of tab stops in columns (e.g. with tabstop 8 in abc\tdef tab should become 5 spaces, not 8. There is a difference only when a tab is after some other characters, so this is only an issue if code is strangely formatted or has tabs in string literals.

It's also not trivial to report line length warnings correctly. The warning's column should be the first character that doesn't fit the length requirement. If tabs alter line length like that then using max_line_length + 1 as the column (the way it's done currently) is incorrect. E.g. if there is a string \t\tfoo() and max line length is 20 and tab stop is 8, line length after tab expansion is 8 + 8 + 5 = 21, and so warning column range should be just the last character, but it's actual column is 1 + 1 + 5 = 7, not 21.

This also ties in with the way editor plugin interpret column ranges, I'm using SublimeLinter-luacheck for Sublime Text 3 which treats column ranges printed by luacheck as character ranges without expanding tabs. Need to check other editors.

And the largest problem is that currently none of the options are available inside main part of the checking. That enables caching of check results that doesn't get invalidated when options change, but it's also very inconvenient. I'm currently working on some internal changes that remove caching and allow access to options during checking.

kevans91 commented 6 years ago

Right, sorry, it only works for me since tabs don't often appear other than "^\t". My apologies. =)

kevans91 commented 6 years ago

I've replaced my patch with a version that at least calculates the replacement size better. It's obviously not ideal, and the reporting is still wrong, but I tend to ignore the column number on this warning because I expect that it'll be pretty obvious where the problem lies when I look at in my editor (with :set ts=8, colorcolumn=80).