Skip to content

Instantly share code, notes, and snippets.

@elijahmanor
Created March 27, 2023 04:59
Show Gist options
  • Save elijahmanor/b279553c0132bfad7eae23e34ceb593b to your computer and use it in GitHub Desktop.
Save elijahmanor/b279553c0132bfad7eae23e34ceb593b to your computer and use it in GitHub Desktop.
Neovim Switcher
alias nvim-lazy="NVIM_APPNAME=LazyVim nvim"
alias nvim-kick="NVIM_APPNAME=kickstart nvim"
alias nvim-chad="NVIM_APPNAME=NvChad nvim"
alias nvim-astro="NVIM_APPNAME=AstroNvim nvim"
function nvims() {
items=("default" "kickstart" "LazyVim" "NvChad" "AstroNvim")
config=$(printf "%s\n" "${items[@]}" | fzf --prompt=" Neovim Config  " --height=~50% --layout=reverse --border --exit-0)
if [[ -z $config ]]; then
echo "Nothing selected"
return 0
elif [[ $config == "default" ]]; then
config=""
fi
NVIM_APPNAME=$config nvim $@
}
bindkey -s ^a "nvims\n"
@andyantrim
Copy link

So to make this a little easier (having to type nvims each time gets a bit old) I have the following:

alias vi="nvim"

alias nvim-lazy="NVIM_APPNAME=LazyVim nvim"
alias nvim-chad="NVIM_APPNAME=NvChad nvim"
alias nvim-astro="NVIM_APPNAME=AstroNvim nvim"

function nvims() {
  items=("default" "LazyVim" "NvChad" "AstroNvim")
  config=$(printf "%s\n" "${items[@]}" | fzf --prompt=" Neovim Config  " --height=~50% --layout=reverse --border --exit-0)
  if [[ -z $config ]]; then
    echo "Nothing selected"
    return 0
  elif [[ $config == "default" ]]; then
    config=""
  else
    alias vi="NVIM_APPNAME=${config} nvim"
  fi
  NVIM_APPNAME=$config nvim $@
}

This has the same behavior, but rewrites the vi alias to take you to the last selected nvim distro. The idea here is nvims can then become a context switcher, that sets the nvim distro/version which can be opened in the future with vi command.

@doctorfree
Copy link

@andyantrim that's a pretty cool trick. I am attempting to incorporate this in the Lazyman definition of nvims. The problem I am trying to solve is continuing to allow the user to override the NVIM_APPNAME environment variable value while also enabling this persistent alias. That is, once the alias has been set, subsequent invocations of vi always set NVIM_APPNAME to whatever was previously selected. The user can no longer override that value other than rerunning nvims and selecting another config.

I'm experimenting with something like the following:

alias vi="NVIM_APPNAME=${NVIM_APPNAME:-${config}} nvim"

With this slightly revised alias, if the user has NVIM_APPNAME set then that is used, if not then the selected config is used in the alias. That is, what persists as an alias for vi is an NVIM_APPNAME setting either 1) from the environment, or 2) from the selection.

Does this make sense?

@QMaxPowerQ
Copy link

in terminal input nvims and enter not a valid number: ~50 nothing selected what's wrong?

any news on this?
I do have the same error while just using nvims without any argument. Using WSL2 - bash

@saccarosium
Copy link

Here a POSIX shell script that can switch between configurations and remember the last selected one.

#!/bin/sh

config=""
history="${XDG_CACHE_HOME:-$HOME/.cache}/nvim-configuration"
items="default kickstart LazyVim NvChad AstroNvim"

trap 'echo "$config" >"$history"' EXIT

case $1 in
    -C | --config)
        if [ -z "$2" ]; then
            config=$(echo "$items" | tr ' ' '\n' | fzf --prompt=" Neovim Config  " --height=~50% --layout=reverse --border --exit-0) || exit 0
            shift
        else
            config="$2"
            shift
            shift
        fi
        ;;
    *)
        config=$(cat "$history")
        ;;
esac

[ "$config" = "default" ] && config=""

NVIM_APPNAME="${config:-""}" nvim "$@"

Usage

NOTE All input extra input is passed to nvim

  • -C without extra input: prompt with fzf to select a configuration
  • -C with extra input: selects passed configuration
  • without any flag: use the last selected one or default

@ajmasia
Copy link

ajmasia commented Sep 14, 2023

I have created this script so that I can use it in a more customised way 😄

#!/usr/bin/env bash

# ANSI color codes
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
CLEAR='\033[0m'

DEFAULT_INSTANCE=nvim-default

show_help() {
	echo -e "Usage: ${YELLOW}nvim-starter ${PURPLE}[COMMAND]${CYAN} [NVIM_OPTIONS...]${CLEAR}"
	echo
	echo "Available commands: (no command start nvim natively)"
	echo -e "  ${PURPLE}sel, select${CLEAR}     Show a selector to choose the Neovim configuration"
	echo -e "  ${PURPLE}def, default${CLEAR}    Start the default instance of Neovim"
	echo -e "  ${PURPLE}help${CLEAR}            Display this help message"
}

select_config() {
	local items=("default" "nvim" "nvim-learning")
	local config=$(printf "%s\n" "${items[@]}" | fzf --prompt=" Neovim Config: " --height=~50% --layout=reverse --exit-0)

	if [[ -z $config ]]; then
		echo "${GREEN}Nothing selected${CLEAR}"
		exit 0
	elif [[ $config == "default" ]]; then
		config=$DEFAULT_INSTANCE
	fi

	NVIM_APPNAME=$config nvim "$@"
}

default_exec() {
	# Default behavior (no script commds)
	nvim "$@"
	exit 0
}

[[ $# -eq 0 ]] && default_exec

while [[ $# -gt 0 ]]; do
	key="$1"

	case $key in
	help)
		show_help
		exit 0
		;;
	sel | select)
		shift # remove the -s or --select
		select_config "$@"
		exit 0
		;;
	def | default)
		shift # remove the -d or --default
		NVIM_APPNAME=$DEFAULT_INSTANCE nvim "$@"
		exit 0
		;;
	*)
		default_exec
		;;
	esac
done

@soomtong
Copy link

soomtong commented Oct 14, 2023

thanks a lot!

my configuration of zshrc for nvims here. made in macOS.

function nvims() {
  local nv_items=("Vanilla" "LazyVim" "NvChad")
  local nv_app=$(printf "%s\n" "${nv_items[@]}" | fzf --prompt=" Neovim Config 󰶻  " --height=~50% --layout=reverse --border --exit-0)

  if [[ -z $nv_app ]]; then
    echo "Nothing selected"
    return 0
  elif [[ $nv_app == "Vanilla" ]]; then
    nv_app=""
  else
    echo "Set $nvims_config to $nv_app"
  fi

  echo "$nv_app" > "$nvims_config"
  alias vi="NVIM_APPNAME=${nv_app} nvim"

  NVIM_APPNAME=$nv_app nvim $@
}

# nvims
if [[ -x /usr/local/bin/nvim || -x /opt/homebrew/bin/nvim ]]; then
  nvims_config="${XDG_CACHE_HOME:-$HOME/.cache}/nvims"
  nvims_app=$(cat "$nvims_config")
  #echo "Bind Neovim to $nvims_app"
  alias vi="NVIM_APPNAME=${nvims_app} nvim"
  export EDITOR="vi"
  bindkey -s "^v" "nvims\n"
fi

@ZediWards
Copy link

in terminal input nvims and enter not a valid number: ~50 nothing selected what's wrong?

any news on this? I do have the same error while just using nvims without any argument. Using WSL2 - bash

I had the same error.
Fix was to make height=50% NOT height=~50%
image

@hasecilu
Copy link

Due to some changes on Nerd Font you may want to update the glyphs to: " Neovim Config 󰄾 "

@wochap
Copy link

wochap commented Dec 5, 2023

For zsh, I refactored the function so you don't need to hardcode the options; it finds any folder in ~/.config with an init.lua file in it and considers it a nvim config folder. Additionally, it adds a preview using lsd to display the folder contents.

function nvims() {
  items=$(find $HOME/.config -maxdepth 2 -name "init.lua" -type f -execdir sh -c 'pwd | xargs basename' \;)
  selected=$(printf "%s\n" "${items[@]}" | FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS-} --preview-window 'right:border-left:50%:<40(right:border-left:50%:hidden)' --preview 'lsd -l -A --tree --depth=1 --color=always --blocks=size,name ~/.config/{} | head -200'" fzf )
  if [[ -z $selected ]]; then
    return 0
  elif [[ $selected == "nvim" ]]; then
    selected=""
  fi
  NVIM_APPNAME=$selected nvim "$@"
}
alias nvs=nvims
Preview:

@hasecilu
Copy link

hasecilu commented Dec 5, 2023

For zsh, I refactored the function so you don't need to hardcode the options;

Nice, works well with eza too.

@Armadillidiid
Copy link

Armadillidiid commented Dec 5, 2023

@wochap I tried your script on my setup and it doesn't seem to detect symlinks. I store all my configs under ~/.dotfiles and generate respective symlinks using Stow. To work around it, I simply added an extra folder to search.

	items=$(
		find $HOME/.config -maxdepth 2 -name "init.lua" -type f -execdir sh -c 'pwd | xargs basename' \;
		find $HOME/.dotfiles -maxdepth 5 -name "init.lua" -type f -execdir sh -c 'pwd | xargs basename' \;
	)

@doctorfree
Copy link

Rather than adding an extra folder to search, the find command can be altered either with:

find $HOME/.config -maxdepth 2 -name "init.lua" "(" -type f -o -type l ")" -execdir sh -c 'pwd | xargs basename' \;

or

find -L $HOME/.config -maxdepth 2 -name "init.lua" -type f -execdir sh -c 'pwd | xargs basename' \;

Either of those will pickup both plain files and symbolic links.

I also ran into a problem on an Ubuntu 20.04 system with the older version of fzf in their repo. It did not understand the preview options:

invalid preview window layout: right:border-left:50%:<40(right:border-left:50%:hidden)

I simplified the preview options to get it to work on that system:

selected=$(printf "%s\n" "${items[@]}" | FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS-} --preview-window=right:50% --preview 'lsd -l -A --tree --depth=1 --color=always --blocks=size,name ~/.config/{} | head -200'" fzf )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment