F# Vim plugin based on FsAutoComplete and LSP protocol
Vim Script
211
333 commits
updated Apr 10, 2026
F# support for Vim/Neovim

Part of the Ionide plugin suite.
A fork of fsharp/vim-fsharp.
Uses LSP-mode of FsAutoComplete as a backend.
Uses one of the following LSP clients:
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!
Neovim or Vim 8+
If you are using Vim or Neovim below version 0.11.3:
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.
No LSP client plugin is required.
Ionide-vim ships an ionide config for vim.lsp.config() and enables it automatically by default.
Install LanguageClient-neovim. Refer to their INSTALL.md.
Here is the example for vim-plug package manager.
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'.
We recommend using hrsh7th/nvim-cmp, but the setup is a bit complicated. See the example in our wiki for how to setup nvim-cmp to be used with Ionide-vim.
Shougo/deoplete.nvim is an easier alternative, but they say its development is complete and it won't get some features such as heredoc.
" 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
Plug 'ionide/Ionide-vim'
call dein#add('ionide/Ionide-vim')
-- Some configuration must be set before Ionide starts
-- vim.g['fsharp#fsautocomplete_command'] = {
-- 'dotnet',
-- 'fsautocomplete'
-- }
return {
-- F# support
'ionide/Ionide-vim',
ft = { 'fsharp', 'fsharp_project' },
config = function()
-- if you need extra configuration/events, example with 'Show tooltips on CursorHold'
-- vim.api.nvim_create_autocmd({ 'CursorHold' }, {
-- pattern = { '*.fs', '*.fsi', '*.fsx' },
-- callback = function()
-- vim.fn['fsharp#showTooltip']()
-- end,
-- })
-- Show fsi in horizontal split
-- vim.g["fsharp#fsi_window_command"] = "vnew"
end
}
Clone Ionide-vim to some runtimepath.
Opening either *.fs, *.fsi or *.fsx files should trigger syntax highlighting and other depending runtime files as well.
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 also contains an example bindings for both Neovim and LanguageClient-neovim.
To be added as requested for F#-specific features.
:FSharpShowLoadedProjects:FSharpLoadProject <files>+sln, slnx or fsproj).:FSharpReloadWorkspace.fsproj files. Can be disabled in settings.:FSharpUpdateServerConfigIonide-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:FsiEval <expr>:FsiEvalBuffer:FsiResetAlt-EnterAlt-@Alt-Enter by default).You can customize the location of FSI, key mappings, etc. See the documentation below.
To be added as requested for F#-specific features.
See some examples in our wiki if you're not sure what you would want to set.
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.disable if you only want the syntax highlighting and the FSI integration.Default: nvim if you are using Neovim 0.11.3+, languageclient-neovim otherwise.
let g:fsharp#backend = "languageclient-neovim"
Default: ['fsautocomplete']
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:
let g:fsharp#fsautocomplete_command =
\ [ 'dotnet',
\ 'fsautocomplete'
\ ]
Note: You have to use an array here. Setting a string value to this option will result in an error.
Default: not set
Ionide-vim does not provide default keybindings for various LSP features, so you will have to set them yourself.
Examples are available at our wiki.
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:
let g:fsharp#lsp_recommended_colorscheme = 0
Default: enabled
Ionide-vim enables the built-in ionide LSP config automatically by default, but you can disable it.
let g:fsharp#lsp_auto_setup = 0
Then configure and enable it yourself with Neovim's built-in LSP API:
vim.lsp.config("ionide", {
-- your overrides
})
vim.lsp.enable("ionide")
require('ionide').setup() is kept only as a deprecated compatibility shim for existing configurations.
Default: enabled
By default, Ionide-vim sets the following so that CodeLens gets refreshed automatically.
augroup FSharp_AutoRefreshCodeLens
autocmd!
autocmd CursorHold,InsertLeave <buffer> lua vim.lsp.codelens.refresh()
augroup END
You can disable this by setting the below option:
let g:fsharp#lsp_codelens = 0
Note: this setting does not affect LanguageClient-neovim's CodeLens feature. Please see their docs for how to configure it.
snake_case for the setting names.
CamelCase can also be used (as it gets serialized to a F# record).snake_case and CamelCase are specified, the snake_case one will be preferred.:FSharpUpdateServerConfig.let g:fsharp#use_recommended_server_config = 0.See the documentation of FSAC for the complete list of available settings. Frequently used ones are:
Default: enabled
let g:fsharp#automatic_workspace_init = 1 " 0 to disable.
Default: 2
let g:fsharp#workspace_mode_peek_deep_level = 2
Default: empty
let g:fsharp#exclude_project_directories = ['paket-files']
Default: all enabled
You may want to bind LanguageClient#textDocument_codeAction() to some shortcut key. Refer to their docs.
" 0 to disable.
let g:fsharp#linter = 1
let g:fsharp#unused_opens_analyzer = 1
let g:fsharp#unused_declarations_analyzer = 1
:FSharpReloadWorkspace on saving fsprojDefault: enabled
let g:fsharp#automatic_reload_workspace = 1 " 0 to disable.
Default: disabled
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.
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
let g:fsharp#fsi_command = "fsharpi"
let g:fsharp#use_sdk_scripts = 0 " for net462 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
FSIExtraInteractiveParameters: specifically for use with the interpreter processFSIExtraSharedParameters: those parameters which should be passed both to the interactive interpreter and the compilerIonide-vim will pass all options from both of these parameters to the interpreter launched by fsharp#fsi_command
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.
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
Default: botright 10new
It must create a new empty window and then focus to it.
See :help opening-window for details.
let g:fsharp#fsi_window_command = "botright vnew"
Default: disabled
If you are using Vim, you might want to enable this to see the result without inputting something.
let g:fsharp#fsi_focus_on_send = 1 " 0 to not to focus.
Default: enabled
let g:fsharp#fsi_trim_indentation = 1 " 0 to disable.
Default: vscode
vscode: Default. Same as in Ionide-VSCode (Alt-Enter to send, Alt-@ to toggle terminal).
<M-CR> in Neovim / <ESC><CR> in Vim: Sends line/selection to FSI.<M-@> in Neovim / <ESC>@ in Vim: Toggles FSI window.vim-fsharp: Same as in fsharp/vim-fsharp. Note that <leader> is mapped to backslash by default. See :help mapleader.
<leader>i : Sends line/selecion to FSI.<leader>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." custom mapping example
let g:fsharp#fsi_keymap = "custom"
let g:fsharp#fsi_keymap_send = "<C-e>"
let g:fsharp#fsi_keymap_toggle = "<C-@>"
Linting (other than the basic ones described above) and formatting is powered by independent tools, FSharpLint and Fantomas respectively.
Both uses their own JSON file for configuration and Ionide-vim does not control them. See their docs about configuration: FSharpLint and Fantomas.
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.
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=<ms>. The default delay is 4 seconds, which you may find too slow.
(top 30 of 41)
Vim Script
92.6%
Lua
6.6%
F# Vim plugin based on FsAutoComplete and LSP protocol
Vim Script
211
333 commits
updated Apr 10, 2026
F# support for Vim/Neovim

Part of the Ionide plugin suite.
A fork of fsharp/vim-fsharp.
Uses LSP-mode of FsAutoComplete as a backend.
Uses one of the following LSP clients:
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!
Neovim or Vim 8+
If you are using Vim or Neovim below version 0.11.3:
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.
No LSP client plugin is required.
Ionide-vim ships an ionide config for vim.lsp.config() and enables it automatically by default.
Install LanguageClient-neovim. Refer to their INSTALL.md.
Here is the example for vim-plug package manager.
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'.
We recommend using hrsh7th/nvim-cmp, but the setup is a bit complicated. See the example in our wiki for how to setup nvim-cmp to be used with Ionide-vim.
Shougo/deoplete.nvim is an easier alternative, but they say its development is complete and it won't get some features such as heredoc.
" 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
Plug 'ionide/Ionide-vim'
call dein#add('ionide/Ionide-vim')
-- Some configuration must be set before Ionide starts
-- vim.g['fsharp#fsautocomplete_command'] = {
-- 'dotnet',
-- 'fsautocomplete'
-- }
return {
-- F# support
'ionide/Ionide-vim',
ft = { 'fsharp', 'fsharp_project' },
config = function()
-- if you need extra configuration/events, example with 'Show tooltips on CursorHold'
-- vim.api.nvim_create_autocmd({ 'CursorHold' }, {
-- pattern = { '*.fs', '*.fsi', '*.fsx' },
-- callback = function()
-- vim.fn['fsharp#showTooltip']()
-- end,
-- })
-- Show fsi in horizontal split
-- vim.g["fsharp#fsi_window_command"] = "vnew"
end
}
Clone Ionide-vim to some runtimepath.
Opening either *.fs, *.fsi or *.fsx files should trigger syntax highlighting and other depending runtime files as well.
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 also contains an example bindings for both Neovim and LanguageClient-neovim.
To be added as requested for F#-specific features.
:FSharpShowLoadedProjects:FSharpLoadProject <files>+sln, slnx or fsproj).:FSharpReloadWorkspace.fsproj files. Can be disabled in settings.:FSharpUpdateServerConfigIonide-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:FsiEval <expr>:FsiEvalBuffer:FsiResetAlt-EnterAlt-@Alt-Enter by default).You can customize the location of FSI, key mappings, etc. See the documentation below.
To be added as requested for F#-specific features.
See some examples in our wiki if you're not sure what you would want to set.
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.disable if you only want the syntax highlighting and the FSI integration.Default: nvim if you are using Neovim 0.11.3+, languageclient-neovim otherwise.
let g:fsharp#backend = "languageclient-neovim"
Default: ['fsautocomplete']
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:
let g:fsharp#fsautocomplete_command =
\ [ 'dotnet',
\ 'fsautocomplete'
\ ]
Note: You have to use an array here. Setting a string value to this option will result in an error.
Default: not set
Ionide-vim does not provide default keybindings for various LSP features, so you will have to set them yourself.
Examples are available at our wiki.
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:
let g:fsharp#lsp_recommended_colorscheme = 0
Default: enabled
Ionide-vim enables the built-in ionide LSP config automatically by default, but you can disable it.
let g:fsharp#lsp_auto_setup = 0
Then configure and enable it yourself with Neovim's built-in LSP API:
vim.lsp.config("ionide", {
-- your overrides
})
vim.lsp.enable("ionide")
require('ionide').setup() is kept only as a deprecated compatibility shim for existing configurations.
Default: enabled
By default, Ionide-vim sets the following so that CodeLens gets refreshed automatically.
augroup FSharp_AutoRefreshCodeLens
autocmd!
autocmd CursorHold,InsertLeave <buffer> lua vim.lsp.codelens.refresh()
augroup END
You can disable this by setting the below option:
let g:fsharp#lsp_codelens = 0
Note: this setting does not affect LanguageClient-neovim's CodeLens feature. Please see their docs for how to configure it.
snake_case for the setting names.
CamelCase can also be used (as it gets serialized to a F# record).snake_case and CamelCase are specified, the snake_case one will be preferred.:FSharpUpdateServerConfig.let g:fsharp#use_recommended_server_config = 0.See the documentation of FSAC for the complete list of available settings. Frequently used ones are:
Default: enabled
let g:fsharp#automatic_workspace_init = 1 " 0 to disable.
Default: 2
let g:fsharp#workspace_mode_peek_deep_level = 2
Default: empty
let g:fsharp#exclude_project_directories = ['paket-files']
Default: all enabled
You may want to bind LanguageClient#textDocument_codeAction() to some shortcut key. Refer to their docs.
" 0 to disable.
let g:fsharp#linter = 1
let g:fsharp#unused_opens_analyzer = 1
let g:fsharp#unused_declarations_analyzer = 1
:FSharpReloadWorkspace on saving fsprojDefault: enabled
let g:fsharp#automatic_reload_workspace = 1 " 0 to disable.
Default: disabled
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.
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
let g:fsharp#fsi_command = "fsharpi"
let g:fsharp#use_sdk_scripts = 0 " for net462 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
FSIExtraInteractiveParameters: specifically for use with the interpreter processFSIExtraSharedParameters: those parameters which should be passed both to the interactive interpreter and the compilerIonide-vim will pass all options from both of these parameters to the interpreter launched by fsharp#fsi_command
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.
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
Default: botright 10new
It must create a new empty window and then focus to it.
See :help opening-window for details.
let g:fsharp#fsi_window_command = "botright vnew"
Default: disabled
If you are using Vim, you might want to enable this to see the result without inputting something.
let g:fsharp#fsi_focus_on_send = 1 " 0 to not to focus.
Default: enabled
let g:fsharp#fsi_trim_indentation = 1 " 0 to disable.
Default: vscode
vscode: Default. Same as in Ionide-VSCode (Alt-Enter to send, Alt-@ to toggle terminal).
<M-CR> in Neovim / <ESC><CR> in Vim: Sends line/selection to FSI.<M-@> in Neovim / <ESC>@ in Vim: Toggles FSI window.vim-fsharp: Same as in fsharp/vim-fsharp. Note that <leader> is mapped to backslash by default. See :help mapleader.
<leader>i : Sends line/selecion to FSI.<leader>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." custom mapping example
let g:fsharp#fsi_keymap = "custom"
let g:fsharp#fsi_keymap_send = "<C-e>"
let g:fsharp#fsi_keymap_toggle = "<C-@>"
Linting (other than the basic ones described above) and formatting is powered by independent tools, FSharpLint and Fantomas respectively.
Both uses their own JSON file for configuration and Ionide-vim does not control them. See their docs about configuration: FSharpLint and Fantomas.
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.
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=<ms>. The default delay is 4 seconds, which you may find too slow.
(top 30 of 41)
Vim Script
92.6%
Lua
6.6%