From 9aa384c1a3f52326afd944905c076045c8be54af Mon Sep 17 00:00:00 2001 From: Job79 Date: Sat, 21 Dec 2024 10:33:05 +0100 Subject: [PATCH] init --- .github/workflows/ci.yaml | 24 ++++++++++ Dockerfile | 31 +++++++++++++ config/nvim/config/keymaps.lua | 16 +++++++ config/nvim/config/lazy.lua | 43 +++++++++++++++++ config/nvim/config/options.lua | 15 ++++++ config/nvim/lazyvim.json | 12 +++++ config/nvim/plugins/colorscheme.lua | 9 ++++ config/nvim/plugins/disabled.lua | 25 ++++++++++ config/user/bashrc | 14 ++++++ config/user/profile | 7 +++ enter.sh | 72 +++++++++++++++++++++++++++++ 11 files changed, 268 insertions(+) create mode 100644 .github/workflows/ci.yaml create mode 100644 Dockerfile create mode 100644 config/nvim/config/keymaps.lua create mode 100644 config/nvim/config/lazy.lua create mode 100644 config/nvim/config/options.lua create mode 100644 config/nvim/lazyvim.json create mode 100644 config/nvim/plugins/colorscheme.lua create mode 100644 config/nvim/plugins/disabled.lua create mode 100644 config/user/bashrc create mode 100644 config/user/profile create mode 100755 enter.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..8b20570 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,24 @@ +name: Build devcontainer +on: + push: + schedule: + - cron: '0 16 * * FRI' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set buildx + uses: docker/setup-buildx-action@v3 + - name: Build and push + uses: docker/build-push-action@v5 + with: + push: true + tags: | + ghcr.io/${{ github.actor }}/devcontainer:latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f471ca3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# ========================================= # +# Containerfile v1.0; job79 # +# Configure and setup a neovim devcontainer # +# for go and nodejs development. # +# ========================================= # +FROM quay.io/fedora/fedora:41 + +# === setup system === +RUN dnf update -y && \ + dnf copr enable -y atim/lazygit && \ + dnf -y install neovim unzip \ + bash-completion zoxide fd-find chafa lazygit procps \ + git go npm + +# === setup container user === +RUN useradd -ms /bin/bash user && usermod -aG wheel user && sed -i '/NOPASSWD/s/^#//g' /etc/sudoers +RUN mkdir /run/user/1000 && chown user:user /run/user/1000 +USER user +WORKDIR /home/user +COPY config/user/bashrc /home/user/.bashrc +COPY config/user/profile /home/user/.bash_profile + +# === setup neovim === +RUN git clone --depth 1 https://github.com/LazyVim/starter ~/.config/nvim +COPY --chown=user:user config/nvim/plugins /home/user/.config/nvim/lua/plugins +COPY --chown=user:user config/nvim/config /home/user/.config/nvim/lua/config +COPY --chown=user:user config/nvim/lazyvim.json /home/user/.config/nvim/lazyvim.json + +# === setup container === +ENV TZ="Europe/Amsterdam" +VOLUME /home/user/.local /home/user/.cache diff --git a/config/nvim/config/keymaps.lua b/config/nvim/config/keymaps.lua new file mode 100644 index 0000000..eb43eda --- /dev/null +++ b/config/nvim/config/keymaps.lua @@ -0,0 +1,16 @@ +-- Configure custom keymaps. +local keymap = vim.keymap.set +local delkeymap = vim.keymap.del +local opts = { noremap = true, silent = true } + +-- Improved line start/end +keymap({ "n", "v" }, "H", "^", opts) +keymap({ "n", "v" }, "L", "$", opts) + +-- Improved escape +keymap("n", "", ":noh", opts) +keymap("t", "", "", opts) + +-- Disable alt j/k to move lines (conflict with default vim motions) +delkeymap({ "i", "v" }, "") +delkeymap({ "i", "v" }, "") diff --git a/config/nvim/config/lazy.lua b/config/nvim/config/lazy.lua new file mode 100644 index 0000000..ede6149 --- /dev/null +++ b/config/nvim/config/lazy.lua @@ -0,0 +1,43 @@ +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +require("lazy").setup({ + spec = { + { "LazyVim/LazyVim", import = "lazyvim.plugins" }, + { import = "plugins" }, + }, + defaults = { + lazy = false, + version = false, + }, + install = {}, + checker = { + enabled = true, + notify = true, + }, + performance = { + rtp = { + disabled_plugins = { + "gzip", + "netrwPlugin", + "tarPlugin", + "tohtml", + "tutor", + "zipPlugin", + }, + }, + }, +}) diff --git a/config/nvim/config/options.lua b/config/nvim/config/options.lua new file mode 100644 index 0000000..ffe07c0 --- /dev/null +++ b/config/nvim/config/options.lua @@ -0,0 +1,15 @@ +-- Set some custom options. +local opt = vim.o +local global = vim.g + +-- Set target text width for gww to 60. +opt.tw = 60 + +-- Use the internal clipboard. +opt.clipboard = "" + +-- Use original gruvbox theme. +global.gruvbox_material_foreground = "original" + +-- Disable snack animations. +global.snacks_animate = false diff --git a/config/nvim/lazyvim.json b/config/nvim/lazyvim.json new file mode 100644 index 0000000..32e2dc8 --- /dev/null +++ b/config/nvim/lazyvim.json @@ -0,0 +1,12 @@ +{ + "extras": [ + "lazyvim.plugins.extras.ai.copilot", + "lazyvim.plugins.extras.dap.core", + "lazyvim.plugins.extras.lang.go", + "lazyvim.plugins.extras.lang.svelte", + "lazyvim.plugins.extras.lang.tailwind", + "lazyvim.plugins.extras.lang.typescript", + "lazyvim.plugins.extras.test.core" + ], + "version": 7 +} diff --git a/config/nvim/plugins/colorscheme.lua b/config/nvim/plugins/colorscheme.lua new file mode 100644 index 0000000..ac12a3c --- /dev/null +++ b/config/nvim/plugins/colorscheme.lua @@ -0,0 +1,9 @@ +-- Configure rose-pine and gruvbox-material colorschemes. +return { + { "rose-pine/neovim", name = "rose-pine" }, + { "sainnhe/gruvbox-material" }, + { + "LazyVim/LazyVim", + opts = { colorscheme = "gruvbox-material" }, + }, +} diff --git a/config/nvim/plugins/disabled.lua b/config/nvim/plugins/disabled.lua new file mode 100644 index 0000000..999edb1 --- /dev/null +++ b/config/nvim/plugins/disabled.lua @@ -0,0 +1,25 @@ +-- Disable unused plugins and functionality. +return { + { + -- Disable the dashboard. + "folke/snacks.nvim", + opts = { + dashboard = { enabled = false }, + notifier = { level = vim.log.levels.WARN }, + }, + }, + { + -- Disable inline hints by default. + "neovim/nvim-lspconfig", + opts = { + inlay_hints = { enabled = false }, + }, + }, + + -- Disable unused plugins. + { "folke/flash.nvim", enabled = false }, + { "folke/todo-comments.nvim", enabled = false }, + { "folke/trouble.nvim", enabled = false }, + { "MagicDuck/grug-far.nvim", enabled = false }, + { "akinsho/bufferline.nvim", enabled = false }, +} diff --git a/config/user/bashrc b/config/user/bashrc new file mode 100644 index 0000000..a176a76 --- /dev/null +++ b/config/user/bashrc @@ -0,0 +1,14 @@ +. /etc/bashrc + +# === environment === +export EDITOR=nvim \ + WAYLAND_DISPLAY=wayland-0 \ + XDG_RUNTIME_DIR=/run/user/1000 \ + SSH_AUTH_SOCK=/run/user/1000/ssh-auth-sock \ + PS1='\[\e[30;46m\] container | \w \[\e[0;36m\]\[\e[m\] ' + +# === aliases and functions === +alias vi=nvim +post() { curl -sF "content=<-" "https://paste.plabble.org/$2?lang=$1" && echo; } +eval "$(zoxide init --cmd cd bash)" +eval "$(fzf --bash)" diff --git a/config/user/profile b/config/user/profile new file mode 100644 index 0000000..683af33 --- /dev/null +++ b/config/user/profile @@ -0,0 +1,7 @@ +. ~/.bashrc + +# === persist copilot auth files inside .local volume === +if [ ! -d ~/.config/github-copilot ]; then + mkdir -p ~/.local/share/github-copilot + ln -s ~/.local/share/github-copilot ~/.config +fi diff --git a/enter.sh b/enter.sh new file mode 100755 index 0000000..fabe63d --- /dev/null +++ b/enter.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# =============================================== # +# enter.sh v1.0; job79 # +# Enter into an existing or new dev container and # +# automatically handle dev container updates. # +# =============================================== # +set -eu +log() { printf '\e[%sm%s\e[0m %s\n' "${3:-36}" "${2:-○}" "$1"; } +arg() { echo -n " $@"; } + +# run_args returns the arguments required for the podman run +# command. +run_args() { + arg "--name $name" + + # Disable some security settings to make it possible to + # mount host directories without problems. + arg "--security-opt label=disable" # disable labeling so mounts don't need to be labeled. + arg "--userns=keep-id" # required for ~/.ssh which is usually 700. + + # Use host networking. + arg "--net=host" + + # Mount the wayland socket. Required to get the system + # clipbard (wl-copy) working. + [ -e "/run/user/$UID/wayland-0" ] && arg "-v /run/user/$UID/wayland-0:/run/user/1000/wayland-0" + + # Mount the ssh socket, directory and the git config + # directory. This gets the host ssh and git configuration + # working inside the container. + [ -e "$SSH_AUTH_SOCK" ] && arg "-v $SSH_AUTH_SOCK:/run/user/1000/ssh-auth-sock" + [ -d "$HOME/.ssh" ] && arg "-v $HOME/.ssh:/home/user/.ssh" + [ -d "$HOME/.config/git" ] && arg "-v $HOME/.config/git:/home/user/.config/git" + + # Mount host directories with programming projects. + [ -d "$HOME/Documents" ] && arg "-v $HOME/Documents:/home/user/Documents" + [ -d "$HOME/.local/share/devcontainer" ] && arg "-v $HOME/.local/share/devcontainer:/home/user/.dev" + + # Add volumes for .local and .cache so these survive + # container restarts. + arg "-v $name-local:/home/user/.local" + arg "-v $name-cache:/home/user/.cache" +} + +### MAIN ### +name="dev" +image="git.plabble.org/job79/dev:latest" +fetch=false + +while test $# -gt 0; do + case "$1" in + --image | -i) shift && fetch=true && image="$1" ;; + --fetch | -f) fetch=true ;; + -*) log "unknown argument '$1'" 'x' 31 ;; + *) name="$1" ;; + esac + shift +done + +if [ "$fetch" = true ] || [ "$(podman container inspect "$name" -f {{.State.Running}} 2>&1)" != 'true' ]; then + log "fetching updates..." + if [ "$(podman pull -q "$image")" != "$(podman container inspect "$name" -f {{.Image}} 2>&1)" ]; then + log "container image downloaded" '✓' 32 + podman container rm -f -t 1 "$name" 1>/dev/null + podman run -td $(run_args) "$image" + else + log "no updates available" '✓' 32 + fi +fi + +podman start "$name" 1>/dev/null +podman exec --detach-keys "" -it "$name" bash -l