Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ionide/Ionide-vim

F# Vim plugin based on FsAutoComplete and LSP protocol
https://github.com/ionide/Ionide-vim

fsharp ionide vim vim-plugin

Last synced: 12 days ago
JSON representation

F# Vim plugin based on FsAutoComplete and LSP protocol

Awesome Lists containing this project

README

        

# Ionide-Vim

**F# support for Vim/Neovim**

![ionide-vim](https://i.imgur.com/3RLcJw6.gif)

_Part of the [Ionide](http://ionide.io) plugin suite._

## About Ionide-Vim

* A fork of [fsharp/vim-fsharp](https://github.com/fsharp/vim-fsharp).

* Uses LSP-mode of [FsAutoComplete](https://github.com/fsharp/FsAutoComplete) as a backend.

* Uses one of the following LSP clients:
- Neovim's built-in LSP client (requires Neovim 0.5+)
- [autozimu/LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim).

## Development Status

Consider this to be beta since it's lacking features compared to Ionide-VSCode and not as battle-tested as that.

That being said, we maintainers use this plugin daily so it will someday become feature-rich and stable for sure.

Feel free to [request features and/or file bug reports](https://github.com/ionide/Ionide-vim/issues)!

## Requirements

* Neovim or Vim 8+

* [.NET Core SDK](https://dotnet.microsoft.com/download)
- Required to install and run FsAutoComplete.
- Very useful for command-line development.

* If you are using Vim or Neovim below version 0.5:
* [autozimu/LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim)
- Required to communicate with FsAutoComplete.
* [junegunn/fzf](https://github.com/junegunn/fzf) (optional)
- Optional dependency of LanguageClient-neovim.
- Multi-entry selection UI.

## Features

- Syntax highlighting
- Auto completions
- Error highlighting, error list, and quick fixes based on errors
- Tooltips
- Codelens
- Go to Definition
- Find all references
- Highlighting usages
- Rename
- Show symbols in file
- Find symbol in workspace
- Show signature in status line
- Integration with F# Interactive
- Integration with [FSharpLint](https://github.com/fsprojects/FSharpLint) (additional hints and quick fixes)
- Integration with [Fantomas](https://github.com/fsprojects/fantomas/) (the best formatter available for F#)

## Getting Started

### Install FsAutoComplete

Install FsAutoComplete with `dotnet tool install`.

If you want to install it as a "global" tool, run `dotnet tool install -g fsautocomplete`.

If you want to install it as a project-local tool, run `dotnet tool install fsautocomplete`
at the root directory of your F# project, and configure `g:fsharp#fsautocomplete_command`
as explained [here](#set-the-path-to-fsac).

### Install a LSP Client

#### For Neovim 0.5+

No LSP client plugin is required.

If you are using [neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig), do *not* enable `fsautocomplete`.
Ionide-vim automatically integrates itself into nvim-lspconfig and will register itself as a server.

#### For Vim / Neovim (below 0.5)

Install [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim). Refer to [their INSTALL.md](https://github.com/autozimu/LanguageClient-neovim/blob/next/INSTALL.md).

Here is the example for [vim-plug](https://github.com/junegunn/vim-plug) package manager.

~~~.vim
Plug 'autozimu/LanguageClient-neovim', {
\ 'branch': 'next',
\ 'do': 'bash install.sh',
\ }
~~~

If you are running Windows, you will have to set the value of `do` to `'powershell -ExecutionPolicy Unrestricted .\install.ps1'`.

### Install an autocompletion plugin

We recommend using [hrsh7th/nvim-cmp](https://github.com/hrsh7th/nvim-cmp), but the setup is a bit complicated.
See [the example](https://github.com/ionide/Ionide-vim/wiki/Configuration-Examples#with-nvim-lspconfig-and-nvim-cmp-for-neovim-05) in our wiki for how to setup nvim-cmp to be used with Ionide-vim.

[Shougo/deoplete.nvim](https://github.com/Shougo/deoplete.nvim) is an easier alternative, but they say its development is complete and it won't get some features such as heredoc.

~~~.vim
" if you use nvim > 0.5:
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
Plug 'deoplete-plugins/deoplete-lsp'

" otherwise:
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'

" also set this in both cases.
let g:deoplete#enable_at_startup = 1
~~~

### Install Ionide-vim

#### [vim-plug](https://github.com/junegunn/vim-plug)

~~~.vim
Plug 'ionide/Ionide-vim'
~~~

#### [dein.vim](https://github.com/Shougo/dein.vim)

~~~.vim
call dein#add('ionide/Ionide-vim')
~~~

#### Installing manually

Clone Ionide-vim to some runtimepath.

## Usage

Opening either `*.fs`, `*.fsi` or `*.fsx` files should trigger syntax highlighting and other depending runtime files as well.

### LSP features (such as go-to-definition or rename)

Ionide-vim only handles F# specific features of FsAutoComplete, and any other generic features such as "go to definition" and
"rename" are provided by either Neovim or autozimu/LanguageClient-neovim.

You should set your key bindings for those features on your own, so please refer to their documentation.
[The examples in our wiki](https://github.com/ionide/Ionide-vim/wiki/Configuration-Examples#with-nvim-lspconfig-and-nvim-cmp-for-neovim-05)
also contains an example bindings for both Neovim and LanguageClient-neovim.

### Commands

To be added as requested for F#-specific features.

#### `:FSharpShowLoadedProjects`
- Shows the projects currently loaded.

#### `:FSharpParseProject +`
- Loads specified projects (`sln` or `fsproj`).

#### `:FSharpReloadWorkspace`
- Reloads all the projects currently loaded.
- Automatically called when you save `.fsproj` files. Can be disabled in settings.

#### `:FSharpUpdateServerConfig`
- Updates FSAC configuration.
- See [FsAutoComplete Settings](#fsautocomplete-settings) for details.

### Working with F# Interactive

Ionide-vim has an integration with F# Interactive.

FSI is displayed using the builtin `:terminal` feature introduced in Vim 8 / Neovim and can be used like in VSCode.

#### `:FsiShow`
- Shows a F# Interactive window.

#### `:FsiEval `
- Evaluates given expression in FSI.

#### `:FsiEvalBuffer`
- Sends the content of current file to FSI.

#### `:FsiReset`
- Resets the current FSI session.

#### `Alt-Enter`
- When in normal mode, sends the current line to FSI.
- When in visual mode, sends the selection to FSI.
- Sending code to FSI opens FSI window but the cursor does not focus to it. Unlike Neovim, Vim doesn't support asynchronous buffer updating so you have to input something (e.g. moving cursor) to see the result. You can change this behavior in settings.

#### `Alt-@`
- Toggles FSI window. FSI windows shown in different tabpages share the same FSI session.
- When opened, the cursor automatically focuses to the FSI window (unlike in `Alt-Enter` by default).

You can customize the location of FSI, key mappings, etc. See [the documentation below](#f-interactive-settings).

### Settings

To be added as requested for F#-specific features.

See some examples in [our wiki](https://github.com/ionide/Ionide-vim/wiki/Configuration-Examples) if you're not sure what you would want to set.

#### LSP Client Settings

##### Set the LSP client used by Ionide-vim

Set `g:fsharp#backend` to
* `nvim` if you want to use neovim's built-in LSP client.
* `languageclient-neovim` if you want to use [autozimu/LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim).
* `disable` if you only want the syntax highlighting and the FSI integration.

*Default:* `nvim` if you are using Neovim 0.5+, `languageclient-neovim` otherwise.

~~~.vim
let g:fsharp#backend = "languageclient-neovim"
~~~

##### Set the path to FSAC

*Default:* `['fsautocomplete', '--background-service-enabled']`

This option overrides the path to the FSAC Ionide-vim uses.

By default, Ionide-vim uses the FSAC installed globally with `dotnet tool install`.

For example, if you want to use a project-local FSAC, set the following:

~~~.vim
let g:fsharp#fsautocomplete_command =
\ [ 'dotnet',
\ 'fsautocomplete',
\ '--background-service-enabled'
\ ]
~~~

Note: You have to use an array here. Setting a string value to this option will result in an error.

##### Set the keybindings for LSP features

*Default:* not set

Ionide-vim does *not* provide default keybindings for various LSP features, so you will have to set them yourself.

* If you are using neovim's built-in LSP client, see [here](https://github.com/neovim/nvim-lspconfig#keybindings-and-completion).
* If you are using LanguageClient-neovim, refer to [their docs](https://github.com/autozimu/LanguageClient-neovim/blob/next/doc/LanguageClient.txt).

Examples are available at [our wiki](https://github.com/ionide/Ionide-vim/wiki/Configuration-Examples).

#### Settings specific to neovim's built-in LSP client

##### Enable/disable the default colorscheme for diagnostics

*Default:* enabled

Neovim's LSP client comes with no default colorscheme, so Ionide-vim sets a VSCode-like one for LSP diagnostics by default.
You can disable this by the following:

~~~.vim
let g:fsharp#lsp_recommended_colorscheme = 0
~~~

##### Enable/disable automatic setup

*Default:* enabled

With [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig), you would manually call the `setup` function for each LSP servers.
Ionide-vim does this automatically by default, but you can disable it.

~~~.vim
let g:fsharp#lsp_auto_setup = 0

lua << EOF
require'ionide'.setup{}
EOF
~~~

##### Enable/disable automatic refreshing CodeLens

*Default:* enabled

By default, Ionide-vim sets the following so that CodeLens gets refreshed automatically.

~~~.vim
augroup FSharp_AutoRefreshCodeLens
autocmd!
autocmd CursorHold,InsertLeave lua vim.lsp.codelens.refresh()
augroup END
~~~

You can disable this by setting the below option:

~~~.vim
let g:fsharp#lsp_codelens = 0
~~~

**Note: this setting does not affect LanguageClient-neovim's CodeLens feature.**
Please see [their docs](https://github.com/autozimu/LanguageClient-neovim/blob/next/doc/LanguageClient.txt) for how to configure it.

#### FsAutoComplete Settings

* Ionide-vim uses `snake_case` for the setting names.
- For FSAC settings only, `CamelCase` can also be used (as it gets serialized to a F# record).
- If both `snake_case` and `CamelCase` are specified, the `snake_case` one will be preferred.
* You can change the values at runtime and then notify the changes to FSAC by `:FSharpUpdateServerConfig`.
* Some of the settings may not work in Ionide-vim as it is lacking the corresponding feature of Ionide-VSCode.
* If not specified, the recommended default values described in the FSAC's documentation will be used.
- You can disable this by `let g:fsharp#use_recommended_server_config = 0`.

See [the documentation of FSAC](https://github.com/fsharp/FsAutoComplete#settings)
for the complete list of available settings. Frequently used ones are:

##### Enable/disable automatic loading of the workspace on opening F# files

*Default:* enabled

~~~.vim
let g:fsharp#automatic_workspace_init = 1 " 0 to disable.
~~~

##### Set the deep level of directory hierarchy when searching for sln/fsprojs

*Default:* `2`

~~~.vim
let g:fsharp#workspace_mode_peek_deep_level = 2
~~~

##### Ignore specific directories when loading a workspace

*Default:* empty

~~~.vim
let g:fsharp#exclude_project_directories = ['paket-files']
~~~

##### Enable/disable linter and unused opens/declarations analyzer

*Default:* all enabled

You may want to bind `LanguageClient#textDocument_codeAction()` to some shortcut key. Refer to their docs.

~~~.vim
" 0 to disable.
let g:fsharp#linter = 1
let g:fsharp#unused_opens_analyzer = 1
let g:fsharp#unused_declarations_analyzer = 1
~~~

#### Editor Settings

##### Enable/disable automatic calling of `:FSharpReloadWorkspace` on saving `fsproj`

*Default:* enabled

~~~.vim
let g:fsharp#automatic_reload_workspace = 1 " 0 to disable.
~~~

##### Show type signature at cursor position

*Default:* disabled

~~~.vim
let g:fsharp#show_signature_on_cursor_move = 0 " 1 to enable.
~~~

> Note: this feature is known to be causing issues in some circumstances (#57, #58).
> So this feature is now disabled by default.

#### F# Interactive Settings

##### Change the F# Interactive command to be used within Ionide-vim

*Default:* `dotnet fsi`

If you want to use a .NET Framework FSI instead of .NET Core one, set `g:fsharp#use_sdk_scripts` to `0`.
See: https://github.com/fsharp/FsAutoComplete/pull/466#issue-324869672

~~~.vim
let g:fsharp#fsi_command = "fsharpi"
let g:fsharp#use_sdk_scripts = 0 " for net462 FSI
~~~

##### Set additional runtime arguments passed to FSI

*Default:* `--readline-`

Sets additional arguments of the FSI instance Ionide-vim spawns and changes the behavior of FSAC accordingly when editing fsx files.
FSAC passes parameters on to the compiler for static analysis of script files.
Not all parameters are shared between the compiler and interpreter, so FSAC splits these into
1. `FSIExtraInteractiveParameters`: specifically for use with the interpreter process
2. `FSIExtraSharedParameters`: those parameters which should be passed both to the interactive interpreter *and* the compiler

Ionide-vim will pass all options from both of these parameters to the interpreter launched by `fsharp#fsi_command`

~~~.vim
let g:fsharp#fsi_extra_interactive_parameters = ['--readline-']
let g:fsharp#fsi_extra_shared_parameters = ['--langversion:preview']
~~~

There is a legacy option that is still supported by Ionide-vim and FSAC, `FSIExtraParameters`, that will be deprecated upstream in the future.
This is a single option that combines the functionality of both mentioned above.
Using interactive-only parameters in this option yields compiler errors.
[See more discussion in the issue for FSAC](https://github.com/Ionide/fsautocomplete/issues/1210).

It is recommended to migrate configuration to the new parameters.
If you are currently using `FSIExtraParameters`, simply copying the options to `FSIExtraSharedParameters` will preserve all current behavior.

Unti

##### Customize how FSI window is opened

*Default:* `botright 10new`

It must create a new empty window and then focus to it.

See [`:help opening-window`](http://vimdoc.sourceforge.net/htmldoc/windows.html#opening-window) for details.

~~~.vim
let g:fsharp#fsi_window_command = "botright vnew"
~~~

##### Set if sending line/selection to FSI shoule make the cursor focus to FSI window

*Default:* disabled

If you are using Vim, you might want to enable this to see the result without inputting something.

~~~.vim
let g:fsharp#fsi_focus_on_send = 1 " 0 to not to focus.
~~~

##### Change the key mappings

*Default:* `vscode`

* `vscode`: Default. Same as in Ionide-VSCode (`Alt-Enter` to send, `Alt-@` to toggle terminal).
- `` in Neovim / `` in Vim: Sends line/selection to FSI.
- `` in Neovim / `@` in Vim: Toggles FSI window.
* `vim-fsharp`: Same as in [fsharp/vim-fsharp](https://github.com/fsharp/vim-fsharp#fsharp-interactive). Note that `` is mapped to backslash by default. See [`:help mapleader`](http://vimdoc.sourceforge.net/htmldoc/map.html#mapleader).
- `i` : Sends line/selecion to FSI.
- `e` : Toggles FSI window.
* `custom`: You must set both `g:fsharp#fsi_keymap_send` and `g:fsharp#fsi_keymap_toggle` by yourself.
- `g:fsharp#fsi_keymap_send` : Sends line/selection to FSI.
- `g:fsharp#fsi_keymap_toggle` : Toggles FSI window.
* `none`: Disables mapping.

~~~.vim
" custom mapping example
let g:fsharp#fsi_keymap = "custom"
let g:fsharp#fsi_keymap_send = ""
let g:fsharp#fsi_keymap_toggle = ""
~~~

#### Linter & Formatter Settings

Linting (other than the basic ones described above) and formatting is powered by independent tools, [FSharpLint](https://github.com/fsprojects/FSharpLint) and [Fantomas](https://github.com/fsprojects/fantomas/) respectively.

Both uses their own JSON file for configuration and Ionide-vim does not control them. See their docs about configuration: [FSharpLint](http://fsprojects.github.io/FSharpLint/#Configuration-Files) and [Fantomas](https://github.com/fsprojects/fantomas/blob/master/docs/Documentation.md#--config-path-to-file-or-folder).

### Advanced Tips

#### Show tooltips on CursorHold

If you are using neovim 0.4.0 or later, floating windows will be used for tooltips and you might find it convenient to make them appear if the cursor does not move for several seconds.

~~~.vim
if has('nvim') && exists('*nvim_open_win')
augroup FSharpShowTooltip
autocmd!
autocmd CursorHold *.fs,*.fsi,*.fsx call fsharp#showTooltip()
augroup END
endif
~~~

Note that you can set the delay time to show the tooltip by [`set updatetime=`](http://vimdoc.sourceforge.net/htmldoc/options.html#'updatetime'). The default delay is 4 seconds, which you may find too slow.

## Maintainers

* The primary maintainer for this repository is [@cannorin](http://github.com/cannorin).