Skip to content

Commit

Permalink
lsp: Make vim support more explicit, add code completions (#5917)
Browse files Browse the repository at this point in the history
* Make vim support more explicit, add code completions

* cleanup
  • Loading branch information
V-FEXrt authored Jan 7, 2025
1 parent 8fc0830 commit 4b4e4b9
Show file tree
Hide file tree
Showing 10 changed files with 16,272 additions and 6,820 deletions.
2 changes: 1 addition & 1 deletion source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

set(GRAMMAR_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_grammar_tables.py")
set(VIMSYNTAX_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_vim_syntax.py")
set(VIMSYNTAX_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/vim/generate_syntax.py")
set(XML_REGISTRY_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_registry_tables.py")
set(LANG_HEADER_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_language_headers.py")

Expand Down
87 changes: 87 additions & 0 deletions utils/vim/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Neovim configuration guide for SPIR-V disassembly files

This directory holds instructions to configure Neovim for SPIR-V assembly files (`.spvasm`)

At the end, Neovim should support:
* Syntax highlighting
* Jump to definition
* Find all references
* Symbol renaming
* Operand hover information
* Formatting
* Completion suggestions for all Opcodes and Ids

While the instructions here are specifically for Neovim, they should translate easily to vim.

## Dependencies

In order to build and install the Visual Studio Code language server extension, you will need to install and have on your `PATH` the following dependencies:
* [`golang 1.16+`](https://golang.org/)

## File type detection

Neovim's default config location is typically `~/.config/nvim` so the rest of the instructions assume that but it will need to be changed if your system is different.

Tell neovim that `*.spvasm` files should be treated as `spvasm` filetype
```bash
echo "au BufRead,BufNewFile *.spvasm set filetype=spvasm" > ~/.config/nvim/ftdetect/spvasm.vim
```

## Syntax Highlighting

### Generate the syntax highlighting file
```bash
cd <spirv-tools dir>
mkdir -p build && cd build
# Any platform is fine, ninja is used an as example
cmake -G Ninja ..
ninja spirv-tools-vimsyntax
```

### Copy the syntax file
```bash
cp spvasm.vim ~/.config/nvim/syntax/spvasm.vim
```

## Language Server

### Building the LSP (masOS / Linux)

Run `build_lsp.sh`
Copy `spirvls` and `spirv.json` to a location in `$PATH`

```bash
cd <spirv-tools dir>/utils/vscode
./build_lsp.sh
sudo cp spirvls/* /usr/local/bin/
```

### Building the LSP (Windows)

TODO

### Configuring Neovim

Configuration will depend a lot on your installed plugins but assuming you are using [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) the following should be sufficient.

```lua
local lspconfig = require 'lspconfig'
local configs = require 'lspconfig.configs'

if not configs.spvasm then
configs.spvasm = {
default_config = {
cmd = { 'spirvls' },
filetypes = { 'spvasm' },
root_dir = function(fname)
return '.'
end,
settings = {},
},
}
end

lspconfig.spvasm.setup {
capabilities = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities()),
}
```
File renamed without changes.
5 changes: 3 additions & 2 deletions utils/vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The extension supports:
* Symbol renaming
* Operand hover information
* Formatting
* Completion suggestions for all Opcodes and Ids

## Dependencies

Expand All @@ -18,8 +19,8 @@ In order to build and install the Visual Studio Code language server extension,

## Installing (macOS / Linux)

Run `install.sh`
Run `install_vscode.sh`

## Installing (Windows)

Run `install.bat`
Run `install_vscode.bat`
28 changes: 28 additions & 0 deletions utils/vscode/build_lsp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Copyright (c) 2019 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e # Fail on any error.

ROOT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

pushd ${ROOT_PATH}
go run ./src/tools/gen-grammar.go --cache ./cache --template ./spirv.json.tmpl --out ./spirv.json
go run ./src/tools/gen-grammar.go --cache ./cache --template ./src/schema/schema.go.tmpl --out ./src/schema/schema.go

mkdir -p ./spirvls
cp ./spirv.json ./spirvls

go build -o ./spirvls/spirvls ./src/langsvr.go
popd
File renamed without changes.
File renamed without changes.
138 changes: 114 additions & 24 deletions utils/vscode/spirv.json

Large diffs are not rendered by default.

58 changes: 54 additions & 4 deletions utils/vscode/src/langsvr.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"context"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path"
Expand Down Expand Up @@ -67,7 +66,7 @@ func (s wSpy) Write(p []byte) (n int, err error) {

// main entry point.
func main() {
log.SetOutput(ioutil.Discard)
log.SetOutput(io.Discard)
if enableDebugLogging {
// create a log file in the executable's directory.
if logfile, err := os.Create(path.Join(path.Dir(os.Args[0]), "log.txt")); err == nil {
Expand Down Expand Up @@ -213,6 +212,10 @@ func (s *server) Initialize(ctx context.Context, p *lsp.ParamInitia) (*lsp.Initi
ReferencesProvider: true,
RenameProvider: true,
DocumentFormattingProvider: true,
CompletionProvider: &lsp.CompletionOptions{
TriggerCharacters: []string{"%"},
ResolveProvider: false,
},
},
}
return &res, nil
Expand All @@ -225,9 +228,56 @@ func (s *server) WillSaveWaitUntil(ctx context.Context, p *lsp.WillSaveTextDocum
log.Println("server.WillSaveWaitUntil()")
return nil, nil
}

func markdownOpcode(op *schema.Opcode) string {
sb := strings.Builder{}
sb.WriteString(fmt.Sprintf("**%s** (%s)\n\n", op.Opname, op.Class))

for idx, operand := range op.Operands {
sb.WriteString(fmt.Sprintf("Operand %d%s: ", idx, operand.Quantifier))
sb.WriteString(fmt.Sprintf("%s (%s)\n", operand.Name, operand.Kind.Kind))
}

return sb.String()
}

func (s *server) Completion(ctx context.Context, p *lsp.CompletionParams) (*lsp.CompletionList, error) {
log.Println("server.Completion()")
return nil, nil
f := s.getFile(p.TextDocument.URI)
if f == nil {
return nil, fmt.Errorf("Unknown file")
}

if p.Context.TriggerCharacter == "%" {
idents := []lsp.CompletionItem{}
for name, ident := range f.res.Identifiers {
idents = append(idents, lsp.CompletionItem{
Label: name,
Kind: 6,
Documentation: ident.Definition.Range.Text(f.res.Lines),
})
}
res := &lsp.CompletionList{
IsIncomplete: false,
Items: idents,
}

return res, nil
}

opcodes := []lsp.CompletionItem{}
for name, opcode := range schema.Opcodes {
opcodes = append(opcodes, lsp.CompletionItem{
Label: name,
Kind: 3,
Documentation: markdownOpcode(opcode),
})
}
res := &lsp.CompletionList{
IsIncomplete: false,
Items: opcodes,
}
return res, nil
}
func (s *server) Resolve(ctx context.Context, p *lsp.CompletionItem) (*lsp.CompletionItem, error) {
log.Println("server.Resolve()")
Expand All @@ -246,7 +296,7 @@ func (s *server) Hover(ctx context.Context, p *lsp.HoverParams) (*lsp.Hover, err
default:
sb.WriteString(fmt.Sprintf("<Unhandled type '%T'>", v))
case *parser.Instruction:
sb.WriteString(fmt.Sprintf("```\n%v\n```", v.Opcode.Opname))
sb.WriteString(markdownOpcode(v.Opcode))
case *parser.Identifier:
sb.WriteString(fmt.Sprintf("```\n%v\n```", v.Definition.Range.Text(f.res.Lines)))
case *parser.Operand:
Expand Down
Loading

0 comments on commit 4b4e4b9

Please sign in to comment.