Categories
Software vim

Save/write all before test in Neotest

Neotest is an excellent plugin for working with tests in a variety of languages in Neovim, but it was driving me mad having to remember to run :wa before running any tests. Why would anyone want to edit a file then run tests against the last saved version rather than the one in the editor?

Anyway, after a bit of familiarisation with how the lua config for lazy.nvim works, it turned out to be pretty easy to override the default keybindings that run tests (copied from the full spec in the LazyVim docs for Neotest) to save everything first. I ended up with this in ~/.config/nvim/lua/plugins/neotest.lua:

return {
  "nvim-neotest/neotest",
  keys = {
    {
      "<leader>tt",
      function()
        vim.cmd("wa")
        require("neotest").run.run(vim.fn.expand("%"))
      end,
      desc = "Run File (Neotest)",
    },
    {
      "<leader>tT",
      function()
        vim.cmd("wa")
        require("neotest").run.run(vim.uv.cwd())
      end,
      desc = "Run All Test Files (Neotest)",
    },
    {
      "<leader>tr",
      function()
        vim.cmd("wa")
        require("neotest").run.run()
      end,
      desc = "Run Nearest (Neotest)",
    },
    {
      "<leader>tl",
      function()
        vim.cmd("wa")
        require("neotest").run.run_last()
      end,
      desc = "Run Last (Neotest)",
    },
  },
}

Categories
Software vim

Opening files in Neovide from the shell or Finder

Another nvim howto, to remind myself how to do this when I want to set up Neovide on a new machine …

I previously (ie up until last week) used MacVim, and was able to open files using the mvim command. By default, Neovide is a bit clunkier, running a new instance in the foreground whenever you open it (this might be improved soon). Fortunately someone else has done the hard work for me, so it’s pretty easy to fix.

Firstly, save this script to somewhere in your path (I put it in /usr/local/bin/nv), and make it executable (chmod u+x /usr/local/bin/nv). This gives you an nv command in the shell, which will either open Neovide if it’s not running, or open the files you give it in a running instance.

If you want to be able to open a file at a specific line with nv path:lineno (or by command-clicking on a stack trace entry etc), I created a fork of the above script which sends the command to jump to the specified line after opening the file.

Secondly, fire up Automator, and create a new application. Add a Run Shell Script action, set it to pass input as arguments, and change the content to the following:

/usr/local/bin/nv "$@"

Save it somewhere (eg in /Applications), then you can tell the Finder to open any files/file types you want to edit in Neovide to open with this application. This also gives you command-click editing in iTerm.

Categories
Elixir Software vim

Projectionist in NeoVim

I’m in the process of tentatively switching from “classic” vim to NeoVim (specifically, LazyVim), and it took me ages to get Tim Pope’s Projectionist plugin working.

In case this helps anyone else (and Google successfully indexes it), the trick seems to have been to set event to BufEnter, to force it to check whether to load itself whenever you open a file (there may be a better way, but this one seems to work). This is what I ended up with in lua/plugins/projectionist.lua (I’m setting it up for Elixir, so you’ll probably want a different language-specific plugin, or to add your own config (see below).

return {
  {
    "tpope/vim-projectionist",
    keys = {
      { "<leader>a", "<cmd>A<cr>", desc = "Go to alternate file" },
    },
    event = "BufEnter",
  },
  { "c-brenn/fuzzy-projectionist.vim" },
  { "andyl/vim-projectionist-elixir" },
}

I think, based on this Stack Overflow answer, that the syntax for adding your own heuristics is as below (see the plugin docs for more details). In this case mix.exs is the path it checks for the existence of to decide whether these mappings apply to the current project.

return {
    "tpope/vim-projectionist",
    config = function()
      vim.g.projectionist_heuristics = {
        ["mix.exs"] = {
          ["src/*.ex"] = {
            alternate = "test/{}_test.exs",
          },
          ["test/*_test.exs"] = {
            alternate = "src/{}.ex",
          },
        },
      }
    end,
    event = "BufEnter",
  },