caddy

Caddy is a reverse proxy and web server that automatically manages TLS certificates, making it a more user-friendly alternative to Nginx,

write a Caddyfile

myapp.local {
    reverse_proxy localhost:3000
}
caddy start

add myapp.local 127.0.0.1 to /etc/hosts, then you can visit https://myapp.local

direnv

brew install direnv

Add to ~/.zshrc:

eval "$(direnv hook zsh)"

In directory with .envrc:

direnv allow

This will record a hash of the content of .envrc, and load the file every time cd to this directory, as long as the hash matches.

Emacs Intergration

(use-package envrc
  :enaure t
  :config (envrc-global-mode))

elixir

iex

iex stands for Interactive Elixir. It’s an interactive REPL for Elixir.

iex -S mix phx.server
  • i for inspect
  • h h for help
  • r MyModule for recompile
  • v(-1) for last value
  • respawn restart but keep history

Attach to Remote iex

Remote:

iex --name server@hostname --cookie secret -S mix

Local:

iex --name client@hostname --cookie secret --remsh server@hostname

Connect to Remote Node

iex --name client@hostname --cookie secret
Node.connect(:"server@hostname")
:rpc.call(:"server@hostname", IO, :puts, ["Hello!"])

Emacs Setup

(use-package elixir-mode
  :ensure t)

;; Alchemist - for mix, compile, testing integration
(use-package alchemist
  :ensure t
  :hook (elixir-mode . alchemist-mode))

(use-package lsp-mode
  :ensure t
  :hook ((elixir-mode . lsp))
  :commands lsp
  :custom
    (lsp-elixir-mix-env "dev")
    (lsp-elixir-server-command '("~/.elixir-ls/release/language_server.sh")))

(use-package lsp-ui
  :ensure t)

(use-package company
  :ensure t
  :config (global-company-mode))

Setup LSP

git clone https://github.com/elixir-lsp/elixir-ls.git ~/.elixir-ls
cd ~/.elixir-ls
mix deps.get && mix compile
mix elixir_ls.release2 -o release

entr

Run arbitrary commands when files change.

github

Reload go web server:

$ git ls-files | entr -r go run main.go

Graphviz:

$ ls web.dot | entr -s 'dot -Tpng web.dot -o web.png'

Typst:

$ ls configuration.yaml main.typ | entr -s 'typst compile main.typ'

fzf

fzf is a general-purpose command-line fuzzy finder. It's an interactive Unix filter.

brew install fzf

Set up shell key bindings (like Ctrl+R for history, Ctrl+T for files) and fuzzy auto-completion:

$(brew --prefix)/opt/fzf/install

Example: use fzf to pickup a recent branch:

git checkout $(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)' | fzf)

To Uninstall

$(brew --prefix)/opt/fzf/uninstall

graphviz

dot -Tpng my.dot -o my.png

mise

echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
mise install ruby
mise use -g ruby@latest

stow

Put your dotfiles inside a folder, then use stow to create symbolic links to your home folder:

stow my-dotfiles

In this way you can track the changes of those files using tools like git inside your specific folder.

tmux

plugins

https://github.com/tmux-plugins/list

move to other session

<prefix> :move-pane -t foo

tmuxinator

~/.config/tmuxinator/project.yml
name: project
root: ~/

windows:
  - editor:
      layout: main-vertical
      panes:
        - editor:
          - vim
        - guard
  - server: bundle exec rails s
  - logs: tail -f log/development.log
tmuxinator start project

uv

uv

project centred package management for python

uv venv

vscode

disable the Apple press and hold

$ defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false

command+x for showCommands

command+shift+p "open keyboard shortcuts json"

[
  { "key": "alt+x", "command": "workbench.action.showCommands" },
    
  {
    "key": "tab",
    "command": "magit.toggle-fold",
    "when": "editorTextFocus && editorLangId == 'magit'"
  },
  {
    "key": "n",
    "command": "cursorDown",
    "when": "editorTextFocus && editorLangId == 'magit'"
  },
  {
    "key": "p",
    "command": "cursorUp",
    "when": "editorTextFocus && editorLangId == 'magit'"
  },
    
]

settings

command+x "open user settings json"

    "vim.useSystemClipboard": true,
    "workbench.editor.showTabs": "none",
    "vim.leader": "|",
    "vim.normalModeKeyBindings": [
    {
        "before": [
            "ctrl+a",
            "l"
        ],
        "commands": [
            "workbench.action.navigateRight"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "h"
        ],
        "commands": [
            "workbench.action.navigateLeft"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "j"
        ],
        "commands": [
            "workbench.action.navigateDown"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "k"
        ],
        "commands": [
            "workbench.action.navigateUp"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "shift+h"
        ],
        "commands": [
            "workbench.action.navigateBack"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "shift+l"
        ],
        "commands": [
            "workbench.action.navigateForward"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "x"
        ],
        "commands": [
            "workbench.action.closeActiveEditor"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "|"
        ],
        "commands": [
            "workbench.action.splitEditor"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "-"
        ],
        "commands": [
            "workbench.action.splitEditorDown"
        ]
    },
    {
        "before": [
            "ctrl+a",
            "o"
        ],
        "commands": [
            "workbench.action.editorLayoutSingle"
        ]
    },
],

all keybindings

command + x then "open Default Keyboard Shortcuts"

whisper-cpp

brew install whisper-cpp

download model:

wget https://ggml.ggerganov.com/ggml-model-whisper-medium.en-q5_0.bin
export GGML_METAL_PATH_RESOURCES="$(brew --prefix whisper-cpp)/share/whisper-cpp"
whisper-cpp -osrt -f input.wav -m ggml-model-whisper-medium.en-q5_0.bin
ffmpeg -i video.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 tmp.wav
ffmpeg -y -i audio.wav -ar 16000 tmp.wav