Coder Social home page Coder Social logo

mirror.vim's Introduction

mirror.vim GitHub release GitHub issues

Live demo

asciicast

Introduction

If some of your projects have multiple environments (e.g. development, staging, production - with nearly the same directory and files structure), then there is a situations when you need to connect to one of this environments via ssh and remotely edit project-related files. Usually you will do something like this:

ssh user@host
cd path/to/you/project
vim /some/file
and so on...

This plugin was created to simplify this process by maintaining special configuration file and adding different commands for quickly doing remote actions for each environment of project you working with. This remote actions use netrw under the hood. You don't need to install netrw - it's part of vim distribution and it used as default file explorer (e.g. :edit .). To get more information about editing remote files with netrw - refer to :h netrw-start.

Requirements

  • Vim with netrw support (any version greater than 7.0).
  • Unix-based system with scp and ssh client installed.

Installation

Use your favourite plugin manager: Pathogen, Vundle, NeoBundle or VimPlug. Add zenbro/mirror.vim to the list of plugins, source that and issue your manager's install command.

Add this lines to .vimrc (probably they already there):

set nocompatible    " disable backward compatibility with Vi
filetype plugin on  " plugins are enabled

Usage

Let's assume that you have a project /home/user/work/my_project. This project have multiple environments - development, staging and production. Development - is your current local environment. Staging and production - remote environments, each placed on their own remote server. Project structure on each environments is nearly similar (from here comes the name of this plugin). If you want to get access to multiple environment-related remote actions, you need to add information about this project to configuration file. Run this command :MirrorConfig and edit configuration file.

For our example it should look like this:

/home/user/work/my_project:
  staging: my_project@staging_host/current
  production: my_project@production_host/current

See Configuration for more details about format and structure of this file.

From now, if you open any file inside /home/user/work/my_project then multiple remote commands should be available. For example, if you want to edit some file on remote server in staging environment (my_project@staging_host), then open this file locally and run :MirrorEdit staging. You should be able to edit this remote file here, locally, with your own vim settings. If you want to see difference between file, you currently edit and version of this file on production server - use this command: :MirrorDiff production.

There are many other remote actions available.

Configuration

Default path of configuration file is ~/.mirrors. Use g:mirror#config_path if you want to change location of configuration file. To open configuration file use :MirrorConfig command. Use q to close it.

Configuration file use simplified YAML format and doesn't support things like &links, arrays, inline objects.

Example of mirrors config:

/home/user/work/project1:
  staging: project1@staging_host/current
  production: project1@production_host/current
/home/user/work/project2:
  staging: project2@another_host:23//opt/project2
/home/user/work/projects/*:
  devel: project2@some_host//some/workplace/*/src/*
  • /home/user/work/project1, /home/user/work/project2 - names of working directories for each project. See also Project discovery. /home/user/work/projects/ - match all projects in "projects" directory.

  • staging, production - names of environments for each projects. You can use whatever name you want when adding environments.

  • project1@staging_host/current - remote path for environment "staging" of project "project1". Path "current" is related to home directory of user "project1" on host "staging_host". It should be available by doing these commands:

ssh project1@staging_host
cd current
  • project2@another_host:23//opt/project2 - remote path for environment "staging" of project "project2". Path "/opt/project2" is related to system root directory on host "another_host". It should be available by doing these commands:
ssh -p 23 project2@another_host
cd /opt/project2

Third example a little bit complex. Lets assume that the "projects" directory contains the following directories: "ProjectA", "ProjectB", "ProjectC". Then the following project path and remote path

  /home/user/work/projects/*:
    devel: project2@some_host//some/workplace/*/src/*

would be expanded like this

  /home/user/work/projects/ProjectA:
    devel: project2@some_host//some/workplace/ProjectA/src/ProjectA
  /home/user/work/projects/ProjectB:
    devel: project2@some_host//some/workplace/ProjectB/src/ProjectB
  /home/user/work/projects/ProjectC:
    devel: project2@some_host//some/workplace/ProjectC/src/ProjectC

If you open any file inside your projects directories, then you should be able to do environment-specific remote actions.

Commands

Global

This command is available everywhere.

  • :MirrorConfig - open configuration file in split. Use q to close it.
    Configuration file path can be changed by g:mirror#config_path.

  • :MirrorConfigReload - if configuration file has been changed from the outside, it can be reloaded manually via this command.

Local

Local commands are only available when you open a file inside one of the projects from configuration.

Project discovery

When you open a file and absolute path of this file containing one of the path from configuration then project discovery succeeded and local commands will be available for current buffer.

In summary, project discovery will be done after following actions:

  • BufNewFile
  • BufReadPost
  • BufWritePost g:mirror#config_path (saving configuration file)

Project discovery can be manually triggered via :MirrorConfigReload.

Default environment

When your project have only one environment, then it will be used automatically for all local commands as default - you don't need to pass it as argument. When your project have multiply environments - you need to pass it explicitly.

To change default environment for current project use one of the following commands.

  • :MirrorEnvironment - show default environment for current project.
  • :MirrorEnvironment <environment> - set default <environment> for current session.
  • :MirrorEnvironment! <environment> - set default <environment> globally.
    Path, where default environments is saved can be changed by g:mirror#cache_dir.

Remote actions

Local file - file you are currently editing.
Remote file - version of local file on remote server.

  • :MirrorEdit <environment> - open remote version of a local file.
    • :MirrorSEdit <environment> - open remote version of a local file in horizontal split.
    • :MirrorVEdit <environment> - open remote version of a local file in vertical split.
  • :MirrorDiff <environment> - open vertical split with difference between remote and local file. Use :diffoff to exit diff mode. Use g:mirror#diff_layout to change default split layout for this command.
    • :MirrorSDiff <environment> - open horizontal split with difference between remote and local file.
    • :MirrorVEdit <environment> - open vertical split with difference between remote and local file.
  • :MirrorPush <environment> - overwrite remote file by local file. If you are using neovim, the command will be executed asynchronously, otherwise synchronously.
  • :MirrorPull <environment> - overwrite local file by remote file. If you are using neovim, the command will be executed asynchronously, otherwise synchronously.
  • :MirrorOpen <environment> - open remote project directory in file explorer (netrw).
  • :MirrorRoot <environment> - open remote system root directory in file explorer.
  • :MirrorParentDir <environment> - open remote parent directory of local file.
  • :MirrorSSH <environment> - establish ssh connection with selected <environment> and jump to the remote project directory. Use g:mirror#ssh_auto_cd to change default behaviour. See also g:mirror#ssh_shell. If you are using neovim, the command will be executed in a new terminal buffer.
  • :MirrorInfo <environment> - get information about remote file.

Variables

This is all available options with their defaults:

let g:mirror#config_path = expand('~/.mirrors')
let g:mirror#open_with = 'Explore'
let g:mirror#diff_layout = 'vsplit'
let g:mirror#ssh_auto_cd = 1
let g:mirror#ssh_shell = '$SHELL --login'
let g:mirror#cache_dir = expand('~/.cache/mirror.vim')
let g:netrw_silent = 1
let g:mirror#spawn_command = '! '
  • g:mirror#config_path - location of configuration file. If you have unusual home path - use expand(), for example: let g:mirror#config_path = expand('~/.mirrors')
  • g:mirror#open_with - file explorer command that used in :MirrorOpen, :MirrorRoot, :MirrorParentDir. If you want to open file explorer in horizontal split - you can use 'Sexplore'. See also :h netrw-explore.
  • g:mirror#diff_layout - split layout for :MirrorDiff command.
  • g:mirror#ssh_auto_cd - auto jump to the remote project directory after establishing an SSH connection with :MirrorSSH.
  • g:mirror#ssh_shell - command for starting shell (e.g. bash, zsh) after ssh connection and changing directory. Used only if g:mirror#ssh_auto_cd enabled. By default, shell will be invoked as "login shell" and all scripts such as /etc/profile and ~/.profile will be loaded. It's necessary for tools like RVM (Ruby Version Manager).
  • g:mirror#cache_dir - directory where cache is stored. Currently used for saving default environments, that set via :MirrorEnvironment! <environment>.
  • g:netrw_silent - this variable is related to netrw configuration.
    Possible values:
    • 0 - transfers done normally (you should see what's going on under the hood when using :MirrorEdit or :MirrorDiff commands)
    • 1 - transfers done silently
      Silent mode will be used by default.
  • g:mirror#spawn_command - vim command in this variable is used for executing scp when copying files. In original vim copying files to remote server will have blocking behavior, in neovim - async. If you want to use dispatch.vim - add this to your .vimrc: let g:mirror#spawn_command = ':Start '

FAQ

Q. Why should I always enter password when executing one of the remote actions?

A. Use SSH config or passwordless authentication with SSH-keys.

Q. What if my development environment is also on a remote server?

A. You can mount any directory from remote server via sshfs.

License

mirror.vim is released under the MIT License.

mirror.vim's People

Contributors

freyskeyd avatar idanarye avatar leigh-ols avatar zenbro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

mirror.vim's Issues

Add support for using tpope/vim-dispatch for running scp commands

Hi,

I'm loving this plugin but I do find the messages from scp annoying and distracting. I could really incorporate it into my workflow if it was less obtrusive. For that reason I would like to request support for running the scp commands with Dispatch! from tpope/vim-dispatch rather than using !. Like here.

I would love to just wrap your commands like MirrorPush in Dispatch but unfortunately it only works for external commands, not vim commands.

Cheers,
Jacob

Add :MirrorConfigReload command

Hello! It's me again to bother you.

I've written myself a small function that runs when I open project files that checks whether the project is already in the mirrors.yml file with readfile() and match() and if not it appends a rudimentary config for that particular project using writefile().

The issue is, your plugin does not recognize the fact that a new project has been added to my mirrors.yml and i have to restart vim in order for this to take effect.

Don't know how hard adding a :MirrorConfigReload command would be to implement but I think it's an essential feature.

YO!

The g:mirror#config_path setting does not accept '~', requires absolute path

I just started playing with mirror.vim and I really like it but I wasted like 10 minutes trying to figure out why my configuration was not being loaded. And that was because my config looked like this:

let g:mirror#config_file = '~/.config/nvim/mirrors.yml'

Only after I changed that to an absolute path it started to work. Just a small nitpick that might annoy new users.

Unable to see remote actions even after adding config file

I have installed the plugin on my Mac using Vundle. I have followed the installation instructions and also added the config file. When I run the ':MirrorConfigReload' nothing seems to happen
Also I dont remote action commands activated. Not sure what am I missing.

Add a "wildcard" like syntax to mirrors config

This is and idea I had in relation to the issue I just opened: #7

I was wondering if mirror.vim config could have a wildcard-like syntax which would match all projects in a directory. For example:

/home/user/projects/*:
    devel: username@some_host.local//some/workplace/*/src/*

Which effectively works for any project in that directory, for example /home/user/projects/ProjectA and works as if this existed in the config:

/home/user/projects/ProjectA:
    devel: username@some_host.loca//some/workplace/ProjectA/src/ProjectA

That would be pretty cool but I expect it to be hard to implement so this is probably a pretty big feature request.

Using mirror.vim to save both locally and in staging at the same time.

So my plan is to essentially live edit my local and staging branch at the same time. At this time, I will also be keeping a gulpfile with browser to load my site when changes are made and in this way I can live the staging site locally.

Therefore, my question is, how can I use mirror.vim to save both locally and in staging?

Automatically read git-config?

Hey there,

nice Plugin you got here!
I've been wondering: Is it possible to read the remote targets from the git-directory?
So this way we wouldn't have to configure it twice.

Kind regards.

Neovim Error

Hello I get this error on Neovim when using MirrorPush

I don't know why, I tired to update and reinstall but nothing change..

Erreur détectée en traitant function <SNR>6_JobHandler :
ligne   24 :
E121: Undefined variable: self
E15: Expression invalide : self.type . ' failed'
ligne   25 :
E121: Undefined variable: self
E116: Arguments invalides pour la fonction has_key(self, 'stderr')
E15: Expression invalide : has_key(self, 'stderr')
ligne   28 :
E121: Undefined variable: message
E15: Expression invalide : message%

Is it possible to always push?

Hi! Thanks for writing this!!

I'm in a slightly different pickle, in that I need to be able to edit files locally but execute them remotely over and over again. Mostly I just use vi/vim on remote VM, but it'd be nice to be able to have it always push on save of a file. Possible? Easy?

Jump to directory when using :MirrorSSH

Great plugin! Would it be possible to have :MirrorSSH automatically jump to the directory as specified in the config?

For example, if config looks like this:

/home/user/work/project2:
  staging: project2@another_host:23//opt/project2

:MirrorSSH could do something like this:

ssh -p 23 -t project2@another_host "cd /opt/project2 && $SHELL"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.