port the Neovim section

Kept as it worked — upstream tarball, symlink, a config repo cloned into the
account's ~/.config/nvim — with the defects fixed rather than the design changed.

The one that mattered: the asset name. Neovim publishes nvim-linux-x86_64.tar.gz
and nvim-linux-arm64.tar.gz. The original mapped aarch64 to "aarch64", which is
not a name Neovim has ever published, so on an arm machine it downloaded a 404
and handed the HTML error page to tar. Verified against the release API — same
class of bug as lazygit's hardcoded x86_64, and the second one this port has
found in an arch mapping. The tarball is now checked with `tar -tzf` before
anything is removed, so a bad download says what is wrong instead of failing
inside tar.

The rest:

  The tarball went to the working directory, via `curl -LO`, and stayed there if
  tar failed. It goes to /tmp and is cleaned up.

  The old /opt install was removed before the new one was known to be good. The
  download and its sanity check now come first, so a failed fetch leaves the
  working copy alone.

  The custom-repo option defaulted to git@gogs:andrepadez/nvim-config.git — a
  private repository nobody else can clone, and the same mistake as defaulting
  the login server to a personal headscale. No default now.

  git clone runs from /, for the reason git config does: the script's working
  directory is usually under the invoking user's home at 0750, which the target
  account cannot stat.

  The ~/.config/nvim/.git removal is now conditional on it being the starter.
  That is a template and dropping its history is right; a config of the user's
  own is something they will want to keep pulling.

  An existing config is left alone and said so, rather than moved to a .bak that
  silently overwrote the previous .bak.

The PATH line the original appended to .zshrc is gone. /usr/local/bin/nvim is
symlinked and already on PATH, so it was doing nothing except growing the file on
every run.

Verified on this host (already current, existing config left alone) and against a
fresh account (LazyVim starter cloned, owned correctly, .git dropped).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 20:54:59 +00:00
co-authored by Claude Opus 5
parent 5a33a517e7
commit 0286cc6db6
2 changed files with 168 additions and 1 deletions
+71
View File
@@ -99,3 +99,74 @@ set_login_shell() {
grep -qxF "$shell" /etc/shells || echo "$shell" >>/etc/shells grep -qxF "$shell" /etc/shells || echo "$shell" >>/etc/shells
chsh -s "$shell" "$USERNAME" chsh -s "$shell" "$USERNAME"
} }
# -----------------------------------------------------------------------------
# Neovim
# -----------------------------------------------------------------------------
#
# From the upstream tarball rather than the distribution, which ships Neovim
# years behind — Ubuntu 24.04 has 0.9 where upstream is on 0.12, and LazyVim
# requires 0.9+ with most plugins wanting newer.
#
# The asset names are x86_64 and arm64. The original mapped aarch64 to
# "aarch64", which is not a name Neovim publishes: on an arm machine it
# downloaded a 404 and tar failed on the HTML error page.
nvim_asset() {
case "$ARCH" in
amd64) echo x86_64 ;;
arm64) echo arm64 ;;
esac
}
nvim_installed_version() { nvim --version 2>/dev/null | awk 'NR == 1 { print $2 }'; }
nvim_latest_version() {
curl -fsSL https://api.github.com/repos/neovim/neovim/releases/latest 2>/dev/null |
jq -r '.tag_name // empty'
}
# Downloaded to /tmp, not to whatever directory the script was launched from —
# the original used `curl -LO`, which drops the tarball beside the script and
# leaves it there if tar fails.
#
# The old install is removed only after the download has succeeded, so a failed
# fetch leaves the working copy alone.
nvim_install() {
local asset tarball dest
asset="$(nvim_asset)"
tarball="/tmp/nvim-linux-${asset}.tar.gz"
dest="/opt/nvim-linux-${asset}"
curl -fsSL -o "$tarball" \
"https://github.com/neovim/neovim/releases/latest/download/nvim-linux-${asset}.tar.gz" || return 1
# A 404 comes back as an HTML page, and tar's failure on it is unhelpful.
# Checking here names the real problem.
tar -tzf "$tarball" >/dev/null 2>&1 || {
rm -f "$tarball"
warn "the download is not a tarball — the release asset may have been renamed"
return 1
}
rm -rf "$dest"
tar -C /opt -xzf "$tarball"
rm -f "$tarball"
ln -sf "${dest}/bin/nvim" /usr/local/bin/nvim
}
# Clone a Neovim config into the account's ~/.config/nvim.
#
# From `cd /` for the same reason git config does: the script's working directory
# is usually under the invoking user's home at 0750, which the target account
# cannot stat, and git fails there before it does anything useful.
nvim_clone_config() {
local repo="$1" dest="${USER_HOME}/.config/nvim"
install -d -m 0755 -o "$USERNAME" -g "$USERNAME" "${USER_HOME}/.config"
(cd / && sudo -H -u "$USERNAME" git clone --depth 1 "$repo" "$dest" >/dev/null 2>&1) || return 1
# The starter is a template, not something to track. Left in place for a
# config of the user's own, which they will want to keep pulling.
[[ "$repo" == *LazyVim/starter* ]] && sudo -u "$USERNAME" rm -rf "${dest}/.git"
return 0
}
+97 -1
View File
@@ -1853,13 +1853,109 @@ EOF
step_ok step_ok
fi fi
# =============================================================================
# 24. Neovim
# =============================================================================
step "Neovim"
if ! skip; then
NVIM_NOW="$(nvim_installed_version)"
NVIM_LATEST="$(nvim_latest_version)"
echo ""
info "Neovim — from upstream, not from the distribution"
echo " installed: ${NVIM_NOW:-not installed}"
echo " latest: ${NVIM_LATEST:-could not reach github}"
echo " Ubuntu ships a Neovim years behind upstream, and LazyVim wants a"
echo " recent one, so this takes the release tarball."
if [[ -z "$NVIM_LATEST" ]]; then
warn "cannot reach the release API — leaving Neovim alone"
SUMMARY+=("Neovim: skipped, could not reach github")
elif [[ "$NVIM_NOW" == "$NVIM_LATEST" ]]; then
echo " already on the latest release, nothing to do"
SUMMARY+=("Neovim: already ${NVIM_NOW}")
else
echo ""
if confirm "${NVIM_NOW:+Upgrade}${NVIM_NOW:-Install} Neovim ${NVIM_LATEST}?"; then
if nvim_install; then
ok "neovim $(nvim_installed_version) at /usr/local/bin/nvim"
SUMMARY+=("Neovim: $(nvim_installed_version)")
else
warn "the Neovim install did not complete"
ERRORS+=("Neovim: install failed")
SUMMARY+=("Neovim: install FAILED")
fi
else
warn "skipped by request"
SUMMARY+=("Neovim: SKIPPED by request")
fi
fi
# ── configuration ──
if command -v nvim &>/dev/null && id "$USERNAME" &>/dev/null; then
NVIM_CONFIG="${USER_HOME}/.config/nvim"
if [[ -d "$NVIM_CONFIG" ]]; then
echo ""
echo " ${USERNAME} already has a Neovim config at ${NVIM_CONFIG}"
SUMMARY+=("Neovim: existing config left alone")
else
echo ""
info "Neovim configuration for ${USERNAME}"
echo " [1] LazyVim starter — a maintained set of defaults, sensible to"
echo " build on and easy to remove"
echo " [2] a git repository of your own"
echo " [3] nothing — plain Neovim"
echo ""
NVIM_REPO=""
NVIM_PICK=""
while [[ -z "$NVIM_PICK" ]]; do
if ! read -rp " Which one? (1/2/3) [1]: " NVIM_CHOICE; then
echo ""
fail "No answer."
fi
case "${NVIM_CHOICE:-1}" in
1)
NVIM_REPO="https://github.com/LazyVim/starter"
NVIM_PICK=config
;;
2)
# No default. The original suggested its author's own private repo,
# which nobody else can clone.
read -rp " Repository URL: " NVIM_REPO || fail "No answer."
[[ -n "$NVIM_REPO" ]] && NVIM_PICK=config || warn "A repository URL is needed."
;;
3) NVIM_PICK=none ;;
*) warn "Pick 1, 2 or 3." ;;
esac
done
if [[ "$NVIM_PICK" == config ]]; then
if nvim_clone_config "$NVIM_REPO"; then
ok "config cloned to ${NVIM_CONFIG}"
SUMMARY+=("Neovim: config from ${NVIM_REPO}")
else
warn "could not clone ${NVIM_REPO}"
ERRORS+=("Neovim: cloning ${NVIM_REPO} failed")
SUMMARY+=("Neovim: config clone FAILED")
fi
else
SUMMARY+=("Neovim: no config, plain Neovim")
fi
fi
fi
step_ok
fi
# ============================================================================= # =============================================================================
# NOT PORTED YET # NOT PORTED YET
# ============================================================================= # =============================================================================
# #
# Sections still to move across from scripts/setup-old/setup-ubuntu.sh, in order: # Sections still to move across from scripts/setup-old/setup-ubuntu.sh, in order:
# #
# neovim · js runtimes · # js runtimes ·
# dev tools · ufw · zshrc # dev tools · ufw · zshrc
# #
# And one that is new rather than ported, to come last of all: # And one that is new rather than ported, to come last of all: