Skip to content

Configuration Examples

cannorin edited this page Sep 2, 2022 · 14 revisions

The absolute minimum example for Neovim 0.5+ with deoplete

We don't recommend deoplete as they say the development of the plugin is finished and so some missing features (such as heredoc) will not be available with it. However, using deoplete is still the fastest way to test if Ionide-vim is working correctly, so we leave it as an example of an absolute minimum configuration.

set nocompatible

syntax on
filetype plugin on

call plug#begin('~/.vim/plugged')

Plug 'ionide/Ionide-vim'
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
Plug 'deoplete-plugins/deoplete-lsp'

call plug#end()

let g:deoplete#enable_at_startup = 1

With nvim-lspconfig and nvim-cmp (for Neovim 0.5+)

This is the recommended way to use this plugin.

"--------------------
"   Basic Settings
"--------------------

set nocompatible

if has("syntax")
  syntax on
endif
filetype plugin on

set completeopt=menu,menuone,noselect

"-----------
"  Plugins
"-----------

" Here we install the required plugins with vim-plug.
function! s:install()

  " This installs vim-plug automatically when missing.
  " Remove this if .. endif if you don't need this.
  if   empty(glob('~/.vim/autoload/plug.vim'))
  \ || empty(glob('~/.local/share/nvim/site/autoload/plug.vim'))
    silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    silent !curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs
        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
  endif

  call plug#begin('~/.vim/plugged')

  " Don't use 'for': 'fsharp'. nvim-lspconfig loads ionide only when editing F# files.
  Plug 'ionide/Ionide-vim'

  Plug 'neovim/nvim-lspconfig'
  Plug 'hrsh7th/cmp-nvim-lsp', { 'branch': 'main' }
  Plug 'hrsh7th/cmp-buffer', { 'branch': 'main' }
  Plug 'hrsh7th/cmp-path', { 'branch': 'main' }
  Plug 'hrsh7th/cmp-cmdline', { 'branch': 'main' }
  Plug 'hrsh7th/nvim-cmp', { 'branch': 'main' }
  Plug 'hrsh7th/cmp-vsnip', { 'branch': 'main' }
  Plug 'hrsh7th/vim-vsnip'

  call plug#end()
endfunction

" Here we configure nvim-cmp.
" See https://github.com/hrsh7th/nvim-cmp for more info.
function! s:nvim_cmp()
lua << EOF
  local cmp = require'cmp'

  cmp.setup({
    snippet = {
      expand = function(args)
        vim.fn["vsnip#anonymous"](args.body)
      end,
    },
    mapping = {
      -- Set your bindings for auto completion feature here.
      ['<C-d>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
      ['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
      ['<M-Space>'] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }),
      ['<C-y>'] = cmp.config.disable,
      ['<C-e>'] = cmp.mapping({
        i = cmp.mapping.abort(),
        c = cmp.mapping.close(),
      }),
      ['<CR>'] = cmp.mapping.confirm({ select = true }),
    },
    sources = cmp.config.sources({ { name = 'nvim_lsp' }, { name = 'vsnip' }, { name = 'buffer' } })
  })

  cmp.setup.cmdline('/', { sources = { { name = 'buffer' } } })

  cmp.setup.cmdline(':', { sources = cmp.config.sources({ { name = 'path' } }, { { name = 'cmdline' } }) })
EOF
endfunction

" Here we configure nvim's LSP feature and nvim-lspconfig.
function! s:nvim_lsp()
lua << EOF
  local on_attach = function(client, bufnr)
    local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
  
    local opts = { noremap=true, silent=true }
    -- Set your bindings for LSP features here.
    buf_set_keymap('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
    buf_set_keymap('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
    buf_set_keymap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
    buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
    buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
    buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
    buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
    buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
    buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
    buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
    buf_set_keymap('n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
    buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
    buf_set_keymap('n', '<space>e', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts)
    buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts)
    buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts)
    buf_set_keymap('n', '<space>q', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts)
    buf_set_keymap('n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)
  end 

  local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities())

  local setup = function(server)
    server.setup {
      autostart = true,
      on_attach = on_attach,
      flags = {
        debounce_text_changes = 150,
      },
      capabilities = capabilities
    }
  end
  local lspconfig = require('lspconfig')
  setup(require('ionide'))
  -- -- add other languages here
  -- setup(lspconfig.ocamllsp)
  -- setup(lspconfig.ccls)
  
  -- Recommended: this makes the hover windows unfocusable.
  vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(
    vim.lsp.handlers.hover, { focusable = false }
  )

  -- Optional: this changes the prefix of diagnostic texts.
  vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(
   vim.lsp.diagnostic.on_publish_diagnostics, {
     virtual_text = {
       prefix = '!',
     },
   }
  )
EOF
endfunction

" Here we configure Ionide-vim.
function! s:fsharp()
  " Required: to be used with nvim-cmp.
  let g:fsharp#lsp_auto_setup = 0

  " Recommended: show tooptip when you hold cursor over something for 1 second.
  if has('nvim') && exists('*nvim_open_win')
    set updatetime=1000
    augroup FSharpShowTooltip
      autocmd!
      autocmd CursorHold *.fs,*.fsi,*.fsx call fsharp#showTooltip()
    augroup END
  endif

  " Recommended: Paket files are excluded from the project loader.
  let g:fsharp#exclude_project_directories = ['paket-files']
endfunction

" Finally, we call each functions.
call s:install()
call s:fsharp()
call s:nvim_cmp()
call s:nvim_lsp()

With deoplete (for Vim 8.x or Neovim <0.5)

nvim's lsp client is not available in vim and nvim<0.5. We again used deoplete to make the configuration simpler. You can swap it to your favorite plugin if you want.

"--------------------
"   Basic Settings
"--------------------

set nocompatible

if has("syntax")
  syntax on
endif
filetype plugin on

"-----------
"  Plugins
"-----------

" Here we install the required plugins with vim-plug.
function! s:install()

  " This installs vim-plug automatically when missing.
  " Remove this if .. endif if you don't need this.
  if   empty(glob('~/.vim/autoload/plug.vim'))
  \ || empty(glob('~/.local/share/nvim/site/autoload/plug.vim'))
    silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    silent !curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs
        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
  endif

  call plug#begin('~/.vim/plugged')

  " On Windows, use 'do': 'powershell -ExecutionPolicy Unrestricted .\install.ps1' instead.
  Plug 'autozimu/LanguageClient-neovim', {
      \ 'branch': 'next',
      \ 'do': 'bash install.sh',
      \ }

  Plug 'ionide/Ionide-vim'

  if has('nvim')
    Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
  else
    Plug 'Shougo/deoplete.nvim'
    Plug 'roxma/nvim-yarp'
    Plug 'roxma/vim-hug-neovim-rpc'
  endif

  call plug#end()
endfunction

" Here we configure deoplete.
" See https://github.com/Shougo/deoplete.nvim and https://github.com/deoplete-plugins/deoplete-lsp for details.
function! s:deoplete()
  let g:deoplete#enable_at_startup = 1
endfunction

" Here we configure LC-neovim.
" See https://github.com/autozimu/LanguageClient-neovim for details.
function! s:lc_neovim()
  nnoremap <silent> xd :call LanguageClient#textDocument_definition()<CR>
  nnoremap <silent> xn :call LanguageClient#textDocument_rename()<CR>
  nnoremap <silent> xf :call LanguageClient#textDocument_formatting()<CR>
  nnoremap <silent> xt :call LanguageClient#textDocument_typeDefinition()<CR>
  nnoremap <silent> xr :call LanguageClient#textDocument_references()<CR>
  nnoremap <silent> xh :call LanguageClient#textDocument_hover()<CR>
  nnoremap <silent> xs :call LanguageClient#textDocument_documentSymbol()<CR>
  nnoremap <silent> xa :call LanguageClient#textDocument_codeAction()<CR>
  nnoremap <silent> xx :call LanguageClient_contextMenu()<CR>
endfunction

" Here we configure Ionide-vim.
function! s:fsharp()
  " Required: for nvim users.
  let g:fsharp#backend = 'languageclient-neovim'

  " Recommended: show tooptip when you hold cursor over something for 1s.
  if has('nvim') && exists('*nvim_open_win')
    set updatetime=1000
    augroup FSharpShowTooltip
      autocmd!
      autocmd CursorHold *.fs,*.fsi,*.fsx call fsharp#showTooltip()
    augroup END
  endif

  " Recommended: Paket files are excluded from the project loader.
  let g:fsharp#exclude_project_directories = ['paket-files']
endfunction

" Finally, we call each functions.
call s:install()
call s:fsharp()
call s:deoplete()
call s:lc_neovim()