diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0803a76b..b70f3cc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,37 +8,35 @@ on: workflow_dispatch: jobs: - build: + commit_lint: + runs-on: ubuntu-latest + steps: + # Check commit messages + - uses: webiny/action-conventional-commits@v1.1.0 + + test: + runs-on: ubuntu-latest + strategy: fail-fast: false matrix: - neovim_branch: ['v0.9.5'] - runs-on: ubuntu-latest + neovim_version: ['0.9.5'] + env: - NEOVIM_BRANCH: ${{ matrix.neovim_branch }} + NEOVIM_VERSION: ${{ matrix.neovim_version }} + steps: - - uses: actions/checkout@v3 - - - name: Setup build dependencies - run: | - sudo apt-get update && - sudo apt-get install -y \ - cmake \ - g++ \ - gettext \ - libtool-bin \ - lua-bitop \ - ninja-build \ - unzip - - - name: Cache neovim - uses: actions/cache@v3 + - name: Checkout + uses: actions/checkout@v4 + + - uses: leafo/gh-actions-lua@v10 with: - path: neovim-${{env.NEOVIM_BRANCH}} - key: build-${{env.NEOVIM_BRANCH}} + luaVersion: "5.1.5" + + - uses: leafo/gh-actions-luarocks@v4 - - name: Build Neovim - run: make neovim NEOVIM_BRANCH=$NEOVIM_BRANCH + - name: Download nvim-test + run: make nvim-test - name: Run Test - run: make test NEOVIM_BRANCH=$NEOVIM_BRANCH + run: make test NEOVIM_VERSION=$NEOVIM_VERSION diff --git a/.gitignore b/.gitignore index a7eef2dd..2fd5ac58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -neovim-* +nvim-test nvim-treesitter diff --git a/Makefile b/Makefile index e28b7d61..bae72831 100644 --- a/Makefile +++ b/Makefile @@ -1,57 +1,29 @@ .DEFAULT_GOAL := test -NEOVIM_BRANCH := v0.9.5 +NEOVIM_VERSION := 0.9.5 -FILTER=.* - -NEOVIM := neovim-$(NEOVIM_BRANCH) +NVIM_TS_SHA := 883c72cd -.PHONY: neovim -neovim: $(NEOVIM) - -$(NEOVIM): - git clone --depth 1 https://github.com/neovim/neovim --branch $(NEOVIM_BRANCH) $@ - make -C $@ +FILTER=.* nvim-treesitter: - git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter + git clone \ + --filter=blob:none \ + https://github.com/nvim-treesitter/nvim-treesitter + cd nvim-treesitter && git checkout $(NVIM_TS_SHA) -nvim-treesitter/parser/%.so: nvim-treesitter $(NEOVIM) - $(RM) -r $@ - VIMRUNTIME=$(NEOVIM)/runtime $(NEOVIM)/build/bin/nvim \ - --headless \ - --clean \ - --cmd 'set rtp+=./nvim-treesitter' \ - -c "TSInstallSync $*" \ - -c "q" - -export VIMRUNTIME=$(PWD)/$(NEOVIM)/runtime - -BUSTED = $$( [ -f $(NEOVIM)/test/busted_runner.lua ] \ - && echo "$(NEOVIM)/build/bin/nvim -ll $(NEOVIM)/test/busted_runner.lua" \ - || echo "$(NEOVIM)/.deps/usr/bin/busted" ) +nvim-test: + git clone https://github.com/lewis6991/nvim-test + nvim-test/bin/nvim-test --init .PHONY: test -test: $(NEOVIM) nvim-treesitter \ - nvim-treesitter/parser/cpp.so \ - nvim-treesitter/parser/lua.so \ - nvim-treesitter/parser/rust.so \ - nvim-treesitter/parser/typescript.so - $(BUSTED) \ - -v \ - --lazy \ - --helper=$(PWD)/test/preload.lua \ - --output test.busted.outputHandlers.nvim \ - --lpath=$(PWD)/$(NEOVIM)/?.lua \ - --lpath=$(PWD)/$(NEOVIM)/build/?.lua \ - --lpath=$(PWD)/$(NEOVIM)/runtime/lua/?.lua \ - --lpath=$(PWD)/nvim-treesitter/lua/?.lua \ - --lpath=$(PWD)/?.lua \ +test: nvim-test nvim-treesitter + nvim-test/bin/nvim-test test \ + --runner_version $(NEOVIM_VERSION) \ + --target_version $(NEOVIM_VERSION) \ --lpath=$(PWD)/lua/?.lua \ --filter=$(FILTER) \ - $(PWD)/test - - -@stty sane + --verbose lint: luacheck lua diff --git a/lua/treesitter-context/render.lua b/lua/treesitter-context/render.lua index e742f29c..1e02b1d8 100644 --- a/lua/treesitter-context/render.lua +++ b/lua/treesitter-context/render.lua @@ -184,6 +184,7 @@ local function highlight_contexts(bufnr, ctx_bufnr, contexts) end_col = necol, priority = priority + p, hl_group = hl_from_capture(query, capture, lang), + conceal = metadata.conceal, }) -- TODO(lewis6991): Extmarks of equal priority appear to apply diff --git a/test/ts_context_spec.lua b/test/ts_context_spec.lua index 3c64efb8..fd1a2546 100644 --- a/test/ts_context_spec.lua +++ b/test/ts_context_spec.lua @@ -1,9 +1,9 @@ -local helpers = require('test.functional.helpers')() -local Screen = require('test.functional.ui.screen') +local helpers = require('nvim-test.helpers') +local Screen = require('nvim-test.screen') local clear = helpers.clear local exec_lua = helpers.exec_lua -local cmd = helpers.command +local cmd = helpers.api.nvim_command local feed = helpers.feed describe('ts_context', function() @@ -27,8 +27,24 @@ describe('ts_context', function() [11] = {foreground = Screen.colors.Fuchsia}; [12] = {foreground = tonumber('0x6a0dad'), background = Screen.colors.LightMagenta}; [13] = {foreground = Screen.colors.White, background = Screen.colors.Red}; + [14] = {background = Screen.colors.LightMagenta, foreground = Screen.colors.SlateBlue}; + [15] = {foreground = Screen.colors.SlateBlue}; }) + cmd [[set runtimepath+=.,./nvim-treesitter]] + + exec_lua[[ + require'nvim-treesitter.configs'.setup { + ensure_installed = { + "c", + "lua", + "rust", + "cpp", + "typescript" + }, + sync_install = true, + } + ]] cmd [[let $XDG_CACHE_HOME='scratch/cache']] cmd [[set packpath=]] cmd('syntax enable') @@ -41,24 +57,25 @@ describe('ts_context', function() it('edit a file', function() exec_lua[[require'treesitter-context'.setup{}]] cmd('edit test/test_file.lua') + exec_lua [[vim.treesitter.start()]] feed'' feed'jj' -- screen:snapshot_util() screen:expect{grid=[[ - {1:local}{2: }{3:function}{2: foo() }| - {4:local} {5:function} bar() | + {1:local}{2: }{1:function}{2: }{3:foo}{14:()}{2: }| + {4:local} {4:function} {5:bar}{15:()} | ^ | | | - {5:end} | + {4:end} | | - {4:local} {5:function} baz() | + {4:local} {4:function} {5:baz}{15:()} | | | | - {5:end} | + {4:end} | | - {5:end} | + {4:end} | {6:~ }| | ]]} @@ -66,18 +83,18 @@ describe('ts_context', function() feed'2' feed'jj' screen:expect{grid=[[ - {1:local}{2: }{3:function}{2: foo() }| - {2: }{1:local}{2: }{3:function}{2: bar() }| + {1:local}{2: }{1:function}{2: }{3:foo}{14:()}{2: }| + {2: }{1:local}{2: }{1:function}{2: }{3:bar}{14:()}{2: }| ^ | - {5:end} | + {4:end} | | - {4:local} {5:function} baz() | + {4:local} {4:function} {5:baz}{15:()} | | | | - {5:end} | + {4:end} | | - {5:end} | + {4:end} | {6:~ }| {6:~ }| {6:~ }| @@ -96,44 +113,38 @@ describe('ts_context', function() it('rust', function() cmd('edit test/test.rs') + exec_lua [[vim.treesitter.start()]] feed'20' screen:expect{grid=[[ - {1:impl}{2: Foo { }| - {2: }{1:fn}{2: }{3:bar}{2:(}{7:&}{10:self}{2:) { }| - {2: }{1:if}{2: condition { }| - {2: }{1:for}{2: i }{1:in}{2: }{10:0}{2:..}{10:100}{2: { }| + {1:impl}{2: }{7:Foo}{2: }{14:{}{2: }| + {2: }{1:fn}{2: }{3:bar}{14:(}{1:&}{3:self}{14:)}{2: }{14:{}{2: }| + {2: }{1:if}{2: }{3:condition}{2: }{14:{}{2: }| + {2: }{1:for}{2: }{3:i}{2: }{1:in}{2: }{10:0}{1:..}{10:100}{2: }{14:{}{2: }| | - ^ } | - } | - } | - } | + ^ {15:}} | + {15:}} | + {15:}} | + {15:}} | | - {4:struct} {5:Foo} { | + {4:struct} {9:Foo} {15:{} | | - active: {9:bool}, | + {5:active}{15::} {9:bool}{15:,} | | - username: {9:String}, | + {5:username}{15::} {9:String}{15:,} | | ]]} feed'14' screen:expect{grid=[[ - {1:struct}{2: }{3:Foo}{2: { }| + {1:struct}{2: }{7:Foo}{2: }{14:{}{2: }| | - email: {9:String}, | + {5:email}{15::} {9:String}{15:,} | | - sign_in_count: {9:u64}, | + {5:sign_in_count}{15::} {9:u64}{15:,} | ^ | - } | - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| + {15:}} | + {6:~ }|*8 | ]]} @@ -141,24 +152,25 @@ describe('ts_context', function() it('c', function() cmd('edit test/test.c') + exec_lua [[vim.treesitter.start()]] feed'' -- Check the struct context screen:expect{grid=[[ - {7:struct}{2: Bert { }| + {1:struct}{2: }{7:Bert}{2: }{14:{}{2: }| {8:// comment} | - {9:int} *f2; | + {9:int} {4:*}f2{15:;} | {8:// comment} | {8:// comment} | ^ {8:// comment} | {8:// comment} | {8:// comment} | - }; | + {15:};} | | - {9:typedef} {9:enum} { | - E1, | - E2, | - E3 | + {4:typedef} {4:enum} {15:{} | + {11:E1}{15:,} | + {11:E2}{15:,} | + {11:E3} | {8:// comment} | | ]]} @@ -167,41 +179,34 @@ describe('ts_context', function() -- Check the enum context screen:expect{grid=[[ - {7:typedef}{2: }{7:enum}{2: { }| - E3 | - {8:// comment} | - {8:// comment} | - {8:// comment} | + {1:typedef}{2: }{1:enum}{2: }{14:{}{2: }| + {11:E3} | + {8:// comment} |*3 ^ {8:// comment} | - {8:// comment} | - {8:// comment} | - } Myenum; | + {8:// comment} |*2 + {15:}} {9:Myenum}{15:;} | | - {9:int} main({9:int} arg1, | - {9:char} **arg2, | - {9:char} **arg3 | - ) | - { | + {9:int} {5:main}{15:(}{9:int} {5:arg1}{15:,} | + {9:char} {4:**}{5:arg2}{15:,} | + {9:char} {4:**}{5:arg3} | + {15:)} | + {15:{} | | ]]} -- func -> if -> for -> do while feed'40' screen:expect{grid=[[ - {7:int}{2: main(}{7:int}{2: arg1, }| - {2: }{7:char}{2: **arg2, }| - {2: }{1:if}{2: (arg1 == }{10:4}{2: }| - {2: && arg2 == arg3) }{13:{}{2: }| - {2: }{1:for}{2: (}{7:int}{2: i = }{10:0}{2:; i < arg1; }| + {7:int}{2: }{3:main}{14:(}{7:int}{2: }{3:arg1}{14:,}{2: }| + {2: }{7:char}{2: }{1:**}{3:arg2}{14:,}{2: }| + {2: }{1:if}{2: }{14:(}{3:arg1}{2: }{1:==}{2: }{10:4}{2: }| + {2: }{1:&&}{2: }{3:arg2}{2: }{1:==}{2: }{3:arg3}{14:)}{2: }{14:{}{2: }| + {2: }{1:for}{2: }{14:(}{7:int}{2: }{3:i}{2: }{1:=}{2: }{10:0}{14:;}{2: }{3:i}{2: }{1:<}{2: }{3:arg1}{14:;}{2: }| ^ | - {4:do} { | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - | - } {4:while} ({11:1}); | + {4:do} {15:{} | + {8:// comment} |*5 + | + {15:}} {4:while} {15:(}{11:1}{15:);} | {8:// comment} | | ]]} @@ -209,169 +214,122 @@ describe('ts_context', function() -- func -> if / else if / else feed'41' screen:expect{grid=[[ - {7:int}{2: main(}{7:int}{2: arg1, }| - {2: }{1:if}{2: (arg1 == }{10:4}{2: }| - {2: && arg2 == arg3) }{13:{}{2: }| - {2: }{13:}}{2: }{1:else}{2: }{1:if}{2: (arg1 == }{10:4}{2:) }{13:{}{2: }| - {2: }{13:}}{2: }{1:else}{2: }{13:{}{2: }| + {7:int}{2: }{3:main}{14:(}{7:int}{2: }{3:arg1}{14:,}{2: }| + {2: }{1:if}{2: }{14:(}{3:arg1}{2: }{1:==}{2: }{10:4}{2: }| + {2: }{1:&&}{2: }{3:arg2}{2: }{1:==}{2: }{3:arg3}{14:)}{2: }{14:{}{2: }| + {2: }{14:}}{2: }{1:else}{2: }{1:if}{2: }{14:(}{3:arg1}{2: }{1:==}{2: }{10:4}{14:)}{2: }{14:{}{2: }| + {2: }{14:}}{2: }{1:else}{2: }{14:{}{2: }| ^ {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | - {8:// comment} | + {8:// comment} |*9 | ]]} end) it('cpp', function() cmd('edit test/test.cpp') + exec_lua [[vim.treesitter.start()]] feed'' screen:expect{grid=[[ - {7:struct}{2: Struct { }| - {9:int} *f2; | - | - | - | + {1:struct}{2: }{7:Struct}{2: }{14:{}{2: }| + {9:int} {4:*}f2{15:;} | + |*3 ^ {8:// cursor position 1} | - }; | - | - | - | - | - | - | - | - | - | + {15:};} | + |*9 ]]} - feed'16' screen:expect{grid=[[ - {7:class}{2: Class { }| - {9:int} *f2; | - | - | - | + {1:class}{2: }{7:Class}{2: }{14:{}{2: }| + {9:int} {4:*}f2{15:;} | + |*3 ^ {8:// cursor position 2} | - }; | - | - | - | - | - | - | - | - | - | + {15:};} | + |*9 ]]} feed'16' screen:expect{grid=[[ - {7:typedef}{2: }{7:enum}{2: { }| - E2, | - E3 | - | - | + {1:typedef}{2: }{1:enum}{2: }{14:{}{2: }| + {11:E2}{15:,} | + {11:E3} | + |*2 ^ {8:// cursor position 3} | - } myenum; | - | - | - | - | - | - | - | - | - | + {15:}} {9:myenum}{15:;} | + |*9 ]]} feed'26' screen:expect{grid=[[ - {7:int}{2: main(}{7:int}{2: arg1, }| - {2: }{1:if}{2: (arg1 == }{10:4}{2: }| - {2: && arg2 == arg3) { }| - {2: }{1:for}{2: (}{7:int}{2: i = }{10:0}{2:; i < arg1; }| - {2: }{1:while}{2: (}{10:1}{2:) { }| + {7:int}{2: }{3:main}{14:(}{7:int}{2: }{3:arg1}{14:,}{2: }| + {2: }{1:if}{2: }{14:(}{3:arg1}{2: }{1:==}{2: }{10:4}{2: }| + {2: }{1:&&}{2: }{3:arg2}{2: }{1:==}{2: }{3:arg3}{14:)}{2: }{14:{}{2: }| + {2: }{1:for}{2: }{14:(}{7:int}{2: }{3:i}{2: }{1:=}{2: }{10:0}{14:;}{2: }{3:i}{2: }{1:<}{2: }{3:arg1}{14:;}{2: }| + {2: }{1:while}{2: }{14:(}{10:1}{14:)}{2: }{14:{}{2: }| ^ {8:// cursor position 4} | - } | - } | - } | - | - | - | - | - | - | - | + {15:}} | + {15:}} | + {15:}} | + |*7 ]]} feed'18' screen:expect{grid=[[ - {7:int}{2: main(}{7:int}{2: arg1, }| - {2: }{7:char}{2: **arg2, }| - {2: }{7:char}{2: **arg3 }| - {2: }{1:do}{2: { }| - {2: }{1:for}{2: (}{7:auto}{2: value : array) {}| + {7:int}{2: }{3:main}{14:(}{7:int}{2: }{3:arg1}{14:,}{2: }| + {2: }{7:char}{2: }{1:**}{3:arg2}{14:,}{2: }| + {2: }{7:char}{2: }{1:**}{3:arg3}{2: }| + {2: }{1:do}{2: }{14:{}{2: }| + {2: }{1:for}{2: }{14:(}{7:auto}{2: }{3:value}{2: }{14::}{2: }{3:array}{14:)}{2: }{14:{}| ^ {8:// cursor position 5} | - } | - } {4:while} ({11:1}); | - } | - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| + {15:}} | + {15:}} {4:while} {15:(}{11:1}{15:);} | + {15:}} | + {6:~ }|*6 | ]]} end) it('typescript', function() cmd('edit test/test.ts') + exec_lua [[vim.treesitter.start()]] feed'' screen:expect{grid=[[ - {1:interface}{2: }{3:User}{2: }{3:{}{2: }| + {1:interface}{2: }{7:User}{2: }{14:{}{2: }| | | | - {5:id}: {9:number}{4:;} | + {5:id}{15::} {9:number}{15:;} | ^ | | | | - {5:}} | + {15:}} |   | - {4:class} UserAccount {5:{} | - {5:name}: {9:string}; | - {5:id}: {9:number}; | + {4:class} {9:UserAccount} {15:{} | + {5:name}{15::} {9:string}{15:;} | + {5:id}{15::} {9:number}{15:;} | | | ]]} feed'21' screen:expect{grid=[[ - {1:class}{2: UserAccount }{3:{}{2: }| - {2: }{3:constructor}{2:(}{12:name}{2::}{12: }{7:string}{1:,}{12: id}| - {2: }{1:for}{2: (}{3:let}{2: i = }{10:0}{1:;}{2: i < }{10:3}{1:;}{2: i++}| + {1:class}{2: }{7:UserAccount}{2: }{14:{}{2: }| + {2: }{14:constructor(}{3:name}{14::}{2: }{7:string}{14:,}{2: }{3:id}| + {2: }{1:for}{2: }{14:(}{1:let}{2: }{3:i}{2: }{1:=}{2: }{10:0}{14:;}{2: }{3:i}{2: }{1:<}{2: }{10:3}{14:;}{2: }{3:i}{1:++}| | | ^ | - {5:}} | + {15:}} | | | | | - {5:}} | - {5:}} | + {15:}} | + {15:}} | | | | @@ -379,15 +337,15 @@ describe('ts_context', function() feed'16' screen:expect{grid=[[ - {1:function}{2: }{3:wrapInArray}{2:(}{12:obj}{2::}{12: }{7:stri}| - {2: }{1:if}{2: (}{3:typeof}{2: obj === }{10:"string"}{2:)}| + {1:function}{2: }{3:wrapInArray}{14:(}{3:obj}{14::}{2: }{7:stri}| + {2: }{1:if}{2: }{14:(}{1:typeof}{2: }{3:obj}{2: }{1:===}{2: }{10:"string"}{14:)}| | | | ^ | - {5:}} | - {4:return} obj; | - {5:}} | + {15:}} | + {4:return} {5:obj}{15:;} | + {15:}} | {6:~ }| {6:~ }| {6:~ }|