38

My work tends to involves using SSH to connect to various machines, and then using vim to edit files on those machines. The problem is that I have to constantly copy my .vimrc file around. It's very annoying to open vim and not have any settings. Is it possible to carry my vim settings around with me from machine to machine without manually copying it everywhere?

Apreche
  • 1,425

16 Answers16

51

Instead of bringing .vimrc to each server you need to work on, why not edit the remote files from your local vim:

In vim/gvim, run:

:e scp://remoteuser@server.tld//path/to/document

or start vim like this:

vim scp://remoteuser@server.tld//path/to/document

This opens the file seamingly in place (it actually copies the file locally), and when you save, it sends the edited file back to the server for you.

It asks for an ssh password, but this can be streamlined via ssh keys.

As others have mentioned the only drawback of this method is that you don't get path/file competion as you would when working directly on the machine.

For more info, check out the following tutorial.

Tom Feiner
  • 18,598
24

I feel your pain. I have all my ~/.*rc files under version control (Subversion), has worked great since I started in 1998, using CVS. One way to do it, is to check out all your rc files like this when you stand in your home directory:

svn co svn+ssh://user@host/path/to/repo/trunk/home/user .
A    .signature
A    .vimrc
A    .bashrc
A    .screenrc
A    .psqlrc
[...]
Checked out revision 7645.

This way the config files will also be synced and updated across the various computers when you run svn update.

sunny256
  • 861
19

You could make a bash script to copy it automatically every time you log in, like this:

#!/usr/bin/env bash

scp ~/.vimrc $1:
ssh $1

You can call it ssh_vim, for instance. It's not an ideal solution but will solve your problem.

You can improve it to check first if there is already there. If you are not always running ssh from the same machine, you could change the script to get the file from scp from another machine.

EDIT1

On a related note, you could also mount the remote machine's filesystem with sshfs. That way you benefit from your environment and tools (not only .vimrc) and you have shell completion (which you don't have using scp://).

EDIT2

I just found out that you can source your .vimrc file using scp://, like this:

:source scp://you@your_computer//yourpath/.vimrc

This works from the vim command line but at the moment I don't know how to automate it. It doesn't seem to work either with the '-u' switch nor in the .vimrc nor with $VIMINIT.

EDIT3

I found it! You can do this to start vim with a .vimrc taken from your host of reference:

vim -c ':source scp://you@your_computer//yourpath/.vimrc'

Option '-c' executes the command right after launching vim.

You can create an alias in your shell of choice to avoid typing. In bash it would be like this:

alias vim="vim -c ':source scp://you@your_computer//yourpath/.vimrc'"
chmeee
  • 7,548
19

If you're using public-key authentication, you can use this in your ~/.ssh/config:

Host *
   PermitLocalCommand yes
   LocalCommand bash -c 'scp -P %p %d/.vimrc %u@%n: &>/dev/null &'

I like it better than the script trick suggested above since it doesn't mess the invocation of the ssh command (when specifying extra parameters, etc.)

4

A couple of solutions:

1) Create an NFS share for your home folder and map it in multiple locations.

2) Create a small script to push your .vimrc to the server you are connecting to with an identity/key file. It could look something like this (pseudocode):

connectString = arg0  #username@ipaddress

scp -i ~/.ssh/indentity connectString:~/ ~/.vimrc
ssh -i ~/.ssh/indentity connectString
moshen
  • 1,564
4

The exact same answer as sunny256, but use git instead of SubVersion.

Keep one main branch with the files that is common for all computers, and have one branch for each new computer.

That way you can have almost the same files on most computers, and still not become to confused.

Johan
  • 825
3

I know this is an old thread, But one way i do it is using sshfs which mounts the file system over fuse. The local vim does all of the editing, so there is no reason to copy .vimrc around.

THis does have the downside that another terminal will have to be open for any commands that need running on the remote server, But for editing i find this way the best.

It also has the added benifit of being able to use the system clipboard.

exussum
  • 539
2

I'm using https://github.com/andsens/homeshick to manage my dotfiles, and storing them on github.

Homeshick is written in 100% bash, and helps you manage "castles" which are just git repos that contain a /home/ directory. It has commands to move existing dot files into the repo and replace them with symlinks. And to symlink all the files in the repo in to your home directory on a new machine.

So the general idea is keep your dotfiles in a version control system, and symlink to them from the real path. This way your repo doesn't need to start from your home dir and contain a ton of files you don't ever want to add.

1

I use a makefile that has a list of all the servers that I log on to and when I make a change on my local machine, 'make' is run using the makefile automatically which updates all the servers with any changes or any plugins

1

If you are like me and have many development machines (Virtual Machines as well) for various reasons you can combine ssh keys, a smart bash_profile, and an RCS of your choice.

I would second using nfs/samaba/sshfs. One draw back is if you don't have network access all the time then you can't access what you need (flying, no wifi, firewalls, routing issues, etc). The machines that I keep in sync are not all reachable at the same time but I want to share information between them.

The following is how I went about it borrowing many ideas from the Internet.

.bash_profile could have something like this

$HOME/bin/shell_ssh_agent

I got this from a couple of places but can't find a link to it now. The shell_ssh_agent file:

#!/bin/bash

SSH_ENV=$HOME/.ssh/environment

#echo "starting"

function start_agent {
    #echo "reaping agents"
    killall ssh-agent
    #echo "Initialising new SSH agent..."
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
    #echo succeeded
    chmod 600 ${SSH_ENV}
    . ${SSH_ENV}
    /usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
    . ${SSH_ENV}
    #echo "sourced ssh env"
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent > /dev/null || { start_agent; }
else
    start_agent;
fi

Now on first login you set up your keys. Log out and in and it just made life easier.

Put all your scripts in an RCS, this makes keeping development machines in sync easier. I use git. Authentication with git is via ssh so ssh keys help here too. Note at this point you could have used something like nfs. I would still be a fan of an RCS for a reason which I mention below.

The use case is

  1. login first time, keys get setup
  2. if RCS isn't set up check out your personal scripts (and update/merge when needed, this could even be part of your .bash_profile if you wanted it)
  3. edit vimrc, special scripts, etc and commit them
  4. when logged into other machines do an update/merge/checkout. This keeps everything in sync; ie no more copying files which sometimes you stomp over and you didn't want to.
  5. as a side benefit you get the power of an RCS. I sometimes make unfavorable changes to scripts or configs and need to roll back and the like.

Something I want to try next is wrap the initial login/setup in a makefile that I copy to the new machine. The makefile can then do the job of setting up your keys, RCS, etc. Obviously there is some overhead here but if you end up setting up a lot of machines this is:

  1. a time saver
  2. easier to keep the configurations and personal scripts of development machines in sync
  3. management of changes to scripts and configs.
rev
  • 113
1

sshrc solves this problem. You put your .vimrc in ~/.sshrc.d/ and then add export VIMINIT="let \$MYVIMRC='$SSHHOME/.sshrc.d/.vimrc' | source \$MYVIMRC" to `/.sshrc.

1

I wrote a simple tool for this that will allow you to natively transport your .vimrc file whenever you ssh, by using SSHd built-in config options in a non-standard way.

No additional svn,scp,copy/paste, etc required.

It is simple, lightweight, and works by default on all server configurations I have tested so far.

https://github.com/gWOLF3/viSSHous

Glenn W
  • 11
0

Using variable VIMINIT:

export VIMINIT='set number'

and forwarding it to remote server:

ssh remoteuser@remoteserver -o SendEnv=LC_VIMINIT -t 'export VIMINIT=$LC_VIMINIT && bash'

is easy using .bash_profiles or .bashrc

export VIMINIT='
set number
'

export LC_VIMINIT=$VIMINIT

sshh (){
ssh -o SendEnv=LC_VIMINIT $1 -t 'export VIMINIT=$LC_VIMINIT && bash'

Now try run vim on remote server using sshh for connection:

sshh remoteuser@remoteserver

If You want to You can take your plugins to remote server as well:

export LC_VIMINIT="
set number
set nocompatible
filetype off
set rtp+=~/.[USER]_vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'


set shell=/bin/bash
call vundle#end()
filetype plugin indent on
"

export VIMINIT=$LC_VIMINIT

sshh (){
        if [[ $1 ]]; then
                ssh-copy-id $1 &>/dev/null &&
                rsync -lzr --partial --del ~/.[USER]_vim ${1}: &&
                ssh -o SendEnv=LC_VIMINIT $1 -t 'export VIMINIT=$LC_VIMINIT && bash';
        else
                echo "Provide remote user@host";
        fi
}
Apoc
  • 1
0

I have the same situation, but it isn't just ".vimrc". I also have things like

  • bash configuration, prompting and functions,
  • ssh configuration and authorization files,
  • shell scripts I like to have handy.
  • of course my vimrc, but also some vim functions and syntax highlighting files.

My solution (started 30 years ago with "dist" originally!) is to set up a nightly cron to rsync a minimal home configuration to all the machines I work on, so that it updates nightly.

That way all the other machines I work with are kept up to date! I can just add a new machine to the 'accounts' list and do a single machine distribution to start it off.

Does not need to be much, and you can start small and make it more complex as you go. As you can imagine after 30 years my distribution is now rather complex, so I won't put it here. Needless to say it also does things like swap out some configuration for others for some networks, home cleanup (EG: trash, cache files), ensure home permissions are all correct, and so on.

NOTE I only allow password-less ssh login from one 'home' machine to all the rest, never back again! Any cross ssh is password protected.

anthony
  • 325
-1

You might consider an EXPECT script that allows you to set your path and environment (like EXRC variables) upon pressing a certain keystroke. Shouldn't be too long before someone posts a similar script.

When your server farms number more than a few dozen (think thousands) then having something easily setup your enviroment on a 'virgin' box is a real lifesaver

Often when I login to a box, it creates my homedir for the first time!

ericslaw
  • 1,592
-1

It was realized with the following bash oneliner. Because it is done with Process Substitution, temporary files are not created.

ssh -t user@host '
bash --rcfile <(
    echo -e ' $(cat <(echo "function lvim() { vim -u <(echo "$(cat ~/.vimrc|base64)"|base64 -d) \$@ ; }") \
                    ~/dotfiles/{.bashrc,sh_function,sh_alias,bash_prompt} \
                    <(echo -e alias vim=lvim) | \
                    base64 
               ) ' \
    |base64 -d)'

https://gist.github.com/blacknon/a47083f3bbbd0374998bdf7e3b3396cc