0

I'd like to connect to a remote server using ssh and have the session running in Vi mode. I have found how to do that for bash:

ssh username@server -t 'bash -o vi'

But I need the same thing for zsh (oh-my-zsh, if that makes any difference). I can't find anywhere how to achieve this. I have tried "zsh -o vi" but that didn't work. Once I figure out the correct command I will just create a shortcut script that would ssh me to the server and set the editing mode to Vi.

Please, don't advise modifying configuration files on the server, I am one of the many users who use the server and unfortunately we use the same account, so it's important that the session is only run in Vi mode for me but not for other users. Thank you very much for any suggestions!

The content of my ~/.zshrc on the remote server (with all comments removed):

export ZSH="/root/.oh-my-zsh"
ZSH_THEME="risto"
plugins=(
  git
  ruby
  gem
  rails
)

source $ZSH/oh-my-zsh.sh

It's pretty much the standard zshrc of oh-my-zsh. I've probably only changed the default theme and added one or two plugins.

And below is the content of /root/.oh-my-zsh/oh-my-zsh.sh, if it can be helpful:

# Set ZSH_CACHE_DIR to the path where cache files should be created
# or else we will use the default cache/
if [[ -z "$ZSH_CACHE_DIR" ]]; then
  ZSH_CACHE_DIR="$ZSH/cache"
fi

# Migrate .zsh-update file to $ZSH_CACHE_DIR
if [ -f ~/.zsh-update ] && [ ! -f ${ZSH_CACHE_DIR}/.zsh-update ]; then
    mv ~/.zsh-update ${ZSH_CACHE_DIR}/.zsh-update
fi

# Check for updates on initial load...
if [ "$DISABLE_AUTO_UPDATE" != "true" ]; then
  env ZSH=$ZSH ZSH_CACHE_DIR=$ZSH_CACHE_DIR DISABLE_UPDATE_PROMPT=$DISABLE_UPDATE_PROMPT zsh -f $ZSH/tools/check_for_upgrade.sh
fi

# Initializes Oh My Zsh

# add a function path
fpath=($ZSH/functions $ZSH/completions $fpath)

# Load all stock functions (from $fpath files) called below.
autoload -U compaudit compinit

# Set ZSH_CUSTOM to the path where your custom config files
# and plugins exists, or else we will use the default custom/
if [[ -z "$ZSH_CUSTOM" ]]; then
    ZSH_CUSTOM="$ZSH/custom"
fi


is_plugin() {
  local base_dir=$1
  local name=$2
  test -f $base_dir/plugins/$name/$name.plugin.zsh \
    || test -f $base_dir/plugins/$name/_$name
}

# Add all defined plugins to fpath. This must be done
# before running compinit.
for plugin ($plugins); do
  if is_plugin $ZSH_CUSTOM $plugin; then
    fpath=($ZSH_CUSTOM/plugins/$plugin $fpath)
  elif is_plugin $ZSH $plugin; then
    fpath=($ZSH/plugins/$plugin $fpath)
  else
    echo "[oh-my-zsh] plugin '$plugin' not found"
  fi
done

# Figure out the SHORT hostname
if [[ "$OSTYPE" = darwin* ]]; then
  # macOS's $HOST changes with dhcp, etc. Use ComputerName if possible.
  SHORT_HOST=$(scutil --get ComputerName 2>/dev/null) || SHORT_HOST=${HOST/.*/}
else
  SHORT_HOST=${HOST/.*/}
fi

# Save the location of the current completion dump file.
if [ -z "$ZSH_COMPDUMP" ]; then
  ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
fi

if [[ $ZSH_DISABLE_COMPFIX != true ]]; then
  source $ZSH/lib/compfix.zsh
  # If completion insecurities exist, warn the user
  handle_completion_insecurities
  # Load only from secure directories
  compinit -i -C -d "${ZSH_COMPDUMP}"
else
  # If the user wants it, load from all found directories
  compinit -u -C -d "${ZSH_COMPDUMP}"
fi


# Load all of the config files in ~/oh-my-zsh that end in .zsh
# TIP: Add files you don't want in git to .gitignore
for config_file ($ZSH/lib/*.zsh); do
  custom_config_file="${ZSH_CUSTOM}/lib/${config_file:t}"
  [ -f "${custom_config_file}" ] && config_file=${custom_config_file}
  source $config_file
done

# Load all of the plugins that were defined in ~/.zshrc
for plugin ($plugins); do
  if [ -f $ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh ]; then
    source $ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh
  elif [ -f $ZSH/plugins/$plugin/$plugin.plugin.zsh ]; then
    source $ZSH/plugins/$plugin/$plugin.plugin.zsh
  fi
done

# Load all of your custom configurations from custom/
for config_file ($ZSH_CUSTOM/*.zsh(N)); do
  source $config_file
done
unset config_file

# Load the theme
if [[ "$ZSH_THEME" == "random" ]]; then
  if [[ "${(t)ZSH_THEME_RANDOM_CANDIDATES}" = "array" ]] && [[ "${#ZSH_THEME_RANDOM_CANDIDATES[@]}" -gt 0 ]]; then
    themes=($ZSH/themes/${^ZSH_THEME_RANDOM_CANDIDATES}.zsh-theme)
  else
    themes=($ZSH/themes/*zsh-theme)
  fi
  N=${#themes[@]}
  ((N=(RANDOM%N)+1))
  RANDOM_THEME=${themes[$N]}
  source "$RANDOM_THEME"
  echo "[oh-my-zsh] Random theme '$RANDOM_THEME' loaded..."
else
  if [ ! "$ZSH_THEME" = ""  ]; then
    if [ -f "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme" ]; then
      source "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme"
    elif [ -f "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme" ]; then
      source "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme"
    else
      source "$ZSH/themes/$ZSH_THEME.zsh-theme"
    fi
  fi
fi
2

Once inside your shell, simply run

bindkey -v

Directly from ssh:

ssh -t username@server 'VISUAL=vi zsh'
  • that's a bit different from what I need. I already know how to get into vim mode. I didn't know about bindkey -v but I can also use set -o vi to achieve the same. But how do you connect via ssh & set the session to Vi mode at the same time? I don't want to run bindkey -v every time after I connect through ssh. I want to have a script that I can just run on my local and it will connect me via ssh and set the session to Vi mode. I've just tried ssh username@server -t 'zsh; bindkey -v' but it didn't work. – Bo Yi Jun 23 '19 at 12:20
  • done; check my updated answer. – matsib.dev Jun 23 '19 at 14:10
  • I appreciate your update to the answer, but I have just tried it and unfortunately it doesn't set the session to Vi mode. – Bo Yi Jun 23 '19 at 18:13
  • ran answer's ssh command. it did set the session to vi mode here (I didn't have any .zshrc. Maybe its content by OP interferes?) – A.B Jun 23 '19 at 22:54
  • hm... you are right. I tried renaming ~/.zshrc to ~/.zshrc.bak, tried the command again and it did work. So it's zshrc of my oh-my-zsh that interferes with it then... – Bo Yi Jun 24 '19 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.