The developper experience for Scheme using vanilla Vim is painful.
The goal of this repository is to provide a modern developper experience in Vim for making RNRS compliant Scheme applications.
Specifically R6RS.
This repository aims to provide a good developper experience for Scheme:
- reasonable Vim settings tailored to Scheme.
- sane and overridable LSP configuration defaults for Scheme.
- a modern LSP experience combining the Racket LSP and the (in development) ChezScheme LSP.
- a remap for the ']' key to automatically close parenthesis or brackets.
- sane and overridable REPL defaults with library path detection using Akku.
- support for easy procedure discoverability, find what you need without leaving Vim.
- support for documentation pop-ups from within Vim.
Setting up a developping environment for Scheme requires many days of configuration for the developper who just wants to make a program.
Examples of such overhead include:
- The little tooling which may exist is difficult to discover.
- The tooling which exists requires far too much time to configure.
- Some tooling is specific to the Scheme language.
- Some tooling is specific to the RNRS standard used.
- ... and last but not least, the developper is forced to develop their own tooling which are usually provided in other more popular languages, which may be demoralizing.
Install this plugin using your plugin manager of choice.
Depending on which plugins you have installed this plugins will have more or less features enabled.
For a full range of functionality you should install all the following plugins.
Here is an example using the vim-plug
manager.
call plug#begin()
" Required
Plug 'dehidehidehi/vim-tools-for-scheme'
" Recommended for full functionality of `vim-tools-for-scheme` plugin
Plug 'airblade/vim-rooter'
Plug 'dehidehidehi/vim-simpl', { 'branch': 'improvement/allow-do-load-to-pass-more-terminal-options' }
Plug 'honza/vim-snippets'
Plug 'mattn/vim-lsp-settings'
Plug 'prabirshrestha/asyncomplete-lsp.vim'
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'sirver/ultisnips'
call plug#end()
packloadall
It is recommended you install Akku, the Scheme library manager.
You will benefit from neat REPL utilities and library loading.
If Akku is not found on your system path, these functionalities are disabled.
- Execute the Akku scheme package manager installation script
To benefit from the scheme-langserver
, you should build
and install it.
Do note that I got it to compile properly on my system using the following command, which is slightly different than the one listed in the build instructions form the scheme-langserver repository.
Specifically, I had to specify the parameter --kernelobj
.
./configure --threads --kernelobj --enable-libffi --installdoc=$HOME/.cache/chez-scheme/docs --installprefix=/usr/.local
Building chez-scheme
then building scheme-langserver
isn't the easiest task, given the documentation is not the clearest.
For now I have provided an ansible script which details how I have automated this process.
I have yet to convert this to a pure shell
script, but I hope it will give you guidance.
You must place the scheme lsp server executable on the system path with the name scheme-langserver
.
If you prefer to name it otherwise, remember to set the following setting with the appropriate name:
let g:vtfs_lsp_chez_scheme_lsp_executable_name = "scheme-langserver"
Let's load this plugin using a minimized .vimrc configuration.
First cd
into the root of this repository after having cloned it.
vim -u test/test-vimrc.vim test/test-scheme-file.sps
This should open a vim buffer with a Scheme Hello world
program.
Try using the <leader>l
remap to execute the program in a REPL buffer :)
You should be prompted to install the Racket LSP.
You should be able to see syntax highlighting provided by the LSP.
First cd
into the root of this repository after having cloned it.
akku init test-with-akku
cd test-with-akku
akku install
.akku/env
Then
cd ..
vim -u test/test-vimrc.vim test-with-akku/test-with-akku.sls
This should open a vim buffer with a Scheme Hello world
program.
This also happens to load the buffer with a Scheme library path, managed by Akku.
You should be prompted to install the Racket LSP.
You should be able to see syntax highlighting provided by the LSP.
Try using the <leader>l
remap to execute the program in a REPL buffer :)
You should see the REPL appear, now let's try to execute the hello
procedure defined by default in the newly created Akku package.
In the REPL, type:
(import (test-with-akku))
(hello "world")
This should output "Hello world!"
.
Try installing a package using the shell command akku install <package>
, then importing and using it in the REPL :)
The documentation for the LSP supported commands is available in the vim-lsp repository.
The bindings will not clobber your own vimrc configurations.
Action | default bindings / rebind with |
---|---|
Insert the λ symbol | au! Filetype scheme inoremap <buffer> <unique> <C-\> <Plug>VtfsInsertLambdaSymbol; |
Open Netrw at project root | au! Filetype scheme nnoremap <buffer> <unique> <C-n> <Plug>VtfsNetrwEx; |
Autoclose bracket with appropriate symbol | au! Filetype scheme silent inoremap <buffer> <unique> ] <Plug>VtfsFindMatchingParenType; |
Load into the REPL in a buffer | au! Filetype scheme silent nnoremap <buffer> <LocalLeader>l <Plug>VtfsReplLoad; |
Toggle LSP virtual text | au! Filetype scheme nnoremap <buffer> <LocalLeader>W <Plug>VtfsLspToggleDiagnostics; |
LspCodeAction | au! Filetype scheme nnoremap <buffer> <LocalLeader>a <Plug>VtfsLspCodeAction; |
LspReferences | au! Filetype scheme nnoremap <buffer> <LocalLeader>b <Plug>VtfsLspReferences; |
LspHover | au! Filetype scheme nnoremap <buffer> <LocalLeader>k <Plug>VtfsLspHover; |
LspNextDiagnostic | au! Filetype scheme nnoremap <buffer> <LocalLeader>n <Plug>VtfsLspNextDiagnostic; |
LspPreviousDiagnostic | au! Filetype scheme nnoremap <buffer> <LocalLeader>p <Plug>VtfsLspPreviousDiagnostic; |
LspDefinition | au! Filetype scheme nnoremap <buffer> <LocalLeader>D <Plug>VtfsLspDefinition; |
LspPeekDefinition | au! Filetype scheme nnoremap <buffer> <LocalLeader>d <Plug>VtfsLspPeekDefinition; |
LspRename | au! Filetype scheme nnoremap <buffer> <LocalLeader>r <Plug>VtfsLspRename; |
LspNextError | au! Filetype scheme nnoremap <buffer> <LocalLeader>e <Plug>VtfsLspNextError; |
LspPreviousError | au! Filetype scheme nnoremap <buffer> <LocalLeader>E <Plug>VtfsLspPreviousError; |
Some commands come without a default binding, it is up to you to decide if you want to use them.
Command name | Description | rebind with |
---|---|---|
VtfsReplPopup | Load file into a popup buffer, exit Scheme using CTRL+D | `au! Filetype scheme nnoremap l VtfsReplPopup; |
` |
This opiniated package also provides settings and extra (more convenient) remappings for Netrw, the file system tray for Vim.
Netrw keyboard mappings may seem unintuitive.
You may refer to this great article for documentation on the remappings : Using Netrw, the Vim built-in file explorer
These will be something you may disable in an upcoming release.
Some examples of provided remaps :
- normal mode:
<C-n>
-> Open Netrw - netrw:
ff
-> create new file in current dir - netrw:
FF
-> delete file under cursor - netrw:
d
-> create new dir in current dir - netrw:
D
-> delete dir under cursor
au FileType scheme let g:vtfs_repl_cols = 50
On large screens, the REPL appears on the side of the current buffer.
When loading the Scheme REPL, defines how many column the REPL buffer should occupy on large screens.
The default value is 50
.
au FileType scheme let g:vtfs_repl_rows = 12
On smaller screens, the REPL appears under the current buffer.
When loading the Scheme REPL, defines how many rows the REPL buffer should occupy on smaller screens.
The default value is 12
.
au FileType scheme let b:vtfs_no_lsp_maps = 1
Disable the provided Vim LSP remaps.
au FileType scheme let g:vtfs_lsp_chez_scheme_lsp_executable_name = "scheme-langserver"
If your (optionally) compiled scheme lsp executable has another name than scheme-langserver
, you must specify it's name using the following property.
au FileType scheme let g:vtfs_lsp_chez_scheme_multithread = 0
Disable multithreading for the scheme-langserver
using 0
.
Do note multithreading
requires that the chez scheme
executable on your system be built with the --threads
parameter, as stated in the chez-scheme
build instructions.
au FileType scheme let g:vtfs_lsp_chez_scheme_type_inference = 0
Disable type inference for the scheme-langserver
using 0
.
Do note the type inference
feature of the LSP requires enabling multithreading
.
au Filetype netrw let g:vtfs_enable_netrw_mappings = 0
Disable provided netrw remaps using 0
.
au Filetype netrw let g:vtfs_enable_netrw_settings = 0
Disable provided netrw settings using 0
.
au Filetype scheme b:vtfs_lsp_diagnostics_echo_enabled = 0
Disable the LSP Diagnostics ON/OFF
echo message.
- Vim Plugin vim/simpl https://github.com/benknoble/vim-simpl
- Function VtfsToggleLspDiagnostics prabirshrestha/vim-lsp#1312
- Function VtfsFindMatchingParen https://gist.github.com/plane/8c872ed174ba4f026b95ea8eb934cead
- Vim Gist better-netrw https://vonheikemen.github.io/devlog/tools/using-netrw-vim-builtin-file-explorer/
- LSP scheme-langserver https://github.com/ufo5260987423/scheme-langserver
- The Scheme Index (repository) : The Scheme index allows searching for Scheme procedures, syntax and constants through types, tags, and names.
- Building Vim from source
- Compiling Vim
- Add VtfsToggleTestAlternateFile functionality.
- Make vimscript suggest installation of the Akku package manager if Akku is not detected on the system.
- Make vimscript execute
LspInstallServer racket-lsp
if theracket-lsp
is not installed. - Provide build scripts and LSP configuration for
scheme-langserver
- Provide functions and keybindings for RNRS documentation pop-ups from within Vim.