My Terminal-Only Development Setup (1)
2024-01-10
Below are some notes I recently took when trying to set up a terminal-only development environment for Python and C++. Everything is assuming a MacOS but should be fairly easy to be ported to a general Unix system. This post will be updated from time to time.
1. Set up ZSH
We will need a terminal before we can call it a terminal-based environment.
To summarize, a terminal is a device or program that provides a user interface, a console can refer to physical hardware or a text-based interface, a shell is a command-line interpreter that processes commands, and the command line is the method of entering textual commands into the shell.
Install ZSH
brew install zsh
and eza for better ls
:
brew install eza
and Starship for customizable prompt:
brew install starship
Inside ~/.config/starship.toml
(disregard the strange squares – they’ll render just fine as long as we have the correct nerd fonts installed):
# editor completions based on the ocnfig schema
"$schema" = 'https://starship.rs/config-schema.json'
# insert a blank line between shell prompts
add_newline = false
# longer timeout for commands like git
command_timeout = 10000
# [character]
# success_symbol = '[➜](bold green)' # the leading symbol of each line
[package]
disabled = true # disable packages from being shown at all
[custom.giturl]
# disabled = true
description = "Display symbol for remote Git server"
command = """
GIT_REMOTE=$(command git ls-remote --get-url 2> /dev/null)
if [[ "$GIT_REMOTE" =~ "github" ]]; then
GIT_REMOTE_SYMBOL=" "
elif [[ "$GIT_REMOTE" =~ "gitlab" ]]; then
GIT_REMOTE_SYMBOL=" "
elif [[ "$GIT_REMOTE" =~ "bitbucket" ]]; then
GIT_REMOTE_SYMBOL=" "
elif [[ "$GIT_REMOTE" =~ "git" ]]; then
GIT_REMOTE_SYMBOL=" "
else
GIT_REMOTE_SYMBOL=" "
fi
echo "$GIT_REMOTE_SYMBOL "
"""
when = 'git rev-parse --is-inside-work-tree 2> /dev/null'
format = "at $output "
[line_break]
disabled = true
Inside ~/.zshrc
add:
# shortcuts
alias ls='eza --icons -F -H --group-directories-first --git -1'
alias ll='ls -alF'
alias vimdiff='nvim -d'
alias vi='lvim'
alias vim='lvim'
# history substring search
autoload -U up-line-or-beginning-search
autoload -U down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey "^[[A" up-line-or-beginning-search
bindkey "^[[B" down-line-or-beginning-search
# case-insensitive completion
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
autoload -Uz compinit && compinit
# starship launched!
eval "$(starship init zsh)"
Set up NeoVim
Download MesloLG from Nerd Fonts
…and installed it to the system.
Install Alacritty terminal emulator
brew install alacritty
Create the config file for Alacritty ~/.config/alacritty/alacritty.toml
:
live_config_reload = true
[window]
dimensions = { columns = 120, lines = 80 }
padding = { x = 0, y = 0 }
opacity = 0.8
blur = true
title = "Terminal"
[shell]
program = "/bin/zsh"
args = ["-l"]
[font]
size = 13
offset = { y = 0 }
normal = { family = "MesloLGM Nerd Font", style = "Regular" }
Install NeoVim
brew install neovim
Install Ripgrep (it’s a dependency of NvChad’s Telescope feature)
brew install ripgrep
Install NvChad from git
git clone https://github.com/NvChad/NvChad ~/.config/nvim --depth 1 && nvim
Enter neovim and install the needed LSPs (and validate using :LspInfo
)
clangd
(automatically installed already by NvChad)pyright
(manually installed via:Mason
, same for below)ruff
neocmakelsp
- etc
Note that Mason
might inherently call npm
which should be installed and validated as a prior through
brew install node
npm -v
and in order to avoid using sudo
when installing packages globally, we can specify an alternative location for the NPM prefix:
mkdir ~/.npm-packages
npm config set prefix "${HOME}/.npm-packages"
and put the following two lines inside ~/.bashrc
or ~/.zshrc
:
export NPM_PACKAGES="${HOME}/.npm-packages"
export PATH="$NPM_PACKAGES/bin:$PATH"
Under ~/.config/nvim/lua/custom
make the following edits
- In
configs/lspconfig.lua
, addpyright
toservers
. - In
configs/conform.lua
, turn onformat_on_save
add following toformatters_by_ft
:
python = { { "ruff_fix", "isort"}, { "ruff_format", "black" } },
cpp = { "clang_format" },
["_"] = { "trim_newlines", "trim_whitespace" },
- In
configs/overrides.lua
add the following toM.treesitter.ensure_installed
:
"cpp",
"java",
"python",
"latex",
"markdown",
"markdown_inline",
and the following to M.mason.ensure_installed
:
-- c/cpp stuff
"clangd",
"clang-format",
-- py stuff
"ruff",
- In
init.lua
add the following (you don’t need to include themarkdown.css
file unless you actually have one just like me):
local g = vim.g
local opt = vim.opt
-- Indenting
opt.expandtab = true
opt.shiftwidth = 4
opt.smartindent = true
opt.tabstop = 4
opt.softtabstop = 4
-- MarkdownPreview
g.mkdp_theme = 'light'
g.mkdp_markdown_css = '~/configs/nvim/lua/custom/markdown.css'
g.mkdp_port = '8842'
- In
plugins.lua
uncomment the line ofevent = "BufWritePre"
, then include the packageMarkdownPreview
:
{
"iamcco/markdown-preview.nvim",
cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" },
ft = { "markdown" },
build = function() vim.fn["mkdp#util#install"]() end,
},