Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a sync on opening the file... #12

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*Previously maintained by [Tan Nhu](https://github.com/tnhu) at [https://github.com/tnhu/SimpleSync](https://github.com/tnhu/SimpleSync)*

# SimpleSync

Simple Sublime Text 2/3 plugin for SSH and local syncing.
Expand All @@ -9,33 +11,34 @@ Simple Sublime Text 2/3 plugin for SSH and local syncing.

## Installation

### Using ST2/3 [Package Control](https://packagecontrol.io/installation)

Search for SimpleSync in ST2/3 Package Control and install it.


### Manually

* Sublime Text 2
Clone this project into your ST2 Packages folder, for example:

``` bash
cd "/Users/tnhu/Library/Application Support/Sublime Text 2/Packages"
git clone https://github.com/tnhu/SimpleSync.git
cd ~/"Library/Application Support/Sublime Text 2/Packages"
git clone https://github.com/hydralien/SimpleSync.git
```

* Sublime Text 3

``` bash
cd "/Users/tnhu/Library/Application Support/Sublime Text 3/Packages"
git clone https://github.com/tnhu/SimpleSync.git
cd ~/"Library/Application Support/Sublime Text 3/Packages"
git clone https://github.com/hydralien/SimpleSync.git
```

### Using ST2/3 Package Control

Search for SimpleSync in ST2/3 Package Control and install it.

## Settings

When you finish installing SimpleSync, its settings can be found in Preferences > Package Settings > SimpleSync > Settings - Default.
And you should put your custom settings in Preferences > Package Settings > SimpleSync > Settings - User.

Sample settings:
Sample settings (remember to replace "username" with yours and adjust paths if needed):

``` javascript
{
Expand All @@ -44,22 +47,39 @@ Sample settings:
"host" : "tnhu-ld",
"port" : "22",
"username" : "tnhu",
"local" : "/Users/tnhu/workspace/trunk",
"remote" : "/home/tnhu/workspace/trunk"
"local" : "/Users/username/project",
"remote" : "/home/tnhu/project"
}, {
"type" : "local",
"local" : "/Users/tnhu/Library/Application Support/Sublime Text 2/Packages/SimpleSync",
"remote" : "/Users/tnhu/Dropbox/projects/SimpleSync"
"local" : "/Users/username/Library/Application Support/Sublime Text 2/Packages/SimpleSync",
"remote" : "/Users/username/Dropbox/projects/SimpleSync"
}]
}
```

Files are saved to remote server automatically when you save them locally. In case of "local" syncing, they are copied to "remote" folder which is on the same machine.

Also when you open a file, it checks its remote counterpart for if it's different (if, say, repository was updated) and asks you to refresh local copy if that's the case. You can switchi this change off by specifying "sync_on_open" : false in user config, like e.g.

``` javascript
{
"sync_on_open" : false,
"sync": [{
"type" : "ssh",
"host" : "tnhu-ld",
"port" : "22",
"username" : "tnhu",
"local" : "/Users/username/project",
"remote" : "/home/username/project"
}]
}
```

## Contributors

* [tnhu](https://github.com/tnhu)
* [gfreezy](https://github.com/gfreezy)
* [hydralien](https://github.com/hydralien/SimpleSync)

## License

Expand Down
71 changes: 65 additions & 6 deletions SimpleSync.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,28 @@
import sublime_plugin
import subprocess
import threading
import tempfile

#
# Run a process
# @param cmd process command
#
def runProcess(cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)


retcode = None
while (True):
retcode = p.poll() #returns None while subprocess is running
line = p.stdout.readline()
yield line.decode('utf-8')
print(line.decode('utf-8'), end='')

if (retcode is not None):
break

if not retcode: # result is OK if return value is 0, we're reversing it here for readbility
return True
return False

#
# Get sync item(s) for a file
# @param local_file full path of a local file
Expand Down Expand Up @@ -66,8 +72,42 @@ def run(self):

print("SimpleSync: ", self.local_file, " -> ", remote)

for line in runProcess(["scp", "-r", "-P", str(self.port) , self.local_file, remote]):
print(line, end='')
if not runProcess(["scp", "-r", "-P", str(self.port) , self.local_file, remote]):
sublime.status_message("Copying to {} on {} failed, see console for details".format(self.remote_file, self.host))
else:
sublime.status_message("Saved {} on {}!".format(self.remote_file, self.host))


class FromScpCopier():
def __init__(self, host, username, local_file, remote_file, port=22):
self.host = host
self.port = port
self.username = username
self.local_file = local_file
self.remote_file = remote_file

def start(self):
remote = self.username + "@" + self.host + ":" + self.remote_file
temp_file = tempfile.NamedTemporaryFile()

print("SimpleSync: ", remote, " -> ", self.local_file, " via temp file ", temp_file.name)

if not runProcess(["scp", "-r", "-P", str(self.port), remote, temp_file.name]):
sublime.status_message("Reading {} on {} failed (but maybe it just does not exist yet), see console for details".format(self.remote_file, self.host))
return

print("Compare ", temp_file.name, " to ", self.local_file)

no_diff = runProcess(["cmp", temp_file.name, self.local_file])

if not no_diff:
if (sublime.ok_cancel_dialog("Local file is different from remote! Replace local file?", "Yes please")):
if not runProcess(['cp', temp_file.name, self.local_file]):
sublime.status_message("Cannot update local file, check console for details")
else:
sublime.status_message("Local file updated")

temp_file.close()

#
# LocalCopier does local copying using threading to avoid UI blocking
Expand All @@ -81,13 +121,32 @@ def __init__(self, local_file, remote_file):
def run(self):
print("SimpleSync: ", self.local_file, " -> ", self.remote_file)

for line in runProcess(['cp', self.local_file, self.remote_file]):
print(line, end='')
if not runProcess(['cp', self.local_file, self.remote_file]):
sublime.status_message("Cannot copy file locally, check console for details")
else:
sublime.status_message("File saved to local mirror")

#
# Subclass sublime_plugin.EventListener
#
class SimpleSync(sublime_plugin.EventListener):
def on_load(self, view):
settings = sublime.load_settings("SimpleSync.sublime-settings")
sync_on_open = settings.get("sync_on_open", True)
if not sync_on_open:
return

local_file = view.file_name()
syncItems = getSyncItem(local_file)

if (len(syncItems) > 0):
for item in syncItems:
remote_file = local_file.replace(item["local"], item["remote"])

if (item["type"] == "ssh"):
FromScpCopier(item["host"], item["username"], local_file, remote_file, port=item["port"]).start()


def on_post_save(self, view):
local_file = view.file_name()
syncItems = getSyncItem(local_file)
Expand Down