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: diff --git a/spec/init-spec.js b/spec/init-spec.js index 67706ce5..a8ba11d5 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 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(); + 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', () => { diff --git a/src/init.js b/src/init.js index b624d3f6..455a1618 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) { @@ -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 @@ -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'); @@ -192,7 +195,10 @@ on the option selected.\ } getTemplatePath(argv, templateType) { - return argv.template != null ? path.resolve(argv.template) : path.resolve(__dirname, '..', 'templates', templateType); + if (argv.template != null) { + return path.resolve(argv.template); + } + return path.resolve(__dirname, '..', 'templates', templateType); } dasherize(string) { 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/.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..f41b3d98 --- /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\`. +`; + +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..b0702444 --- /dev/null +++ b/templates/package-javascript-transpiled/package.json @@ -0,0 +1,30 @@ +{ + "name": "__package-name__", + "type": "module", + "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": "npm:@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..c5d2318d --- /dev/null +++ b/templates/package-javascript-transpiled/spec/__package-name__-spec.js.template @@ -0,0 +1,74 @@ +'use babel'; + +import __PackageName__ from '../lib/index'; + +// 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. + +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..d09cb0c0 --- /dev/null +++ b/templates/package-javascript-transpiled/styles/__package-name__.less.template @@ -0,0 +1,9 @@ +// 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. +@import "ui-variables"; + +.__package-name__ { +} 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/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" } } 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.