├── .gitignore
├── MIT-License
├── Main.sublime-commands
├── Main.sublime-menu
├── README.md
├── auto_save.py
├── auto_save.sublime-settings
├── demo.gif
├── messages.json
├── messages
├── 1.0.1.txt
├── 1.0.2.txt
├── 1.0.3.txt
├── 1.0.4.txt
├── 1.0.5.txt
├── 1.0.6.txt
├── 1.0.7.txt
├── 1.0.8.txt
└── install.txt
└── repository.json
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/MIT-License:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 James Zhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/Main.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | { "caption": "Toggle AutoSave: all files", "command": "auto_save" },
3 | { "caption": "Toggle AutoSave: current file only", "command": "auto_save", "args": {"all_files": false} },
4 | { "caption": "Toggle AutoSave Backup: current file only", "command": "auto_save", "args": {"all_files": false, "backup": true} }
5 | ]
6 |
--------------------------------------------------------------------------------
/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "preferences",
4 | "children":
5 | [
6 | {
7 | "caption": "Package Settings",
8 | "mnemonic": "P",
9 | "id": "package-settings",
10 | "children":
11 | [
12 | {
13 | "caption": "Auto-save",
14 | "children":
15 | [
16 | {
17 | "command": "open_file",
18 | "args": {"file": "${packages}/auto-save/README.md"},
19 | "caption": "README"
20 | },
21 | { "caption": "-" },
22 | {
23 | "command": "open_file",
24 | "args": {"file": "${packages}/auto-save/auto_save.sublime-settings"},
25 | "caption": "Settings – Default"
26 | },
27 | {
28 | "command": "open_file",
29 | "args": {"file": "${packages}/User/auto_save.sublime-settings"},
30 | "caption": "Settings – User"
31 | },
32 | { "caption": "-" },
33 | {
34 | "command": "open_file",
35 | "args": {"file": "${packages}/auto-save/Default (${platform}).sublime-keymap"},
36 | "caption": "Key Bindings – Default"
37 | },
38 | {
39 | "command": "open_file",
40 | "args": {"file": "${packages}/User/Default (${platform}).sublime-keymap"},
41 | "caption": "Key Bindings – User"
42 | }
43 | ]
44 | }
45 | ]
46 | }
47 | ]
48 | }
49 | ]
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | auto-save
2 | ===============
3 | A [Sublime Text](http://www.sublimetext.com/) plugin that **automatically saves the current file after every modification**.
4 |
5 | - [Synopsis](#synopsis)
6 | - [Demo](#demo)
7 | - [Installation](#installation)
8 | - [Usage](#usage)
9 | - [License](#license)
10 | - [Author](#author)
11 |
12 | Synopsis
13 | -------
14 | In the occasion where you'd want Sublime Text to save the current file after
15 | each change, you can use this plugin.
16 |
17 | Demo
18 | -------
19 | 
20 |
21 | Installation
22 | -------
23 | #### From Package Control
24 | auto-save is available through [Sublime Package Control](https://sublime.wbond.net/packages/auto-save)
25 | and is the recommended way to install.
26 |
27 | #### From Github
28 | Alternatively, you may install via GitHub by cloning this repository into the `Packages`
29 | directory under Sublime Text's data directory:
30 |
31 | On Mac:
32 |
33 | ```
34 | cd ~/Library/Application Support/Sublime Text 3/Packages
35 | git clone https://github.com/jamesfzhang/auto-save.git
36 | ```
37 |
38 | Usage
39 | -------
40 | **By default, auto-save is disabled** because it is a fairly invasive plugin. To make it less invasive, you can instruct it to only auto-save changes to the file that is active when you turn on auto-save. In this mode, it will ignore changes to all other files.
41 |
42 | To run auto-save whenever a file is modified, set `"auto_save_on_modified": true` in your user settings. To ignore certain files, set `auto_save_ignore_files` to a list of file suffices like `[".yml", "package.json"]`.
43 |
44 | You can also instruct it to auto-backup the file instead of auto-saving it. The backup gets created in the same directory as its source file. The backup file takes the same name as its source file, with the string `.autosave` inserted directly before the file extension. When auto-save is disabled, the backup file is deleted.
45 |
46 | There are two ways to enable it. You can press Command + Shift + P to bring up the Command Palette, and search for **AutoSave**. Here, there are 3 options:
47 |
48 | - Toggle AutoSave: all files
49 | - Toggle AutoSave: current file only
50 | - Toggle AutoSave Backup: current file only
51 |
52 | Alternatively, you can bind commands to turn the plugin on or off. For example, to toggle auto-save for all files, open "Preferences / Key Bindings - User" and add:
53 |
54 | ```js
55 | { "keys": ["ctrl+shift+s"], "command": "auto_save" }
56 | ```
57 |
58 | To toggle it for only the current file, and instruct to make a backup of the file instead of saving the file itself, you could add:
59 |
60 | ```js
61 | { "keys": ["ctrl+shift+s"], "command": "auto_save", "args": {"all_files": false, "backup": true} }
62 | ```
63 |
64 | This key bindings file takes an array of key bindings so please ensure that this key binding, along with any existing ones, are properly wrapped in `[]`.
65 |
66 | With this setting, pressing Ctrl + Shift + S will turn the plugin
67 | on or off. A status message will be displayed in the Sublime Status Bar each
68 | time the plugin is turned on or off.
69 |
70 | By default, auto-save debounces "save" events by 1 second. For fast typers, this improves
71 | performance dramatically such that "save" events are not called constantly, just when it matters.
72 |
73 | License
74 | -------
75 | [MIT-License](https://raw.github.com/jamesfzhang/auto-save/master/MIT-License).
76 |
77 | Author
78 | -------
79 | auto-save was created and maintained by James Zhang. Give him a shoutout at [@jamesfzhang](https://twitter.com/jamesfzhang)
80 | if you have comments or questions.
81 |
--------------------------------------------------------------------------------
/auto_save.py:
--------------------------------------------------------------------------------
1 | '''
2 | AutoSave - Sublime Text Plugin
3 |
4 | Provides a convenient way to turn on and turn off
5 | automatically saving the current file after every modification.
6 | '''
7 |
8 | import os
9 | import sublime
10 | import sublime_plugin
11 | from threading import Timer
12 |
13 |
14 | settings_filename = "auto_save.sublime-settings"
15 |
16 | on_modified_field = "auto_save_on_modified"
17 | delay_field = "auto_save_delay_in_seconds"
18 | all_files_field = "auto_save_all_files"
19 | current_file_field = "auto_save_current_file"
20 | ignore_files_field = "auto_save_ignore_files"
21 | backup_field = "auto_save_backup"
22 | backup_suffix_field = "auto_save_backup_suffix"
23 |
24 |
25 | class AutoSaveListener(sublime_plugin.EventListener):
26 |
27 | save_queue = [] # Save queue for on_modified events.
28 |
29 | @staticmethod
30 | def generate_backup_filename(filename, backup_suffix):
31 | dirname, basename = [os.path.dirname(filename),
32 | os.path.basename(filename).split('.')]
33 | if len(basename) > 1:
34 | basename.insert(-1, backup_suffix)
35 | else:
36 | basename.append(backup_suffix)
37 | return dirname + '/' + '.'.join(basename)
38 |
39 |
40 | def on_modified(self, view):
41 | settings = sublime.load_settings(settings_filename)
42 | filename = view.file_name()
43 |
44 | if view.is_auto_complete_visible():
45 | return
46 |
47 | if not (settings.get(on_modified_field) and filename and view.is_dirty()):
48 | return
49 |
50 | for path in settings.get(ignore_files_field):
51 | if filename.endswith(path):
52 | return
53 |
54 | if not settings.get(all_files_field) and settings.get(current_file_field) != filename:
55 | return
56 |
57 |
58 | def callback():
59 | '''
60 | Must use this callback for ST2 compatibility
61 | '''
62 | if view.is_dirty() and not view.is_loading() and not view.is_auto_complete_visible():
63 | if not settings.get(backup_field): # Save file
64 | view.run_command("save")
65 | else: # Save backup file
66 | content = view.substr(sublime.Region(0, view.size()))
67 | try:
68 | with open(AutoSaveListener.generate_backup_filename(
69 | view.file_name(), settings.get(backup_suffix_field)), 'w', encoding='utf-8') as f:
70 | f.write(content)
71 | except Exception as e:
72 | sublime.status_message(e)
73 | raise e
74 |
75 |
76 | def debounce_save():
77 | '''
78 | If the queue is longer than 1, pop the last item off,
79 | Otherwise save and reset the queue.
80 | '''
81 | if len(AutoSaveListener.save_queue) > 1:
82 | AutoSaveListener.save_queue.pop()
83 | else:
84 | sublime.set_timeout(callback, 0)
85 | AutoSaveListener.save_queue = []
86 |
87 |
88 | AutoSaveListener.save_queue.append(0) # Append to queue for every on_modified event.
89 | Timer(settings.get(delay_field), debounce_save).start() # Debounce save by the specified delay.
90 |
91 |
92 |
93 |
94 | class AutoSaveCommand(sublime_plugin.ApplicationCommand):
95 |
96 | def run(self, **kwargs):
97 | '''
98 | Toggle auto-save on and off. Can be bound to a keystroke, e.g. ctrl+alt+s.
99 | If enable argument is given, auto save will be enabled (if True) or disabled (if False).
100 | If enable is not provided, auto save will be toggled (on if currently off and vice versa).
101 | '''
102 | enable = kwargs.get('enable', None)
103 | all_files = kwargs.get('all_files', True)
104 | backup = kwargs.get('backup', False)
105 |
106 | settings = sublime.load_settings(settings_filename)
107 | if enable is None: # toggle
108 | enable = not settings.get(on_modified_field)
109 |
110 | if not enable:
111 | message = "AutoSave Turned Off"
112 | filename = settings.get(current_file_field)
113 | if settings.get(backup_field) and filename: # Delete backup file
114 | try:
115 | os.remove(AutoSaveListener.generate_backup_filename(
116 | filename, settings.get(backup_suffix_field)))
117 | except:
118 | pass
119 |
120 | settings.set(on_modified_field, enable)
121 | settings.set(all_files_field, all_files)
122 | filename = sublime.Window.active_view(sublime.active_window()).file_name()
123 | settings.set(current_file_field, filename)
124 | settings.set(backup_field, backup)
125 |
126 | if enable:
127 | message = "AutoSave %sTurned On" % ("Backup " if backup else "")
128 | if not all_files:
129 | message += " for: " + os.path.basename(filename)
130 | sublime.status_message(message)
131 |
--------------------------------------------------------------------------------
/auto_save.sublime-settings:
--------------------------------------------------------------------------------
1 | // AutoSave's default settings.
2 |
3 | {
4 | "auto_save_on_modified": false,
5 | "auto_save_delay_in_seconds": 1,
6 | "auto_save_all_files": true,
7 | "auto_save_current_file": "",
8 | "auto_save_ignore_files": [],
9 | "auto_save_backup": false,
10 | "auto_save_backup_suffix": "autosave"
11 | }
12 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamesfzhang/auto-save/c1b0651d116561bef6a3462bb9d5b01041eff84b/demo.gif
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "install": "messages/install.txt",
3 | "1.0.1": "messages/1.0.1.txt",
4 | "1.0.2": "messages/1.0.2.txt",
5 | "1.0.3": "messages/1.0.3.txt",
6 | "1.0.4": "messages/1.0.4.txt",
7 | "1.0.5": "messages/1.0.5.txt",
8 | "1.0.6": "messages/1.0.6.txt",
9 | "1.0.7": "messages/1.0.7.txt",
10 | "1.0.8": "messages/1.0.8.txt"
11 | }
12 |
--------------------------------------------------------------------------------
/messages/1.0.1.txt:
--------------------------------------------------------------------------------
1 | Fixes:
2 |
3 | * Don't try to save files that don't exist yet. Thanks to https://github.com/jisaacks
4 |
5 |
--------------------------------------------------------------------------------
/messages/1.0.2.txt:
--------------------------------------------------------------------------------
1 | Improvements:
2 |
3 | * Debounce save to improve performance dramatically.
4 | - New setting called "auto_save_delay_in_seconds", which defaults to 1.
5 | - The higher this number, the longer "save" is debounced.
6 | - Anywhere between 1-3 seconds is reasonable.
7 | - Set to 0 to avoid debouncing all together (not recommended).
8 |
--------------------------------------------------------------------------------
/messages/1.0.3.txt:
--------------------------------------------------------------------------------
1 | Fixes:
2 |
3 | * Fixed bug where turning on/off resulted in plugin breaking.
4 | * Thanks for reporting the issue, https://github.com/fertingoff
5 |
--------------------------------------------------------------------------------
/messages/1.0.4.txt:
--------------------------------------------------------------------------------
1 | Fixes:
2 |
3 | * Fixed bug where plugin was broken for ST2.
4 | * Thanks for reporting the issue and fixing it https://github.com/mateuszjarzewski
5 |
--------------------------------------------------------------------------------
/messages/1.0.5.txt:
--------------------------------------------------------------------------------
1 | Fixes:
2 |
3 | * Fixed bug when file is reloaded from disk (thanks https://github.com/scholer)
4 |
--------------------------------------------------------------------------------
/messages/1.0.6.txt:
--------------------------------------------------------------------------------
1 | Improvements:
2 |
3 | * Add explicit enable/disable flag in addition to toggle (thanks https://github.com/scholer)
4 | * Add preferences menu
5 | * Performance optimizations
6 |
--------------------------------------------------------------------------------
/messages/1.0.7.txt:
--------------------------------------------------------------------------------
1 | Improvements:
2 |
3 | * Add option for enabling this plugin for only current file
4 | * Add option for enabling "auto backup"
5 |
6 | See [this pull request](https://github.com/jamesfzhang/auto-save/pull/26) for more information. Thanks [kylebebak](https://github.com/kylebebak)!
7 |
--------------------------------------------------------------------------------
/messages/1.0.8.txt:
--------------------------------------------------------------------------------
1 | Improvements:
2 |
3 | * Add option for ignoring files
4 | * Don't save when auto-complete menu is open--otherwise, the menu closes unexpectedly
5 |
--------------------------------------------------------------------------------
/messages/install.txt:
--------------------------------------------------------------------------------
1 | Thank you for installing AutoSave
2 | ----------------------------------------
3 |
4 | You're one step closer to having your files save automatically after every modification!
5 |
6 |
7 | Documentation
8 | =============
9 | The plugin is dead simple. When turned on, the current file you are viewing will
10 | save automatically as you modify it. In other words, the file saves after every keystroke.
11 | The plugin is turned off by default since it is so invasive. You may enable it by adding
12 | a key binding to the "auto_save" command in "Preferences / Key Bindings - User", for example:
13 |
14 | { "keys": ["ctrl+shift+s"], "command": "auto_save" }
15 |
16 | See links below for more help.
17 |
18 | Useful Links
19 | ============
20 | * Documentation & Code: https://github.com/jamesfzhang/auto-save
21 | * Report issues: https://github.com/jamesfzhang/auto-save/issues
22 | * Follow me on Twitter: @jamesfzhang
23 |
--------------------------------------------------------------------------------
/repository.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema_version": "2.0",
3 | "packages": [
4 | {
5 | "details": "https://github.com/jamesfzhang/auto-save",
6 | "releases": [
7 | {
8 | "sublime_text": "*",
9 | "details": "https://github.com/jamesfzhang/auto-save/tags"
10 | }
11 | ]
12 | }
13 | ]
14 | }
--------------------------------------------------------------------------------