My web development environment (Alacritty, Tmux, Neovim)
Tags: vim, fedora, development, webdev
Published: 2021-01-02 19:24:04

**This article is based on Neovim 0.4.4 without the new LSP!**

During first years of my software engineering career I noticed that most of my co-workers were using Fedora, Ubuntu, Manjaro etc. distros on their machines. That raised my interest enough to start exploring the opportunities on the Linux side of things, since before this I had only Windows or MacOS machines. I decided to first try out Fedora on my personal home PC and install it alongside of Windows 10. The first impressions were just like "Okay, this looks nice" and installed VSCode along with other tools I used back then. After a while I was intrigued of the productivity side of things. Some folks were using VSCode, Vim, Emacs etc. and I read a lot of articles of how using (Neo)Vim can boost your productivity and be blazing fast when working with code.

That was about 7-8 months ago, and during the last 6 months I've been tweaking my setup to become even more productive. Today I'm sharing my own development environment with you with all the dot-files so you can also try it out! For each tools I have listed the reasons I use that particular tool.

_*Note:* This is the setup what I use everywhere and is my personal configuration_

# Background and what I do

As a software engineer I do web development for most of my time. This includes front- and backend development, Terraform scripts, CI configuration via yml-files etc. Below is a few key technologies what I use

- Ruby, Type-/JavaScript, Elixir languages and related CLI tooling
- Terraform (IaC)
- Run Docker containers
        - These also include web applications, DB's, key-value storages etc
- AWS and GCP tooling
- Firefox and other browsers are under heavy usage

# [Fedora](https://getfedora.org/) - OS

![OS info](https://dev-to-uploads.s3.amazonaws.com/i/o6xliy8i0oupl0ohyzg4.png)

This was kind of obvious thing. I really like how every Fedora release brings something new on board and does it very well. So far I have not countered any bugs and the last upgrade from 32 to 33 went smoothly. The actual key things for me in Fedora was that it offers built-in OCI image support, is built for developers in mind and has many open source tools available. The Gnome desktop environment sits like a glove for me. Some say that it is slow and buggy, but personally I like it a lot.

Also, I use Nvidia graphics card and for some distros it is just pain to install any Nvidia related stuff, but for Fedora it just works and there are good community support and guides for it.

And as a Theme for Fedora I use the dark theme which comes along with fresh Fedora installation. I haven't installed any Gnome plugins since personally I'm okay with the default shortcuts for handling windows, moving between workspaces and arranging stuff in general.

# [Alacritty](https://github.com/alacritty/alacritty) - Terminal Emulator

Before Alacritty I had only used the default terminal emulators on MacOS and Fedora, and also iTerm on MacOS. I came across to Alacritty on some blog post or article that I read half a year ago and thought this is nice maybe I should try it out, so I tried. The main selling point for me was that Alacritty is GPU accelerated terminal emulator which means it should be blazing fast. It is also cross-platform so I can use it everywhere (Linux, MacOS, Windows etc.).

Below you can find my Alacritty configuration file

#### **`alacritty.yml`**
```yml
# Configuration for Alacritty, the GPU enhanced terminal emulator.
shell:
  program: /bin/zsh
  args:
    - -l
    - -c
    - "tmux"

window:
  # Window padding (changes require restart)
  #
  # Blank space added around the window in pixels. This padding is scaled
  # by DPI and the specified value is always added at both opposing sides.
  padding:
    x: 0
    y: 0

  # Spread additional padding evenly around the terminal content.
  dynamic_padding: true

  # Window decorations
  #
  # Values for `decorations`:
  #     - full: Borders and title bar
  #     - none: Neither borders nor title bar
  #
  # Values for `decorations` (macOS only):
  #     - transparent: Title bar, transparent background and title bar buttons
  #     - buttonless: Title bar, transparent background, but no title bar buttons
  decorations: full

  # Startup Mode (changes require restart)
  #
  # Values for `startup_mode`:
  #   - Windowed
  #   - Maximized
  #   - Fullscreen
  #
  # Values for `startup_mode` (macOS only):
  #   - SimpleFullscreen
  startup_mode: Windowed

scrolling:
  # Maximum number of lines in the scrollback buffer.
  # Specifying '0' will disable scrolling.
  history: 10000

  # Number of lines the viewport will move for every line scrolled when
  # scrollback is enabled (history > 0).
  multiplier: 3

# Font configuration (changes require restart)
font:
  normal:
    # Font family
    family: "JetBrains Mono"
    style: Regular

  # Point size
  size: 11.0

  # Offset is the extra space around each character. `offset.y` can be thought of
  # as modifying the line spacing, and `offset.x` as modifying the letter spacing.
  offset:
    x: 0
    y: 0

  # Glyph offset determines the locations of the glyphs within their cells with
  # the default being at the bottom. Increasing `x` moves the glyph to the right,
  # increasing `y` moves the glyph upwards.
  glyph_offset:
    x: 0
    y: 0

  # Thin stroke font rendering (macOS only)
  #
  # Thin strokes are suitable for retina displays, but for non-retina screens
  # it is recommended to set `use_thin_strokes` to `false`
  #
  # macOS >= 10.14.x:
  #
  # If the font quality on non-retina display looks bad then set
  # `use_thin_strokes` to `true` and enable font smoothing by running the
  # following command:
  #   `defaults write -g CGFontRenderingFontSmoothingDisabled -bool NO`
  #
  # This is a global setting and will require a log out or restart to take
  # effect.
  use_thin_strokes: true

# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true

# Colors (Gruvbox dark)
colors:
  primary:
    hard contrast: background = '0x1d2021'
    background: "0x282828"
    soft contrast: background = '0x32302f'
    foreground: "0xebdbb2"

  # Normal colors
  normal:
    black: "0x282828"
    red: "0xcc241d"
    green: "0x98971a"
    yellow: "0xd79921"
    blue: "0x458588"
    magenta: "0xb16286"
    cyan: "0x689d6a"
    white: "0xa89984"

  # Bright colors
  bright:
    black: "0x928374"
    red: "0xfb4934"
    green: "0xb8bb26"
    yellow: "0xfabd2f"
    blue: "0x83a598"
    magenta: "0xd3869b"
    cyan: "0x8ec07c"
    white: "0xebdbb2"

mouse:
  # Click settings
  #
  # The `double_click` and `triple_click` settings control the time
  # alacritty should wait for accepting multiple clicks as one double
  # or triple click.
  #double_click: { threshold: 300 }
  #triple_click: { threshold: 300 }
  # If this is `true`, the cursor is temporarily hidden when typing.
  hide_when_typing: false

selection:
  semantic_escape_chars: ',│`|:"'' ()[]{}<>'

  # When set to `true`, selected text will be copied to the primary clipboard.
  save_to_clipboard: false

cursor:
  # Cursor style
  #
  # Values for `style`:
  #   - ▇ Block
  #   - _ Underline
  #   - | Beam
  style: Block
  # If this is `true`, the cursor will be rendered as a hollow box when the
  # window is not focused.
  unfocused_hollow: true

# Live config reload (changes require restart)
live_config_reload: true

# Shell
#
# You can set `shell.program` to the path of your favorite shell, e.g. `/bin/fish`.
# Entries in `shell.args` are passed unmodified as arguments to the shell.
#
# Default:
#   - (macOS) /bin/bash --login
#   - (Linux) user login shell
#   - (Windows) powershell
# shell:
# program: /usr/bin/zsh
#  args:
#    - --login

# Startup directory
#
# Directory the shell is started in. If this is unset, or `None`, the working
# directory of the parent process will be used.
working_directory: None

# Send ESC (\x1b) before characters when alt is pressed.
alt_send_esc: true

debug:
  # Display the time it takes to redraw each frame.
  render_timer: false

  # Keep the log file after quitting Alacritty.
  persistent_logging: false

  # Log level
  #
  # Values for `log_level`:
  #   - None
  #   - Error
  #   - Warn
  #   - Info
  #   - Debug
  #   - Trace
  log_level: Warn

  # Print all received window events.
  print_events: false

  # Record all characters and escape sequences as test data.
  ref_test: false

# Key bindings
#
# Key bindings are specified as a list of objects. Each binding will specify a
# key and modifiers required to trigger it, terminal modes where the binding is
# applicable, and what should be done when the key binding fires. It can either
# send a byte sequence to the running application (`chars`), execute a
# predefined action (`action`) or fork and execute a specified command plus
# arguments (`command`).
#
# Bindings are always filled by default, but will be replaced when a new binding
# with the same triggers is defined. To unset a default binding, it can be
# mapped to the `None` action.
#
# Example:
#   `- { key: V, mods: Control|Shift, action: Paste }`
#
# Available fields:
#   - key
#   - mods (optional)
#   - chars | action | command (exactly one required)
#   - mode (optional)
#
# Values for `key`:
#   - `A` -> `Z`
#   - `F1` -> `F12`
#   - `Key1` -> `Key0`
#
#   A full list with available key codes can be found here:
#   https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants
#
#   Instead of using the name of the keys, the `key` field also supports using
#   the scancode of the desired key. Scancodes have to be specified as a
#   decimal number.
#   This command will allow you to display the hex scancodes for certain keys:
#     `showkey --scancodes`
#
# Values for `mods`:
#   - Command
#   - Control
#   - Option
#   - Super
#   - Shift
#   - Alt
#
#   Multiple `mods` can be combined using `|` like this: `mods: Control|Shift`.
#   Whitespace and capitalization is relevant and must match the example.
#
# Values for `chars`:
#   The `chars` field writes the specified string to the terminal. This makes
#   it possible to pass escape sequences.
#   To find escape codes for bindings like `PageUp` ("\x1b[5~"), you can run
#   the command `showkey -a` outside of tmux.
#   Note that applications use terminfo to map escape sequences back to
#   keys. It is therefore required to update the terminfo when
#   changing an escape sequence.
#
# Values for `action`:
#   - Paste
#   - PasteSelection
#   - Copy
#   - IncreaseFontSize
#   - DecreaseFontSize
#   - ResetFontSize
#   - ScrollPageUp
#   - ScrollPageDown
#   - ScrollLineUp
#   - ScrollLineDown
#   - ScrollToTop
#   - ScrollToBottom
#   - ClearHistory
#   - Hide
#   - Quit
#   - ClearLogNotice
#   - SpawnNewInstance
#   - ToggleFullscreen
#   - None
#
# Values for `action` (macOS only):
#   - ToggleSimpleFullscreen: Enters fullscreen without occupying another space
#
# Values for `command`:
#   The `command` field must be a map containing a `program` string and
#   an `args` array of command line parameter strings.
#
#   Example:
#       `command: { program: "alacritty", args: ["-e", "vttest"] }`
#
# Values for `mode`:
#   - ~AppCursor
#   - AppCursor
#   - ~AppKeypad
#   - AppKeypad
key_bindings:
  # (Windows/Linux only)
  #- { key: V,        mods: Control|Shift, action: Paste            }
  #- { key: C,        mods: Control|Shift, action: Copy             }
  #- { key: Insert,   mods: Shift,         action: PasteSelection   }
  #- { key: Key0,     mods: Control,       action: ResetFontSize    }
  #- { key: Equals,   mods: Control,       action: IncreaseFontSize }
  #- { key: Add,      mods: Control,       action: IncreaseFontSize }
  #- { key: Subtract, mods: Control,       action: DecreaseFontSize }
  #- { key: Minus,    mods: Control,       action: DecreaseFontSize }
  #- { key: Return,   mods: Alt,           action: ToggleFullscreen }

  # (macOS only)
  #- { key: Key0,   mods: Command,         action: ResetFontSize    }
  #- { key: Equals, mods: Command,         action: IncreaseFontSize }
  #- { key: Add,    mods: Command,         action: IncreaseFontSize }
  #- { key: Minus,  mods: Command,         action: DecreaseFontSize }
  #- { key: K,      mods: Command,         action: ClearHistory     }
  #- { key: K,      mods: Command,         chars: "\x0c"            }
  #- { key: V,      mods: Command,         action: Paste            }
  #- { key: C,      mods: Command,         action: Copy             }
  #- { key: H,      mods: Command,         action: Hide             }
  #- { key: Q,      mods: Command,         action: Quit             }
  #- { key: W,      mods: Command,         action: Quit             }
  #- { key: F,      mods: Command|Control, action: ToggleFullscreen }

  - { key: Paste, action: Paste }
  - { key: Copy, action: Copy }
  - { key: L, mods: Control, action: ClearLogNotice }
  - { key: L, mods: Control, chars: "\x0c" }
  - { key: Home, mods: Alt, chars: "\x1b[1;3H" }
  - { key: Home, chars: "\x1bOH", mode: AppCursor }
  - { key: Home, chars: "\x1b[H", mode: ~AppCursor }
  - { key: End, mods: Alt, chars: "\x1b[1;3F" }
  - { key: End, chars: "\x1bOF", mode: AppCursor }
  - { key: End, chars: "\x1b[F", mode: ~AppCursor }
  - { key: PageUp, mods: Shift, action: ScrollPageUp, mode: ~Alt }
  - { key: PageUp, mods: Shift, chars: "\x1b[5;2~", mode: Alt }
  - { key: PageUp, mods: Control, chars: "\x1b[5;5~" }
  - { key: PageUp, mods: Alt, chars: "\x1b[5;3~" }
  - { key: PageUp, chars: "\x1b[5~" }
  - { key: PageDown, mods: Shift, action: ScrollPageDown, mode: ~Alt }
  - { key: PageDown, mods: Shift, chars: "\x1b[6;2~", mode: Alt }
  - { key: PageDown, mods: Control, chars: "\x1b[6;5~" }
  - { key: PageDown, mods: Alt, chars: "\x1b[6;3~" }
  - { key: PageDown, chars: "\x1b[6~" }
  - { key: Tab, mods: Shift, chars: "\x1b[Z" }
  - { key: Back, chars: "\x7f" }
  - { key: Back, mods: Alt, chars: "\x1b\x7f" }
  - { key: Insert, chars: "\x1b[2~" }
  - { key: Delete, chars: "\x1b[3~" }
  - { key: Left, mods: Shift, chars: "\x1b[1;2D" }
  - { key: Left, mods: Control, chars: "\x1b[1;5D" }
  - { key: Left, mods: Alt, chars: "\x1b[1;3D" }
  - { key: Left, chars: "\x1b[D", mode: ~AppCursor }
  - { key: Left, chars: "\x1bOD", mode: AppCursor }
  - { key: Right, mods: Shift, chars: "\x1b[1;2C" }
  - { key: Right, mods: Control, chars: "\x1b[1;5C" }
  - { key: Right, mods: Alt, chars: "\x1b[1;3C" }
  - { key: Right, chars: "\x1b[C", mode: ~AppCursor }
  - { key: Right, chars: "\x1bOC", mode: AppCursor }
  - { key: Up, mods: Shift, chars: "\x1b[1;2A" }
  - { key: Up, mods: Control, chars: "\x1b[1;5A" }
  - { key: Up, mods: Alt, chars: "\x1b[1;3A" }
  - { key: Up, chars: "\x1b[A", mode: ~AppCursor }
  - { key: Up, chars: "\x1bOA", mode: AppCursor }
  - { key: Down, mods: Shift, chars: "\x1b[1;2B" }
  - { key: Down, mods: Control, chars: "\x1b[1;5B" }
  - { key: Down, mods: Alt, chars: "\x1b[1;3B" }
  - { key: Down, chars: "\x1b[B", mode: ~AppCursor }
  - { key: Down, chars: "\x1bOB", mode: AppCursor }
  - { key: F1, chars: "\x1bOP" }
  - { key: F2, chars: "\x1bOQ" }
  - { key: F3, chars: "\x1bOR" }
  - { key: F4, chars: "\x1bOS" }
  - { key: F5, chars: "\x1b[15~" }
  - { key: F6, chars: "\x1b[17~" }
  - { key: F7, chars: "\x1b[18~" }
  - { key: F8, chars: "\x1b[19~" }
  - { key: F9, chars: "\x1b[20~" }
  - { key: F10, chars: "\x1b[21~" }
  - { key: F11, chars: "\x1b[23~" }
  - { key: F12, chars: "\x1b[24~" }
  - { key: F1, mods: Shift, chars: "\x1b[1;2P" }
  - { key: F2, mods: Shift, chars: "\x1b[1;2Q" }
  - { key: F3, mods: Shift, chars: "\x1b[1;2R" }
  - { key: F4, mods: Shift, chars: "\x1b[1;2S" }
  - { key: F5, mods: Shift, chars: "\x1b[15;2~" }
  - { key: F6, mods: Shift, chars: "\x1b[17;2~" }
  - { key: F7, mods: Shift, chars: "\x1b[18;2~" }
  - { key: F8, mods: Shift, chars: "\x1b[19;2~" }
  - { key: F9, mods: Shift, chars: "\x1b[20;2~" }
  - { key: F10, mods: Shift, chars: "\x1b[21;2~" }
  - { key: F11, mods: Shift, chars: "\x1b[23;2~" }
  - { key: F12, mods: Shift, chars: "\x1b[24;2~" }
  - { key: F1, mods: Control, chars: "\x1b[1;5P" }
  - { key: F2, mods: Control, chars: "\x1b[1;5Q" }
  - { key: F3, mods: Control, chars: "\x1b[1;5R" }
  - { key: F4, mods: Control, chars: "\x1b[1;5S" }
  - { key: F5, mods: Control, chars: "\x1b[15;5~" }
  - { key: F6, mods: Control, chars: "\x1b[17;5~" }
  - { key: F7, mods: Control, chars: "\x1b[18;5~" }
  - { key: F8, mods: Control, chars: "\x1b[19;5~" }
  - { key: F9, mods: Control, chars: "\x1b[20;5~" }
  - { key: F10, mods: Control, chars: "\x1b[21;5~" }
  - { key: F11, mods: Control, chars: "\x1b[23;5~" }
  - { key: F12, mods: Control, chars: "\x1b[24;5~" }
  - { key: F1, mods: Alt, chars: "\x1b[1;6P" }
  - { key: F2, mods: Alt, chars: "\x1b[1;6Q" }
  - { key: F3, mods: Alt, chars: "\x1b[1;6R" }
  - { key: F4, mods: Alt, chars: "\x1b[1;6S" }
  - { key: F5, mods: Alt, chars: "\x1b[15;6~" }
  - { key: F6, mods: Alt, chars: "\x1b[17;6~" }
  - { key: F7, mods: Alt, chars: "\x1b[18;6~" }
  - { key: F8, mods: Alt, chars: "\x1b[19;6~" }
  - { key: F9, mods: Alt, chars: "\x1b[20;6~" }
  - { key: F10, mods: Alt, chars: "\x1b[21;6~" }
  - { key: F11, mods: Alt, chars: "\x1b[23;6~" }
  - { key: F12, mods: Alt, chars: "\x1b[24;6~" }
  - { key: F1, mods: Super, chars: "\x1b[1;3P" }
  - { key: F2, mods: Super, chars: "\x1b[1;3Q" }
  - { key: F3, mods: Super, chars: "\x1b[1;3R" }
  - { key: F4, mods: Super, chars: "\x1b[1;3S" }
  - { key: F5, mods: Super, chars: "\x1b[15;3~" }
  - { key: F6, mods: Super, chars: "\x1b[17;3~" }
  - { key: F7, mods: Super, chars: "\x1b[18;3~" }
  - { key: F8, mods: Super, chars: "\x1b[19;3~" }
  - { key: F9, mods: Super, chars: "\x1b[20;3~" }
  - { key: F10, mods: Super, chars: "\x1b[21;3~" }
  - { key: F11, mods: Super, chars: "\x1b[23;3~" }
  - { key: F12, mods: Super, chars: "\x1b[24;3~" }
  - { key: NumpadEnter, chars: "\n" }
```

# ZSH and [Oh my Zsh](https://ohmyz.sh/)

For a shell I use ZSH, which I picked up when I was using MacOS and have used it since. It is stable, easy to configure and the Oh My Zsh is wonderful with its themes. Can't really say anything from the other like Fish or Bash, but ZSH has been working fine so I see no reason to change to other!

I'm not going to paste my `.zshrc` here since it has so little modifications it. Basically I have just changed the theme to agnoster, set my default editor to Neovim and put some aliases which you can find below.

```
alias zshconfig="nvim ~/.zshrc"
alias ohmyzsh="nvim ~/.oh-my-zsh"
alias ls="ls -al"
alias up="docker-compose up"
alias run="docker-compose run"
alias n="nvim"
```

# [ASDF](https://asdf-vm.com/#/) - Language management tool

This is relatively new tool for me also, I recently find it out since I had problem installing the newest version of Elixir to my machine and the official Fedora repositories had only up to 1.10 or so.

I use this tool to manage all the versions of the programming languages and runtimes I use. It has a simplistic CLI and has all the configuration options I need. For example if you have installed Nodejs versions 12 and 14, you can temporarily set version 12 to one shell session if you are working with older project which uses version 12. This makes it really easy and handy to use in different situations. It supports all the major programming languages and I have had 0 issues with it. I Definitely recommended to use this piece of software!

# [TMUX](https://github.com/tmux/tmux) - Multiplexer

Tmux is as far as I know the most used terminal multiplexer (I base this assumption to Github stars). It comes pre-installed in Fedora and has handy shortcuts. On the first sight when I started to use Tmux I was kind of confused how this should make my life easier since I can have just two separate terminal windows, but after a while I realised that I can split the terminal window in to multiple terminal windows which you can detach and let run in the background, move between Tmux screens/pages etc.

#### **`.tmux.conf`**
```
# Scroll up with mouse
set-option -g mouse on
set -g set-clipboard on

# Scrollback buffer
set -g history-limit 10000

# tmux display things in 256 colors
set-option -g default-terminal "screen-256color"
set-option -g terminal-overrides "screen-256color"

# allow for navigating between words with option
set-window-option -g xterm-keys on

# command delay? We don't want that, make it short
set -g escape-time 10

# Allow the arrow key to be used immediately after changing windows
set-option -g repeat-time 0

# Set window notifications
set -g monitor-activity on
set -g visual-activity on

# Update files on focus (using for vim)
set -g focus-events on

# Status update interval
set -g status-interval 1

# Reduce time to wait for Escape key. You'll want this for neovim.
set-option escape-time 40

# Option to clear histroy
bind -n C-k clear-history
bind-key -n C-l send-keys 'C-l'
bind-key R switch-client -r

######### DISPLAY ##########
set -g renumber-windows on    # renumber windows when a window is closed

######### THEME  ##########
set -g status-bg colour237
set -g status-fg colour246
set-option -g pane-active-border-style fg=colour239
set-option -g pane-border-style fg=colour237
set -g mode-style fg=colour235,bg=colour66
set-option -g message-style bg=colour66,fg=colour235

set-option -g status-justify "left"
set-option -g status-left-style none
set-option -g status-left-length "80"
set-option -g status-right-style none
set-option -g status-right-length "80"

set-option -g status-right '#(gitmux -cfg ~/.gitmux.conf "#{pane_current_path}") %H:%M:%S '
set-window-option -g window-status-separator " "
set-window-option -g window-status-current-format "#[fg=colour66]#W"
set-window-option -g window-status-format "#W"

# Allow us to reload our Tmux configuration while
# using Tmux
bind r source-file ~/.tmux.conf \; display "Reloaded!"

if "test ! -d ~/.tmux/plugins/tpm" \
   "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'"

set -g @plugin 'casonadams/tmux-vi-navigation'
set -g @yank_selection 'clipboard'
set -g @yank_selection_mouse 'clipboard'

run -b '~/.tmux/plugins/tpm/tpm'

 aleksi@localhost  ~  n
 aleksi@localhost  ~  cat .tmux.conf
# Scroll up with mouse
set-option -g mouse on
set -g set-clipboard on

# Scrollback buffer
set -g history-limit 10000

# tmux display things in 256 colors
set-option -g default-terminal "screen-256color"
set-option -g terminal-overrides "screen-256color"

# allow for navigating between words with option
set-window-option -g xterm-keys on

# command delay? We don't want that, make it short
set -g escape-time 10

# Allow the arrow key to be used immediately after changing windows
set-option -g repeat-time 0

# Set window notifications
set -g monitor-activity on
set -g visual-activity on

# Update files on focus (using for neovim)
set -g focus-events on

# Status update interval
set -g status-interval 1

# Reduce time to wait for Escape key. You'll want this for neovim.
set-option escape-time 40

# Option to clear histroy
bind -n C-k clear-history
bind-key -n C-l send-keys 'C-l'
bind-key R switch-client -r

set -g renumber-windows on    # renumber windows when a window is closed

set -g status-bg colour237
set -g status-fg colour246
set-option -g pane-active-border-style fg=colour239
set-option -g pane-border-style fg=colour237
set -g mode-style fg=colour235,bg=colour66
set-option -g message-style bg=colour66,fg=colour235

set-option -g status-justify "left"
set-option -g status-left-style none
set-option -g status-left-length "80"
set-option -g status-right-style none
set-option -g status-right-length "80"

set-option -g status-right '#(gitmux -cfg ~/.gitmux.conf "#{pane_current_path}") %H:%M:%S '
set-window-option -g window-status-separator " "
set-window-option -g window-status-current-format "#[fg=colour66]#W"
set-window-option -g window-status-format "#W"

# Allow us to reload our Tmux configuration while
# using Tmux
bind r source-file ~/.tmux.conf \; display "Reloaded!"

if "test ! -d ~/.tmux/plugins/tpm" \
   "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'"

set -g @plugin 'casonadams/tmux-vi-navigation'
set -g @yank_selection 'clipboard'
set -g @yank_selection_mouse 'clipboard'

run -b '~/.tmux/plugins/tpm/tpm'
```

# [Neovim](https://github.com/neovim/neovim) - Editor

Along my studies and career I have used multiple different editors from CodeBlocks(yes, we used this on our first programming course for C) to VSCode and none of those have ever felt so comfortable to use as Neovim. At some point of first thoughts about Vim I decided to try it out and shortly after I realised that the learning curve is steep and went back to VSCode. After reading few articles of Neovim, I decided that now is the time to make the transition from VSCode to Neovim. First I struggled with the different modes, movement etc. but after a while I get used to it and nowadays if I switch back to VSCode or to some other editor, I'm totally lost because they don't have any of the remappings and shortcuts what I have when I use Neovim.

## Plugins

For managing plugins I use the `vim-plug` since it is minimalistic and supported among the plugin developers. Below is a list of plugins from my `init.vim` and every plugin or plugin group has a comment above which explains what it brings to the table.

#### **`init.vim - plugins section`**
```
call plug#begin()
  " Git status icons
  Plug 'airblade/vim-gitgutter'

  " Configure editor
  Plug 'editorconfig/editorconfig-vim'

  " Tab through coc
  Plug 'ervandew/supertab'

  " Fuzzy finder
  Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
  Plug 'junegunn/fzf.vim'

  " Buffer line on the bottom
  Plug 'itchyny/lightline.vim'
  Plug 'mengelbrecht/lightline-bufferline'

  " Theme and coloring
  Plug 'morhetz/gruvbox'

  " Code completion
  Plug 'neoclide/coc.nvim', {'branch': 'release'}

  " Icons for different file types
  Plug 'ryanoasis/vim-devicons'

  " Comment out lines
  Plug 'tpope/vim-commentary'

  " NERDTree
  Plug 'preservim/nerdtree'

  " Languages
  Plug 'elixir-editors/vim-elixir'
  Plug 'hashivim/vim-terraform'

  " Show error hints and highlights
  Plug 'vim-syntastic/syntastic'

  " Select multiple same items
  Plug 'mg979/vim-visual-multi', {'branch': 'master'}

  " Terraform completion and syntax highlight
  Plug 'juliosueiras/vim-terraform-completion'

  " Git blamer
  Plug 'APZelos/blamer.nvim'

  " Dockerfile syntax
  Plug 'ekalinin/Dockerfile.vim'

  " Markdown
  Plug 'iamcco/markdown-preview.nvim', { 'do': 'cd app && yarn install'  }

  " Cheat.sh integration
  Plug 'RishabhRD/popfix'
  Plug 'RishabhRD/nvim-cheat.sh'
call plug#end()
```

## The rest of the `init.vim`

Here is the rest of my Neovim configuration. There is a lot of remappings and configuration options. Some of them are my own and some of them are copy-pasted from various sources.

#### **`init.vim - rest of the file`**
```
" Settings
let mapleader = "\<Space>"
filetype plugin on
set completeopt=longest,menuone
set mouse=a
set nobackup
set nocompatible
set noswapfile
set nowritebackup
set number
set title
set wrap
setlocal wrap
set encoding=UTF-8

" persist
set undofile " Maintain undo history between sessions
set undodir=~/.vim/undodir

" Persist cursor
autocmd BufReadPost *
  \ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
  \ |   exe "normal! g`\""
  \ | endif

" SuperTab
let g:SuperTabMappingForward = '<S-tab>'
let g:SuperTabMappingBackward = '<tab>'

" Theme
syntax on
colorscheme gruvbox
set background=dark
set cursorline
set hidden
set list
set listchars=tab:»·,trail:·

" let buffers be clickable
let g:lightline#bufferline#clickable=1
let g:lightline#bfferline#shorten_path=1
let g:lightline#bufferline#min_buffer_count=1

" Git blamer
let g:blamer_enabled = 1
let g:blamer_delay = 200

" Remaps
nmap <Leader>p :Rg<CR>
nmap <Leader>h :History<CR>
nmap <Leader>n :NERDTreeToggle<CR>
imap jj <Esc>:w<CR>a
nmap <Leader>r :NERDTreeFocus<cr>R<c-w><c-p>

" Give more space for displaying messages.
set cmdheight=2

" Reduce updatetime
set updatetime=300

" Don't pass messages to |ins-completion-menu|.
set shortmess+=c

" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
set signcolumn=yes

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current
" position. Coc only does snippet and additional edit on confirm.
if exists('*complete_info')
  inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"
else
  imap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
endif

" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction

" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')

" Launch NERDTree on start-up
autocmd VimEnter * NERDTree
let g:NERDTreeShowHidden=1

" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)

augroup mygroup
  autocmd!
  " Setup formatexpr specified filetype(s).
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder.
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Apply AutoFix to problem on the current line.
nmap <leader>qf  <Plug>(coc-fix-current)

inoremap " ""<left>
inoremap ' ''<left>
inoremap ( ()<left>
inoremap [ []<left>
inoremap { {}<left>
inoremap {<CR> {<CR>}<ESC>O
inoremap {;<CR> {<CR>};<ESC>O

" Use <TAB> for selections ranges.
" NOTE: Requires 'textDocument/selectionRange' support from the language server.
" coc-tsserver, coc-python are the examples of servers that support it.
nmap <silent> <TAB> <Plug>(coc-range-select)
xmap <silent> <TAB> <Plug>(coc-range-select)

" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')

" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR   :call     CocAction('runCommand', 'editor.action.organizeImport')

command! -nargs=0 Prettier :CocCommand prettier.formatFile

" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline^=%{coc#status()}
```

## [CoC - Conquer of Completion](https://github.com/neoclide/coc.nvim)

I'm using CoC since I'm still on Neovim 0.4.4, and when Neovim 0.5 gets released I'm going to move from CoC to the built-in LSP. Nevertheless, below is my `coc-settings.json` since there is some language specific configurations.

#### **`coc-settings.json`**
```json
{
  "codeLens.enable": true,
  "elixir.pathToElixirLS": "~/.elixir-ls/release/language_server.sh",
  "languageserver": {
    "terraform": {
      "command": "terraform-lsp",
      "filetypes": [
        "terraform",
        "tf"
      ],
      "initializationOptions": {},
      "settings": {}
    }
  },
  "coc.preferences.formatOnSaveFiletypes": [
    "css",
    "markdown",
    "typescript",
    "javascript",
    "json",
    "elixir"
  ]
}
```

As seen, I have enabled to codelens, set manually path to ElixirLS since I have built it from source, configurations for Terraform LSP and set format on save for specific languages.


# Conclusion

![Editor](https://dev-to-uploads.s3.amazonaws.com/i/caj06lvuzy5rceuicdhj.png)

So there it is, my development configuration for general web development and how it looks. It is not complete yet, since I think there is always something you could do better or more efficiently, but till now it's good enough.

Hope this helped you to make your current development environment better, thanks!