10 Commits
Author SHA1 Message Date
bdeshi 92c7a27dc2 1.0.0 2026-08-02 02:42:09 +06:00
bdeshi 0983970abf leave onChange alone if another plugin patched it after us 2026-08-02 01:50:20 +06:00
bdeshi 14cfe46c26 skip layout-ready setup if already unloaded 2026-08-02 00:36:38 +06:00
bdeshi 697966deff cancel the pending enforce on unload 2026-08-01 21:37:45 +06:00
bdeshi 4de8def0bb use obsidian's builtin debounce 2026-08-01 20:27:10 +06:00
bdeshi 5f564b5f18 rename to obsidian-ribbon-clasp 2026-08-01 18:25:44 +06:00
bdeshi c3c1a98574 add a doc for release process refresher 2026-07-27 17:11:27 +06:00
bdeshi ef35f26937 release a zip and skip versions.json 2026-07-27 16:32:10 +06:00
bdeshi eb3e462603 create tags from release 2026-07-27 16:04:33 +06:00
bdeshi 3190d176f2 add release workflow 2026-07-27 15:24:01 +06:00
7 changed files with 80 additions and 24 deletions
+12
View File
@@ -0,0 +1,12 @@
## Releasing new releases
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
- Create new GitHub release using your new version number as the "Tag version".
Use the exact version number, don't include a prefix `v`.
See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments.
Note: The `manifest.json` file must be in two places, first the root path of your repository and also in the release.
- Publish the release.
From <https://github.com/obsidianmd/obsidian-sample-plugin/blob/master/README.md#releasing-new-releases>
+14
View File
@@ -0,0 +1,14 @@
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
syntax-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: node --check main.js
+25
View File
@@ -0,0 +1,25 @@
name: Release
on:
release:
types: [published]
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
env:
REPO_NAME: ${{ github.event.repository.name}}
steps:
- uses: actions/checkout@v4
- name: Create zip archive
run: |
zip -j "${REPO_NAME}.zip" main.js manifest.json
- name: Upload release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | #shell
gh release upload "${{ github.event.release.tag_name }}" \
main.js manifest.json "${REPO_NAME}.zip"
+6 -4
View File
@@ -1,6 +1,6 @@
# Ribbon Order Lock # Obsidian Ribbon Clasp
Obsidian plugin that stops the left ribbon icons from reshuffling themselves. An [Obsidian][^1] plugin that stops the left ribbon icons from reshuffling themselves.
The plugin should work completely transparently, but it relies on undocumented The plugin should work completely transparently, but it relies on undocumented
internals within Obsidian's `workspace.leftRibbon` object, so some future app internals within Obsidian's `workspace.leftRibbon` object, so some future app
@@ -8,9 +8,11 @@ update could break it. Please open an issue if the ribbon ever stops behaving.
## Install ## Install
**BRAT**: `bdeshi/obsidian-ribbon-order-lock` **BRAT**: `bdeshi/obsidian-ribbon-clasp`
**Manual**: extract the latest release archive inside **Manual**: extract the latest release archive inside
`.obsidian/plugins/ribbon-order-lock/`, and enable it. `.obsidian/plugins/ribbon-clasp/`, and enable it.
If you're using lazy-plugins, set this plugin's startup type to "Instant". If you're using lazy-plugins, set this plugin's startup type to "Instant".
[^1]: https://obsidian.md/
+16 -16
View File
@@ -1,22 +1,16 @@
const { Plugin } = require('obsidian'); const { Plugin, debounce } = require('obsidian');
// a bunch of ribbon icons can attach within milliseconds of each other on module.exports = class RibbonClasp extends Plugin {
// startup, so debounce instead of re-checking the order on every single one
function debounce(fn, wait) {
let timer = null;
return () => {
clearTimeout(timer);
timer = setTimeout(fn, wait);
};
}
module.exports = class RibbonOrderLock extends Plugin {
async onload() { async onload() {
this.settings = Object.assign({ order: [] }, await this.loadData()); this.settings = Object.assign({ order: [] }, await this.loadData());
this.enforcing = false; this.enforcing = false;
this.debouncedEnforce = debounce(() => this.enforceOrder(), 200); // icons can attach within milliseconds of each other on startup
// (resetTimer, or it fires 200ms after the first one instead of the last)
this.debouncedEnforce = debounce(() => this.enforceOrder(), 200, true);
this.app.workspace.onLayoutReady(() => { this.app.workspace.onLayoutReady(() => {
// not tied to our lifecycle; still fires if we were disabled during boot
if (this.unloaded) return;
this.patchRibbon(); this.patchRibbon();
this.enforceOrder(); this.enforceOrder();
this.observeRibbon(); this.observeRibbon();
@@ -24,9 +18,14 @@ module.exports = class RibbonOrderLock extends Plugin {
} }
onunload() { onunload() {
this.unloaded = true;
this.observer?.disconnect(); this.observer?.disconnect();
// disconnect doesn't stop an already-scheduled call
this.debouncedEnforce?.cancel();
const ribbon = this.getRibbon(); const ribbon = this.getRibbon();
if (ribbon && this.originalOnChange) { // don't restore over someone else's patch, just go inert instead
if (ribbon && ribbon.onChange === this.wrapper) {
ribbon.onChange = this.originalOnChange; ribbon.onChange = this.originalOnChange;
} }
} }
@@ -58,12 +57,13 @@ module.exports = class RibbonOrderLock extends Plugin {
const original = ribbon.onChange.bind(ribbon); const original = ribbon.onChange.bind(ribbon);
this.originalOnChange = original; this.originalOnChange = original;
ribbon.onChange = (save) => { this.wrapper = (save) => {
original(save); original(save);
if (save && !this.enforcing) { if (save && !this.enforcing && !this.unloaded) {
this.recordOrder(ribbon); this.recordOrder(ribbon);
} }
}; };
ribbon.onChange = this.wrapper;
} }
enforceOrder() { enforceOrder() {
+4 -4
View File
@@ -1,9 +1,9 @@
{ {
"id": "ribbon-order-lock", "id": "ribbon-clasp",
"name": "Ribbon Order Lock", "name": "Ribbon Clasp",
"version": "0.9.0", "version": "1.0.0",
"minAppVersion": "1.1.0", "minAppVersion": "1.1.0",
"description": "Keeps left-ribbon icon order stable across restarts", "description": "Stops the left ribbon icons from reshuffling themselves.",
"author": "bdeshi", "author": "bdeshi",
"authorUrl": "https://github.com/bdeshi", "authorUrl": "https://github.com/bdeshi",
"isDesktopOnly": false "isDesktopOnly": false
+3
View File
@@ -0,0 +1,3 @@
{
"1.0.0": "1.1.0"
}