Developer Productivity V2
December 05, 2025https://frontendmasters.com/workshops/developer-productivity-v2/#player
https://frontendmasters.github.io/dev-prod-2/
https://github.com/theprimeagen/dev
#!/usr/bin/env bash
script_dir="$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)"
filter=""
dry="0"
cd $script_dir
scripts=$(find runs -maxdepth 1 -mindepth 1 -executable -type f)
while [[ $# > 0 ]]; do
if [[ "$1" == "--dry" ]]; then
dry="1"
else
filter="$1"
fi
shift
done
log() {
if [[ $dry == "1" ]]; then
echo "[DRY_RUN]: $@"
else
echo "$@"
fi
}
execute() {
log "execute: $@"
if [[ $dry == "1" ]]; then
return
fi
"$@"
}
log "run: filter=$filter"
for script in $scripts; do
if echo "$script" | grep -qv "$filter"; then
log "filtered: $filter -- $script"
continue
fi
log "running script: $script"
execute ./$script
done
#!/usr/bin/env bash
git clone git@github.com:neovim/neovim.git ~/personal/neovim
cd ~/personal/neovim
git fetch
git checkout v0.9.2
sudo apt install cmake gettext lua5.1 liblua5.1-0-dev
make CMAKE_BUILD_TYPE=RelWithDebInfo
sudo make install
dotfiles
pushd
pushes location onto stack.
popd
pops location off stack.
$XDG_CONFIG_HOME
is a nix thing that is usually ~/.config
Mac doesn't natively support it. https://stackoverflow.com/questions/3373948/equivalents-of-xdg-config-home-and-xdg-data-home-on-mac-os-x
For macOS, the equivalent locations are typically:
$XDG_CONFIG_HOME
can be set to ~/Library/Application Support
or ~/.config
.
$XDG_DATA_HOME
can be set to ~/Library/Application Support
or ~/.local/share
.
$XDG_CACHE_HOME
can be set to ~/Library/Caches
or ~/.cache
.
#!/usr/bin/env bash
dry="0"
XDG_CONFIG_HOME="$HOME/.fem-config"
while [[ $# > 0 ]]; do
if [[ "$1" == "--dry" ]]; then
dry="1"
fi
shift
done
log() {
if [[ $dry == "1" ]]; then
echo "[DRY_RUN]: $@"
else
echo "$@"
fi
}
execute() {
log "execute: $@"
if [[ $dry == "1" ]]; then
return
fi
"$@"
}
log "--------- dev-env ---------"
copy_dir() {
from=$1
to=$2
pushd $from > /dev/null
dirs=$(find . -mindepth 1 -maxdepth 1 -type d)
for dir in $dirs; do
execute rm -rf $to/$dir
execute cp -r $dir $to/$dir
done
popd > /dev/null
}
copy_file() {
from=$1
to=$2
name=$(basename $from)
execute rm $to/$name
execute cp $from $to/$name
}
copy_dir .config $XDG_CONFIG_HOME
copy_file .specialconfig $HOME
Navigation
window manager
user mentioned
opening programs
terminal experience
-
sessions that last even when i close my terminal
-
multiple running sessions, and these sessions are based on directory
-
"tabs" within a session
-
navigate to any session by directory name "instantly"
-
navigate to any session by directory with fuzzy find
-
run scripts or whatever programs i want when navigating to a directory
brew install tmux
brew install --cask ghostty
tmux
set -g default-terminal "tmux-256color"
set -s escape-time 0
set -g base-index 1
# optional -- i like C-a not C-b (pure preference)
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# vi key movement for copy/pasta mode
set-window-option -g mode-keys vi
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
# <WHERE YOUR TMUX CONF GOES> = XDG_CONFIG_HOME/tmux/tmux.conf
# <WHERE YOUR TMUX CONF GOES> = ~/.tmux.conf
bind r source-file <WHERE YOUR TMUX CONF GOES> \; display-message "tmux.conf reloaded"
default prefix is ctrl + b
, if you used ^^ it will be ctrl + a
prefix + c
creating window
prefix + d
detaching
prefix + num
navigate to that window num
tmux attach
or tmux a
attach previous session
prefix + w
showing all running sessions
x
in show all running sesions will kill session
ctrl + d
kill terminal and pane / window / session
prefix + "
horizontal split
prefix + %
vertical split
prefix + z
focus on pane, repeat to unfocus
prefix + L
go back to previous session
navigating can be confusing, can be mapped to vim keys
bind -r h select-pane -L
bind -r j select-pane -D
bind -r k select-pane -U
bind -r l select-pane -R
tmux new-session -s <sname> -n <initial wname> -d[etach]
create a new session and detach current session
tmux list-sessions
list all sessions
tmux attach-session -t <target>
tmux has-session -t <target>
# don't forget -t vs -t=, -t
is first part of match, -t=
is exact match
tmux switch-client -t <target>
tmux new-window -n <name> [-t session:window_index]
or tmux neww
create new window
tmux list-windows [-t session]
list all windows
tmux select-window -t session:[window_idx | window_name].[pane_idx]
select window
tmux send-keys -t <target> "text" [ctrl keys,...]
sends commands to target. e.g. tmux send-keys -t dev:foobar "echo hello"
. adding ^M
will execute the command. e.g. tmux send-keys -t dev:foobar "echo hello" ^M
opening script
create .local/scripts
in your dotfile repo. Add a file called ready-tmux
in scripts and paste thee following:
#!/usr/bin/env bash
if [[ -x ./.ready-tmux ]]; then
./.ready-tmux
elif [[ -x ~/.ready-tmux ]]; then
~/.ready-tmux
fi
clear
add the script to your path.
export PATH="$HOME/.local/scripts:$PATH"
create another file in any directory called .ready-tmux
and paste the following:
#!/usr/bin/env bash
tmux new-window -n foofoo
naviate to the directory with the .ready-tmux
file. Enter tmux
and run ready-tmux
.
fcf
https://junegunn.github.io/fzf/
brew install fzf
source <(fzf --zsh)
to zsh config.
notice ctrl + r
is a fuzzy finder.
echo "1\n2\n3\n" | fzf
will display a selectable list. Choossing the option will echo that one.
tmux sessionizer
#!/usr/bin/env bash
selected=$(find ~/personal -mindepth 1 -maxdepth 1 -type d | fzf)
if [[ -z $selected ]]; then
exit 0
fi
selected_name=$(basename "$selected" | tr ":,. " "____")
switch_to() {
if [[ -z $TMUX ]]; then
tmux attach-session -t "$selected_name"
else
tmux switch-client -t "$selected_name"
fi
}
if tmux has-session -t="$selected_name" 2> /dev/null; then
switch_to
exit 0
fi
tmux new-session -ds "$selected_name" -c "$selected"
switch_to
tmux send-keys -t "$selected_name" "ready-tmux" ^M
vim.keymap.set("n", "<C-f>", "<cmd>silent !tmux neww tmux-sessionizer<CR>")
in vim to run sessionizer.
bind-keyu -r f run-shell "tmux neww ~/.local/bin/tmux-sessionizer"
in tmux.conf
jq
brew install jq
create a file sample.json
with these contents:
{"type": "foo", "values": [1, 2, 3, 4, 5]}
{"type": "foo", "values": [69, 420, 42, 69420]}
{"type": "bar", "values": {"a": 42, "b": 69}}
{"type": "bar", "values": {"a": 1337, "b": 420}}
{"type": "bar", "values": {"a": 111, "b": 222}}
cat sample.json
cat sample.json | jq
cat sample.json | jq -c
# filter by type
cat sample.json | jq 'select(.type == "foo")'
# get values of filtered items
cat sample.json | jq 'select(.type == "foo") | .values'
# sum of filtered items values
cat sample.json | jq 'select(.type == "foo") | .values | add' -c
# add valueSum to each item
cat sample.json | jq 'select(.type == "foo") | .valueSum = (.values | add)' -c
# select items with sum > 20
cat sample.json | jq 'select(.type == "foo") | .valueSum = (.values | add) | select(.valueSum > 20)' -c
vim !jq
sed
fighting one eyed curvy `"(.*)"
vim: :
then %s/: "\(.*\)",/: "\1\1",
cat sample.json | sed 's/: "\(.*\)",/: "\1,\1",/'
find
find . -maxdepth 1 -mindepth 1 -type f -exec grep -Hn "foo" {} \;
xargs
echo "1\n2\n3" | xargs -I {} curl https://{}.com
parallel
https://savannah.gnu.org/projects/parallel/
brew install parallel
create a count
file with the following contents:
1
2
3
4
5
6
7
8
9
cat count | parallel -j 5 "curl https://{}.com"
# preserve order
cat count | parallel -kj 2 "curl https://{}.com"
awk
ps aux | grep vim | awk '{ sum += $2 } END { print sum }'
editors
editor: https://zed.dev/
https://github.com/nvim-lua/kickstart.nvim
https://frontendmasters.com/courses/vim-fundamentals/
neovim: use your name to group your configs and avoid conflict
vim
df(
delete up to and include (
dj
delete current line and one below
ct(
delete up to and include (
and insert
v
visual mode
ap
in visual mode and select the paragraph
d
is delete, combine with ap
to delete the paragraph
yap
yank the paragraph
dip
delete inside paragraph
yiW
yank inside word
ci"
change inside quotes
d2i(
delete up to and include two sets of parentheses
Vf{%y
visual mode and find the next {%
and yank it i.e. copy function
quick fix list from search results to navigate results
:cdo <command>
execute command on all results in the quick fix list
use:
- stack trace to quick fix list could be useful
- add lsp refs to quick fix list
harpoon is sticky files for quick swap
%s
every line sed
`%s/mul
https://adventofcode.com/2024/day/3
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
vim::
%s/\(mul(\d\{1,3},\d\{1,3})\)/\1\r/g
vim::
%s/.*mul(\(\d\{1,3}\),\(\d\{1,3}\))/\1*\2/
vim::
s/\n/+
vim: V
to select line
vim: :
!bc
https://frontendmasters.com/learn/fullstack/
nvim test.lua
:so
execute lua file
vim.api.nvim_open_win(0, true, { relative = "win", row = 3, col = 3, width = 12, height = 3 })
ctrl + w
to get window commands, o
to close all
local function read_file_with_system(filename)
local pipe = vim.system({"cat", filename})
local content = pipe:wait().stdout
local lines = vim.split(content, "\n", { trimempty = true })
return lines
end
local api = vim.api
local buf = api.nvim_create_buf(false, true)
local win = api.nvim_open_win(buf, false, {
relative="editor",
width=80,
height=24,
row=0,
col=0,
})
api.nvim_buf_set_lines(buf, 0, -1, false, read_file_with_system("./package.json"))
vim.defer_fn(function()
api.nvim_win_close(win, true)
end, 5000)
ai
ask ai to create a plugin to interface with an ai api
vimbegood
:VimBeGood
updates
edit dev and copy to live location