roryokane / detectindent

Vim script for automatically detecting indent settings
21 stars 6 forks source link

Sets sw=1, ts=1 when file uses tabs #18

Open HaleTom opened 4 years ago

HaleTom commented 4 years ago

Here's the file:

https://raw.githubusercontent.com/git/git/master/git-add--interactive.perl

I was expecting sw=4, ts=4 (preferred) or sw=8, ts=8.

Perhaps a user-settable variable to allow a person do define 2, 4, or 8 spaces as default if there are only TABs?

roryokane commented 4 years ago

Thanks for the bug report. In a local branch, I added the file you linked as a test case, and can reproduce the problem.

Desired behavior

I think the desired behavior for :DetectIndent on this file is to not modify sw or ts in the local buffer. That way, you can configure your desired sw and ts for tab-only files by setting them in your vimrc (e.g. set tabstop=4).

The cause of the bug

To determine where the code is going wrong, I checked the output of :verbose DetectIndent for that file:

Using tabs to indent. leading_tab_count: 795, leading_space_count: 4, leading_spaces_gcd: 1, leading_space_dict: {'11': 2, '6': 2} Changes from the buffer’s initial settings: tabstop changed from 8 to 1, shiftwidth changed from 8 to 1, softtabstop changed from 0 to -1

That output shows that the file actually does not use only tabs for indentation. (I think DetectIndent already handles files with only tabbed indentation correctly, leaving sw and ts at their global values.) Rather, this plugin changes sw and ts because 4 of the 1,890 lines in this file are indented with spaces. An example of such a line:

    my $i;
    my @prefixes = find_unique_prefixes(@stuff) unless $opts->{LIST_ONLY};

      TOPLOOP: # <------
    while (1) {
        my $last_lf = 0;

The algorithm wrongly guesses that since two of the lines in the file start with 6 spaces, and two lines start with 11 spaces, the desired visual indent size should be the greatest common denominator of 6 and 11, which is 1.

How to fix the bug

I’m still thinking of the best heuristic for fixing this. In this particular file it seems the indentation of the four space-indented lines should be ignored because they are more properly thought of as using spaces for alignment, not spaces for indentation. But what’s the best heuristic for handling a mix of space-indented lines and tab-indented lines in general?

In files where 10% of lines are indented with spaces, the sizes of those indents currently affect the displayed tabstop size, but I think they shouldn’t. However, I think that space-indented lines that consist of 49% of indented lines still should affect the tabstop size. What should the cutoff be? There should probably also be a minimum absolute number of space-indented lines for space-indented lines to be taken into account.

HaleTom commented 4 years ago

Good questions without definite answers. Perhaps they could be used configurable?