From 1ef78c60bb71795fa9f10806e2d268180b02d58e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Szabo?= Date: Tue, 8 Oct 2024 23:10:04 -0300 Subject: [PATCH 1/5] Added fixture for init script --- spec/fixtures/init-script.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 spec/fixtures/init-script.js diff --git a/spec/fixtures/init-script.js b/spec/fixtures/init-script.js new file mode 100644 index 0000000000..92af0405bc --- /dev/null +++ b/spec/fixtures/init-script.js @@ -0,0 +1,3 @@ +atom.commands.add(window, 'test-case', () => { + atom.notifications.addInfo("Hello!") +}) From 981ea5d39afc7117c1634ec38e5f19065817ee8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Szabo?= Date: Tue, 8 Oct 2024 23:10:22 -0300 Subject: [PATCH 2/5] Spec for an init script --- spec/atom-environment-spec.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/atom-environment-spec.js b/spec/atom-environment-spec.js index 2a44b24042..8f2dd012ee 100644 --- a/spec/atom-environment-spec.js +++ b/spec/atom-environment-spec.js @@ -488,6 +488,28 @@ describe('AtomEnvironment', () => { }); }); + describe('init script handling', () => { + let pulsar + afterEach(() => { + if(pulsar) { + pulsar.unloadEditorWindow(); + pulsar.destroy(); + } + }) + + it('loads the init script and applies the configurations', async () => { + pulsar = new AtomEnvironment({ + applicationDelegate: atom.applicationDelegate + }); + const initPath = path.join(__dirname, 'fixtures', 'init-script.js') + pulsar.getUserInitScriptPath = () => initPath + await pulsar.requireUserInitScript(); + const commands = atom.commands.findCommands({target: window}) + const command = commands.find(({name}) => name === 'test-case') + expect(command).toEqual({name: 'test-case', displayName: 'Test Case'}) + }) + }) + describe('attemptRestoreProjectStateForPaths(state, projectPaths, filesToOpen)', () => { describe('when the window is clean (empty or has only unnamed, unmodified buffers)', () => { beforeEach(async () => { From cede871b4d259f7c67914ea51d94e753dcdf548b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Szabo?= Date: Tue, 8 Oct 2024 23:53:53 -0300 Subject: [PATCH 3/5] Fixtures for reloadable init scripts --- spec/fixtures/different-init-script.js | 3 +++ spec/fixtures/reloadable-init-script.js | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 spec/fixtures/different-init-script.js create mode 100644 spec/fixtures/reloadable-init-script.js diff --git a/spec/fixtures/different-init-script.js b/spec/fixtures/different-init-script.js new file mode 100644 index 0000000000..04c60a5b19 --- /dev/null +++ b/spec/fixtures/different-init-script.js @@ -0,0 +1,3 @@ +disposable.add(atom.commands.add(window, 'test-case-2', () => { + atom.notifications.addInfo("Hello!") +})) diff --git a/spec/fixtures/reloadable-init-script.js b/spec/fixtures/reloadable-init-script.js new file mode 100644 index 0000000000..81aa1352f7 --- /dev/null +++ b/spec/fixtures/reloadable-init-script.js @@ -0,0 +1,3 @@ +disposable.add(atom.commands.add(window, 'test-case', () => { + atom.notifications.addInfo("Hello!") +})) From 40c87d18a838cbb9ca5481945d39b7dd93759778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Szabo?= Date: Tue, 8 Oct 2024 23:54:31 -0300 Subject: [PATCH 4/5] Allowing init scripts to be reloadable --- spec/atom-environment-spec.js | 53 ++++++++++++++++++++++++++++------- src/atom-environment.js | 15 +++++++++- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/spec/atom-environment-spec.js b/spec/atom-environment-spec.js index 8f2dd012ee..bd8f27f9ad 100644 --- a/spec/atom-environment-spec.js +++ b/spec/atom-environment-spec.js @@ -497,16 +497,49 @@ describe('AtomEnvironment', () => { } }) - it('loads the init script and applies the configurations', async () => { - pulsar = new AtomEnvironment({ - applicationDelegate: atom.applicationDelegate - }); - const initPath = path.join(__dirname, 'fixtures', 'init-script.js') - pulsar.getUserInitScriptPath = () => initPath - await pulsar.requireUserInitScript(); - const commands = atom.commands.findCommands({target: window}) - const command = commands.find(({name}) => name === 'test-case') - expect(command).toEqual({name: 'test-case', displayName: 'Test Case'}) + describe('when the config to reload init scripts is not set', () => { + it('loads the script and requires it, but will not reload the init script', () => { + pulsar = new AtomEnvironment({ + applicationDelegate: atom.applicationDelegate + }); + pulsar.config.set('core.autoReloadInitScript', false) + + let initPath = path.join(__dirname, 'fixtures', 'init-script.js') + pulsar.getUserInitScriptPath = () => initPath + pulsar.requireUserInitScript(); + let commands = atom.commands.findCommands({target: window}) + .filter(({name}) => name.match(/test-case/)) + expect(commands).toEqual([{name: 'test-case', displayName: 'Test Case'}]) + + initPath = path.join(__dirname, 'fixtures', 'different-init-script.js') + pulsar.requireUserInitScript(); + commands = atom.commands.findCommands({target: window}) + .filter(({name}) => name.match(/test-case/)) + expect(commands).toEqual([{name: 'test-case', displayName: 'Test Case'}]) + }) + }) + + describe('when the config to reload init scripts is set', () => { + it('allows for the init script to be reloaded', () => { + pulsar = new AtomEnvironment({ + applicationDelegate: atom.applicationDelegate + }); + pulsar.config.set('core.autoReloadInitScript', true) + + let initPath = path.join(__dirname, 'fixtures', 'reloadable-init-script.js') + pulsar.getUserInitScriptPath = () => initPath + pulsar.requireUserInitScript(); + let commands = atom.commands.findCommands({target: window}) + .filter(({name}) => name.match(/test-case/)) + expect(commands).toEqual([{name: 'test-case', displayName: 'Test Case'}]) + + initPath = path.join(__dirname, 'fixtures', 'different-init-script.js') + pulsar.getUserInitScriptPath = () => initPath + pulsar.requireUserInitScript(); + commands = atom.commands.findCommands({target: window}) + .filter(({name}) => name.match(/test-case/)) + expect(commands).toEqual([{name: 'test-case-2', displayName: 'Test Case 2'}]) + }) }) }) diff --git a/src/atom-environment.js b/src/atom-environment.js index acdd901edc..94750ee52f 100644 --- a/src/atom-environment.js +++ b/src/atom-environment.js @@ -75,6 +75,7 @@ class AtomEnvironment { this.loadTime = null; this.emitter = new Emitter(); this.disposables = new CompositeDisposable(); + this.initScriptDisposables = new CompositeDisposable(); this.pathsWithWaitSessions = new Set(); /** @type {DeserializerManager} */ @@ -1563,7 +1564,19 @@ or use Pane::saveItemAs for programmatic saving.`); const userInitScriptPath = this.getUserInitScriptPath(); if (userInitScriptPath) { try { - if (fs.isFileSync(userInitScriptPath)) require(userInitScriptPath); + if (fs.isFileSync(userInitScriptPath)) { + if(this.config.get('core.autoReloadInitScript')) { + this.disposables.delete(this.initScriptDisposables) + this.initScriptDisposables.dispose() + this.initScriptDisposables = new CompositeDisposable(); + this.disposables.add(this.initScriptDisposables) + let contents = fs.readFileSync(userInitScriptPath, 'utf-8') + contents = `((disposable) => { ${contents}\n })(this.initScriptDisposables)` + eval(contents) + } else { + require(userInitScriptPath); + } + } } catch (error) { this.notifications.addError( `Failed to load \`${userInitScriptPath}\``, From f21f55d3f5fd0dc0a423f065f6696b4216124771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Szabo?= Date: Tue, 8 Oct 2024 23:54:44 -0300 Subject: [PATCH 5/5] Added schema for reloadable scripts config --- src/config-schema.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/config-schema.js b/src/config-schema.js index d1a2ed2fe4..c8a75a248b 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -410,7 +410,13 @@ const configSchema = { default: false, title: 'Allow Window Transparency', description: `Allows editor windows to be see-through. When this setting is enabled, UI themes and user stylesheets can use background colors with an alpha channel to make editor windows translucent. Takes effect after a restart of Pulsar.` - } + }, + autoReloadInitScript: { + type: 'boolean', + default: false, + description: + 'Automatically reloads the init script when the file was changed. Adds a global `disposable` object that can be used at the init script to dispose old commands, old callbacks, etc. DO NOT enable this without using `disposable` in your init script, otherwise you will have duplicated commands.' + }, } }, editor: {