Neovim Update Method

Keeping My Neovim Fresh

Category: Neovim
4 min read

Go back


As a Neovim enthusiast enthusiast who loves experimenting with nightly builds, I wanted an effortless way to grab the latest version without manual downloads or multiple terminal commands. Enter my custom zsh/bash function: nvim-update. It's my go-to tool for fetching the latest Neovim nightly builds and keeping my setup running smoothly.

To get the latest nightly build: Simply run nvim-update.

To install a specific version: Use nvim-update v0.10.4 (or any desired version).

Configuration: I added these paths for easy access:
$HOME/.neovim/nvim-linux64/bin
$HOME/.neovim/nvim-linux-x86_64/bin

Here’s the full script for reference:

nvim-update() {
    local build=${1:-nightly}
    local current=$(pwd)
    local nvim_dir=$HOME/.neovim
    local stow_dir=$HOME/stow-dotfiles
    local stow_dir_hidden=$HOME/.stow-dotfiles
    local directory=""
    local filename=""
    local target=""

    echo "One moment..."
    
    # Check if neovim is installed and compare versions
    if command -v nvim > /dev/null; then
        local nvim_version=$(nvim -v | cut -d' ' -f2 | head -n1)
        if [[ "$nvim_version" != "$build" ]]; then
            echo "You requested a different Neovim version ($build)"
            echo "The current version ($nvim_version) will be replaced."
            rm -rf "$nvim_dir"
        else
            echo "You already have the current Neovim version: $nvim_version"
            return 0
        fi
    else
        echo "A new version of Neovim will be installed: $build"
    fi

    # Make the neovim directory
    echo "Fetching neovim if necessary..."
    mkdir -p "$nvim_dir"
    cd "$nvim_dir" || { echo "Failed to change directory to $nvim_dir"; return 1; }

    # Determine correct release URL
    local URL1="https://github.com/neovim/neovim/releases/download/$build/nvim-linux-x86_64.tar.gz"
    local URL2="https://github.com/neovim/neovim/releases/download/$build/nvim-linux64.tar.gz"
    
    if curl -Ifs "$URL1" > /dev/null; then
        echo "Download succeeded from primary neovim URL."
        target=$URL1
        directory="nvim-linux-x86_64"
    elif curl -Ifs "$URL2" > /dev/null; then
        echo "Download succeeded from fallback neovim URL."
        target=$URL2
        directory="nvim-linux64"
    else
        echo "Both neovim URLs failed."
        return 1
    fi
    
    filename="$directory.tar.gz"

    # Check if the file exists and is older than 1 day
    if [ ! -f "$filename" ] || [ "$(find "$filename" -mtime +0 2>/dev/null)" ]; then
        echo "Downloading Neovim..."
        rm -rf "$directory" "$filename"
        curl -LO "$target" || { echo "Download failed"; return 1; }
        tar -xzf "$filename" || { echo "Extraction failed"; return 1; }
    else
        echo "Neovim is up-to-date"
    fi

    # Update dotfiles from the appropriate directory
    echo "Pulling stow-dotfiles..."
    
    local dotfiles_dir=""
    if [ -d "$stow_dir" ]; then
        dotfiles_dir="$stow_dir"
    elif [ -d "$stow_dir_hidden" ]; then
        dotfiles_dir="$stow_dir_hidden"
    else
        echo "Stow dotfiles directory not found"
        cd "$current" || return 1
        return 1
    fi
    
    cd "$dotfiles_dir" || { echo "Failed to change directory to $dotfiles_dir"; return 1; }
    
    # Check and reset lazy-lock.json if it exists
    local lazy_lock="$dotfiles_dir/nvim/.config/nvim/lazy-lock.json"
    if [ -f "$lazy_lock" ]; then
        git checkout "$lazy_lock"
    fi

    # Update neovim plugins
    local pull_output
    pull_output=$(git pull -v)
    echo "$pull_output"
    
    if [[ "$pull_output" != *"Already up to date."* ]]; then
        echo "Updating neovim plugins..."
        nvim --headless "+Lazy! update" +UpdateRemotePlugins +TSUpdate +qa
        echo "Update complete!"
        exec zsh
    else
        echo "All good, no updates are necessary!"
    fi
    
    cd "$current" || return 1
}

Here’s a breakdown:

  • The build variable defaults to nightly unless a specific version is passed as an argument. This gives flexibility to experiment with other releases.
  • The script checks the currently installed version of Neovim. If the version matches the requested build and it’s not outdated (for nightly builds, it checks if the directory is older than a day), it exits early.
  • The script ensures a fresh archive is downloaded and extracted if necessary.
  • For those using GNU Stow to manage dotfiles, the script updates the lazy-lock.json file to keep plugin setups synchronized. It handles both visible and hidden directories.
  • If updates are available, the script runs Neovim in headless mode to update plugins, remote plugins, and Treesitter parsers.
  • After completing updates, the script returns to the original directory and ensures everything is neat.

If you’re using Neovim and want to streamline your updates, feel free to adapt this script to your own workflow!


image/svg+xmlPICOL Icon2009-03-15Melih BilgilCreative Commons BY-SAPICOL - Pictorial Communication Languagehttp://blog.picol.orghttp://blog.picol.orgenPICOLiconiconssignGUIvectorinterfaceThis is one icon out of all PICOL iconsMelih Bilgil (www.lonja.de), Christopher Adjei (www.boffer.net) Created 2025-01-22
image/svg+xmlPICOL Icon2009-03-15Melih BilgilCreative Commons BY-SAPICOL - Pictorial Communication Languagehttp://blog.picol.orghttp://blog.picol.orgenPICOLiconiconssignGUIvectorinterfaceThis is one icon out of all PICOL iconsMelih Bilgil (www.lonja.de), Christopher Adjei (www.boffer.net) Last updated 5 months ago