Easy Access to Terminal Commands in Neovim using FTerm
Tags: neovim, vim, editor
Published: 2024-03-18 13:26:14

---
title: Easy Access to Terminal Commands in Neovim using FTerm
published: true
description: The article will describe how to customize your neovim config to provide easy, in-editor access to any command you can render in the terminal
tags: neovim,vim,editor
# cover_image: https://i.imgur.com/IzOBTdG.png
# Use a ratio of 100:42 for best results.
# published_at: 2024-03-18 12:36 +0000
---

Have you ever found yourself having to switch contexts too many times in the course of using your favorite text editor Neovim? I certainly have.

Having a common set of tools already set up in different windows or sessions in [Tmux](https://github.com/tmux/tmux) or [Zellij](https://github.com/zellij-org/zellij) is obviously an option, but there is a subset of us ( :wave: ) that would rather just have fingertip access to our common tools inside of our editor.

This quick article will show you how to achieve such a state.

## The Setup

Obviously, you should probably have Neovim installed and are somewhat familiar working with it.

In my case, I have switched to [Lazy.nvim](https://github.com/folke/lazy.nvim) for all of my Neovim plugin needs ( Thanks again Folke! ), so it would be great if you were at least minimally familiar with how Lazy works as well.

The last thing you really need is a common set of tools that you want fingertip access to. I really commonly use [LazyGit](https://github.com/jesseduffield/lazygit) and [K9s](https://github.com/derailed/k9s) in my day job so those are the tools I will show off in this article.

## The Plugin

To achieve our goals of fingertip access nirvana, we are going to be using a plugin called [FTerm.nvim](https://github.com/numToStr/FTerm.nvim).

If you want to see an exhaustive list of all the things you can do with FTerm, go check out the repository (and leave a star or whatever).

## The How

In typical Lazy.nvim fashion, we simply add a lua file in the normal plugins directory that looks like so:

```lua
-- ~/.nvim/lua/plugins/fterm.lua

return {
  {
    'numToStr/FTerm.nvim'
  }
}
```

If you save that, you now have access to FTerm as soon as you run `:Lazy` or restart Neovim.

The default state is not exactly ergonomic though because to launch it, you would need to run `:lua require("FTerm").toggle()` to get it to show up, but now that we have access to the FTerm API, we can get all kinds of fancy with user commands or with custom keybindings as I will show here.

```lua
-- ~/.nvim/lua/plugins/fterm.lua

return {
  {
    'numToStr/FTerm.nvim',
    config = function()
      local fterm = require('FTerm')
      vim.keymap.set('n', '<leader>tt', function() fterm:toggle() end, {desc = '[T]oggle [T]terminal'})
      vim.keymap.set('t', '<leader>tt', function() fterm:toggle() end, {desc = '[T]oggle [T]erminal'})
    end,
  }
}
```

This didn't add a whole lot, but now FTerm is a whole lot easier to get access to. While in `NORMAL` (`n`) mode, you simply have to press `<leader>tt` to toggle open the floating terminal, and the same to toggle it closed assuming you are in that floating terminal (which is in `TERM` (`t`) mode).

FTerm, by default, will simply open your `$SHELL` which is great for a whole lot of reasons, but we are wanting direct access to a handful of terminal commands, so lets add them:

```lua
-- ~/.nvim/lua/plugins/fterm.lua

return {
  {
    'numToStr/FTerm.nvim',
    config = function()
      local fterm = require('FTerm')
      vim.keymap.set('n', '<leader>tt', function() fterm:toggle() end, {desc = '[T]oggle [T]terminal'})
      vim.keymap.set('t', '<leader>tt', function() fterm:toggle() end, {desc = '[T]oggle [T]erminal'})
    end,
  },
  {
    'numToStr/FTerm.nvim',
    name = 'FTerm.LazyGit.nvim',
    config = function()
      local fterm = require('FTerm')
      local lazygit = fterm:new({
        cmd = 'lazygit',
      })

      vim.keymap.set('n', '<leader>lg', function() lazygit:toggle() end, {desc = 'Toggle [L]azy[G]it'})
      vim.keymap.set('t', '<leader>lg', function() lazygit:toggle() end, {desc = 'Toggle [L]azy[G]it'})
    end,
  },
  {
    'numToStr/FTerm.nvim',
    name = 'FTerm.k9s.nvim',
    config = function()
      local fterm = require('FTerm')
      local k9s = fterm:new({
        cmd = 'k9s',
      })

      vim.keymap.set('n', '<leader>tk', function() k9s:toggle() end, {desc = '[T]oggle [K]9s'})
      vim.keymap.set('t', '<leader>tk', function() k9s:toggle() end, {desc = '[T]oggle [K]9s'})
    end,
  }
}
```

So things got just a little more complicated, but lets walk through it:

Now we have 3 plugins being returned by the same lua file that I've called fterm.lua, but if you notice, they are all the same source, just renamed. This is how I am getting custom behavior.

The first is just the behavior we defined before because I do still want access to just my `$SHELL`.

The second renames the plugin from the default (FTerm.nvim) to `FTerm.LazyGit.nvim` (this is just so Lazy doesn't smash all of the configs together in one directory and we get weird behavior). The last little bit we added was the custom command we want to run; `lazygit` in this case. We then do basically the same thing as before, but with new keybindings to get easy access to our custom command.

The third is a repeat of the second, but with `k9s` rather than `lazygit`.

In doing this, I now have access to `lazygit` in a floating window just by typing `<leader>lg` and access to `k9s` in a floating window by typing `<leader>tk`.

Feel free to rinse and repeat with your favorite commands :smile:

If you liked this content, let me know and I can create some more. Even better if you have a topic. Heck, maybe I'll even make a series.