nvim-treesitter icon indicating copy to clipboard operation
nvim-treesitter copied to clipboard

Python indent is wrong for files indented with tabs

Open Diomendius opened this issue 2 years ago • 2 comments

Describe the bug

# vim: ft=python et sw=4
def foo():
    print()

When editing the above file with Treesitter indent enabled, adding a new line below print() either with o or A<cr> correctly puts the cursor on a line already indented to the same level as print().

When editing a file indented with tabs, autoindent works correctly when adding lines in the middle of a scope, but indents to the level of the enclosing scope when adding lines at the end of a scope. With :TSDisable indent, indentation is correct with or without tab-based indent.

To Reproduce

# vim: ft=python noet sw=0
def foo():
	print()
  1. Ensure Treesitter indentation is enabled and the python parser is installed.
  2. Save the above to a file and open it in Nvim.
  3. Place the cursor in insert mode after print() and press return.
  4. Observe incorrect autoindent.

Expected behavior

Automatic indentation should behave the same regardless of whether tabs or spaces are used for indentation.

Output of :checkhealth nvim-treesitter

Installation ~
- OK `tree-sitter` found 0.20.8 (parser generator, only needed for :TSInstallFromGrammar)
- OK `node` found v20.3.1 (only needed for :TSInstallFromGrammar)
- OK `git` executable found.
- OK `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
  Version: cc (GCC) 13.1.1 20230429
- OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.

OS Info:
{
  machine = "x86_64",
  release = "6.3.9-arch1-1",
  sysname = "Linux",
  version = "#1 SMP PREEMPT_DYNAMIC Wed, 21 Jun 2023 20:46:20 +0000"
} ~

Parser/Features         H L F I J
  - bash                ✓ ✓ ✓ . ✓
  - c                   ✓ ✓ ✓ ✓ ✓
  - cpp                 ✓ ✓ ✓ ✓ ✓
  - json                ✓ ✓ ✓ ✓ .
  - lua                 ✓ ✓ ✓ ✓ ✓
  - luadoc              ✓ . . . .
  - python              ✓ ✓ ✓ ✓ ✓
  - query               ✓ ✓ ✓ ✓ ✓
  - rust                ✓ ✓ ✓ ✓ ✓
  - vim                 ✓ ✓ ✓ . ✓
  - vimdoc              ✓ . . . ✓
  - yaml                ✓ ✓ ✓ ✓ ✓

  Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
         +) multiple parsers found, only one will be used
         x) errors found in the query, try to run :TSUpdate {lang} ~

Output of nvim --version

NVIM v0.10.0-dev-596+g7d0a23973
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-10 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wvla -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -fno-common -Wno-unused-result -Wimplicit-fallthrough -fdiagnostics-color=always -fstack-protector-strong -DUNIT_TESTING -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_TS_HAS_SET_MAX_START_DEPTH -I/__w/neovim/neovim/.deps/usr/include/luajit-2.1 -I/usr/include -I/__w/neovim/neovim/.deps/usr/include -I/__w/neovim/neovim/build/src/nvim/auto -I/__w/neovim/neovim/build/include -I/__w/neovim/neovim/build/cmake.config -I/__w/neovim/neovim/src -I/usr/include -I/__w/neovim/neovim/.deps/usr/include -I/__w/neovim/neovim/.deps/usr/include -I/__w/neovim/neovim/.deps/usr/include -I/__w/neovim/neovim/.deps/usr/include -I/__w/neovim/neovim/.deps/usr/include -I/__w/neovim/neovim/.deps/usr/include

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/__w/neovim/neovim/build/nvim.AppDir/usr/share/nvim"

Additional context

It doesn't seem to matter whether expandtab is set. The bug seems to present itself when either the first or last indented line of a scope contains at least one tab character. The indent composition of the lines between doesn't seem to matter.

If you take a Python file indented with tabs, set et and run :%retab, the parse tree remains identical save for column numbers. It thus seems unlikely that this bug is caused by the parser.

Diomendius avatar Jun 29 '23 09:06 Diomendius

this is because of https://github.com/nvim-treesitter/nvim-treesitter/blob/ad75d3c4bdd1e88bcac2c385d355c591ba7dee67/lua/nvim-treesitter/indent.lua#L179

Where we set indent_size to be related to shiftwidth. But it's not respecting tabstop and expandtab, hmm

lucario387 avatar Jun 29 '23 09:06 lucario387

Huh, you're right. With :set ts=1 sw=1, the correct indentation is applied.

Diomendius avatar Jun 29 '23 10:06 Diomendius

Can confirm 2d917106d172d8a207042f357c8d983afd391050 fixes this, closing.

Diomendius avatar Jul 06 '24 03:07 Diomendius