NotionSave
Sublime Text plugin to save and close notes to Notion with a durable background queue
Links
Versions
1.0.2
·
NotionSave
Adds Save to Notion to Sublime Text's editor context menu, tab context menu, File menu, and Command Palette. Saves the full buffer locally, closes the selected tab without a save prompt, and uploads it to your Notion database in a worker thread.
Targets Sublime Text 2 (build 2221+) with Python 2.6-compatible runtime code; also accommodates Sublime Text 3 and 4. Legacy editor compatibility should be verified on the specific build you use. Requires a curl executable with modern HTTPS/certificate support; there are no Python dependencies.
Install
- Download the source ZIP, or clone this repository.
- In Sublime Text, choose Preferences → Browse Packages….
- Copy the extracted repository into that folder as NotionSave.
notion_save_plugin.pymust be directly insidePackages/NotionSave/, alongsidenotion_save/. - Restart Sublime Text.
- Open the Command Palette and run Preferences: NotionSave Settings.
Alternatively, download NotionSave.sublime-package from the latest release. Developers can build it with python3 scripts/build_package.py. Put that archive in Sublime's Installed Packages directory, which is next to Packages, then restart. Install either the source folder or the archive, not both.
Connect Notion
Create an internal connection at Notion's integration settings. Enable Read content, Insert content, and Update content. Add the connection to the target database using its ••• → Connections menu.
Run Preferences: NotionSave Settings, enter your token and database URL or ID, then save:
{
"api_key": "YOUR_NOTION_API_TOKEN",
"database_id": "YOUR_DATABASE_URL_OR_ID",
"data_source_id": "",
"curl_path": "curl"
}
The settings command shows bundled defaults and your editable user settings side by side. Settings are stored in Packages/User/NotionSave.sublime-settings, outside the plugin repository. Leave the bundled settings empty. Instead of api_key, you can set NOTION_API_KEY in the environment inherited by Sublime (GUI-launched apps may not inherit shell variables).
database_id: accepts a database ID or full Notion database URL. A database with one data source is resolved automatically.data_source_id: optional, takes precedence overdatabase_id. Set it explicitly if the database has multiple data sources. The title property is discovered automatically.show_context_menu: defaults totrue. Setfalseto hide editor/tab context entries while keeping the File menu and Command Palette commands. Entries only appear for loaded editor views, not input widgets.curl_path: defaults tocurl. On macOS,/usr/bin/curlis an explicit alternative. On Windows/Linux, install a current curl if necessary and supply its absolute path.
No credentials are needed by the website or Vercel. Never commit your token.
Use
Right-click in the editor or on a tab, then choose Save to Notion. The tab closes after a durable local snapshot; there is no network wait or upload dialog. The status bar reports the result. This command saves the entire buffer, not just the selection.
A saved file uses its filename as the Notion page title. An untitled buffer uses its first nonempty line (or Untitled). Text is stored in paragraph blocks, preserving text and whitespace within the blocks. Markdown syntax stays plain text. Long lines become multiple blocks; the per-buffer limit is 5 MB. Each invocation creates a new page, rather than updating an earlier page.
The source file on disk is not changed or deleted. Unsaved edits are included in the snapshot sent to Notion. Closing a tab does not quit Sublime; uploads run while the app is open. There is a small local disk-write cost before closing, which avoids losing the note if the app or network fails.
Recovery
The queue is stored as plain-text JSON in Packages/User/Notion Save Queue. Queue entries contain the text and destination, never the API token. Successful uploads are removed. Queue files use owner-only permissions on POSIX; on Windows they inherit your user directory permissions.
- Notion: Retry Uploads retries pending and failed jobs after fixing credentials or permissions. Pending jobs retain their original destination, so changing the configured database affects new saves only. For an incorrectly selected destination, recover the text, remove the old entry while Sublime is closed, and save again.
- Notion: Recover Pending Upload lists snapshots and errors, and opens a copy of the selected text. The original queue entry is retained and may still upload.
- Notion: Open Queue Folder opens the snapshots for inspection or backup. Quit Sublime before manually editing or deleting queue entries.
Connection failures before sending, read failures, and rate limits retry with backoff (up to one hour between attempts). Retry-After is respected across the queue. Authentication/validation failures wait for Retry Uploads.
If a non-idempotent write times out, returns an ambiguous server error, or is interrupted by quitting Sublime, it is marked uncertain and is not automatically retried. Notion may have accepted the request. Check the database, recover the local copy, and only send it again if needed. A partially uploaded large note may already have a page; its ID and confirmed block offset are recorded in the queue file. Exactly-once delivery cannot be guaranteed across a remote write and a local process crash.
Pending jobs resume when Sublime restarts. An upload is not guaranteed to continue after quitting the app.
Website / Vercel
site/index.html is a single static page with embedded CSS and JavaScript, plus a local JetBrains Mono font. It follows the visual style of Adel Dev Tools. The editor preview is an illustrative demo and sends no data.
Import this repository into Vercel, keep the Root Directory at the repository root, and select Other for the framework. vercel.json publishes only site/, with no install/build command or environment variables. The Python plugin, tests, and queue are not deployed. Download links point to the public GitHub repository and release archive.
Preview locally:
python3 -m http.server 8765 --directory site
Package Control
The package name is NotionSave. Version 1.0.0 is submitted to the default channel and awaiting review; until accepted, use the manual installation above. The submission record tracks its status.
License
MIT, copyright 2026 Adel Hamad. The documentation website's bundled JetBrains Mono font uses its separate SIL Open Font License in site/FONT-LICENSE.txt; website assets are excluded from the plugin package.
Development
python3 -m unittest discover -s tests -v
python3 scripts/build_package.py
The suite uses fake Notion responses and Sublime API stubs. It covers durable snapshots, failure recovery, Unicode and request limits, destination resolution, thread behavior, rate-limit handling, secret handling, and saving/closing the correct tab. It does not replace manual testing in actual Sublime Text versions or a live Notion workspace.
Keep notion_save_plugin.py and notion_save/ compatible with Python 2.6. Development scripts and tests use Python 3.10+.
References: Sublime Text 2 API, Notion create page, Notion limits, Package Control submission.