DEV Community

Cover image for Neovim y LunarVim para trabajar con Rails
Mario Alberto Chávez
Mario Alberto Chávez

Posted on • Originally published at mariochavez.io

Neovim y LunarVim para trabajar con Rails

Post publicado originalmente en https://mariochavez.io/desarrollo/2022/08/05/neovim-lunarvim-rail/


Desde hace más de 15 años he utilizado, primero Vim, luego Neovim para desarrollar software. Mi tendencia es tratar de personalizar solamente lo suficiente para trabajar cómodamente con el código.

En los últimos años, estuve haciendo uso de Vim con Spacevim, pero para ser sincero nunca hice uso al 100% de todo lo que ofrecía Spacevim. El año pasado vi un tweet sobre Neovim y algo llamado Lunarvim y me pareció interesante, en particular el soporte que Neovim presentaba para los Language Servers.

Así que tomé la decisión de borrar mi configuración de Vim de años y comenzar desde cero con Neovim.

Instalar Neovim es relativamente fácil, normalmente implica ejecutar un par de comando o descargar un binario. En MacOS es un comando con Homebrew.

brew install neovim

Una vez que está instalado Neovim, el siguiente paso es instalar Lunarvim, nuevamente un comando en la terminal y se instala en un par de minutos, recomiendo la versión estable.

bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
Enter fullscreen mode Exit fullscreen mode

Durante la instalación va a preguntar si deseamos instalar las dependencias de Javascript, Python y Rust, hay que responder que sí.

LunarVim crear un directorio en ~/.config/lvim donde se encuentra el archivo de configuración de Neovim y Lunarvim config.lua

Aquí está mi archivo de configuración config.lua

En ese archivo es donde podemos configurar como deseamos que el editor se comporte y agregar plugins necesarios. Mi configuración es muy básica, solamente hice los siguientes cambios.

Deshabilité que autoformatee mi código al guardar.

lvim.format_on_save = false
Enter fullscreen mode Exit fullscreen mode

No mostrar los mensajes de error al lado del código

lvim.lsp.diagnostics.virtual_text = false
Enter fullscreen mode Exit fullscreen mode

Mostrar una línea en la columna 120  y que la numeración de las líneas fuese relativa a donde se encuentra el cursor.

vim.opt["colorcolumn"] = "120"
vim.opt["relativenumber"] = true
Enter fullscreen mode Exit fullscreen mode

Cambié el leader a que sea una coma.

lvim.leader = ","
Enter fullscreen mode Exit fullscreen mode

Agregué Spectre, un plugin para buscar y reemplazar texto en el proyecto, al menú

lvim.builtin.which_key.mappings["S"] = { "<cmd>lua require('spectre').open()<CR>", "Spectre" }
Enter fullscreen mode Exit fullscreen mode

Modifiqué la búsqueda de archivos para que solo muestre archivos que estén bajo el control de git.

lvim.builtin.which_key.mappings["f"] = { "<cmd>Telescope git_files<CR>", "Find File" }
Enter fullscreen mode Exit fullscreen mode

Modifiqué el comportamiento para que al guardar un archivo borre espacios en blanco al final de las líneas.

vim.cmd([[
  au FocusLost * :wa
  autocmd FileType ruby,javascript,css,ts autocmd BufWritePre * :%s/\s\+$//e
  autocmd FileType ruby,javascript,css,ts autocmd BufWritePre * :%s/\t/  /e
  match ErrorMsg '\s\+$'
]])
Enter fullscreen mode Exit fullscreen mode

Agregué los siguientes plugins: tpope/vim-fugitive, tpope/vim-rails, EdenEast/nightfox.nvim, windwp/nvim-spectre, principalmente.

Configuré la indentación para Ruby.

lvim.autocommands.custom_groups = {
  { "BufWinEnter", "*.lua", "setlocal ts=8 sw=8" },
  { "BufWinEnter", "*.rb", "setlocal ts=2 sw=2" },
}
Enter fullscreen mode Exit fullscreen mode

Agregué los shortcuts ,wv y ,wh para dividir la pantalla verticalmente y horizontalmente.

lvim.builtin.which_key.mappings["w"] = {
  name = "Splits",
  w = { "<C-w>v<C-w>l", "Vertical" },
  h = { "<C-w>new<C-w>l", "Horizontal" },
}
Enter fullscreen mode Exit fullscreen mode

Finalmente, activé el soporte para Tailwind.

require("lvim.lsp.manager").setup("tailwindcss")
Enter fullscreen mode Exit fullscreen mode

Dentro de Neovim hay que instalar los Language Server para que ayuden a autocompletar y ofrecer diagnóstico ayuda en el código. En mi caso instalé los siguientes:

:LspInstall ruby javascript tailwindcss solargraph
Enter fullscreen mode Exit fullscreen mode

Para el caso de Solargraph que ayuda a autocompletar en Ruby, también configuré StandardRb para diagnóstico y formateo. La configuración de StandardRb requirió de un par de pasos manuales. Hay que navegar al directorio donde se instaló el Language Server de Solargraph y ejecutar la siguiente línea:

cd ~/.local/share/nvim/lsp_servers/solargraph
gem install solargraph-standardrb solargraph-rails standardrb --install-dir .
Enter fullscreen mode Exit fullscreen mode

Luego en el directorio donde está el binario reemplace el contenido de Solargraph con el siguiente código para activar StandardRb.

cd ~/.local/share/nvim/lsp_servers/solargraph/bin
Enter fullscreen mode Exit fullscreen mode

Aquí existe un ejecutable Solargraph, hay que abrirlo con el editor, borrar el contenido y reemplazarlos con el siguiente código.

#!/usr/bin/env ruby
# frozen_string_literal: true

# Solargraph has plugins for linting, but not for formatting. So do a bit of
# dirty monkeypatching of the formatter[1] until/when they add plugin support
# for formatting. There aren't great hooks, as this wasn't designed to be
# extended, so much of #process had to be copied verbatium
# 1: https://github.com/castwide/solargraph/blob/940b28932626e236871c10293da5e0f5eacf94c0/lib/solargraph/language_server/message/text_document/formatting.rb

# ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
# require "bundler/setup"

require "solargraph"
require "standard"

class Solargraph::LanguageServer::Message::TextDocument::Formatting
  def process
    file_uri = params["textDocument"]["uri"]
    config = config_for(file_uri)
    original = host.read_text(file_uri)
    args = cli_args(file_uri, config)

    # require_rubocop(config['version'])
    # options, paths = RuboCop::Options.new.parse(args)
    std = Standard::BuildsConfig.new.call(args)
    options = std.rubocop_options
    options[:stdin] = original
    corrections = redirect_stdout do
      RuboCop::Runner.new(options, std.rubocop_config_store).run(std.paths)
    end
    result = options[:stdin]

    log_corrections(corrections)

    format original, result
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
    set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
  end

  def formatter_class(_config)
    Standard::Formatter
  end
end

Solargraph::Shell.start(ARGV)
Enter fullscreen mode Exit fullscreen mode

Después de esto solo queda en cada proyecto de Ruby on Rails agregar dos archivos, uno para indicar la configuración de Solargraph y otro para la configuración de StandardRb.

# .solargraph.yml
plugins:
  - solargraph-standardrb
  - solargraph-rails
reporters:
  - standardrb
Enter fullscreen mode Exit fullscreen mode
# .standard.yml
fix: true               # default: false
parallel: true          # default: false
format: progress        # default: Standard::Formatter
ruby_version: 3.2.2     # default: RUBY_VERSION
default_ignores: false  # default: true
Enter fullscreen mode Exit fullscreen mode

Top comments (0)