Robot Language Server - Vim

Hi all,

i’m looking for a way how to integrate LSP into VIM editor. I found that there are lsp implementation in VIM. But I’m doing this first time, and I have no idea how to run robot lsp itself to configure vim lsp to ask for an keywords and stuff around

Does anybody tried to do something like this? There are few plugins with robot framework syntax highlighting, but lsp would be great.

I found in some presentation that plugin is working with neovim, but I do not find any link to download neovim plugin.

Thanks

2 Likes

I am looking for the same: Syntax Highlight and LSP Server.
Using Neovim 0.7.

1 Like

For lsp I managed to get it up and running with just these:

nvim-lspconfig/server_configurations.md at master · neovim/nvim-lspconfig · GitHub

and installed the lsp with pip3 install robotframework-lsp

Syntax highlighting was ok with GitHub - mfukar/robotframework-vim: Some vim scripts for use with the Robot framework.

1 Like

I got this working mostly as per the above.

For syntax highlighting I guess it’s not supported by nvim-treesitter. So copy files from the repo as follows:

git clone https://github.com/mfukar/robotframework-vim
cd robotframework-vim
cp ftdetect/robot.vim .config/nvim/ftdetect/
cp after/syntax/robot.vim .config/nvim/syntax/robot.vim

For LSP support add the following lines to init.lua to bootstrap with Packer:

-- Bootstrap packer.nvim
-- from https://github.com/wbthomason/packer.nvim#bootstrapping

local ensure_packer = function()
  local fn = vim.fn
  local install_path = fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
  if fn.empty(fn.glob(install_path)) > 0 then
    fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path})
    vim.cmd [[packadd packer.nvim]]
    return true
  end
  return false
end

local packer_bootstrap = ensure_packer()

return require('packer').startup(function(use)
  use 'wbthomason/packer.nvim'
  -- My plugins here

  -- LSP nvim-cmp
  use 'neovim/nvim-lspconfig' -- Collection of configurations for built-in LSP client
  use 'hrsh7th/nvim-cmp' -- Autocompletion plugin
  use 'hrsh7th/cmp-nvim-lsp' -- LSP source for nvim-cmp
  use 'saadparwaiz1/cmp_luasnip' -- Snippets source for nvim-cmp
  use 'L3MON4D3/LuaSnip' -- Snippets plugin
  use 'williamboman/mason.nvim' -- manage LSP and DAP servers, linters and formatters

  -- Automatically set up your configuration after cloning packer.nvim
  -- Put this at the end after all plugins
  if packer_bootstrap then
    require('packer').sync()
  end
end)

Then add in init.lua or a submodule within .config/nvim/lua/ the following to setup Mason:

require("mason").setup()

And then add the following lines to setup nvim-cmp (auto complete) for C, python and robot framework:

-- Add additional capabilities supported by nvim-cmp
local capabilities = require("cmp_nvim_lsp").default_capabilities()

local lspconfig = require('lspconfig')

-- Enable some language servers with the additional completion capabilities offered by nvim-cmp
local servers = { 'clangd', 'pylsp', 'robotframework_ls' }
for _, lsp in ipairs(servers) do
  lspconfig[lsp].setup {
    -- on_attach = my_custom_on_attach,
    capabilities = capabilities,
  }
end

require('lspconfig')['pylsp'].setup {
    capabilities = capabilities,
    settings = {
        pylsp = {
            plugins = {
                jedi_completion = {
                    include_params = true,
                },
            },
        },
    },
}

-- luasnip setup
local luasnip = require 'luasnip'

-- nvim-cmp setup
local cmp = require 'cmp'
cmp.setup {
  snippet = {
    expand = function(args)
      luasnip.lsp_expand(args.body)
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ['<C-d>'] = cmp.mapping.scroll_docs(-4),
    ['<C-f>'] = cmp.mapping.scroll_docs(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<CR>'] = cmp.mapping.confirm {
      behavior = cmp.ConfirmBehavior.Replace,
      select = true,
    },
    ['<Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      elseif luasnip.expand_or_jumpable() then
        luasnip.expand_or_jump()
      else
        fallback()
      end
    end, { 'i', 's' }),
    ['<S-Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      elseif luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, { 'i', 's' }),
  }),
  sources = {
    { name = 'nvim_lsp' },
    { name = 'luasnip' },
  },
}

At this stage I exited neovim and restarted it, then ran commands:

:PackerSync

to install the new plugins and

:Mason

to launch the Mason interface, where I scrolled down to robotframework-lsp and pressed the i key to install it. Also installed the python-lsp-server.

Used pylsp instead of the default python language server because it supports function argument signatures and shows docstrings.

For robot files when I ran nvim command :LspInfo I was getting the following error for root directory: Not found:

I noticed here, it is looking for either robotidy.toml or pyproject.toml to indocate the root directory, or a git repo. I just ran git init and then it started working. You can also just create one of those two files.

Still not quite as nice as VS Code robocorp plugin as it’s missing the docstrings in the autocomplete for the robot framework keywords. Also missing is the DAP protcol for the robotframework_debug_adapter for debugging support. Also integration of robocop linter and robotidy formatter would be nice. Should all be doable I’d imagine. Though robocop/robotide can all be done at the CLI easily enough.

Perhaps a neovim plugin that pulls all of this together is in order.

1 Like

Things have changed since I last looked at this. The robocorp plugin is no longer supported and robotcode is now the plugin of choice. @daniel any pointers on to get started with neovim and robotcode?

0 experience with NeoVim but on standard vim i have GitHub - natebosch/vim-lsc: A vim plugin for communicating with a language server addon to support lsp in general. Installed via pathogen. And then on my .vimrc:

let g:lsc_server_commands = {'python': 'pylsp', 'robot': 'robotcode.language_server'}
let g:lsc_auto_map = v:true

That gives basic lsp functionality…

Hey, sorry—I don’t really have any experience with Neovim. It’s been over 20 years since I last used vi.

However, there are lots of tutorials online explaining how to integrate various language servers with Neovim or Vim. Unfortunately, I currently don’t have the time—or honestly the motivation—to figure this out specifically for RobotCode, as I don’t use Neovim myself.

This might be a good chance for the community to step in. If someone could put together a quick guide, I’d gladly publish it on RobotCode.io.

You can find instructions on installing and launching the RobotCode Language Server here:

The rest would have to come from you.

Also, @rasjani has already shared some info—maybe that’ll help get you started.

I now have the robotcode language server working in neovim with Mason and have submitted a PR to have robotcode added to the mason-registry Added robotcode LSP and DAP package by kimfaint · Pull Request #9372 · mason-org/mason-registry · GitHub

This gives me code completion and linting. Yay!

I don’t yet have the debugger working, so I have more work required here to work out what vscode does when it launches the robotcode debug command. For example if I run a single test case in vscode I see a command like the following:

robotcode --default-path . debug --debugpy -- --parse-include tests/hello.robot --name My-Project --suite My-Project.Tests.Hello --by-longname "My-Project.Tests.Hello.World

So it looks like after the -- are some arguments that are passed by robotcode to the robot command like --parse-include, --name, and --suite. But not sure about --by-longname? I guess that is selecting the World test case from the Hello suite, like with the robot --test option?

Then once this is running, does vscode connect to it on tcp port 6612?