From 455bcfcbd4ae7037c3f21c355fb2fe2f9ebef32b Mon Sep 17 00:00:00 2001 From: Vladimir Viatskii Date: Sun, 8 Nov 2026 21:25:51 +0300 Subject: [PATCH] Add lima-docker app --- 50-docker.conf | 31 +++++++++++++++++ zsh/11-autocomplete.zsh | 4 +++ zsh/apps/lima-docker.app.zsh | 66 ++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 50-docker.conf create mode 100644 zsh/apps/lima-docker.app.zsh diff --git a/50-docker.conf b/50-docker.conf new file mode 100644 index 0000000..0f8bbea --- /dev/null +++ b/50-docker.conf @@ -0,0 +1,31 @@ +function _docker_with_platform() { + local platform=$1 + local extra_flags=$2 + shift 2 + local args=$@ + local original="docker ${args}" + local cmd="${original}" + _substitutableCmds=(build pull run) + + if [[ ${args} != *"--platform"* ]]; then + for command in ${_substitutableCmds[@]}; do + if [[ ${args} =~ (^|[[:space:]])${command}([[:space:]]|$) ]]; then + cmd=${cmd/${command}/${command} --platform=${platform}${extra_flags:+ ${extra_flags}}} + fi + done + fi + + if [[ "${cmd}" != "${original}" ]]; then + echo -e "\e[34m-> ${cmd}\e[0m" + fi + + eval "command ${cmd}" +} + +function docker() { + _docker_with_platform "linux/arm64/v8" "" $@ +} + +function docker-amd64() { + _docker_with_platform "linux/amd64" "--device=lima-vm.io/rosetta=cached" $@ +} diff --git a/zsh/11-autocomplete.zsh b/zsh/11-autocomplete.zsh index 322e2cb..95c4eab 100644 --- a/zsh/11-autocomplete.zsh +++ b/zsh/11-autocomplete.zsh @@ -15,3 +15,7 @@ compinit zstyle ':completion:*' menu select=2 zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' + +if [ "${LIMA_DOCKER}" = "1" ]; then + compdef docker-amd64=docker +fi diff --git a/zsh/apps/lima-docker.app.zsh b/zsh/apps/lima-docker.app.zsh new file mode 100644 index 0000000..dcadcb4 --- /dev/null +++ b/zsh/apps/lima-docker.app.zsh @@ -0,0 +1,66 @@ +# Functions for docker in Lima for macOS. +# Requires lima, docker, docker-compose and docker-credentials-helper to be installed. + +if [ "${OS/Darwin}" != "${OS}" ]; then + LIMA_DOCKER=1 + + # Candidates cobra offers for the last argument, one per line, without the directive line or descriptions + function _docker_complete() { + local -a out=("${(@f)$(command docker __complete "$@" 2>/dev/null)}") + print -rl -- "${(@)${(@)out:#:*}%%$'\t'*}" + } + + function _docker_with_platform() { + local platform=$1 extra=$2 + shift 2 + local -a args=("$@") + + # Completion requests and explicitly pinned platforms pass through untouched + if [[ $1 == __complete* ]] || (( ${args[(I)(--platform|--platform=*)]} )); then + command docker "$@" + return + fi + + # Walk the command path; stop at the first command that accepts --platform + local -i i pos=0 + local -a cmds flags + for (( i = 1; i <= $#args; i++ )); do + [[ ${args[i]} == -* ]] && continue + + cmds=("${(@f)$(_docker_complete "${(@)args[1,i-1]}" "")}") + if (( ! ${cmds[(Ie)${args[i]}]} )); then + # Not a command: either the previous option's value, or we've left the command path + (( i > 1 )) && [[ ${args[i-1]} == -* && ${args[i-1]} != *=* ]] && continue + break + fi + + flags=("${(@f)$(_docker_complete "${(@)args[1,i]}" -)}") + if (( ${flags[(Ie)--platform]} )); then + pos=$i + break + fi + done + + if (( pos )); then + local -a inject=(--platform=$platform) + local f name + for f in ${=extra}; do + name=${f%%=*} + # Only if this command accepts it and the user didn't pass it already + (( ${flags[(Ie)$name]} && ! ${args[(I)$name(|=*)]} )) && inject+=("$f") + done + args=("${(@)args[1,pos]}" $inject "${(@)args[pos+1,-1]}") + print -u2 $'\e[34m-> docker '"${(j: :)${(@q-)args}}"$'\e[0m' + fi + + command docker "${args[@]}" + } + + function docker() { + _docker_with_platform "linux/arm64/v8" "" "$@" + } + + function docker-amd64() { + _docker_with_platform "linux/amd64" "--device=lima-vm.io/rosetta=cached" "$@" + } +fi