My development environment is 100% text based - Fish Shell, Tmux, and Neovim - Here are my Dotfiles
Tags: neovim, tmux, fishshell, javascript
Published: 2022-10-13 06:01:26

## Background

Since migrating to EndeavourOS from Ubuntu I have been tinkering with moving to text based development environment for my regular web development work.

And, what could be better than using Vi editor.

So I configured my terminal to use

- Fish Shell
- Tmux
- Neovim

## My Dotfiles

Following are my dotfiles in ~/.config folder

### Fish Shell

```
if status is-interactive
    # Commands to run in interactive sessions can go here
end
rvm default

set fish_greeting ""

set -gx TERM xterm-256color

# theme
set -g theme_color_scheme terminal-dark
set -g fish_prompt_pwd_dir_length 1
set -g theme_display_user yes
set -g theme_hide_hostname no
set -g theme_hostname always

# aliases
alias ls "ls -p -G"
alias la "ls -A"
alias ll "ls -l"
alias lla "ll -A"
alias g git
command -qv nvim && alias vim nvim
alias tmx="tmux -u new"

set -gx EDITOR nvim

set -gx PATH bin $PATH
set -gx PATH ~/bin $PATH
set -gx PATH ~/.local/bin $PATH

# NodeJS
set -gx PATH node_modules/.bin $PATH

# Go
set -g GOPATH $HOME/go
set -gx PATH $GOPATH/bin $PATH

# NVM
function __check_rvm --on-variable PWD --description 'Do nvm stuff'
  status --is-command-substitution; and return

  if test -f .nvmrc; and test -r .nvmrc;
    nvm use
  else
  end
end

switch (uname)
  case Darwin
    source (dirname (status --current-filename))/config-osx.fish
  case Linux
    source (dirname (status --current-filename))/config-linux.fish
  case '*'
    source (dirname (status --current-filename))/config-windows.fish
end

set LOCAL_CONFIG (dirname (status --current-filename))/config-local.fish
if test -f $LOCAL_CONFIG
  source $LOCAL_CONFIG
end
```

- Some of my dotfiles follow/use/clone dotfiles from [https://github.com/craftzdog/dotfiles-public](https://github.com/craftzdog/dotfiles-public)
- I use [https://github.com/IlanCosman/tide](https://github.com/IlanCosman/tide) for my fish shell promt which basically gives it look 'n' feel of oh-my-zsh.

### Tmux

```
#set -g default-terminal "tmux-256color"
set -g default-terminal "xterm-256color"
#set -ga terminal-overrides ",*256col*:Tc"
set -ga terminal-overrides ",xterm-256color:Tc"
# action key
unbind C-b
set-option -g prefix C-t
set-option -g repeat-time 0
set-option -g focus-events on

#### Key bindings

set-window-option -g mode-keys vi

#bind t send-key C-t
# Reload settings
bind r source-file ~/.tmux.conf \; display "Reloaded!"
# Open current directory
bind o run-shell "open #{pane_current_path}"
bind -r e kill-pane -a

# vim-like pane switching
bind -r k select-pane -U 
bind -r j select-pane -D 
bind -r h select-pane -L 
bind -r l select-pane -R 

# Moving window
bind-key -n C-S-Left swap-window -t -1 \; previous-window
bind-key -n C-S-Right swap-window -t +1 \; next-window

# Resizing pane
bind -r C-k resize-pane -U 5
bind -r C-j resize-pane -D 5
bind -r C-h resize-pane -L 5
bind -r C-l resize-pane -R 5

#### basic settings

set-option -g status-justify "left"
#set-option utf8-default on
#set-option -g mouse-select-pane
set-window-option -g mode-keys vi
#set-window-option -g utf8 on
# look'n feel
set-option -g status-fg cyan
set-option -g status-bg black
set -g pane-active-border-style fg=colour166,bg=default
set -g window-style fg=colour10,bg=default
set -g window-active-style fg=colour12,bg=default
set-option -g history-limit 64096

set -sg escape-time 10

#### COLOUR

# default statusbar colors
set-option -g status-style bg=colour235,fg=colour136,default

# default window title colors
set-window-option -g window-status-style fg=colour244,bg=colour234,dim

# active window title colors
set-window-option -g window-status-current-style fg=colour166,bg=default,bright

# pane border
set-option -g pane-border-style fg=colour235 #base02
set-option -g pane-active-border-style fg=colour136,bg=colour235

# message text
set-option -g message-style bg=colour235,fg=colour166

# pane number display
set-option -g display-panes-active-colour colour33 #blue
set-option -g display-panes-colour colour166 #orange

# clock
set-window-option -g clock-mode-colour colour64 #green

# allow the title bar to adapt to whatever host you connect to
set -g set-titles on
set -g set-titles-string "#T"

# import
# if-shell "uname -s | grep -q Darwin" "source ~/.config/tmux/macos.conf"

source ~/.config/tmux/statusline.conf
source ~/.config/tmux/utility.conf

# List of plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.config/tmux/plugins/tpm/tpm'
```

### Neovim

```
call plug#begin()
  Plug 'morhetz/gruvbox' "https://github.com/morhetz/gruvbox
  Plug 'preservim/nerdtree'
  Plug 'nvim-lualine/lualine.nvim'
  " If you want to have icons in your statusline choose one of these
  Plug 'kyazdani42/nvim-web-devicons'
  Plug 'nvim-lua/plenary.nvim'
  Plug 'nvim-telescope/telescope.nvim', { 'tag': '0.1.0' }
  " or                                , { 'branch': '0.1.x' }
  Plug 'nvim-treesitter/nvim-treesitter'
  Plug 'sharkdp/fd'
  Plug 'nvim-telescope/telescope-file-browser.nvim'
  Plug 'dinhhuy258/git.nvim'
  Plug 'akinsho/bufferline.nvim', { 'tag': 'v2.*' }
  Plug 'lewis6991/gitsigns.nvim'
  Plug 'tomtom/tcomment_vim'
  Plug 'tpope/vim-rails'
  Plug 'tpope/vim-dispatch'
  Plug 'thoughtbot/vim-rspec'
  Plug 'tpope/vim-endwise'
  Plug 'vimwiki/vimwiki'
  Plug 'ervandew/supertab'
  Plug 'neovim/nvim-lspconfig'
  Plug 'hrsh7th/cmp-nvim-lsp'
  Plug 'hrsh7th/cmp-buffer'
  Plug 'hrsh7th/cmp-path'
  Plug 'hrsh7th/cmp-cmdline'
  Plug 'hrsh7th/nvim-cmp'
  Plug 'hrsh7th/vim-vsnip'
  " post install (yarn install | npm install) then load plugin only for editing supported files
  Plug 'prettier/vim-prettier', { 'do': 'yarn install --frozen-lockfile --production' }
call plug#end()

set ruler
set number
syntax enable
set mouse=a
set tabstop=2
set shiftwidth=2

set termguicolors
set background=dark
colorscheme gruvbox

" Start NERDTree and put the cursor back in the other window.
" autocmd VimEnter * NERDTree | wincmd p

let mapleader = ','

" shortcuts for NERDTree
nnoremap <leader>ntfo :NERDTreeFocus<CR>
nnoremap <leader>nt :NERDTree<CR>
nnoremap <leader>ntt :NERDTreeToggle<CR>
nnoremap <leader>ntf :NERDTreeFind<CR>

" All generic shortcuts
nmap <leader>z :u<CR>
nmap <leader>Q :qa!<CR>
nmap <leader>q :bw<CR>
nnoremap <C-S-Up>   :m '<-2<CR>gv=gv
nnoremap <C-S-Down> :m '>+1<CR>gv=gv

" Find files using Telescope command-line sugar.
nnoremap <leader>ff <cmd>Telescope find_files<cr>
nnoremap <leader>fg <cmd>Telescope live_grep<cr>
nnoremap <leader>fb <cmd>Telescope buffers<cr>
nnoremap <leader>fh <cmd>Telescope help_tags<cr>

" setup all Lua based Neovim configs - e.g. lualine, git.nvim

lua << EOF
  require('lualine').setup({
    options = {
      icons_enabled = false,
    }
  })
  require('git').setup()
  require('nvim-web-devicons').setup()
  vim.opt.termguicolors = true
  -- Setup Bufferline
  require('bufferline').setup{}
  -- Setup Gitsings - not using often
  require('gitsigns').setup()
  -- Setup nvim-cmp - autoxomplete
  local cmp = require'cmp'
  cmp.setup({
    snippet = {
      -- REQUIRED - you must specify a snippet engine
      expand = function(args)
        vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
        -- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
        -- require('snippy').expand_snippet(args.body) -- For `snippy` users.
        -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
      end,
    },
    window = {
      -- completion = cmp.config.window.bordered(),
      -- documentation = cmp.config.window.bordered(),
    },
    mapping = cmp.mapping.preset.insert({
      ['<C-b>'] = cmp.mapping.scroll_docs(-4),
      ['<C-f>'] = cmp.mapping.scroll_docs(4),
      ['<C-Space>'] = cmp.mapping.complete(),
      ['<C-e>'] = cmp.mapping.abort(),
      ['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
    }),
    sources = cmp.config.sources({
      { name = 'nvim_lsp' },
      { name = 'vsnip' }, -- For vsnip users.
      -- { name = 'luasnip' }, -- For luasnip users.
      -- { name = 'ultisnips' }, -- For ultisnips users.
      -- { name = 'snippy' }, -- For snippy users.
    }, {
      { name = 'buffer' },
    })
  })
  -- Setup Solargraph
  local nvim_lsp = require('lspconfig')
  local servers = {'solargraph'}
  for _, lsp in ipairs(servers) do
    nvim_lsp[lsp].setup {
      on_attach = on_attach,
    }
  end
  require'nvim-treesitter.configs'.setup {
    highlight = {
        enable = true
    },
  }
  -- Setup Telescope with webicons
  local status, telescope = pcall(require, "telescope")
  if (not status) then return end
  local actions = require('telescope.actions')
  local builtin = require("telescope.builtin")
  local function telescope_buffer_dir()
    return vim.fn.expand('%:p:h')
  end
  local fb_actions = require "telescope".extensions.file_browser.actions
  telescope.setup {
    defaults = {
      mappings = {
        n = {
          ["q"] = actions.close
        },
      },
    },
    extensions = {
      file_browser = {
        theme = "dropdown",
        -- disables netrw and use telescope-file-browser in its place
        hijack_netrw = true,
        mappings = {
          -- your custom insert mode mappings
          ["i"] = {
            ["<C-w>"] = function() vim.cmd('normal vbd') end,
          },
          ["n"] = {
            -- your custom normal mode mappings
            ["N"] = fb_actions.create,
            ["h"] = fb_actions.goto_parent_dir,
            ["/"] = function()
              vim.cmd('startinsert')
            end
          },
        },
      },
    },
  }
  telescope.load_extension("file_browser")
  vim.keymap.set("n", "sf", function()
    telescope.extensions.file_browser.file_browser({
      path = "%:p:h",
      cwd = telescope_buffer_dir(),
      respect_gitignore = false,
      hidden = true,
      grouped = true,
      previewer = false,
      initial_mode = "normal",
      layout_config = { height = 40 }
    })
  end)
  -- keymaps
  vim.keymap.set('n', ';f',
    function()
      builtin.find_files({
        no_ignore = false,
        hidden = true
      })
    end)
  vim.keymap.set('n', ';r', function()
    builtin.live_grep()
  end)
  vim.keymap.set('n', '\\\\', function()
    builtin.buffers()
  end)
  vim.keymap.set('n', ';t', function()
    builtin.help_tags()
  end)
  vim.keymap.set('n', ';;', function()
    builtin.resume()
  end)
  vim.keymap.set('n', ';e', function()
    builtin.diagnostics()
  end)
EOF
```

## Download my Dotfiles from my Github repo

[https://github.com/chetanmittaldev/Dotfiles](https://github.com/chetanmittaldev/Dotfiles)

## Credits

**My Fish shel, Tmux, and Neovim setup follows the guides from various developers especially**

- [https://dev.to/craftzdog/my-neovim-setup-for-react-typescript-tailwind-css-etc-58fb](https://dev.to/craftzdog/my-neovim-setup-for-react-typescript-tailwind-css-etc-58fb)
- [https://www.youtube.com/watch?v=KKxhf50FIPI](https://www.youtube.com/watch?v=KKxhf50FIPI)
- [https://dev.to/andrenbrandao/terminal-setup-with-zsh-tmux-dracula-theme-48lm](https://dev.to/andrenbrandao/terminal-setup-with-zsh-tmux-dracula-theme-48lm)
- [https://raygervais.dev/articles/2021/3/neovim-lsp/](https://raygervais.dev/articles/2021/3/neovim-lsp/)

**Originally posted on** - [https://blog.chetanmittaldev.com/i-have-moved-to-using-fish-shell-tmux-and-neovim-as-my-web-development-tools](https://blog.chetanmittaldev.com/i-have-moved-to-using-fish-shell-tmux-and-neovim-as-my-web-development-tools)