From fc42277ab977228b97a5e38ae49d3a566605cc78 Mon Sep 17 00:00:00 2001 From: Marvin Dietermann Date: Wed, 8 Apr 2026 14:04:42 +0200 Subject: [PATCH] Initial commit --- archduino-guide.md | 787 +++++++++++++++++++++++++++++++++++++++++++++ bootstrap.sh | 568 ++++++++++++++++++++++++++++++++ 2 files changed, 1355 insertions(+) create mode 100644 archduino-guide.md create mode 100644 bootstrap.sh diff --git a/archduino-guide.md b/archduino-guide.md new file mode 100644 index 0000000..887d16e --- /dev/null +++ b/archduino-guide.md @@ -0,0 +1,787 @@ +# Archduino — TUI-Only Arch Linux Arduino Development Environment + +A keyboard-driven, mouse-free Arch Linux setup for Arduino development built on **Zellij + Neovim + Arduino CLI**, themed in **Gruvbox**, targeting both WSL2 and native Arch. + +--- + +## Architecture Overview + +``` +┌─────────────────────────────────────────────────┐ +│ Zellij (multiplexer + workspace manager) │ +│ ┌─────────────────────┬───────────────────────┐ │ +│ │ Neovim (LazyVim) │ Serial Monitor │ │ +│ │ - clangd LSP │ (arduino-cli monitor)│ │ +│ │ - Arduino syntax │ │ │ +│ │ - compile/upload │ │ │ +│ │ keybinds │ │ │ +│ ├─────────────────────┼───────────────────────┤ │ +│ │ Terminal / Build │ lazygit │ │ +│ │ output pane │ │ │ +│ └─────────────────────┴───────────────────────┘ │ +│ [zjstatus bar — board | port | project | git] │ +└─────────────────────────────────────────────────┘ +``` + +## Table of Contents + +1. [Base System](#1-base-system) +2. [Shell — Zsh + Starship](#2-shell--zsh--starship) +3. [Zellij](#3-zellij) +4. [Neovim + LazyVim](#4-neovim--lazyvim) +5. [Arduino CLI](#5-arduino-cli) +6. [Serial Monitor](#6-serial-monitor) +7. [Git + Lazygit](#7-git--lazygit) +8. [Project Scaffolding](#8-project-scaffolding) +9. [Zellij Arduino Layout](#9-zellij-arduino-layout) +10. [Neovim Arduino Keybinds](#10-neovim-arduino-keybinds) +11. [WSL2-Specific Notes](#11-wsl2-specific-notes) +12. [Quick Reference Card](#12-quick-reference-card) + +--- + +## 1. Base System + +### Native Arch + +```bash +sudo pacman -Syu +sudo pacman -S base-devel git curl unzip wget ripgrep fd bat eza tree jq +``` + +### WSL2 Arch + +If you hit SSL issues (common behind corporate proxies): + +```bash +sed -i 's|https://|http://|g' /etc/pacman.d/mirrorlist +pacman -Syu ca-certificates archlinux-keyring --noconfirm +sed -i 's|http://|https://|g' /etc/pacman.d/mirrorlist +``` + +### Create your user (if root-only) + +```bash +pacman -S sudo +useradd -m -G wheel -s /bin/zsh myuser +passwd myuser +EDITOR=nano visudo # uncomment: %wheel ALL=(ALL) ALL +``` + +Add to `/etc/wsl.conf`: + +```ini +[user] +default=myuser +``` + +--- + +## 2. Shell — Zsh + Starship + +### Install Zsh + +```bash +sudo pacman -S zsh +chsh -s /bin/zsh +``` + +### Oh My Zsh + +```bash +sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +``` + +### Zsh Plugins + +```bash +git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions +git clone https://github.com/zsh-users/zsh-syntax-highlighting ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting +``` + +Edit `~/.zshrc`: + +```bash +plugins=(git zsh-autosuggestions zsh-syntax-highlighting) +``` + +### Starship Prompt + +```bash +sudo pacman -S starship +``` + +Add to `~/.zshrc`: + +```bash +eval "$(starship init zsh)" +``` + +Create `~/.config/starship.toml`: + +```toml +palette = "gruvbox_dark" + +format = """ +$directory$git_branch$git_status$character""" + +[directory] +style = "bold fg:bright-yellow" +truncation_length = 3 + +[git_branch] +style = "bold fg:bright-green" +format = " [$branch]($style) " + +[git_status] +style = "bold fg:bright-red" + +[character] +success_symbol = "[❯](bold fg:bright-green)" +error_symbol = "[❯](bold fg:bright-red)" + +[palettes.gruvbox_dark] +bright-yellow = "#fabd2f" +bright-green = "#b8bb26" +bright-red = "#fb4934" +bright-blue = "#83a598" +bright-purple = "#d3869b" +bright-aqua = "#8ec07c" +bright-orange = "#fe8019" +``` + +--- + +## 3. Zellij + +### Install + +```bash +sudo pacman -S zellij +``` + +Or latest binary: + +```bash +curl -kL https://github.com/zellij-org/zellij/releases/latest/download/zellij-x86_64-unknown-linux-musl.tar.gz | tar xz -C /tmp +sudo mv /tmp/zellij /usr/local/bin/ +``` + +### Gruvbox Theme Config + +Create `~/.config/zellij/config.kdl`: + +```kdl +theme "gruvbox-dark" + +default_layout "default" +default_mode "normal" +pane_frames false +simplified_ui true +mouse_mode false + +keybinds { + shared { + bind "Alt h" { MoveFocusOrTab "Left"; } + bind "Alt l" { MoveFocusOrTab "Right"; } + bind "Alt j" { MoveFocus "Down"; } + bind "Alt k" { MoveFocus "Up"; } + bind "Alt n" { NewPane "Down"; } + bind "Alt v" { NewPane "Right"; } + bind "Alt f" { ToggleFloatingPanes; } + bind "Alt t" { NewTab; } + } +} + +themes { + gruvbox-dark { + fg "#ebdbb2" + bg "#282828" + black "#1d2021" + red "#cc241d" + green "#98971a" + yellow "#d79921" + blue "#458588" + magenta "#b16286" + cyan "#689d6a" + white "#a89984" + orange "#d65d0e" + } +} +``` + +### Auto-start Zellij + +Add to `~/.zshrc`: + +```bash +if [[ -z "$ZELLIJ" ]]; then + zellij attach --create archduino +fi +``` + +--- + +## 4. Neovim + LazyVim + +### Install latest Neovim + +```bash +curl -kLO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz +sudo tar -xzf nvim-linux-x86_64.tar.gz -C /opt +sudo ln -sf /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvim +rm nvim-linux-x86_64.tar.gz +``` + +### Install LazyVim + +```bash +mv ~/.config/nvim{,.bak} 2>/dev/null +mv ~/.local/share/nvim{,.bak} 2>/dev/null +mv ~/.local/state/nvim{,.bak} 2>/dev/null +mv ~/.cache/nvim{,.bak} 2>/dev/null + +git clone https://github.com/LazyVim/starter ~/.config/nvim +rm -rf ~/.config/nvim/.git +``` + +### LSP for Arduino (clangd) + +```bash +sudo pacman -S clang +``` + +### LazyVim Gruvbox + Arduino config + +Create `~/.config/nvim/lua/plugins/gruvbox.lua`: + +```lua +return { + { + "ellisonleao/gruvbox.nvim", + priority = 1000, + config = function() + require("gruvbox").setup({ + contrast = "hard", + }) + end, + }, + { + "LazyVim/LazyVim", + opts = { + colorscheme = "gruvbox", + }, + }, +} +``` + +Create `~/.config/nvim/lua/plugins/arduino.lua`: + +```lua +return { + -- Arduino filetype & syntax + { + "stevearc/vim-arduino", + ft = { "arduino", "cpp", "c" }, + config = function() + vim.g.arduino_use_cli = 1 + vim.g.arduino_cli_path = "arduino-cli" + end, + }, + -- Better C/C++ treesitter support + { + "nvim-treesitter/nvim-treesitter", + opts = function(_, opts) + vim.list_extend(opts.ensure_installed, { "c", "cpp", "arduino" }) + end, + }, +} +``` + +Create `~/.config/nvim/lua/plugins/lsp.lua`: + +```lua +return { + { + "neovim/nvim-lspconfig", + opts = { + servers = { + clangd = { + cmd = { + "clangd", + "--background-index", + "--clang-tidy", + "--header-insertion=iwyu", + "--completion-style=detailed", + }, + }, + }, + }, + }, +} +``` + +--- + +## 5. Arduino CLI + +### Install + +```bash +curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh +``` + +If SSL issues: + +```bash +curl -kfsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh +``` + +### Initialize & install cores + +```bash +arduino-cli config init +arduino-cli core update-index + +# AVR boards (Uno, Mega, Nano) +arduino-cli core install arduino:avr + +# ESP32 +arduino-cli config add board_manager.additional_urls \ + https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json +arduino-cli core update-index +arduino-cli core install esp32:esp32 + +# ESP8266 +arduino-cli config add board_manager.additional_urls \ + https://arduino.esp8266.com/stable/package_esp8266com_index.json +arduino-cli core update-index +arduino-cli core install esp8266:esp8266 +``` + +### Install common libraries + +```bash +arduino-cli lib install "Servo" +arduino-cli lib install "WiFi" +arduino-cli lib install "ArduinoJson" +arduino-cli lib install "Adafruit Unified Sensor" +arduino-cli lib install "DHT sensor library" +``` + +--- + +## 6. Serial Monitor + +### TUI Serial Monitor — tio + +```bash +sudo pacman -S tio +``` + +Usage: + +```bash +tio /dev/ttyUSB0 -b 115200 +``` + +`tio` auto-detects ports, supports timestamps, and is fully keyboard-driven. Quit with `Ctrl+t q`. + +### WSL2 serial passthrough + +WSL2 doesn't natively see USB devices. You need **usbipd-win** on Windows: + +```powershell +# In Windows PowerShell (admin) +winget install usbipd + +# List USB devices +usbipd list + +# Bind and attach your Arduino +usbipd bind --busid +usbipd attach --wsl --busid +``` + +Then in WSL: + +```bash +ls /dev/ttyUSB* # or /dev/ttyACM* +``` + +### Add user to dialout group + +```bash +sudo usermod -aG uucp $USER # Arch +sudo usermod -aG dialout $USER # if needed +``` + +--- + +## 7. Git + Lazygit + +```bash +sudo pacman -S git lazygit +``` + +### Git config + +```bash +git config --global user.name "Your Name" +git config --global user.email "you@example.com" +git config --global init.defaultBranch main +``` + +### Lazygit Gruvbox + +Create `~/.config/lazygit/config.yml`: + +```yaml +gui: + theme: + activeBorderColor: + - "#fabd2f" + - bold + inactiveBorderColor: + - "#665c54" + selectedLineBgColor: + - "#3c3836" + cherryPickedCommitFgColor: + - "#b8bb26" + defaultFgColor: + - "#ebdbb2" +``` + +### Neovim lazygit keybind + +Already included in LazyVim — press `gg` to open lazygit in a floating terminal. + +--- + +## 8. Project Scaffolding + +Create the scaffolding script at `~/.local/bin/arduino-new`: + +```bash +#!/bin/bash +set -e + +TEMPLATE_DIR="$HOME/.config/archduino/templates" + +declare -A FQBN_MAP=( + ["uno"]="arduino:avr:uno" + ["mega"]="arduino:avr:mega" + ["nano"]="arduino:avr:nano" + ["esp32"]="esp32:esp32:esp32" + ["esp32s3"]="esp32:esp32:esp32s3" + ["esp8266"]="esp8266:esp8266:nodemcuv2" +) + +usage() { + echo "Usage: arduino-new " + echo "" + echo "Available boards:" + for board in "${!FQBN_MAP[@]}"; do + printf " %-12s %s\n" "$board" "${FQBN_MAP[$board]}" + done + exit 1 +} + +[[ $# -lt 2 ]] && usage + +PROJECT="$1" +BOARD="$2" +FQBN="${FQBN_MAP[$BOARD]}" + +[[ -z "$FQBN" ]] && echo "Unknown board: $BOARD" && usage + +mkdir -p "$PROJECT" +cd "$PROJECT" + +# Copy board-specific template or default +if [[ -f "$TEMPLATE_DIR/$BOARD.ino" ]]; then + cp "$TEMPLATE_DIR/$BOARD.ino" "$PROJECT.ino" +else + cp "$TEMPLATE_DIR/default.ino" "$PROJECT.ino" +fi + +# Project-local config +cat > sketch.yaml < .clangd < .gitignore < + +const char* ssid = "YOUR_SSID"; +const char* password = "YOUR_PASS"; + +void setup() { + Serial.begin(115200); + delay(1000); + + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + Serial.println(); + Serial.print("Connected! IP: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + // Your code here + delay(1000); +} +``` + +Create `~/.config/archduino/templates/esp8266.ino`: + +```cpp +#include + +const char* ssid = "YOUR_SSID"; +const char* password = "YOUR_PASS"; + +void setup() { + Serial.begin(115200); + delay(1000); + + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + Serial.println(); + Serial.print("Connected! IP: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + // Your code here + delay(1000); +} +``` + +Make it executable and on PATH: + +```bash +chmod +x ~/.local/bin/arduino-new +# Ensure ~/.local/bin is in PATH (add to .zshrc if needed) +export PATH="$HOME/.local/bin:$PATH" +``` + +### Usage + +```bash +arduino-new blink-test uno +arduino-new wifi-scanner esp32 +``` + +--- + +## 9. Zellij Arduino Layout + +Create `~/.config/zellij/layouts/arduino.kdl`: + +```kdl +layout { + tab name="code" focus=true { + pane split_direction="vertical" { + pane size="65%" { + command "nvim" + args "." + } + pane split_direction="horizontal" { + pane size="60%" name="terminal" + pane size="40%" name="serial" { + command "bash" + args "-c" "echo 'Run: tio /dev/ttyUSB0 -b 115200'" + } + } + } + } + tab name="git" { + pane { + command "lazygit" + } + } + tab name="monitor" { + pane { + command "bash" + args "-c" "echo 'Board monitor — run: arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200'" + } + } +} +``` + +Launch with: + +```bash +zellij --layout arduino +``` + +Or add a shell alias in `~/.zshrc`: + +```bash +alias adev="zellij --layout arduino" +``` + +--- + +## 10. Neovim Arduino Keybinds + +Create `~/.config/nvim/lua/plugins/arduino-keys.lua`: + +```lua +return { + { + "folke/which-key.nvim", + opts = function(_, opts) + opts.spec = opts.spec or {} + table.insert(opts.spec, { + { "a", group = "Arduino", icon = "⚡" }, + }) + end, + }, + { + "stevearc/vim-arduino", + keys = { + { "ac", "ArduinoChooseBoard", desc = "Choose Board" }, + { "ap", "ArduinoChoosePort", desc = "Choose Port" }, + { "av", "ArduinoVerify", desc = "Verify (compile)" }, + { "au", "ArduinoUpload", desc = "Upload" }, + { "as", "ArduinoSerial", desc = "Serial Monitor" }, + { "ai", "ArduinoInfo", desc = "Board Info" }, + }, + }, +} +``` + +Quick reference: +- `av` — compile/verify sketch +- `au` — upload to board +- `ac` — pick board +- `ap` — pick port +- `as` — open serial monitor +- `gg` — lazygit (built into LazyVim) + +--- + +## 11. WSL2-Specific Notes + +### USB passthrough (required for uploading) + +Install on Windows: + +```powershell +winget install usbipd +``` + +Create a helper script at `~/.local/bin/arduino-usb`: + +```bash +#!/bin/bash +# Quick attach Arduino USB in WSL2 +# Run the Windows-side command via PowerShell interop +powershell.exe -Command "usbipd list" +echo "" +echo "To attach, run in Windows PowerShell:" +echo " usbipd attach --wsl --busid " +``` + +### Git SSL workaround (corporate proxies) + +```bash +git config --global http.sslVerify false +echo 'insecure' >> ~/.curlrc +``` + +### Performance tip + +Add to `/etc/wsl.conf`: + +```ini +[interop] +appendWindowsPath = false + +[network] +generateResolvConf = true +``` + +Disabling `appendWindowsPath` significantly speeds up shell startup. + +--- + +## 12. Quick Reference Card + +| Action | Keybind / Command | +|----------------------|-------------------------------| +| New project | `arduino-new ` | +| Open dev workspace | `adev` | +| Compile | `av` | +| Upload | `au` | +| Choose board | `ac` | +| Choose port | `ap` | +| Serial monitor | `as` or `tio` | +| Lazygit | `gg` | +| New Zellij pane ↓ | `Alt+n` | +| New Zellij pane → | `Alt+v` | +| Navigate panes | `Alt+h/j/k/l` | +| Floating pane | `Alt+f` | +| New tab | `Alt+t` | diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100644 index 0000000..f5baea8 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,568 @@ +#!/bin/bash +# +# Archduino Bootstrap — TUI Arduino Development Environment +# Works on both native Arch Linux and Arch/Ubuntu WSL2 +# +# Usage: curl -kL | bash +# or: chmod +x bootstrap.sh && ./bootstrap.sh +# +set -euo pipefail + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' + +info() { echo -e "${GREEN}[✓]${NC} $1"; } +warn() { echo -e "${YELLOW}[!]${NC} $1"; } +error() { echo -e "${RED}[✗]${NC} $1"; exit 1; } +step() { echo -e "\n${GREEN}━━━ $1 ━━━${NC}"; } + +# ── Detect environment ────────────────────────────────────────── +IS_WSL=false +[[ -f /proc/version ]] && grep -qi microsoft /proc/version && IS_WSL=true + +IS_ARCH=false +IS_UBUNTU=false +if command -v pacman &>/dev/null; then + IS_ARCH=true + PKG_INSTALL="sudo pacman -S --needed --noconfirm" +elif command -v apt &>/dev/null; then + IS_UBUNTU=true + PKG_INSTALL="sudo apt install -y" +else + error "Unsupported distro. Need Arch (pacman) or Ubuntu (apt)." +fi + +echo "" +echo " ╔═══════════════════════════════════════╗" +echo " ║ ⚡ Archduino Bootstrap ⚡ ║" +echo " ║ TUI Arduino Dev Environment Setup ║" +echo " ╚═══════════════════════════════════════╝" +echo "" +$IS_WSL && info "Detected WSL2" || info "Detected native Linux" +$IS_ARCH && info "Package manager: pacman (Arch)" || info "Package manager: apt (Ubuntu)" +echo "" + +# ── 1. Base packages ──────────────────────────────────────────── +step "1/9 — Installing base packages" + +if $IS_ARCH; then + sudo pacman -Syu --noconfirm + $PKG_INSTALL base-devel git curl unzip wget ripgrep fd bat eza tree jq zsh clang tio +else + sudo apt update && sudo apt upgrade -y + $PKG_INSTALL build-essential git curl unzip wget ripgrep bat eza tree jq zsh clang-format tio + # fd is named differently on Ubuntu + sudo apt install -y fd-find 2>/dev/null || true +fi +info "Base packages installed" + +# ── 2. Zsh + Oh My Zsh + plugins ─────────────────────────────── +step "2/9 — Setting up Zsh" + +if [[ ! -d "$HOME/.oh-my-zsh" ]]; then + RUNZSH=no KEEP_ZSHRC=yes sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" || \ + RUNZSH=no KEEP_ZSHRC=yes sh -c "$(curl -kfsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" + info "Oh My Zsh installed" +else + info "Oh My Zsh already present" +fi + +ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" + +[[ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ]] && \ + git clone https://github.com/zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions" + +[[ ! -d "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" ]] && \ + git clone https://github.com/zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" + +info "Zsh plugins installed" + +# ── 3. Starship prompt ────────────────────────────────────────── +step "3/9 — Installing Starship" + +if ! command -v starship &>/dev/null; then + if $IS_ARCH; then + $PKG_INSTALL starship + else + curl -ksS https://starship.rs/install.sh | sh -s -- -y + fi +fi +info "Starship installed" + +mkdir -p ~/.config +cat > ~/.config/starship.toml << 'STARSHIP' +palette = "gruvbox_dark" +format = """$directory$git_branch$git_status$character""" + +[directory] +style = "bold fg:bright-yellow" +truncation_length = 3 + +[git_branch] +style = "bold fg:bright-green" +format = " [$branch]($style) " + +[git_status] +style = "bold fg:bright-red" + +[character] +success_symbol = "[❯](bold fg:bright-green)" +error_symbol = "[❯](bold fg:bright-red)" + +[palettes.gruvbox_dark] +bright-yellow = "#fabd2f" +bright-green = "#b8bb26" +bright-red = "#fb4934" +bright-blue = "#83a598" +bright-purple = "#d3869b" +bright-aqua = "#8ec07c" +bright-orange = "#fe8019" +STARSHIP +info "Starship configured with Gruvbox" + +# ── 4. Zellij ─────────────────────────────────────────────────── +step "4/9 — Installing Zellij" + +if ! command -v zellij &>/dev/null; then + if $IS_ARCH; then + $PKG_INSTALL zellij + else + curl -kL https://github.com/zellij-org/zellij/releases/latest/download/zellij-x86_64-unknown-linux-musl.tar.gz | tar xz -C /tmp + sudo mv /tmp/zellij /usr/local/bin/ + fi +fi +info "Zellij installed" + +mkdir -p ~/.config/zellij/layouts + +cat > ~/.config/zellij/config.kdl << 'ZELLIJ_CFG' +theme "gruvbox-dark" +default_layout "default" +default_mode "normal" +pane_frames false +simplified_ui true +mouse_mode false + +keybinds { + shared { + bind "Alt h" { MoveFocusOrTab "Left"; } + bind "Alt l" { MoveFocusOrTab "Right"; } + bind "Alt j" { MoveFocus "Down"; } + bind "Alt k" { MoveFocus "Up"; } + bind "Alt n" { NewPane "Down"; } + bind "Alt v" { NewPane "Right"; } + bind "Alt f" { ToggleFloatingPanes; } + bind "Alt t" { NewTab; } + } +} + +themes { + gruvbox-dark { + fg "#ebdbb2" + bg "#282828" + black "#1d2021" + red "#cc241d" + green "#98971a" + yellow "#d79921" + blue "#458588" + magenta "#b16286" + cyan "#689d6a" + white "#a89984" + orange "#d65d0e" + } +} +ZELLIJ_CFG + +cat > ~/.config/zellij/layouts/arduino.kdl << 'LAYOUT' +layout { + tab name="code" focus=true { + pane split_direction="vertical" { + pane size="65%" { + command "nvim" + args "." + } + pane split_direction="horizontal" { + pane size="60%" name="terminal" + pane size="40%" name="serial" { + command "bash" + args "-c" "echo '⚡ Serial — run: tio /dev/ttyUSB0 -b 115200'" + } + } + } + } + tab name="git" { + pane { + command "lazygit" + } + } +} +LAYOUT +info "Zellij configured with Gruvbox + Arduino layout" + +# ── 5. Neovim ─────────────────────────────────────────────────── +step "5/9 — Installing Neovim (latest)" + +NVIM_NEEDED=true +if command -v nvim &>/dev/null; then + NVIM_VER=$(nvim --version | head -1 | grep -oP '\d+\.\d+\.\d+') + if [[ "$(printf '%s\n' "0.11.2" "$NVIM_VER" | sort -V | head -1)" == "0.11.2" ]]; then + NVIM_NEEDED=false + info "Neovim $NVIM_VER already meets requirements" + fi +fi + +if $NVIM_NEEDED; then + curl -kLO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz + sudo rm -rf /opt/nvim-linux-x86_64 + sudo tar -xzf nvim-linux-x86_64.tar.gz -C /opt + sudo ln -sf /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvim + rm nvim-linux-x86_64.tar.gz + info "Neovim installed: $(nvim --version | head -1)" +fi + +# ── 6. LazyVim + plugins ──────────────────────────────────────── +step "6/9 — Setting up LazyVim" + +if [[ ! -d "$HOME/.config/nvim/lua" ]]; then + for d in ~/.config/nvim ~/.local/share/nvim ~/.local/state/nvim ~/.cache/nvim; do + [[ -d "$d" ]] && mv "$d" "${d}.bak.$(date +%s)" + done + git clone https://github.com/LazyVim/starter ~/.config/nvim + rm -rf ~/.config/nvim/.git + info "LazyVim starter cloned" +else + info "Neovim config already exists, skipping LazyVim clone" +fi + +mkdir -p ~/.config/nvim/lua/plugins + +cat > ~/.config/nvim/lua/plugins/gruvbox.lua << 'LUA' +return { + { + "ellisonleao/gruvbox.nvim", + priority = 1000, + config = function() + require("gruvbox").setup({ contrast = "hard" }) + end, + }, + { + "LazyVim/LazyVim", + opts = { colorscheme = "gruvbox" }, + }, +} +LUA + +cat > ~/.config/nvim/lua/plugins/arduino.lua << 'LUA' +return { + { + "stevearc/vim-arduino", + ft = { "arduino", "cpp", "c" }, + config = function() + vim.g.arduino_use_cli = 1 + vim.g.arduino_cli_path = "arduino-cli" + end, + keys = { + { "ac", "ArduinoChooseBoard", desc = "Choose Board" }, + { "ap", "ArduinoChoosePort", desc = "Choose Port" }, + { "av", "ArduinoVerify", desc = "Verify (compile)" }, + { "au", "ArduinoUpload", desc = "Upload" }, + { "as", "ArduinoSerial", desc = "Serial Monitor" }, + { "ai", "ArduinoInfo", desc = "Board Info" }, + }, + }, + { + "nvim-treesitter/nvim-treesitter", + opts = function(_, opts) + vim.list_extend(opts.ensure_installed, { "c", "cpp" }) + end, + }, +} +LUA + +cat > ~/.config/nvim/lua/plugins/lsp.lua << 'LUA' +return { + { + "neovim/nvim-lspconfig", + opts = { + servers = { + clangd = { + cmd = { + "clangd", + "--background-index", + "--clang-tidy", + "--header-insertion=iwyu", + "--completion-style=detailed", + }, + }, + }, + }, + }, +} +LUA +info "LazyVim plugins configured (Gruvbox + Arduino + LSP)" + +# ── 7. Arduino CLI ────────────────────────────────────────────── +step "7/9 — Installing Arduino CLI + board cores" + +if ! command -v arduino-cli &>/dev/null; then + curl -kfsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh +fi +info "Arduino CLI installed: $(arduino-cli version 2>/dev/null | head -1)" + +arduino-cli config init 2>/dev/null || true + +# Add ESP board manager URLs +arduino-cli config add board_manager.additional_urls \ + https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json 2>/dev/null || true +arduino-cli config add board_manager.additional_urls \ + https://arduino.esp8266.com/stable/package_esp8266com_index.json 2>/dev/null || true + +arduino-cli core update-index + +info "Installing AVR core..." +arduino-cli core install arduino:avr + +info "Installing ESP32 core..." +arduino-cli core install esp32:esp32 + +info "Installing ESP8266 core..." +arduino-cli core install esp8266:esp8266 + +# Common libs +arduino-cli lib install "Servo" "ArduinoJson" "Adafruit Unified Sensor" "DHT sensor library" 2>/dev/null || true +info "Board cores & libraries installed" + +# ── 8. Git + Lazygit ──────────────────────────────────────────── +step "8/9 — Setting up Git + Lazygit" + +if ! command -v lazygit &>/dev/null; then + if $IS_ARCH; then + $PKG_INSTALL lazygit + else + LAZYGIT_VERSION=$(curl -ks "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | jq -r '.tag_name' | sed 's/v//') + curl -kLo /tmp/lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz" + tar xf /tmp/lazygit.tar.gz -C /tmp lazygit + sudo mv /tmp/lazygit /usr/local/bin/ + fi +fi +info "Lazygit installed" + +mkdir -p ~/.config/lazygit +cat > ~/.config/lazygit/config.yml << 'LAZYGIT' +gui: + theme: + activeBorderColor: + - "#fabd2f" + - bold + inactiveBorderColor: + - "#665c54" + selectedLineBgColor: + - "#3c3836" + cherryPickedCommitFgColor: + - "#b8bb26" + defaultFgColor: + - "#ebdbb2" +LAZYGIT +info "Lazygit configured with Gruvbox" + +# ── 9. Scaffolding tool + templates ───────────────────────────── +step "9/9 — Creating project scaffolding tool" + +mkdir -p ~/.local/bin ~/.config/archduino/templates + +cat > ~/.local/bin/arduino-new << 'SCAFFOLD' +#!/bin/bash +set -e + +TEMPLATE_DIR="$HOME/.config/archduino/templates" + +declare -A FQBN_MAP=( + ["uno"]="arduino:avr:uno" + ["mega"]="arduino:avr:mega" + ["nano"]="arduino:avr:nano" + ["esp32"]="esp32:esp32:esp32" + ["esp32s3"]="esp32:esp32:esp32s3" + ["esp8266"]="esp8266:esp8266:nodemcuv2" +) + +usage() { + echo "Usage: arduino-new " + echo "" + echo "Available boards:" + for board in "${!FQBN_MAP[@]}"; do + printf " %-12s %s\n" "$board" "${FQBN_MAP[$board]}" + done + exit 1 +} + +[[ $# -lt 2 ]] && usage + +PROJECT="$1" +BOARD="$2" +FQBN="${FQBN_MAP[$BOARD]}" + +[[ -z "$FQBN" ]] && echo "Unknown board: $BOARD" && usage + +mkdir -p "$PROJECT" +cd "$PROJECT" + +if [[ -f "$TEMPLATE_DIR/$BOARD.ino" ]]; then + cp "$TEMPLATE_DIR/$BOARD.ino" "$PROJECT.ino" +else + cp "$TEMPLATE_DIR/default.ino" "$PROJECT.ino" +fi + +cat > sketch.yaml < .clangd < .gitignore < ~/.config/archduino/templates/default.ino << 'INO' +void setup() { + Serial.begin(115200); + while (!Serial) { ; } + Serial.println("Hello from Arduino!"); +} + +void loop() { + // Your code here +} +INO + +cat > ~/.config/archduino/templates/esp32.ino << 'INO' +#include + +const char* ssid = "YOUR_SSID"; +const char* password = "YOUR_PASS"; + +void setup() { + Serial.begin(115200); + delay(1000); + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + Serial.print("Connected! IP: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + delay(1000); +} +INO + +cat > ~/.config/archduino/templates/esp8266.ino << 'INO' +#include + +const char* ssid = "YOUR_SSID"; +const char* password = "YOUR_PASS"; + +void setup() { + Serial.begin(115200); + delay(1000); + WiFi.begin(ssid, password); + Serial.print("Connecting to WiFi"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + Serial.print("Connected! IP: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + delay(1000); +} +INO +info "Scaffolding tool + templates created" + +# ── Write .zshrc ──────────────────────────────────────────────── +step "Finalizing shell config" + +# Append archduino block to .zshrc if not already present +if ! grep -q "ARCHDUINO" ~/.zshrc 2>/dev/null; then + cat >> ~/.zshrc << 'ZSHRC' + +# ── ARCHDUINO CONFIG ──────────────────────────────────────────── +plugins=(git zsh-autosuggestions zsh-syntax-highlighting) + +export PATH="$HOME/.local/bin:$PATH" +export EDITOR="nvim" +export VISUAL="nvim" + +eval "$(starship init zsh)" + +# Auto-start Zellij +if [[ -z "$ZELLIJ" ]]; then + zellij attach --create archduino +fi + +# Arduino aliases +alias adev="zellij --layout arduino" +alias ac="arduino-cli" +alias acc="arduino-cli compile" +alias acu="arduino-cli upload" +alias acm="arduino-cli monitor" +alias acb="arduino-cli board list" +alias lg="lazygit" +alias v="nvim" +# ── END ARCHDUINO ─────────────────────────────────────────────── +ZSHRC + info "Shell config updated" +else + info "Shell config already contains Archduino block" +fi + +# ── WSL2 extras ───────────────────────────────────────────────── +if $IS_WSL; then + step "WSL2 extras" + warn "USB passthrough requires usbipd-win on Windows." + warn "Install it with: winget install usbipd" + warn "Then attach your Arduino: usbipd attach --wsl --busid " + + # Add user to dialout for serial access + sudo usermod -aG dialout "$USER" 2>/dev/null || true + sudo usermod -aG uucp "$USER" 2>/dev/null || true +fi + +# ── Done ──────────────────────────────────────────────────────── +echo "" +echo " ╔═══════════════════════════════════════╗" +echo " ║ ⚡ Archduino Setup Complete ⚡ ║" +echo " ╚═══════════════════════════════════════╝" +echo "" +info "Start a new shell or run: source ~/.zshrc" +info "Quick start:" +echo " arduino-new my-project uno # scaffold a project" +echo " adev # launch Arduino workspace" +echo " av # compile in Neovim" +echo " au # upload in Neovim" +echo ""