From bc3bc781fd04ba10b22ea8de71fdc7851442f356 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 22 Nov 2025 21:58:32 -0800 Subject: [PATCH 1/9] Add skeleton template files for transpiled-JS project --- .../.gitignore.template | 3 + .../CHANGELOG.md | 3 + .../package-javascript-transpiled/LICENSE.md | 20 +++++ .../package-javascript-transpiled/README.md | 26 +++++++ .../keymaps/__package-name__.json.template | 5 ++ .../lib/index.cjs | 11 +++ .../menus/__package-name__.json.template | 26 +++++++ .../package.json | 31 ++++++++ .../rollup.config.js | 74 +++++++++++++++++++ .../spec/__package-name__-spec.js.template | 73 ++++++++++++++++++ .../__package-name__-view-spec.js.template | 9 +++ .../src/__package-name__-view.js.template | 31 ++++++++ .../src/index.js | 47 ++++++++++++ .../styles/__package-name__.less.template | 8 ++ 14 files changed, 367 insertions(+) create mode 100644 templates/package-javascript-transpiled/.gitignore.template create mode 100644 templates/package-javascript-transpiled/CHANGELOG.md create mode 100644 templates/package-javascript-transpiled/LICENSE.md create mode 100644 templates/package-javascript-transpiled/README.md create mode 100644 templates/package-javascript-transpiled/keymaps/__package-name__.json.template create mode 100644 templates/package-javascript-transpiled/lib/index.cjs create mode 100644 templates/package-javascript-transpiled/menus/__package-name__.json.template create mode 100644 templates/package-javascript-transpiled/package.json create mode 100644 templates/package-javascript-transpiled/rollup.config.js create mode 100644 templates/package-javascript-transpiled/spec/__package-name__-spec.js.template create mode 100644 templates/package-javascript-transpiled/spec/__package-name__-view-spec.js.template create mode 100644 templates/package-javascript-transpiled/src/__package-name__-view.js.template create mode 100644 templates/package-javascript-transpiled/src/index.js create mode 100644 templates/package-javascript-transpiled/styles/__package-name__.less.template diff --git a/templates/package-javascript-transpiled/.gitignore.template b/templates/package-javascript-transpiled/.gitignore.template new file mode 100644 index 00000000..ade14b91 --- /dev/null +++ b/templates/package-javascript-transpiled/.gitignore.template @@ -0,0 +1,3 @@ +.DS_Store +npm-debug.log +node_modules diff --git a/templates/package-javascript-transpiled/CHANGELOG.md b/templates/package-javascript-transpiled/CHANGELOG.md new file mode 100644 index 00000000..c3d858c8 --- /dev/null +++ b/templates/package-javascript-transpiled/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 - First Release +* Every feature added +* Every bug fixed diff --git a/templates/package-javascript-transpiled/LICENSE.md b/templates/package-javascript-transpiled/LICENSE.md new file mode 100644 index 00000000..d7dd6a89 --- /dev/null +++ b/templates/package-javascript-transpiled/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) __current_year__ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/templates/package-javascript-transpiled/README.md b/templates/package-javascript-transpiled/README.md new file mode 100644 index 00000000..f74fe51e --- /dev/null +++ b/templates/package-javascript-transpiled/README.md @@ -0,0 +1,26 @@ +# __package-name__ package + +A short description of your package. + +![A screenshot of your package](https://f.cloud.github.com/assets/69169/2290250/c35d867a-a017-11e3-86be-cd7c5bf3ff9b.gif) + +## Package authors + +If you’ve just generated this package, here’s how to proceed: + +1. `npm install` will install the packages necessary for the build toolchain. +2. `npm run watch` can be used during development; it will automatically recompile when files change. +3. Specs run in JavaScript and should import the package (if necessary) from `../lib/index` rather than `../src/index`. +4. `npm run build` can perform a build and should be run for safety’s sake before publishing. When you make changes, make sure you commit both the source files in `src` and the generated files in `lib`. + +Other tasks to perform before publishing: + +- [ ] Create a corresponding repository on GitHub and push your code to that location. +- [ ] Add specs in the `spec` folder and ensure they pass. +- [ ] Update the `LICENSE` and `CHANGELOG` files. +- [ ] Edit `package.json` to… + - [ ] …change the URL of the `repository` to match the GitHub repo you created. + - [ ] …add keywords. + - [ ] …write an accurate `description`. + - [ ] …change or remove the `activationCommands` field. +- [ ] Edit the `README` to add detail about your package — and to remove this instructional text! diff --git a/templates/package-javascript-transpiled/keymaps/__package-name__.json.template b/templates/package-javascript-transpiled/keymaps/__package-name__.json.template new file mode 100644 index 00000000..5baee680 --- /dev/null +++ b/templates/package-javascript-transpiled/keymaps/__package-name__.json.template @@ -0,0 +1,5 @@ +{ + "atom-workspace": { + "ctrl-alt-o": "__package-name__:toggle" + } +} diff --git a/templates/package-javascript-transpiled/lib/index.cjs b/templates/package-javascript-transpiled/lib/index.cjs new file mode 100644 index 00000000..4aa6ac10 --- /dev/null +++ b/templates/package-javascript-transpiled/lib/index.cjs @@ -0,0 +1,11 @@ +const description = `After installing your dependencies with \`npm install\`, you must run \`npm run build\` or \`npm run watch\` from the root in order to compile your project — at which point you will no longer see this warning. + +If you're stuck, follow the directions in your new package's \`README.md\`. +`; +s +exports.activate = () => { + atom.notifications.addWarning( + '__package-name__ is created but not built', + { description, dismissable: true } + ); +}; diff --git a/templates/package-javascript-transpiled/menus/__package-name__.json.template b/templates/package-javascript-transpiled/menus/__package-name__.json.template new file mode 100644 index 00000000..ea3c2a94 --- /dev/null +++ b/templates/package-javascript-transpiled/menus/__package-name__.json.template @@ -0,0 +1,26 @@ +{ + "context-menu": { + "atom-text-editor": [ + { + "label": "Toggle __package-name__", + "command": "__package-name__:toggle" + } + ] + }, + "menu": [ + { + "label": "Packages", + "submenu": [ + { + "label": "__package-name__", + "submenu": [ + { + "label": "Toggle", + "command": "__package-name__:toggle" + } + ] + } + ] + } + ] +} diff --git a/templates/package-javascript-transpiled/package.json b/templates/package-javascript-transpiled/package.json new file mode 100644 index 00000000..685c9557 --- /dev/null +++ b/templates/package-javascript-transpiled/package.json @@ -0,0 +1,31 @@ +{ + "name": "__package-name__", + "type": "module", + "source": "./src/index.ts", + "main": "./lib/index.cjs", + "version": "0.0.0", + "description": "A short description of your package", + "keywords": [ + ], + "activationCommands": { + "atom-workspace": "__package-name__:toggle" + }, + "repository": "https://github.com/__package-author__/__package-name__", + "license": "MIT", + "engines": { + "atom": ">=1.0.0 <2.0.0" + }, + "scripts": { + "build": "rollup -c rollup.config.js", + "watch": "rollup --watch -c rollup.config.js" + }, + "dependencies": { + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.1", + "rollup": "^4.40.0", + "@types/atom": "github:pulsar-edit/types" + } +} diff --git a/templates/package-javascript-transpiled/rollup.config.js b/templates/package-javascript-transpiled/rollup.config.js new file mode 100644 index 00000000..f3810938 --- /dev/null +++ b/templates/package-javascript-transpiled/rollup.config.js @@ -0,0 +1,74 @@ +import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; +import json from '@rollup/plugin-json'; + +// This is a preset Rollup configuration file designed for Pulsar community +// packages written in JavaScript. It is useful when you've got dependencies +// written in ESM that need to be transpiled to CJS. Here's what it gives us: +// +// * All dependencies that use CommonJS are preserved as-is. +// * All dependencies that use ES Modules are bundled and transpiled to +// CommonJS. (This is necessary because it is impossible for ESM files loaded +// in Electron's renderer process to have access to anything from a Node +// environment, whether built-in or NPM.) +// * JSON files can be imported directly with `import` syntax and do not need +// the "import attribute" clause. This corresponds to CommonJS's ability to +// `require('foo.json')`. +// +// Read https://www.electronjs.org/docs/latest/tutorial/esm#renderer-process +// for more information about the limitations of ESM in Electron's renderer +// process. +// +// Known caveats: +// +// * Not all ESM can be transpiled to CommonJS. If your module uses top-level +// `await` or does dynamic importing (via `await import`), Rollup might be +// unable to transpile it. If so, you'll have to find a workaround or use a +// different dependency. +// +// One possible workaround is reverting to an older version of the same +// dependency. Many popular packages that use newer ES features will have an +// older version that doesn't rely on those features, and perhaps an even +// older version that is written in CommonJS. +// +export default { + input: 'src/index.js', + output: { + file: 'lib/index.cjs', + // Output CommonJS as required by Electron in renderer code. + format: 'cjs', + exports: 'auto', + interop: 'auto', + sourcemap: true + }, + plugins: [ + resolve({ + extensions: ['.js', '.jsx', '.json'], + // Look in `node_modules` for dependencies. + preferBuiltins: true, + // Prefer the `main` field to the `module` field in `package.json`; this + // means that, when a package offers both CommonJS and ESM versions of + // itself, we'll prefer the CJS so that transpilation can be avoided. + mainFields: ['main', 'module'] + }), + commonjs({ + // Transpile everything, even things in `node_modules`. + include: /node_modules/, + // Enable transformations of ES modules in `node_modules`. + transformMixedEsModules: true, + // Handle requiring of JSON files. + ignoreDynamicRequires: false + }), + // Allows requiring of JSON files directly. + json() + ], + // Mark certain packages as external; this tells Rollup not to try to + // transpile the code in these packages. You may opt into this for any + // dependency that exports a CommonJS version. + // + // `atom` _must_ be present in this list because imports from `atom` will be + // resolved at runtime. + external: [ + 'atom' + ] +} diff --git a/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template b/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template new file mode 100644 index 00000000..ef61887d --- /dev/null +++ b/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template @@ -0,0 +1,73 @@ +'use babel'; + +import __PackageName__ from '../lib/index'; + +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// +// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` +// or `fdescribe`). Remove the `f` to unfocus the block. + +describe('__PackageName__', () => { + let workspaceElement, activationPromise; + + beforeEach(() => { + workspaceElement = atom.views.getView(atom.workspace); + activationPromise = atom.packages.activatePackage('__package-name__'); + }); + + describe('when the __package-name__:toggle event is triggered', () => { + it('hides and shows the modal panel', () => { + // Before the activation event the view is not on the DOM, and no panel + // has been created + expect(workspaceElement.querySelector('.__package-name__')).not.toExist(); + + // This is an activation event, triggering it will cause the package to be + // activated. + atom.commands.dispatch(workspaceElement, '__package-name__:toggle'); + + waitsForPromise(() => { + return activationPromise; + }); + + runs(() => { + expect(workspaceElement.querySelector('.__package-name__')).toExist(); + + let __packageName__Element = workspaceElement.querySelector('.__package-name__'); + expect(__packageName__Element).toExist(); + + let __packageName__Panel = atom.workspace.panelForItem(__packageName__Element); + expect(__packageName__Panel.isVisible()).toBe(true); + atom.commands.dispatch(workspaceElement, '__package-name__:toggle'); + expect(__packageName__Panel.isVisible()).toBe(false); + }); + }); + + it('hides and shows the view', () => { + // This test shows you an integration test testing at the view level. + + // Attaching the workspaceElement to the DOM is required to allow the + // `toBeVisible()` matchers to work. Anything testing visibility or focus + // requires that the workspaceElement is on the DOM. Tests that attach the + // workspaceElement to the DOM are generally slower than those off DOM. + jasmine.attachToDOM(workspaceElement); + + expect(workspaceElement.querySelector('.__package-name__')).not.toExist(); + + // This is an activation event, triggering it causes the package to be + // activated. + atom.commands.dispatch(workspaceElement, '__package-name__:toggle'); + + waitsForPromise(() => { + return activationPromise; + }); + + runs(() => { + // Now we can test for view visibility + let __packageName__Element = workspaceElement.querySelector('.__package-name__'); + expect(__packageName__Element).toBeVisible(); + atom.commands.dispatch(workspaceElement, '__package-name__:toggle'); + expect(__packageName__Element).not.toBeVisible(); + }); + }); + }); +}); diff --git a/templates/package-javascript-transpiled/spec/__package-name__-view-spec.js.template b/templates/package-javascript-transpiled/spec/__package-name__-view-spec.js.template new file mode 100644 index 00000000..4b627836 --- /dev/null +++ b/templates/package-javascript-transpiled/spec/__package-name__-view-spec.js.template @@ -0,0 +1,9 @@ +'use babel'; + +import __PackageName__View from '../lib/__package-name__-view'; + +describe('__PackageName__View', () => { + it('has one valid test', () => { + expect('life').toBe('easy'); + }); +}); diff --git a/templates/package-javascript-transpiled/src/__package-name__-view.js.template b/templates/package-javascript-transpiled/src/__package-name__-view.js.template new file mode 100644 index 00000000..43f6e087 --- /dev/null +++ b/templates/package-javascript-transpiled/src/__package-name__-view.js.template @@ -0,0 +1,31 @@ +export default class __PackageName__View { + element = null; + + constructor(serializedState) { + // Create root element + this.element = document.createElement('div'); + this.element.classList.add('__package-name__'); + + // Create message element + const message = document.createElement('div'); + message.textContent = `The __PackageName__ package is Alive! It's ALIVE!`; + message.classList.add('message'); + this.element.appendChild(message); + } + + // Returns an object that can be retrieved when package is activated + serialize() { + return { + // TODO + }; + } + + // Tear down any state and detach + destroy() { + this.element.remove(); + } + + getElement() { + return this.element; + } +} diff --git a/templates/package-javascript-transpiled/src/index.js b/templates/package-javascript-transpiled/src/index.js new file mode 100644 index 00000000..69c48185 --- /dev/null +++ b/templates/package-javascript-transpiled/src/index.js @@ -0,0 +1,47 @@ +import __PackageName__View from './__package-name__-view'; +import { CompositeDisposable, Panel } from 'atom'; + +export default { + __packageName__View: null, + modalPanel: null, + subscriptions: null, + + activate(state) { + this.__packageName__View = new __PackageName__View(state.__packageName__ViewState); + this.modalPanel = atom.workspace.addModalPanel({ + item: this.__packageName__View.getElement(), + visible: false + }); + + // Events subscribed to in Pulsar's system can be easily cleaned up with a + // CompositeDisposable + this.subscriptions = new CompositeDisposable(); + + // Register command that toggles this view + this.subscriptions.add(atom.commands.add('atom-workspace', { + '__package-name__:toggle': () => this.toggle() + })); + }, + + deactivate() { + this.modalPanel?.destroy(); + this.subscriptions?.dispose(); + this.__packageName__View?.destroy(); + }, + + serialize() { + return { + __packageName__ViewState: this.__packageName__View?.serialize() ?? null + }; + }, + + toggle() { + console.log('__PackageName__ was toggled!'); + if (!this.modalPanel) return; + return ( + this.modalPanel.isVisible() ? + this.modalPanel.hide() : + this.modalPanel.show() + ); + } +}; diff --git a/templates/package-javascript-transpiled/styles/__package-name__.less.template b/templates/package-javascript-transpiled/styles/__package-name__.less.template new file mode 100644 index 00000000..faa60980 --- /dev/null +++ b/templates/package-javascript-transpiled/styles/__package-name__.less.template @@ -0,0 +1,8 @@ +// The ui-variables file is provided by base themes provided by Atom. +// +// See https://github.com/pulsar-edit/pulsar/blob/master/packages/atom-dark-ui/styles/ui-variables.less +// for a full listing of what's available. +@import "ui-variables"; + +.__package-name__ { +} From 51da28b07d793f9e7173044e8b227e500e370a13 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 22 Nov 2025 21:59:19 -0800 Subject: [PATCH 2/9] Add `--transpiled` flag for opting into the transpiled-JS project type --- src/init.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/init.js b/src/init.js index b624d3f6..161a151f 100644 --- a/src/init.js +++ b/src/init.js @@ -25,7 +25,7 @@ class Init extends Command { options.usage(`\ Usage: ppm init -p - ppm init -p --syntax + ppm init -p --syntax [--transpiled] ppm init -p -c ~/Downloads/r.tmbundle ppm init -p -c https://github.com/textmate/r.tmbundle ppm init -p --template /path/to/your/package/template @@ -47,6 +47,7 @@ on the option selected.\ options.alias('l', 'language').string('language').describe('language', 'Generates a basic language package'); options.alias('c', 'convert').string('convert').describe('convert', 'Path or URL to TextMate bundle/theme to convert'); options.alias('h', 'help').describe('help', 'Print this usage message'); + options.describe('transpiled', 'Choose the "transpiled" flavor of JavaScript project (valid only when --syntax is javascript)'); return options.string('template').describe('template', 'Path to the package or theme template'); } @@ -67,7 +68,7 @@ on the option selected.\ // Expose the error value as a value for now. return `You must specify one of ${this.supportedSyntaxes.join(', ')} after the --syntax argument`; } - templatePath = this.getTemplatePath(options.argv, `package-${syntax}`); + templatePath = this.getTemplatePath(options.argv, syntax); this.generateFromTemplate(packagePath, templatePath); return; } @@ -191,8 +192,15 @@ on the option selected.\ return string.replace('__current_year__', new Date().getFullYear()); } - getTemplatePath(argv, templateType) { - return argv.template != null ? path.resolve(argv.template) : path.resolve(__dirname, '..', 'templates', templateType); + getTemplatePath(argv, syntax) { + if (argv.template != null) { + return path.resolve(argv.template); + } + let templateName = `package-${syntax}`; + if (syntax === 'javascript' && argv.transpiled) { + templateName = 'package-javascript-transpiled'; + } + return path.resolve(__dirname, '..', 'templates', templateName); } dasherize(string) { From 6ca9620a2e35bc2379d67a074be40b69853a24bd Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 22 Nov 2025 22:03:12 -0800 Subject: [PATCH 3/9] Add spec for `--transpiled` flag --- spec/init-spec.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spec/init-spec.js b/spec/init-spec.js index 67706ce5..0ec79618 100644 --- a/spec/init-spec.js +++ b/spec/init-spec.js @@ -80,6 +80,30 @@ describe('apm init', () => { expect(JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))).name).toBe('fake-package'); expect(JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))).repository).toBe('https://github.com/somebody/fake-package'); }); + + it('allows the user to opt into a transpiled JavaScript project with the --transpiled flag', async () => { + await apmRun(['init', '--syntax', 'javascript', '--package', 'fake-package', '--transpiled']); + expect(fs.existsSync(packagePath)).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'keymaps'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'keymaps', 'fake-package.json'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'lib'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'lib', 'index.cjs'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'src'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'src', 'fake-package-view.js'))).toBeTruthy(); + // Transpiled JavaScript template uses `src/index.js` instead of naming + // the entry point after the package. + expect(fs.existsSync(path.join(packagePath, 'src', 'index.js'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'menus'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'menus', 'fake-package.json'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'spec', 'fake-package-view-spec.js'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'spec', 'fake-package-spec.js'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'styles', 'fake-package.less'))).toBeTruthy(); + expect(fs.existsSync(path.join(packagePath, 'package.json'))).toBeTruthy(); + // Transpiled JavaScript template includes a Rollup config file. + expect(fs.existsSync(path.join(packagePath, 'rollup.config.js'))).toBeTruthy(); + expect(JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))).name).toBe('fake-package'); + expect(JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))).repository).toBe('https://github.com/somebody/fake-package'); + }); }); describe('when package syntax is TypeScript', () => { From ff65c94084d13f7e148d4cea2e59fc2773ca7845 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 22 Nov 2025 22:13:23 -0800 Subject: [PATCH 4/9] =?UTF-8?q?Point=20both=20`@types/atom`=20references?= =?UTF-8?q?=20to=20the=20published=20types=20package=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …not the one on GitHub. --- templates/package-javascript-transpiled/package.json | 2 +- templates/package-typescript/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/package-javascript-transpiled/package.json b/templates/package-javascript-transpiled/package.json index 685c9557..6ee4de2e 100644 --- a/templates/package-javascript-transpiled/package.json +++ b/templates/package-javascript-transpiled/package.json @@ -26,6 +26,6 @@ "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "rollup": "^4.40.0", - "@types/atom": "github:pulsar-edit/types" + "@types/atom": "npm:@pulsar-edit/types" } } diff --git a/templates/package-typescript/package.json b/templates/package-typescript/package.json index 813895c2..612bd659 100644 --- a/templates/package-typescript/package.json +++ b/templates/package-typescript/package.json @@ -29,6 +29,6 @@ "rollup": "^4.40.0", "tslib": "^2.8.1", "typescript": "^5.8.3", - "@types/atom": "github:pulsar-edit/types" + "@types/atom": "npm:@pulsar-edit/types" } } From 4f711fac0361353c4d7ca4ab07f5bb6876e53444 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 22 Nov 2025 22:30:35 -0800 Subject: [PATCH 5/9] Fix the specs --- src/init.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/init.js b/src/init.js index 161a151f..f631625c 100644 --- a/src/init.js +++ b/src/init.js @@ -68,7 +68,7 @@ on the option selected.\ // Expose the error value as a value for now. return `You must specify one of ${this.supportedSyntaxes.join(', ')} after the --syntax argument`; } - templatePath = this.getTemplatePath(options.argv, syntax); + templatePath = this.getTemplatePath(options.argv, `package-${syntax}`); this.generateFromTemplate(packagePath, templatePath); return; } @@ -192,15 +192,14 @@ on the option selected.\ return string.replace('__current_year__', new Date().getFullYear()); } - getTemplatePath(argv, syntax) { + getTemplatePath(argv, templateType) { if (argv.template != null) { return path.resolve(argv.template); } - let templateName = `package-${syntax}`; - if (syntax === 'javascript' && argv.transpiled) { - templateName = 'package-javascript-transpiled'; + if (templateType === 'package-javascript' && argv.transpiled) { + templateType = 'package-javascript-transpiled'; } - return path.resolve(__dirname, '..', 'templates', templateName); + return path.resolve(__dirname, '..', 'templates', templateType); } dasherize(string) { From 4770877af6420af622d181f4bc0a06b51962965c Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 20 Jun 2026 11:35:11 -0700 Subject: [PATCH 6/9] =?UTF-8?q?Change=20`init`=20syntax;=20make=20transpil?= =?UTF-8?q?ed=20a=20flavor=20of=20`syntax`=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …rather than introduce a new boolean flag. --- spec/init-spec.js | 4 ++-- src/init.js | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/init-spec.js b/spec/init-spec.js index 0ec79618..a8ba11d5 100644 --- a/spec/init-spec.js +++ b/spec/init-spec.js @@ -81,8 +81,8 @@ describe('apm init', () => { expect(JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'))).repository).toBe('https://github.com/somebody/fake-package'); }); - it('allows the user to opt into a transpiled JavaScript project with the --transpiled flag', async () => { - await apmRun(['init', '--syntax', 'javascript', '--package', 'fake-package', '--transpiled']); + it('allows the user to opt into a transpiled JavaScript project with the javascript-transpiled syntax option', async () => { + await apmRun(['init', '--syntax', 'javascript-transpiled', '--package', 'fake-package']); expect(fs.existsSync(packagePath)).toBeTruthy(); expect(fs.existsSync(path.join(packagePath, 'keymaps'))).toBeTruthy(); expect(fs.existsSync(path.join(packagePath, 'keymaps', 'fake-package.json'))).toBeTruthy(); diff --git a/src/init.js b/src/init.js index f631625c..f1d30d48 100644 --- a/src/init.js +++ b/src/init.js @@ -16,7 +16,7 @@ class Init extends Command { // // The first item in this list will be the default language if one is not // opted into via `-s`/`--syntax`. - this.supportedSyntaxes = ["javascript", "typescript", "coffeescript"]; + this.supportedSyntaxes = ["javascript", "typescript", "javascript-transpiled", "coffeescript"]; } parseOptions(argv) { @@ -42,7 +42,10 @@ on the option selected.\ ` ); options.alias('p', 'package').string('package').describe('package', 'Generates a basic package'); - options.alias('s', 'syntax').string('syntax').describe('syntax', 'Sets package syntax to JavaScript or TypeScript (applies only to -p/--package option)'); + options.alias('s', 'syntax') + .string('syntax') + .choices(this.supportedSyntaxes) + .describe('syntax', 'Sets package syntax (applies only to -p/--package option)'); options.alias('t', 'theme').string('theme').describe('theme', 'Generates a basic theme'); options.alias('l', 'language').string('language').describe('language', 'Generates a basic language package'); options.alias('c', 'convert').string('convert').describe('convert', 'Path or URL to TextMate bundle/theme to convert'); From 57115b2b241da6f3516c373d0adb6884b7a24cc7 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 20 Jun 2026 14:04:30 -0700 Subject: [PATCH 7/9] Remove last traces of the `--transpiled` flag --- src/init.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/init.js b/src/init.js index f1d30d48..23a77319 100644 --- a/src/init.js +++ b/src/init.js @@ -25,7 +25,7 @@ class Init extends Command { options.usage(`\ Usage: ppm init -p - ppm init -p --syntax [--transpiled] + ppm init -p --syntax ppm init -p -c ~/Downloads/r.tmbundle ppm init -p -c https://github.com/textmate/r.tmbundle ppm init -p --template /path/to/your/package/template @@ -50,7 +50,6 @@ on the option selected.\ options.alias('l', 'language').string('language').describe('language', 'Generates a basic language package'); options.alias('c', 'convert').string('convert').describe('convert', 'Path or URL to TextMate bundle/theme to convert'); options.alias('h', 'help').describe('help', 'Print this usage message'); - options.describe('transpiled', 'Choose the "transpiled" flavor of JavaScript project (valid only when --syntax is javascript)'); return options.string('template').describe('template', 'Path to the package or theme template'); } @@ -199,9 +198,6 @@ on the option selected.\ if (argv.template != null) { return path.resolve(argv.template); } - if (templateType === 'package-javascript' && argv.transpiled) { - templateType = 'package-javascript-transpiled'; - } return path.resolve(__dirname, '..', 'templates', templateType); } From 8b65e59102a56f03e93acf5580bf8ccaf3f7f9b3 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Sat, 20 Jun 2026 14:06:47 -0700 Subject: [PATCH 8/9] =?UTF-8?q?Test=20on=20Node=2020=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …and point to `windows-2022` rather than `windows-latest`. --- .github/workflows/CI.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3652f412..a0a9640d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -16,11 +16,10 @@ jobs: os: - ubuntu-latest - macos-14 - - windows-latest + - windows-2022 node_version: - - 14 - - 16 - 18 + - 20 node_arch: - x64 steps: From 83fde13f352095081e02e60be99833e5e4d7d816 Mon Sep 17 00:00:00 2001 From: Andrew Dupont Date: Mon, 22 Jun 2026 18:23:45 -0700 Subject: [PATCH 9/9] Address feedback --- src/init.js | 2 +- .../styles/__package-name__.less.template | 5 +++-- templates/package-javascript-transpiled/lib/index.cjs | 2 +- templates/package-javascript-transpiled/package.json | 1 - .../spec/__package-name__-spec.js.template | 7 ++++--- .../styles/__package-name__.less.template | 3 ++- .../spec/__package-name__-spec.js.template | 7 ++++--- .../styles/__package-name__.less.template | 5 +++-- .../spec/__package-name__-spec.js.template | 7 ++++--- .../styles/__package-name__.less.template | 3 ++- 10 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/init.js b/src/init.js index 23a77319..455a1618 100644 --- a/src/init.js +++ b/src/init.js @@ -25,7 +25,7 @@ class Init extends Command { options.usage(`\ Usage: ppm init -p - ppm init -p --syntax + ppm init -p --syntax ppm init -p -c ~/Downloads/r.tmbundle ppm init -p -c https://github.com/textmate/r.tmbundle ppm init -p --template /path/to/your/package/template diff --git a/templates/package-coffeescript/styles/__package-name__.less.template b/templates/package-coffeescript/styles/__package-name__.less.template index 6488b4ba..d09cb0c0 100644 --- a/templates/package-coffeescript/styles/__package-name__.less.template +++ b/templates/package-coffeescript/styles/__package-name__.less.template @@ -1,6 +1,7 @@ -// The ui-variables file is provided by base themes provided by Atom. +// ui-variables provides a useful set of UI-related variables specific to the +// active UI theme. // -// See https://github.com/atom/atom-dark-ui/blob/master/styles/ui-variables.less +// See https://github.com/pulsar-edit/pulsar/blob/master/packages/atom-dark-ui/styles/ui-variables.less // for a full listing of what's available. @import "ui-variables"; diff --git a/templates/package-javascript-transpiled/lib/index.cjs b/templates/package-javascript-transpiled/lib/index.cjs index 4aa6ac10..f41b3d98 100644 --- a/templates/package-javascript-transpiled/lib/index.cjs +++ b/templates/package-javascript-transpiled/lib/index.cjs @@ -2,7 +2,7 @@ const description = `After installing your dependencies with \`npm install\`, yo If you're stuck, follow the directions in your new package's \`README.md\`. `; -s + exports.activate = () => { atom.notifications.addWarning( '__package-name__ is created but not built', diff --git a/templates/package-javascript-transpiled/package.json b/templates/package-javascript-transpiled/package.json index 6ee4de2e..b0702444 100644 --- a/templates/package-javascript-transpiled/package.json +++ b/templates/package-javascript-transpiled/package.json @@ -1,7 +1,6 @@ { "name": "__package-name__", "type": "module", - "source": "./src/index.ts", "main": "./lib/index.cjs", "version": "0.0.0", "description": "A short description of your package", diff --git a/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template b/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template index ef61887d..c5d2318d 100644 --- a/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template +++ b/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template @@ -2,10 +2,11 @@ import __PackageName__ from '../lib/index'; -// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p on macOS, +// ctrl-shift-y on Windows/Linux) to run specs. // -// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` -// or `fdescribe`). Remove the `f` to unfocus the block. +// To run a specific `it` or `describe` block add an `f` to the front (e.g., +// `fit` or `fdescribe`). Remove the `f` to unfocus the block. describe('__PackageName__', () => { let workspaceElement, activationPromise; diff --git a/templates/package-javascript-transpiled/styles/__package-name__.less.template b/templates/package-javascript-transpiled/styles/__package-name__.less.template index faa60980..d09cb0c0 100644 --- a/templates/package-javascript-transpiled/styles/__package-name__.less.template +++ b/templates/package-javascript-transpiled/styles/__package-name__.less.template @@ -1,4 +1,5 @@ -// The ui-variables file is provided by base themes provided by Atom. +// ui-variables provides a useful set of UI-related variables specific to the +// active UI theme. // // See https://github.com/pulsar-edit/pulsar/blob/master/packages/atom-dark-ui/styles/ui-variables.less // for a full listing of what's available. diff --git a/templates/package-javascript/spec/__package-name__-spec.js.template b/templates/package-javascript/spec/__package-name__-spec.js.template index c21b3798..b7cab342 100644 --- a/templates/package-javascript/spec/__package-name__-spec.js.template +++ b/templates/package-javascript/spec/__package-name__-spec.js.template @@ -2,10 +2,11 @@ import __PackageName__ from '../lib/__package-name__'; -// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p on macOS, +// ctrl-shift-y on Windows/Linux) to run specs. // -// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` -// or `fdescribe`). Remove the `f` to unfocus the block. +// To run a specific `it` or `describe` block add an `f` to the front (e.g., +// `fit` or `fdescribe`). Remove the `f` to unfocus the block. describe('__PackageName__', () => { let workspaceElement, activationPromise; diff --git a/templates/package-javascript/styles/__package-name__.less.template b/templates/package-javascript/styles/__package-name__.less.template index 6488b4ba..d09cb0c0 100644 --- a/templates/package-javascript/styles/__package-name__.less.template +++ b/templates/package-javascript/styles/__package-name__.less.template @@ -1,6 +1,7 @@ -// The ui-variables file is provided by base themes provided by Atom. +// ui-variables provides a useful set of UI-related variables specific to the +// active UI theme. // -// See https://github.com/atom/atom-dark-ui/blob/master/styles/ui-variables.less +// See https://github.com/pulsar-edit/pulsar/blob/master/packages/atom-dark-ui/styles/ui-variables.less // for a full listing of what's available. @import "ui-variables"; diff --git a/templates/package-typescript/spec/__package-name__-spec.js.template b/templates/package-typescript/spec/__package-name__-spec.js.template index ef61887d..c5d2318d 100644 --- a/templates/package-typescript/spec/__package-name__-spec.js.template +++ b/templates/package-typescript/spec/__package-name__-spec.js.template @@ -2,10 +2,11 @@ import __PackageName__ from '../lib/index'; -// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p on macOS, +// ctrl-shift-y on Windows/Linux) to run specs. // -// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` -// or `fdescribe`). Remove the `f` to unfocus the block. +// To run a specific `it` or `describe` block add an `f` to the front (e.g., +// `fit` or `fdescribe`). Remove the `f` to unfocus the block. describe('__PackageName__', () => { let workspaceElement, activationPromise; diff --git a/templates/package-typescript/styles/__package-name__.less.template b/templates/package-typescript/styles/__package-name__.less.template index faa60980..d09cb0c0 100644 --- a/templates/package-typescript/styles/__package-name__.less.template +++ b/templates/package-typescript/styles/__package-name__.less.template @@ -1,4 +1,5 @@ -// The ui-variables file is provided by base themes provided by Atom. +// ui-variables provides a useful set of UI-related variables specific to the +// active UI theme. // // See https://github.com/pulsar-edit/pulsar/blob/master/packages/atom-dark-ui/styles/ui-variables.less // for a full listing of what's available.