diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 2823f956..00000000 --- a/.eslintrc +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parser": "babel-eslint", - "extends": ["eslint:recommended", "plugin:react/recommended", "plugin:cypress/recommended"], - "env": { - "es6": true, - "browser": true, - "node": true, - "jest": true, - "cypress/globals": true - }, - "globals": { - "NETLIFY_CMS_VERSION": false, - "NETLIFY_CMS_APP_VERSION": false, - "NETLIFY_CMS_CORE_VERSION": false, - "CMS_ENV": false - }, - "rules": { - "no-console": [0], - "react/prop-types": [0], - "no-duplicate-imports": "error", - "emotion/jsx-import": "error", - "emotion/no-vanilla": "error", - "emotion/import-from-emotion": "error", - "emotion/styled-import": "error" - }, - "plugins": ["emotion", "cypress"], - "settings": { - "react": { - "version": "detect" - } - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..b1287ff9 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,38 @@ +module.exports = { + parser: 'babel-eslint', + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:cypress/recommended', + 'prettier/react', + 'prettier/babel', + 'prettier', + ], + env: { + es6: true, + browser: true, + node: true, + jest: true, + 'cypress/globals': true, + }, + globals: { + NETLIFY_CMS_VERSION: false, + NETLIFY_CMS_APP_VERSION: false, + NETLIFY_CMS_CORE_VERSION: false, + CMS_ENV: false, + }, + rules: { + 'no-console': [0], + 'react/prop-types': [0], + 'no-duplicate-imports': 'error', + 'emotion/no-vanilla': 'error', + 'emotion/import-from-emotion': 'error', + 'emotion/styled-import': 'error', + }, + plugins: ['babel', 'emotion', 'cypress'], + settings: { + react: { + version: 'detect', + }, + }, +}; diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 76c95075..b66bdf2b 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [8.x, 10.x] + node-version: [10.x, 12.x] steps: - uses: actions/checkout@v1 diff --git a/.stylelintrc b/.stylelintrc index c1ead471..484c2914 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,21 +1,12 @@ { - "processors": [ - ["stylelint-processor-styled-components", { - "parserPlugins": [ - "jsx", - "objectRestSpread", - "exportDefaultFrom", - "classProperties", - ], - }], - ], "extends": [ "stylelint-config-recommended", - "stylelint-config-styled-components", ], "rules": { "block-no-empty": null, "no-duplicate-selectors": null, + "no-empty-source": null, + "no-extra-semicolons": null, "selector-type-no-unknown": [true, { "ignoreTypes": ["$dummyValue"], }], diff --git a/babel.config.js b/babel.config.js index 29e460af..e1cbcabe 100644 --- a/babel.config.js +++ b/babel.config.js @@ -19,6 +19,10 @@ const defaultPlugins = [ '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-export-default-from', + '@babel/plugin-proposal-nullish-coalescing-operator', + '@babel/plugin-proposal-optional-chaining', + '@babel/plugin-syntax-dynamic-import', + 'babel-plugin-inline-json-import', [ 'module-resolver', isESM @@ -69,20 +73,22 @@ const defaultPlugins = [ ]; const presets = () => { - return ['@babel/preset-react', '@babel/preset-env']; + return [ + '@babel/preset-react', + '@babel/preset-env', + [ + '@emotion/babel-preset-css-prop', + { + autoLabel: true, + }, + ], + ]; }; const plugins = () => { if (isESM) { return [ ...defaultPlugins, - [ - 'emotion', - { - sourceMap: true, - autoLabel: true, - }, - ], [ 'transform-define', { @@ -104,13 +110,6 @@ const plugins = () => { if (isTest) { return [ ...defaultPlugins, - [ - 'emotion', - { - sourceMap: false, - autoLabel: false, - }, - ], [ 'inline-react-svg', { @@ -123,29 +122,10 @@ const plugins = () => { } if (!isProduction) { - return [ - ...defaultPlugins, - [ - 'emotion', - { - sourceMap: true, - autoLabel: true, - }, - ], - 'react-hot-loader/babel', - ]; + return [...defaultPlugins, 'react-hot-loader/babel']; } - return [ - ...defaultPlugins, - [ - 'emotion', - { - sourceMap: true, - autoLabel: true, - }, - ], - ]; + return defaultPlugins; }; module.exports = { diff --git a/cypress/integration/markdown_widget_backspace_spec.js b/cypress/integration/markdown_widget_backspace_spec.js new file mode 100644 index 00000000..67c41d61 --- /dev/null +++ b/cypress/integration/markdown_widget_backspace_spec.js @@ -0,0 +1,82 @@ +import '../utils/dismiss-local-backup'; + +describe('Markdown widget', () => { + + before(() => { + Cypress.config('defaultCommandTimeout', 4000); + cy.task('setupBackend', { backend: 'test' }); + cy.loginAndNewPost(); + }); + + beforeEach(() => { + cy.clearMarkdownEditorContent(); + }); + + after(() => { + cy.task('teardownBackend', { backend: 'test' }); + }); + + describe('pressing backspace', () => { + it('sets non-default block to default when empty', () => { + cy.focused() + .clickHeadingOneButton() + .backspace() + .confirmMarkdownEditorContent(` +

+ `); + }); + it('does nothing at start of first block in document when non-empty and non-default', () => { + cy.focused() + .clickHeadingOneButton() + .type('foo') + .setCursorBefore('foo') + .backspace({ times: 4 }) + .confirmMarkdownEditorContent(` +

foo

+ `); + }); + it('deletes individual characters in middle of non-empty non-default block in document', () => { + cy.focused() + .clickHeadingOneButton() + .type('foo') + .setCursorAfter('fo') + .backspace({ times: 3 }) + .confirmMarkdownEditorContent(` +

o

+ `); + }); + it('at beginning of non-first block, moves default block content to previous block', () => { + cy.focused() + .clickHeadingOneButton() + .type('foo') + .enter() + .type('bar') + .setCursorBefore('bar') + .backspace() + .confirmMarkdownEditorContent(` +

foobar

+ `); + }); + it('at beginning of non-first block, moves non-default block content to previous block', () => { + cy.focused() + .type('foo') + .enter() + .clickHeadingOneButton() + .type('bar') + .enter() + .clickHeadingTwoButton() + .type('baz') + .setCursorBefore('baz') + .backspace() + .confirmMarkdownEditorContent(` +

foo

+

barbaz

+ `) + .setCursorBefore('bar') + .backspace() + .confirmMarkdownEditorContent(` +

foobarbaz

+ `); + }); + }); +}); diff --git a/cypress/integration/markdown_widget_code_block_spec.js b/cypress/integration/markdown_widget_code_block_spec.js new file mode 100644 index 00000000..69c7d27c --- /dev/null +++ b/cypress/integration/markdown_widget_code_block_spec.js @@ -0,0 +1,120 @@ +import { oneLineTrim, stripIndent } from 'common-tags'; +import '../utils/dismiss-local-backup'; + +describe('Markdown widget', () => { + before(() => { + Cypress.config('defaultCommandTimeout', 4000); + cy.task('setupBackend', { backend: 'test' }); + cy.loginAndNewPost(); + }); + + beforeEach(() => { + cy.clearMarkdownEditorContent(); + }); + + after(() => { + cy.task('teardownBackend', { backend: 'test' }); + }); + describe('code block', () => { + it('outputs code', () => { + cy.insertCodeBlock() + .type('foo') + .enter() + .type('bar') + .confirmMarkdownEditorContent(` + ${codeBlock(` + foo + bar + `)} + `) + .clickModeToggle() + .confirmMarkdownEditorContent(` + ${codeBlockRaw(` + foo + bar + `)} + `) + }) + }) +}) + +function codeBlockRaw(content) { + return ['```', ...stripIndent(content).split('\n'), '```'].map(line => oneLineTrim` +
+ + + ${line} + + +
+ `).join(''); +} + +function codeBlock(content) { + const lines = stripIndent(content).split('\n').map((line, idx) => ` +
+
+
${idx + 1}
+
+
${line}
+
+ `).join(''); + + return oneLineTrim` +
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
xxxxxxxxxx
+
+
+
+
+
 
+
+
+ ${lines} +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `; +} diff --git a/cypress/integration/markdown_widget_enter_spec.js b/cypress/integration/markdown_widget_enter_spec.js new file mode 100644 index 00000000..c2220a3b --- /dev/null +++ b/cypress/integration/markdown_widget_enter_spec.js @@ -0,0 +1,108 @@ +import '../utils/dismiss-local-backup'; + +describe('Markdown widget breaks', () => { + before(() => { + Cypress.config('defaultCommandTimeout', 4000); + cy.task('setupBackend', { backend: 'test' }); + cy.loginAndNewPost(); + }); + + beforeEach(() => { + cy.clearMarkdownEditorContent(); + }); + + after(() => { + cy.task('teardownBackend', { backend: 'test' }); + }); + + describe('pressing enter', () => { + it('creates new default block from empty block', () => { + cy.focused() + .enter() + .confirmMarkdownEditorContent(` +

+

+ `); + }); + it('creates new default block when selection collapsed at end of block', () => { + cy.focused() + .type('foo') + .enter() + .confirmMarkdownEditorContent(` +

foo

+

+ `); + }); + it('creates new default block when selection collapsed at end of non-default block', () => { + cy.clickHeadingOneButton() + .type('foo') + .enter() + .confirmMarkdownEditorContent(` +

foo

+

+ `); + }); + it('creates new default block when selection collapsed in empty non-default block', () => { + cy.clickHeadingOneButton() + .enter() + .confirmMarkdownEditorContent(` +

+

+ `); + }); + it('splits block into two same-type blocks when collapsed selection at block start', () => { + cy.clickHeadingOneButton() + .type('foo') + .setCursorBefore('foo') + .enter() + .confirmMarkdownEditorContent(` +

+

foo

+ `); + }); + it('splits block into two same-type blocks when collapsed in middle of selection at block start', () => { + cy.clickHeadingOneButton() + .type('foo') + .setCursorBefore('oo') + .enter() + .confirmMarkdownEditorContent(` +

f

+

oo

+ `); + }); + it('deletes selected content and splits to same-type block when selection is expanded', () => { + cy.clickHeadingOneButton() + .type('foo bar') + .setSelection('o b') + .enter() + .confirmMarkdownEditorContent(` +

fo

+

ar

+ `); + }); + }); + + describe('pressing shift+enter', () => { + it('creates line break', () => { + cy.focused() + .enter({ shift: true }) + .confirmMarkdownEditorContent(` +

+
+

+ `); + }); + it('creates consecutive line break', () => { + cy.focused() + .enter({ shift: true, times: 4 }) + .confirmMarkdownEditorContent(` +

+
+
+
+
+

+ `); + }); + }); +}); diff --git a/cypress/integration/markdown_widget_list_spec.js b/cypress/integration/markdown_widget_list_spec.js new file mode 100644 index 00000000..c88cbeae --- /dev/null +++ b/cypress/integration/markdown_widget_list_spec.js @@ -0,0 +1,681 @@ +import '../utils/dismiss-local-backup'; + +describe('Markdown widget', () => { + describe('list', () => { + before(() => { + Cypress.config('defaultCommandTimeout', 4000); + cy.task('setupBackend', { backend: 'test' }); + cy.loginAndNewPost(); + }); + + beforeEach(() => { + cy.clearMarkdownEditorContent(); + }); + + after(() => { + cy.task('teardownBackend', { backend: 'test' }); + }); + + describe('toolbar buttons', () => { + it('creates and focuses empty list', () => { + cy.clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `); + }); + + it('removes list', () => { + cy.clickUnorderedListButton({ times: 2 }) + .confirmMarkdownEditorContent(` +

+ `); + }); + + it('creates nested list when selection is collapsed in non-first block of list item', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .type('bar') + .enter() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `); + }); + + it('converts empty nested list item to empty block in parent list item', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter() + .clickUnorderedListButton() + .type('bar') + .enter() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .backspace({ times: 4 }) + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `); + }); + + it('moves nested list item content to parent list item when in first block', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter() + .clickUnorderedListButton() + .type('bar') + .enter() + .clickUnorderedListButton() + .type('baz') + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .up() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .up() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` +

foo

+

bar

+

baz

+ `); + }); + + it('affects only the current block with collapsed selection', () => { + cy.focused() + .type('foo') + .enter() + .type('bar') + .enter() + .type('baz') + .up() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` +

foo

+ +

baz

+ `); + }); + + it('combines adjacent same-typed lists, not differently typed lists', () => { + cy.focused() + .type('foo') + .enter() + .type('bar') + .enter() + .type('baz') + .up() + .clickUnorderedListButton() + .up() + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + +

baz

+ `) + .down({ times: 2 }) + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .up() + .enter() + .type('qux') + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .up() + .enter() + .type('quux') + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .clickOrderedListButton() + .confirmMarkdownEditorContent(` + + `) + .setSelection({ + anchorQuery: 'ul > li > ol p', + anchorOffset: 1, + focusQuery: 'ul > li > ul:last-child p', + focusOffset: 2, + }); + }); + + it('affects only selected list items', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .type('bar') + .enter({ times: 2 }) + .type('baz') + .setSelection('bar') + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + +

bar

+ + `) + .clickUnorderedListButton() + .setSelection('bar', 'baz') + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + +

bar

+

baz

+ `) + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + .setSelection('baz') + .clickUnorderedListButton() + .setCursorAfter('baz') + .enter() + .clickUnorderedListButton() + .type('qux') + .setSelection('baz') + .clickOrderedListButton() + .setCursorAfter('qux') + .enter({ times: 4 }) + .clickUnorderedListButton() + .confirmMarkdownEditorContent(` + + `) + }); + }); + + describe('on Enter', () => { + it('removes the list item and list if empty', () => { + cy.clickUnorderedListButton() + .enter() + .confirmMarkdownEditorContent(` +

+ `); + }); + + it('creates a new paragraph in a non-empty paragraph within a list item', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter() + .confirmMarkdownEditorContent(` + + `) + .type('bar') + .enter() + .confirmMarkdownEditorContent(` + + `); + }); + + it('creates a new list item in an empty paragraph within a non-empty list item', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .confirmMarkdownEditorContent(` + + `) + .type('bar') + .enter() + .confirmMarkdownEditorContent(` + + `); + }); + + it('creates a new block below list', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 3 }) + .confirmMarkdownEditorContent(` + +

+ `); + }); + }); + + describe('on Backspace', () => { + it('removes the list item and list if empty', () => { + cy.clickUnorderedListButton() + .backspace() + .confirmMarkdownEditorContent(` +

+ `); + }); + + it('removes empty block in non-empty list item', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter() + .backspace() + .confirmMarkdownEditorContent(` + + `); + }); + + it('removes the list item if list not empty', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .backspace() + .confirmMarkdownEditorContent(` + + `); + }); + + it('does not remove list item if empty with non-default block', () => { + cy.clickUnorderedListButton() + .clickHeadingOneButton() + .backspace() + .confirmMarkdownEditorContent(` + + `); + }); + }); + + describe('on Tab', () => { + it('does nothing in top level list', () => { + cy.clickUnorderedListButton() + .tabkey() + .confirmMarkdownEditorContent(` + + `) + .type('foo') + .tabkey() + .confirmMarkdownEditorContent(` + + `) + }); + + it('indents nested list items', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .type('bar') + .tabkey() + .confirmMarkdownEditorContent(` + + `) + .enter({ times: 2 }) + .tabkey() + .confirmMarkdownEditorContent(` + + `) + }); + + it('only nests up to one level down from the parent list', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .tabkey({ times: 5 }) + .confirmMarkdownEditorContent(` + + `); + }); + + it('unindents nested list items with shift', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .tabkey() + .tabkey({ shift: true }) + .confirmMarkdownEditorContent(` + + `) + }); + + it('indents and unindents from one level below parent back to document root', () => { + cy.clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .tabkey() + .type('bar') + .enter({ times: 2 }) + .tabkey() + .type('baz') + .confirmMarkdownEditorContent(` + + `) + .tabkey({ shift: true }) + .confirmMarkdownEditorContent(` + + `) + .tabkey({ shift: true }) + .confirmMarkdownEditorContent(` + + `) + }); + }); + }); +}); diff --git a/cypress/integration/markdown_widget_marks_spec.js b/cypress/integration/markdown_widget_marks_spec.js new file mode 100644 index 00000000..3f204936 --- /dev/null +++ b/cypress/integration/markdown_widget_marks_spec.js @@ -0,0 +1,36 @@ +import '../utils/dismiss-local-backup'; + +describe('Markdown widget', () => { + describe('code mark', () => { + before(() => { + Cypress.config('defaultCommandTimeout', 4000); + cy.task('setupBackend', { backend: 'test' }); + cy.loginAndNewPost(); + }); + + beforeEach(() => { + cy.clearMarkdownEditorContent(); + }); + + after(() => { + cy.task('teardownBackend', { backend: 'test' }); + }); + + describe('toolbar button', () => { + it('can combine code mark with other marks', () => { + cy.clickItalicButton() + .type('foo') + .setSelection('oo') + .clickCodeButton() + .confirmMarkdownEditorContent(` +

+ f + + oo + +

+ `); + }); + }); + }); +}); diff --git a/cypress/integration/markdown_widget_quote_spec.js b/cypress/integration/markdown_widget_quote_spec.js new file mode 100644 index 00000000..9c6d90d1 --- /dev/null +++ b/cypress/integration/markdown_widget_quote_spec.js @@ -0,0 +1,307 @@ +import '../utils/dismiss-local-backup'; + +describe('Markdown widget', () => { + describe('quote block', () => { + before(() => { + Cypress.config('defaultCommandTimeout', 4000); + cy.task('setupBackend', { backend: 'test' }); + cy.loginAndNewPost(); + }); + + beforeEach(() => { + cy.clearMarkdownEditorContent(); + }); + + after(() => { + cy.task('teardownBackend', { backend: 'test' }); + }); + + describe('toggle quote', () => { + it('toggles empty quote block on and off in empty editor', () => { + cy.clickQuoteButton() + .confirmMarkdownEditorContent(` +
+

+
+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` +

+ `); + }); + it('toggles empty quote block on and off for current block', () => { + cy.focused() + .type('foo') + .clickQuoteButton() + .confirmMarkdownEditorContent(` +
+

foo

+
+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` +

foo

+ `); + }); + it('toggles entire quote block without expanded selection', () => { + cy.clickQuoteButton() + .type('foo') + .enter() + .type('bar') + .clickQuoteButton() + .confirmMarkdownEditorContent(` +

foo

+

bar

+ `); + }); + it('toggles entire quote block with complex content', () => { + cy.clickQuoteButton() + .clickUnorderedListButton() + .clickHeadingOneButton() + .type('foo') + .enter({ times: 3 }) + .clickQuoteButton() + .confirmMarkdownEditorContent(` + +

+ `); + }); + it('toggles empty quote block on and off for selected blocks', () => { + cy.focused() + .type('foo') + .enter() + .type('bar') + .setSelection('foo', 'bar') + .clickQuoteButton() + .confirmMarkdownEditorContent(` +
+

foo

+

bar

+
+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` +

foo

+

bar

+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` +
+

foo

+

bar

+
+ `); + }); + it('toggles empty quote block on and off for partially selected blocks', () => { + cy.focused() + .type('foo') + .enter() + .type('bar') + .setSelection('oo', 'ba') + .clickQuoteButton() + .confirmMarkdownEditorContent(` +
+

foo

+

bar

+
+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` +

foo

+

bar

+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` +
+

foo

+

bar

+
+ `); + }); + it('toggles quote block on and off for multiple selected list items', () => { + cy.focused() + .clickUnorderedListButton() + .type('foo') + .enter({ times: 2 }) + .type('bar') + .setSelection('foo', 'bar') + .clickQuoteButton() + .confirmMarkdownEditorContent(` +
+ +
+ `) + .clickQuoteButton() + .confirmMarkdownEditorContent(` + + `) + .setCursorAfter('bar') + .enter({ times: 2 }) + .type('baz') + .setSelection('bar', 'baz') + .clickQuoteButton() + .confirmMarkdownEditorContent(` + +
+ +
+ `) + }); + it('creates new quote block if parent is not a quote, can deeply nest', () => { + cy.clickQuoteButton() + .clickUnorderedListButton() + .clickQuoteButton() + .clickUnorderedListButton() + .clickQuoteButton() + .clickUnorderedListButton() + .clickQuoteButton() + .type('foo') + .enter({ times: 10 }) + .type('bar') + .confirmMarkdownEditorContent(` +
+ +

bar

+
+ `) + .backspace({ times: 12 }) + }); + }); + + describe('backspace inside quote', () => { + it('joins two paragraphs', () => { + cy.clickQuoteButton() + .type('foo') + .enter() + .type('bar') + .setCursorBefore('bar') + .backspace() + .confirmMarkdownEditorContent(` +
+

foobar

+
+ `); + }); + it('joins quote with previous quote', () => { + cy.clickQuoteButton() + .type('foo') + .enter({ times: 2 }) + .clickQuoteButton() + .type('bar') + .confirmMarkdownEditorContent(` +
+

foo

+
+
+

bar

+
+ `) + .setCursorBefore('bar') + .backspace() + .confirmMarkdownEditorContent(` +
+

foo

+

bar

+
+ `); + }); + it('removes first block from quote when focused at first block at start', () => { + cy.clickQuoteButton() + .type('foo') + .enter() + .type('bar') + .setCursorBefore('foo') + .backspace() + .confirmMarkdownEditorContent(` +

foo

+
+

bar

+
+ `) + }); + }); + + describe('enter inside quote', () => { + it('creates new block inside quote', () => { + cy.clickQuoteButton() + .type('foo') + .enter() + .confirmMarkdownEditorContent(` +
+

foo

+

+
+ `) + .type('bar') + .setCursorAfter('ba') + .enter() + .confirmMarkdownEditorContent(` +
+

foo

+

ba

+

r

+
+ `); + }); + it('creates new block after quote from empty last block', () => { + cy.clickQuoteButton() + .type('foo') + .enter() + .enter() + .confirmMarkdownEditorContent(` +
+

foo

+
+

+ `) + }); + }); + }); +}); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index bd08da0d..07e9389d 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -23,8 +23,11 @@ // // -- This is will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -const { escapeRegExp } = require('../utils/regexp'); -const path = require('path'); +import path from 'path'; +import rehype from 'rehype'; +import visit from 'unist-util-visit'; +import { oneLineTrim } from 'common-tags'; +import { escapeRegExp } from '../utils/regexp'; const matchRoute = (route, fetchArgs) => { const url = fetchArgs[0]; @@ -86,3 +89,241 @@ Cypress.Commands.add('stubFetch', ({ fixture }) => { cy.on('window:before:load', win => stubFetch(win, routes)); }); }); + +function runTimes(cyInstance, fn, count = 1) { + let chain = cyInstance, i = count; + while (i) { + i -= 1; + chain = fn(chain); + } + return chain; +} + +[ + 'enter', + 'backspace', + ['selectAll', 'selectall'], + ['up', 'upArrow'], + ['down', 'downArrow'], + ['left', 'leftArrow'], + ['right', 'rightArrow'], +].forEach(key => { + const [ cmd, keyName ] = typeof key === 'object' ? key : [key, key]; + Cypress.Commands.add(cmd, { prevSubject: true }, (subject, { shift, times = 1 } = {}) => { + const fn = chain => chain.type(`${shift ? '{shift}' : ''}{${keyName}}`); + return runTimes(cy.wrap(subject), fn, times); + }); +}); + +// Convert `tab` command from plugin to a child command with `times` support +Cypress.Commands.add('tabkey', { prevSubject: true }, (subject, { shift, times } = {}) => { + const fn = chain => chain.tab({ shift }); + return runTimes(cy, fn, times).wrap(subject); +}); + +Cypress.Commands.add('selection', { prevSubject: true }, (subject, fn) => { + cy.wrap(subject) + .trigger('mousedown') + .then(fn) + .trigger('mouseup') + + cy.document().trigger('selectionchange'); + return cy.wrap(subject); +}); + +Cypress.Commands.add('print', { prevSubject: 'optional' }, (subject, str) => { + cy.log(str); + console.log(`cy.log: ${str}`); + return cy.wrap(subject); +}); + +Cypress.Commands.add('setSelection', { prevSubject: true }, (subject, query, endQuery) => { + return cy.wrap(subject) + .selection($el => { + if (typeof query === 'string') { + const anchorNode = getTextNode($el[0], query); + const focusNode = endQuery ? getTextNode($el[0], endQuery) : anchorNode; + const anchorOffset = anchorNode.wholeText.indexOf(query); + const focusOffset = endQuery ? + focusNode.wholeText.indexOf(endQuery) + endQuery.length : + anchorOffset + query.length; + setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset); + } else if (typeof query === 'object') { + const el = $el[0]; + const anchorNode = getTextNode(el.querySelector(query.anchorQuery)); + const anchorOffset = query.anchorOffset || 0; + const focusNode = query.focusQuery ? getTextNode(el.querySelector(query.focusQuery)) : anchorNode; + const focusOffset = query.focusOffset || 0; + setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset); + } + }); +}); + +Cypress.Commands.add('setCursor', { prevSubject: true }, (subject, query, atStart) => { + return cy.wrap(subject) + .selection($el => { + const node = getTextNode($el[0], query); + const offset = node.wholeText.indexOf(query) + (atStart ? 0 : query.length); + const document = node.ownerDocument; + document.getSelection().removeAllRanges(); + document.getSelection().collapse(node, offset); + }); +}); + +Cypress.Commands.add('setCursorBefore', { prevSubject: true }, (subject, query) => { + cy.wrap(subject).setCursor(query, true); +}); + +Cypress.Commands.add('setCursorAfter', { prevSubject: true }, (subject, query) => { + cy.wrap(subject).setCursor(query); +}); + +Cypress.Commands.add('login', () => { + cy.viewport(1200, 1200); + cy.visit('/'); + cy.contains('button', 'Login').click(); +}); + +Cypress.Commands.add('loginAndNewPost', () => { + cy.login(); + cy.contains('a', 'New Post').click(); +}); + +Cypress.Commands.add('drag', { prevSubject: true }, subject => { + return cy.wrap(subject) + .trigger('dragstart', { + dataTransfer: {}, + force: true, + }); +}); + +Cypress.Commands.add('drop', { prevSubject: true }, subject => { + return cy.wrap(subject) + .trigger('drop', { + dataTransfer: {}, + force: true, + }); +}); + +Cypress.Commands.add('clickToolbarButton', (title, { times } = {}) => { + const isHeading = title.startsWith('Heading') + if (isHeading) { + cy.get('button[title="Headings"]').click(); + } + const instance = isHeading ? cy.contains('div', title) : cy.get(`button[title="${title}"]`); + const fn = chain => chain.click(); + return runTimes(instance, fn, times).focused(); +}); + +Cypress.Commands.add('insertEditorComponent', title => { + cy.get('button[title="Add Component"]').click() + cy.contains('div', title).click().focused(); +}); + + +[ + ['clickHeadingOneButton', 'Heading 1'], + ['clickHeadingTwoButton', 'Heading 2'], + ['clickOrderedListButton', 'Numbered List'], + ['clickUnorderedListButton', 'Bulleted List'], + ['clickCodeButton', 'Code'], + ['clickItalicButton', 'Italic'], + ['clickQuoteButton', 'Quote'], +].forEach(([commandName, toolbarButtonName]) => { + Cypress.Commands.add(commandName, opts => { + return cy.clickToolbarButton(toolbarButtonName, opts); + }); +}); + +Cypress.Commands.add('clickModeToggle', () => { + cy.get('button[role="switch"]') + .click() + .focused(); +}); + +[ + ['insertCodeBlock', 'Code Block'], +].forEach(([commandName, componentTitle]) => { + Cypress.Commands.add(commandName, () => { + return cy.insertEditorComponent(componentTitle); + }); +}); + + +Cypress.Commands.add('getMarkdownEditor', () => { + return cy.get('[data-slate-editor]'); +}); + +Cypress.Commands.add('confirmMarkdownEditorContent', expectedDomString => { + return cy.getMarkdownEditor() + .should(([element]) => { + // Slate makes the following representations: + // - blank line: 2 BOM's +
+ // - blank element (placed inside empty elements): 1 BOM +
+ // We replace to represent a blank line as a single
, and remove the + // contents of elements that are actually empty. + const actualDomString = toPlainTree(element.innerHTML) + .replace(/\uFEFF\uFEFF
/g, '
') + .replace(/\uFEFF
/g, ''); + expect(actualDomString).toEqual(oneLineTrim(expectedDomString)); + }); +}); + +Cypress.Commands.add('clearMarkdownEditorContent', () => { + return cy.getMarkdownEditor() + .selectAll() + .backspace({ times: 2 }); +}); + +function toPlainTree(domString) { + return rehype() + .use(removeSlateArtifacts) + .data('settings', { fragment: true }) + .processSync(domString) + .contents; +} + +function getActualBlockChildren(node) { + if (node.tagName === 'span') { + return node.children.flatMap(getActualBlockChildren); + } + if (node.children) { + return { ...node, children: node.children.flatMap(getActualBlockChildren) }; + } + return node; +} + +function removeSlateArtifacts() { + return function transform(tree) { + visit(tree, 'element', node => { + // remove all element attributes + delete node.properties; + + // remove slate padding spans to simplify test cases + if (['h1', 'p'].includes(node.tagName)) { + node.children = node.children.flatMap(getActualBlockChildren); + } + }); + } +} + +function getTextNode(el, match){ + const walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false); + if (!match) { + return walk.nextNode(); + } + + const nodes = []; + let node; + while(node = walk.nextNode()) { + if (node.wholeText.includes(match)) { + return node; + } + } +} + +function setBaseAndExtent(...args) { + const document = args[0].ownerDocument; + document.getSelection().removeAllRanges(); + document.getSelection().setBaseAndExtent(...args); +} diff --git a/cypress/support/index.js b/cypress/support/index.js index d68db96d..0c07e000 100644 --- a/cypress/support/index.js +++ b/cypress/support/index.js @@ -12,9 +12,11 @@ // You can read more here: // https://on.cypress.io/configuration // *********************************************************** +require('cypress-plugin-tab'); // Import commands.js using ES2015 syntax: -import './commands' +import './commands'; // Alternatively you can use CommonJS syntax: // require('./commands') +import 'cypress-jest-adapter'; diff --git a/cypress/utils/constants.js b/cypress/utils/constants.js index eaecdfde..bd178eab 100644 --- a/cypress/utils/constants.js +++ b/cypress/utils/constants.js @@ -1,7 +1,7 @@ const workflowStatus = { draft: 'Drafts', review: 'In Review', ready: 'Ready' }; const editorStatus = { draft: 'Draft', review: 'In review', ready: 'Ready' }; const setting1 = { limit: 10, author: 'John Doe' }; -const setting2 = { name: 'Andrew Wommack', description: 'A Gospel Teacher' }; +const setting2 = { name: 'Jane Doe', description: 'description' }; const publishTypes = { publishNow: 'Publish now' }; const notifications = { saved: 'Entry saved', diff --git a/cypress/utils/steps.js b/cypress/utils/steps.js index 24c6549e..c78f679c 100644 --- a/cypress/utils/steps.js +++ b/cypress/utils/steps.js @@ -51,16 +51,10 @@ function updateWorkflowStatus({ title }, fromColumnHeading, toColumnHeading) { cy.contains('h2', fromColumnHeading) .parent() .contains('a', title) - .trigger('dragstart', { - dataTransfer: {}, - force: true, - }); + .drag(); cy.contains('h2', toColumnHeading) .parent() - .trigger('drop', { - dataTransfer: {}, - force: true, - }); + .drop(); assertNotification(notifications.updated); } @@ -171,7 +165,7 @@ function populateEntry(entry) { for (let key of keys) { const value = entry[key]; if (key === 'body') { - cy.get('[data-slate-editor]') + cy.getMarkdownEditor() .click() .clear() .type(value); @@ -288,7 +282,7 @@ function validateListFields({ name, description }) { cy.get('input') .eq(2) .type(name); - cy.get('[data-slate-editor]') + cy.getMarkdownEditor() .eq(2) .type(description); cy.contains('button', 'Save').click(); diff --git a/package.json b/package.json index bca84f12..f234e07b 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test:unit": "cross-env NODE_ENV=test jest --no-cache", "test:e2e": "run-s build:demo test:e2e:run", "test:e2e:ci": "run-s build:demo test:e2e:run-ci", - "test:e2e:dev": "start-test develop 8080 test:e2e:exec-dev", + "test:e2e:dev": "run-p clean && start-test develop 8080 test:e2e:exec-dev", "test:e2e:serve": "http-server dev-test", "test:e2e:exec": "cypress run", "test:e2e:exec-ci": "cypress run --record --parallel --ci-build-id $GITHUB_SHA --group 'GitHub CI' displayName: 'Run Cypress tests'", @@ -31,11 +31,11 @@ "mock:server:start": "node -e 'require(\"./cypress/utils/mock-server\").start()'", "mock:server:stop": "node -e 'require(\"./cypress/utils/mock-server\").stop()'", "lint": "run-p -c --aggregate-output \"lint:*\"", - "lint-quiet": "run-p -c --aggregate-output \"lint:* -- --quiet\"", + "lint-quiet": "run-p -c --aggregate-output \"lint:* --quiet\"", "lint:css": "stylelint --ignore-path .gitignore \"{packages/**/*.{css,js},website/**/*.css}\"", "lint:js": "eslint --color --ignore-path .gitignore \"{{packages,scripts,website}/**/,}*.js\"", "lint:format": "prettier \"{{packages,scripts,website}/**/,}*.{js,css}\" --list-different", - "format": "run-s \"lint:css -- --fix --quiet\" \"lint:js -- --fix --quiet\" \"format:prettier -- --write\"", + "format": "run-s \"lint:js --fix --quiet\" \"format:prettier --write\"", "format:prettier": "prettier \"{{packages,scripts,website}/**/,}*.{js,css}\"", "publish": "run-s publish:before-manual-version publish:after-manual-version", "publish:ci": "run-s publish:prepare \"publish:version --yes\" build publish:push-git \"publish:from-git --yes\"", @@ -72,20 +72,24 @@ "@babel/core": "^7.3.4", "@babel/plugin-proposal-class-properties": "^7.3.4", "@babel/plugin-proposal-export-default-from": "^7.2.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4", "@babel/plugin-proposal-object-rest-spread": "^7.3.4", + "@babel/plugin-proposal-optional-chaining": "^7.2.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "^7.3.4", "@babel/preset-react": "^7.0.0", - "@commitlint/cli": "^8.2.0", + "@commitlint/cli": "^8.3.3", "@commitlint/config-conventional": "^8.2.0", "@octokit/rest": "^16.28.7", "@testing-library/jest-dom": "^4.2.3", "@testing-library/react": "^9.3.2", "all-contributors-cli": "^6.0.0", "babel-core": "^7.0.0-bridge.0", - "babel-eslint": "^10.0.1", + "babel-eslint": "^11.0.0-beta.0", "babel-jest": "^24.5.0", "babel-loader": "^8.0.5", "babel-plugin-emotion": "^10.0.9", + "babel-plugin-inline-json-import": "^0.3.2", "babel-plugin-inline-react-svg": "^1.1.0", "babel-plugin-lodash": "^3.3.4", "babel-plugin-module-resolver": "^3.2.0", @@ -98,6 +102,8 @@ "cross-env": "^6.0.0", "css-loader": "^3.0.0", "cypress": "^3.4.1", + "cypress-jest-adapter": "^0.0.3", + "cypress-plugin-tab": "^1.0.0", "dom-testing-library": "^4.0.0", "dotenv": "^8.0.0", "eslint": "^5.15.1", @@ -121,25 +127,36 @@ "npm-run-all": "^4.1.5", "prettier": "^1.19.1", "react-test-renderer": "^16.8.4", + "rehype": "^7.0.0", "rimraf": "^3.0.0", "simple-git": "^1.124.0", "start-server-and-test": "^1.7.11", + "style-loader": "^0.23.1", "stylelint": "^9.10.1", "stylelint-config-recommended": "^2.1.0", "stylelint-config-styled-components": "^0.1.1", - "stylelint-processor-styled-components": "^1.5.2", "svg-inline-loader": "^0.8.0", "to-string-loader": "^1.1.5", + "unist-util-visit": "^1.4.0", "webpack": "^4.29.6", "webpack-cli": "^3.2.3", "webpack-dev-server": "^3.2.1" }, - "workspaces": [ - "packages/*" - ], + "workspaces": { + "packages": [ + "packages/*" + ], + "nohoist": [ + "husky", + "run-node" + ] + }, "private": true, "dependencies": { + "@emotion/babel-preset-css-prop": "^10.0.9", "emotion": "^10.0.9", + "eslint-config-prettier": "^6.5.0", + "eslint-plugin-babel": "^5.3.0", "lerna": "^3.15.0" }, "husky": { diff --git a/packages/netlify-cms-app/src/backends.js b/packages/netlify-cms-app/src/backends.js deleted file mode 100644 index 3da2ce3f..00000000 --- a/packages/netlify-cms-app/src/backends.js +++ /dev/null @@ -1,12 +0,0 @@ -import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; -import { GitHubBackend } from 'netlify-cms-backend-github'; -import { GitLabBackend } from 'netlify-cms-backend-gitlab'; -import { GitGatewayBackend } from 'netlify-cms-backend-git-gateway'; -import { BitbucketBackend } from 'netlify-cms-backend-bitbucket'; -import { TestBackend } from 'netlify-cms-backend-test'; - -CMS.registerBackend('git-gateway', GitGatewayBackend); -CMS.registerBackend('github', GitHubBackend); -CMS.registerBackend('gitlab', GitLabBackend); -CMS.registerBackend('bitbucket', BitbucketBackend); -CMS.registerBackend('test-repo', TestBackend); diff --git a/packages/netlify-cms-app/src/editor-components.js b/packages/netlify-cms-app/src/editor-components.js deleted file mode 100644 index cdf023eb..00000000 --- a/packages/netlify-cms-app/src/editor-components.js +++ /dev/null @@ -1,4 +0,0 @@ -import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; -import image from 'netlify-cms-editor-component-image'; - -CMS.registerEditorComponent(image); diff --git a/packages/netlify-cms-app/src/widgets.js b/packages/netlify-cms-app/src/extensions.js similarity index 64% rename from packages/netlify-cms-app/src/widgets.js rename to packages/netlify-cms-app/src/extensions.js index 9b58ff42..53a69c85 100644 --- a/packages/netlify-cms-app/src/widgets.js +++ b/packages/netlify-cms-app/src/extensions.js @@ -1,4 +1,14 @@ +// Core import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; + +// Backends +import { GitHubBackend } from 'netlify-cms-backend-github'; +import { GitLabBackend } from 'netlify-cms-backend-gitlab'; +import { GitGatewayBackend } from 'netlify-cms-backend-git-gateway'; +import { BitbucketBackend } from 'netlify-cms-backend-bitbucket'; +import { TestBackend } from 'netlify-cms-backend-test'; + +// Widgets import NetlifyCmsWidgetString from 'netlify-cms-widget-string'; import NetlifyCmsWidgetNumber from 'netlify-cms-widget-number'; import NetlifyCmsWidgetText from 'netlify-cms-widget-text'; @@ -14,6 +24,18 @@ import NetlifyCmsWidgetMap from 'netlify-cms-widget-map'; import NetlifyCmsWidgetDate from 'netlify-cms-widget-date'; import NetlifyCmsWidgetDatetime from 'netlify-cms-widget-datetime'; +// Editor Components +import image from 'netlify-cms-editor-component-image'; + +// Locales +import { en } from 'netlify-cms-locales'; + +// Register all the things +CMS.registerBackend('git-gateway', GitGatewayBackend); +CMS.registerBackend('github', GitHubBackend); +CMS.registerBackend('gitlab', GitLabBackend); +CMS.registerBackend('bitbucket', BitbucketBackend); +CMS.registerBackend('test-repo', TestBackend); CMS.registerWidget([ NetlifyCmsWidgetString.Widget(), NetlifyCmsWidgetNumber.Widget(), @@ -30,3 +52,5 @@ CMS.registerWidget([ NetlifyCmsWidgetDate.Widget(), NetlifyCmsWidgetDatetime.Widget(), ]); +CMS.registerEditorComponent(image); +CMS.registerLocale('en', en); diff --git a/packages/netlify-cms-app/src/index.js b/packages/netlify-cms-app/src/index.js index e62e2077..26f78bff 100644 --- a/packages/netlify-cms-app/src/index.js +++ b/packages/netlify-cms-app/src/index.js @@ -1,13 +1,8 @@ import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; -import './backends'; -import './widgets'; -import './editor-components'; -import './locales'; +import './extensions.js'; +// Log version if (typeof window !== 'undefined') { - /** - * Log the version number. - */ if (typeof NETLIFY_CMS_APP_VERSION === 'string') { console.log(`netlify-cms-app ${NETLIFY_CMS_APP_VERSION}`); } diff --git a/packages/netlify-cms-core/package.json b/packages/netlify-cms-core/package.json index 94761a86..828c4bf8 100644 --- a/packages/netlify-cms-core/package.json +++ b/packages/netlify-cms-core/package.json @@ -33,6 +33,7 @@ "gotrue-js": "^0.9.24", "gray-matter": "^4.0.2", "history": "^4.7.2", + "immer": "^3.1.3", "js-base64": "^2.5.1", "js-yaml": "^3.12.2", "jwt-decode": "^2.1.0", diff --git a/packages/netlify-cms-core/src/components/App/Header.js b/packages/netlify-cms-core/src/components/App/Header.js index 27134f7d..d8c40248 100644 --- a/packages/netlify-cms-core/src/components/App/Header.js +++ b/packages/netlify-cms-core/src/components/App/Header.js @@ -1,9 +1,8 @@ -/** @jsx jsx */ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; -import { jsx, css } from '@emotion/core'; +import { css } from '@emotion/core'; import { translate } from 'react-polyglot'; import { NavLink } from 'react-router-dom'; import { diff --git a/packages/netlify-cms-core/src/components/Editor/Editor.js b/packages/netlify-cms-core/src/components/Editor/Editor.js index 554bdce0..5b489b3a 100644 --- a/packages/netlify-cms-core/src/components/Editor/Editor.js +++ b/packages/netlify-cms-core/src/components/Editor/Editor.js @@ -399,6 +399,7 @@ export class Editor extends React.Component { logoutUser, deployPreview, loadDeployPreview, + draftKey, slug, t, } = this.props; @@ -421,6 +422,7 @@ export class Editor extends React.Component { return ( {({ css, cx }) => ( - + {widget.globalStyles && } - - {errors && - errors.map( + {errors && ( + + {errors.map( error => error.message && typeof error.message === 'string' && ( @@ -212,25 +176,15 @@ class EditorControl extends React.Component { ), )} - - + this.setState({ styleActive: true })} setInactiveStyle={() => this.setState({ styleActive: false })} resolveWidget={resolveWidget} + widget={widget} getEditorComponents={getEditorComponents} ref={processControlRef && partial(processControlRef, field)} controlRef={controlRef} @@ -289,10 +244,12 @@ class EditorControl extends React.Component { isFetching={isFetching} fieldsErrors={fieldsErrors} onValidateObject={onValidateObject} + isEditorComponent={isEditorComponent} + isNewEditorComponent={isNewEditorComponent} t={t} /> {fieldHint && ( - + {fieldHint} )} diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js index a0c21f9f..6134c6cb 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js @@ -44,6 +44,7 @@ export default class Widget extends Component { onRemoveInsertedMedia: PropTypes.func.isRequired, getAsset: PropTypes.func.isRequired, resolveWidget: PropTypes.func.isRequired, + widget: PropTypes.object.isRequired, getEditorComponents: PropTypes.func.isRequired, isFetching: PropTypes.bool, controlRef: PropTypes.func, @@ -56,6 +57,8 @@ export default class Widget extends Component { loadEntry: PropTypes.func.isRequired, t: PropTypes.func.isRequired, onValidateObject: PropTypes.func, + isEditorComponent: PropTypes.bool, + isNewEditorComponent: PropTypes.bool, }; shouldComponentUpdate(nextProps) { @@ -238,6 +241,7 @@ export default class Widget extends Component { editorControl, uniqueFieldId, resolveWidget, + widget, getEditorComponents, query, queryHits, @@ -247,6 +251,8 @@ export default class Widget extends Component { loadEntry, fieldsErrors, controlRef, + isEditorComponent, + isNewEditorComponent, t, } = this.props; return React.createElement(controlComponent, { @@ -275,6 +281,7 @@ export default class Widget extends Component { hasActiveStyle, editorControl, resolveWidget, + widget, getEditorComponents, query, queryHits, @@ -282,6 +289,8 @@ export default class Widget extends Component { clearFieldErrors, isFetching, loadEntry, + isEditorComponent, + isNewEditorComponent, fieldsErrors, controlRef, t, diff --git a/packages/netlify-cms-core/src/components/Editor/EditorInterface.js b/packages/netlify-cms-core/src/components/Editor/EditorInterface.js index 2ea9675a..4478ae31 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorInterface.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorInterface.js @@ -4,12 +4,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { css, Global } from '@emotion/core'; import styled from '@emotion/styled'; import SplitPane from 'react-split-pane'; -import { colors, colorsRaw, components, transitions } from 'netlify-cms-ui-default'; +import { colors, colorsRaw, components, transitions, IconButton } from 'netlify-cms-ui-default'; import { ScrollSync, ScrollSyncPane } from 'react-scroll-sync'; import EditorControlPane from './EditorControlPane/EditorControlPane'; import EditorPreviewPane from './EditorPreviewPane/EditorPreviewPane'; import EditorToolbar from './EditorToolbar'; -import EditorToggle from './EditorToggle'; const PREVIEW_VISIBLE = 'cms.preview-visible'; const SCROLL_SYNC_ENABLED = 'cms.scroll-sync-enabled'; @@ -27,6 +26,10 @@ const styles = { `, }; +const EditorToggle = styled(IconButton)` + margin-bottom: 12px; +`; + const ReactSplitPaneGlobalStyles = () => ( - + - - + {collectionPreviewEnabled && ( + + )} + {collectionPreviewEnabled && previewVisible && ( + + )} {collectionPreviewEnabled && this.state.previewVisible ? ( editorWithPreview @@ -312,6 +320,7 @@ EditorInterface.propTypes = { onLogoutClick: PropTypes.func.isRequired, deployPreview: ImmutablePropTypes.map, loadDeployPreview: PropTypes.func.isRequired, + draftKey: PropTypes.string.isRequired, }; export default EditorInterface; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js index efb2fbb8..00766c46 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js @@ -26,6 +26,7 @@ export default class PreviewPane extends React.Component { const { getAsset, entry } = props; const widget = resolveWidget(field.get('widget')); const key = idx ? field.get('name') + '_' + idx : field.get('name'); + const valueIsInMap = value && !widget.allowMapValue && Map.isMap(value); /** * Use an HOC to provide conditional updates for all previews. @@ -36,7 +37,7 @@ export default class PreviewPane extends React.Component { key={key} field={field} getAsset={getAsset} - value={value && Map.isMap(value) ? value.get(field.get('name')) : value} + value={valueIsInMap ? value.get(field.get('name')) : value} entry={entry} fieldsMetaData={metadata} /> diff --git a/packages/netlify-cms-core/src/components/Editor/EditorToggle.js b/packages/netlify-cms-core/src/components/Editor/EditorToggle.js deleted file mode 100644 index 635ef85f..00000000 --- a/packages/netlify-cms-core/src/components/Editor/EditorToggle.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import styled from '@emotion/styled'; -import { Icon, colors, colorsRaw, shadows, buttons } from 'netlify-cms-ui-default'; - -const EditorToggleButton = styled.button` - ${buttons.button}; - ${shadows.dropMiddle}; - background-color: ${colorsRaw.white}; - color: ${props => colors[props.isActive ? `active` : `inactive`]}; - border-radius: 32px; - display: flex; - justify-content: center; - align-items: center; - width: 40px; - height: 40px; - padding: 0; - margin-bottom: 12px; -`; - -const EditorToggle = ({ enabled, active, onClick, icon, title }) => - !enabled ? null : ( - - - - ); - -EditorToggle.propTypes = { - enabled: PropTypes.bool, - active: PropTypes.bool, - onClick: PropTypes.func.isRequired, - icon: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, -}; - -export default EditorToggle; diff --git a/packages/netlify-cms-core/src/components/UI/Toast.js b/packages/netlify-cms-core/src/components/UI/Toast.js index 2b621d1e..9f796b3b 100644 --- a/packages/netlify-cms-core/src/components/UI/Toast.js +++ b/packages/netlify-cms-core/src/components/UI/Toast.js @@ -1,8 +1,7 @@ -/** @jsx jsx */ // eslint-disable-next-line no-unused-vars import React from 'react'; import PropTypes from 'prop-types'; -import { jsx, css, Global } from '@emotion/core'; +import { css, Global } from '@emotion/core'; import { translate } from 'react-polyglot'; import reduxNotificationsStyles from 'redux-notifications/lib/styles.css'; import { shadows, colors, lengths } from 'netlify-cms-ui-default'; diff --git a/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js b/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js index 352839cf..daa15c80 100644 --- a/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js +++ b/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js @@ -1,8 +1,7 @@ -/** @jsx jsx */ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { jsx, css } from '@emotion/core'; +import { css } from '@emotion/core'; import styled from '@emotion/styled'; import moment from 'moment'; import { translate } from 'react-polyglot'; diff --git a/packages/netlify-cms-core/src/lib/registry.js b/packages/netlify-cms-core/src/lib/registry.js index dee15b78..489c2007 100644 --- a/packages/netlify-cms-core/src/lib/registry.js +++ b/packages/netlify-cms-core/src/lib/registry.js @@ -1,4 +1,5 @@ import { Map } from 'immutable'; +import produce from 'immer'; import { oneLine } from 'common-tags'; import EditorComponent from 'ValueObjects/EditorComponent'; @@ -23,6 +24,7 @@ export default { getPreviewTemplate, registerWidget, getWidget, + getWidgets, resolveWidget, registerEditorComponent, getEditorComponents, @@ -81,10 +83,12 @@ export function registerWidget(name, control, preview) { name: widgetName, controlComponent: control, previewComponent: preview, + allowMapValue, globalStyles, + ...options } = name; if (registry.widgets[widgetName]) { - console.error(oneLine` + console.warn(oneLine` Multiple widgets registered with name "${widgetName}". Only the last widget registered with this name will be used. `); @@ -92,7 +96,7 @@ export function registerWidget(name, control, preview) { if (!control) { throw Error(`Widget "${widgetName}" registered without \`controlComponent\`.`); } - registry.widgets[widgetName] = { control, preview, globalStyles }; + registry.widgets[widgetName] = { control, preview, globalStyles, allowMapValue, ...options }; } else { console.error('`registerWidget` failed, called with incorrect arguments.'); } @@ -100,6 +104,11 @@ export function registerWidget(name, control, preview) { export function getWidget(name) { return registry.widgets[name]; } +export function getWidgets() { + return produce(Object.entries(registry.widgets), draft => { + return draft.map(([key, value]) => ({ name: key, ...value })); + }); +} export function resolveWidget(name) { return getWidget(name || 'string') || getWidget('unknown'); } @@ -109,7 +118,19 @@ export function resolveWidget(name) { */ export function registerEditorComponent(component) { const plugin = EditorComponent(component); - registry.editorComponents = registry.editorComponents.set(plugin.get('id'), plugin); + if (plugin.type === 'code-block') { + const codeBlock = registry.editorComponents.find(c => c.type === 'code-block'); + + if (codeBlock) { + console.warn(oneLine` + Only one editor component of type "code-block" may be registered. Previously registered code + block component(s) will be overwritten. + `); + registry.editorComponents = registry.editorComponents.delete(codeBlock.id); + } + } + + registry.editorComponents = registry.editorComponents.set(plugin.id, plugin); } export function getEditorComponents() { return registry.editorComponents; diff --git a/packages/netlify-cms-core/src/reducers/__tests__/entryDraft.spec.js b/packages/netlify-cms-core/src/reducers/__tests__/entryDraft.spec.js index a63c0416..588a7dc3 100644 --- a/packages/netlify-cms-core/src/reducers/__tests__/entryDraft.spec.js +++ b/packages/netlify-cms-core/src/reducers/__tests__/entryDraft.spec.js @@ -2,12 +2,15 @@ import { Map, List, fromJS } from 'immutable'; import * as actions from 'Actions/entries'; import reducer from '../entryDraft'; +jest.mock('uuid/v4', () => jest.fn(() => '1')); + const initialState = Map({ entry: Map(), mediaFiles: List(), fieldsMetaData: Map(), fieldsErrors: Map(), hasChanged: false, + key: '', }); const entry = { @@ -23,7 +26,8 @@ const entry = { describe('entryDraft reducer', () => { describe('DRAFT_CREATE_FROM_ENTRY', () => { it('should create draft from the entry', () => { - expect(reducer(initialState, actions.createDraftFromEntry(fromJS(entry)))).toEqual( + const state = reducer(initialState, actions.createDraftFromEntry(fromJS(entry))); + expect(state).toEqual( fromJS({ entry: { ...entry, @@ -33,6 +37,7 @@ describe('entryDraft reducer', () => { fieldsMetaData: Map(), fieldsErrors: Map(), hasChanged: false, + key: '1', }), ); }); @@ -40,7 +45,8 @@ describe('entryDraft reducer', () => { describe('DRAFT_CREATE_EMPTY', () => { it('should create a new draft ', () => { - expect(reducer(initialState, actions.emptyDraftCreated(fromJS(entry)))).toEqual( + const state = reducer(initialState, actions.emptyDraftCreated(fromJS(entry))); + expect(state).toEqual( fromJS({ entry: { ...entry, @@ -50,6 +56,7 @@ describe('entryDraft reducer', () => { fieldsMetaData: Map(), fieldsErrors: Map(), hasChanged: false, + key: '1', }), ); }); @@ -127,6 +134,7 @@ describe('entryDraft reducer', () => { fieldsMetaData: {}, fieldsErrors: {}, hasChanged: false, + key: '', }); }); }); @@ -144,6 +152,7 @@ describe('entryDraft reducer', () => { fieldsMetaData: {}, fieldsErrors: {}, hasChanged: false, + key: '', }); }); }); @@ -161,6 +170,7 @@ describe('entryDraft reducer', () => { fieldsMetaData: {}, fieldsErrors: {}, hasChanged: false, + key: '', }); }); }); @@ -181,6 +191,7 @@ describe('entryDraft reducer', () => { fieldsMetaData: {}, fieldsErrors: {}, hasChanged: true, + key: '1', }); }); }); @@ -201,6 +212,7 @@ describe('entryDraft reducer', () => { entry, mediaFiles: [{ id: '1' }], }, + key: '', }); }); }); diff --git a/packages/netlify-cms-core/src/reducers/entryDraft.js b/packages/netlify-cms-core/src/reducers/entryDraft.js index 636b6cef..dc8b29ab 100644 --- a/packages/netlify-cms-core/src/reducers/entryDraft.js +++ b/packages/netlify-cms-core/src/reducers/entryDraft.js @@ -1,4 +1,5 @@ import { Map, List, fromJS } from 'immutable'; +import uuid from 'uuid/v4'; import { DRAFT_CREATE_FROM_ENTRY, DRAFT_CREATE_EMPTY, @@ -30,6 +31,7 @@ const initialState = Map({ fieldsMetaData: Map(), fieldsErrors: Map(), hasChanged: false, + key: '', }); const entryDraftReducer = (state = Map(), action) => { @@ -46,6 +48,7 @@ const entryDraftReducer = (state = Map(), action) => { state.set('fieldsMetaData', action.payload.metadata || Map()); state.set('fieldsErrors', Map()); state.set('hasChanged', false); + state.set('key', uuid()); }); case DRAFT_CREATE_EMPTY: // New Entry @@ -56,6 +59,7 @@ const entryDraftReducer = (state = Map(), action) => { state.set('fieldsMetaData', Map()); state.set('fieldsErrors', Map()); state.set('hasChanged', false); + state.set('key', uuid()); }); case DRAFT_CREATE_FROM_LOCAL_BACKUP: // Local Backup @@ -69,6 +73,7 @@ const entryDraftReducer = (state = Map(), action) => { state.set('fieldsMetaData', Map()); state.set('fieldsErrors', Map()); state.set('hasChanged', true); + state.set('key', uuid()); }); case DRAFT_CREATE_DUPLICATE_FROM_ENTRY: // Duplicate Entry diff --git a/packages/netlify-cms-core/src/valueObjects/EditorComponent.js b/packages/netlify-cms-core/src/valueObjects/EditorComponent.js index eb5406b3..f0753413 100644 --- a/packages/netlify-cms-core/src/valueObjects/EditorComponent.js +++ b/packages/netlify-cms-core/src/valueObjects/EditorComponent.js @@ -1,39 +1,35 @@ -import { Record, fromJS } from 'immutable'; +import { fromJS } from 'immutable'; import { isFunction } from 'lodash'; const catchesNothing = /.^/; -/* eslint-disable no-unused-vars */ -const EditorComponent = Record({ - id: null, - label: 'unnamed component', - icon: 'exclamation-triangle', - fields: [], - pattern: catchesNothing, - fromBlock(match) { - return {}; - }, - toBlock(attributes) { - return 'Plugin'; - }, - toPreview(attributes) { - return 'Plugin'; - }, -}); -/* eslint-enable */ +const bind = fn => isFunction(fn) && fn.bind(null); export default function createEditorComponent(config) { - const configObj = new EditorComponent({ - id: config.id || config.label.replace(/[^A-Z0-9]+/gi, '_'), - label: config.label, - icon: config.icon, - fields: fromJS(config.fields), - pattern: config.pattern, - fromBlock: isFunction(config.fromBlock) ? config.fromBlock.bind(null) : null, - toBlock: isFunction(config.toBlock) ? config.toBlock.bind(null) : null, - toPreview: isFunction(config.toPreview) - ? config.toPreview.bind(null) - : config.toBlock.bind(null), - }); + const { + id = null, + label = 'unnamed component', + icon = 'exclamation-triangle', + type = 'shortcode', + widget = 'object', + pattern = catchesNothing, + fields = [], + fromBlock, + toBlock, + toPreview, + ...remainingConfig + } = config; - return configObj; + return { + id: id || label.replace(/[^A-Z0-9]+/gi, '_'), + label, + type, + icon, + widget, + pattern, + fromBlock: bind(fromBlock) || (() => ({})), + toBlock: bind(toBlock) || (() => 'Plugin'), + toPreview: bind(toPreview) || (!widget && (bind(toBlock) || (() => 'Plugin'))), + fields: fromJS(fields), + ...remainingConfig, + }; } diff --git a/packages/netlify-cms-default-exports/package.json b/packages/netlify-cms-default-exports/package.json index ab4a6fe3..7e5ab460 100644 --- a/packages/netlify-cms-default-exports/package.json +++ b/packages/netlify-cms-default-exports/package.json @@ -5,7 +5,7 @@ "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports", "bugs": "https://github.com/netlify/netlify-cms/issues", "module": "dist/esm/index.js", - "main": "dist/netlify-cms-editor-component-image.js", + "main": "dist/netlify-cms-default-exports.js", "license": "MIT", "keywords": [ "netlify", diff --git a/packages/netlify-cms-ui-default/src/FieldLabel.js b/packages/netlify-cms-ui-default/src/FieldLabel.js new file mode 100644 index 00000000..665d790e --- /dev/null +++ b/packages/netlify-cms-ui-default/src/FieldLabel.js @@ -0,0 +1,58 @@ +import styled from '@emotion/styled'; +import { colors, colorsRaw, transitions, text } from './styles'; + +const stateColors = { + default: { + background: colors.textFieldBorder, + text: colors.controlLabel, + }, + active: { + background: colors.active, + text: colors.textLight, + }, + error: { + background: colors.errorText, + text: colorsRaw.white, + }, +}; + +const getStateColors = ({ isActive, hasErrors }) => { + if (hasErrors) return stateColors.error; + if (isActive) return stateColors.active; + return stateColors.default; +}; + +const FieldLabel = styled.label` + ${text.fieldLabel}; + color: ${props => getStateColors(props).text}; + background-color: ${props => getStateColors(props).background}; + display: inline-block; + border: 0; + border-radius: 3px 3px 0 0; + padding: 3px 6px 2px; + margin: 0; + transition: all ${transitions.main}; + position: relative; + + /** + * Faux outside curve into top of input + */ + &:before, + &:after { + content: ''; + display: block; + position: absolute; + top: 0; + right: -4px; + height: 100%; + width: 4px; + background-color: inherit; + } + + &:after { + border-bottom-left-radius: 3px; + background-color: #fff; + } +`; + +export default FieldLabel; diff --git a/packages/netlify-cms-ui-default/src/IconButton.js b/packages/netlify-cms-ui-default/src/IconButton.js new file mode 100644 index 00000000..05c2f005 --- /dev/null +++ b/packages/netlify-cms-ui-default/src/IconButton.js @@ -0,0 +1,37 @@ +import React from 'react'; +import styled from '@emotion/styled'; +import Icon from './Icon'; +import { buttons, colors, colorsRaw, shadows } from './styles'; + +const sizes = { + small: '28px', + large: '40px', +}; + +const ButtonRound = styled.button` + ${buttons.button}; + ${shadows.dropMiddle}; + background-color: ${colorsRaw.white}; + color: ${props => colors[props.isActive ? `active` : `inactive`]}; + border-radius: 32px; + display: flex; + justify-content: center; + align-items: center; + width: ${props => sizes[props.size]}; + height: ${props => sizes[props.size]}; + padding: 0; +`; + +const IconButton = ({ size, isActive, type, onClick, className, title }) => ( + + + +); + +export default IconButton; diff --git a/packages/netlify-cms-ui-default/src/index.js b/packages/netlify-cms-ui-default/src/index.js index 40eba40a..ccaceafa 100644 --- a/packages/netlify-cms-ui-default/src/index.js +++ b/packages/netlify-cms-ui-default/src/index.js @@ -2,6 +2,8 @@ import Dropdown, { DropdownItem, DropdownButton, StyledDropdownButton } from './ import Icon from './Icon'; import ListItemTopBar from './ListItemTopBar'; import Loader from './Loader'; +import FieldLabel from './FieldLabel'; +import IconButton from './IconButton'; import Toggle, { ToggleContainer, ToggleBackground, ToggleHandle } from './Toggle'; import AuthenticationPage from './AuthenticationPage'; import WidgetPreviewContainer from './WidgetPreviewContainer'; @@ -14,6 +16,7 @@ import { lengths, components, buttons, + text, shadows, borders, transitions, @@ -28,7 +31,9 @@ export const NetlifyCmsUiDefault = { DropdownButton, StyledDropdownButton, ListItemTopBar, + FieldLabel, Icon, + IconButton, Loader, Toggle, ToggleContainer, @@ -44,6 +49,7 @@ export const NetlifyCmsUiDefault = { components, buttons, shadows, + text, borders, transitions, effects, @@ -56,7 +62,9 @@ export { DropdownButton, StyledDropdownButton, ListItemTopBar, + FieldLabel, Icon, + IconButton, Loader, Toggle, ToggleContainer, @@ -72,6 +80,7 @@ export { components, buttons, shadows, + text, borders, transitions, effects, diff --git a/packages/netlify-cms-ui-default/src/styles.js b/packages/netlify-cms-ui-default/src/styles.js index 4b2aba9a..4195d80f 100644 --- a/packages/netlify-cms-ui-default/src/styles.js +++ b/packages/netlify-cms-ui-default/src/styles.js @@ -120,6 +120,15 @@ const shadows = { `, }; +const text = { + fieldLabel: css` + font-size: 12px; + text-transform: uppercase; + font-weight: 600; + color: ${colors.controlLabel}; + `, +}; + const gradients = { checkerboard: ` linear-gradient( @@ -465,6 +474,7 @@ export { lengths, components, buttons, + text, shadows, borders, transitions, diff --git a/packages/netlify-cms-widget-boolean/src/BooleanControl.js b/packages/netlify-cms-widget-boolean/src/BooleanControl.js index 96df542e..0c0cb27a 100644 --- a/packages/netlify-cms-widget-boolean/src/BooleanControl.js +++ b/packages/netlify-cms-widget-boolean/src/BooleanControl.js @@ -1,8 +1,7 @@ -/** @jsx jsx */ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { jsx, css } from '@emotion/core'; +import { css } from '@emotion/core'; import { Toggle, ToggleBackground, colors } from 'netlify-cms-ui-default'; const BooleanBackground = ({ isActive, ...props }) => ( diff --git a/packages/netlify-cms-widget-code/README.md b/packages/netlify-cms-widget-code/README.md new file mode 100644 index 00000000..91370813 --- /dev/null +++ b/packages/netlify-cms-widget-code/README.md @@ -0,0 +1,11 @@ +# Docs coming soon! + +Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. +That's over 20 Readme's! We haven't created one for this package yet, but we will soon. + +In the meantime, you can: + +1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation + site](https://www.netlifycms.org) for more info. +2. Reach out to the [community chat](https://gitter.im/netlify/netlifycms/) if you need help. +3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-code/README.md)! diff --git a/packages/netlify-cms-widget-code/data/languages-raw.yml b/packages/netlify-cms-widget-code/data/languages-raw.yml new file mode 100644 index 00000000..c2a9b8e2 --- /dev/null +++ b/packages/netlify-cms-widget-code/data/languages-raw.yml @@ -0,0 +1,6133 @@ +# https://github.com/github/linguist/blob/d2e09563c19fe026873289bad3ceb586a1be09d7/lib/linguist/languages.yml +# +# Defines all Languages known to GitHub. +# +# fs_name - Optional field. Only necessary as a replacement for the sample directory name if the +# language name is not a valid filename under the Windows filesystem (e.g., if it +# contains an asterisk). +# type - Either data, programming, markup, prose, or nil +# aliases - An Array of additional aliases (implicitly +# includes name.downcase) +# ace_mode - A String name of the Ace Mode used for highlighting whenever +# a file is edited. This must match one of the filenames in http://git.io/3XO_Cg. +# Use "text" if a mode does not exist. +# codemirror_mode - A String name of the CodeMirror Mode used for highlighting whenever a file is edited. +# This must match a mode from https://git.io/vi9Fx +# codemirror_mime_type - A String name of the file mime type used for highlighting whenever a file is edited. +# This should match the `mime` associated with the mode from https://git.io/f4SoQ +# wrap - Boolean wrap to enable line wrapping (default: false) +# extensions - An Array of associated extensions (the first one is +# considered the primary extension, the others should be +# listed alphabetically) +# filenames - An Array of filenames commonly associated with the language +# interpreters - An Array of associated interpreters +# searchable - Boolean flag to enable searching (defaults to true) +# language_id - Integer used as a language-name-independent indexed field so that we can rename +# languages in Linguist without reindexing all the code on GitHub. Must not be +# changed for existing languages without the explicit permission of GitHub staff. +# color - CSS hex color to represent the language. Only used if type is "programming" or "markup". +# tm_scope - The TextMate scope that represents this programming +# language. This should match one of the scopes listed in +# the grammars.yml file. Use "none" if there is no grammar +# for this language. +# group - Name of the parent language. Languages in a group are counted +# in the statistics as the parent language. +# +# Any additions or modifications (even trivial) should have corresponding +# test changes in `test/test_blob.rb`. +# +# Please keep this list alphabetized. Capitalization comes before lowercase. + +--- +1C Enterprise: + type: programming + color: "#814CCC" + extensions: + - ".bsl" + - ".os" + tm_scope: source.bsl + ace_mode: text + language_id: 0 +ABAP: + type: programming + color: "#E8274B" + extensions: + - ".abap" + tm_scope: source.abap + ace_mode: abap + language_id: 1 +ABNF: + type: data + ace_mode: text + extensions: + - ".abnf" + tm_scope: source.abnf + language_id: 429 +AGS Script: + type: programming + color: "#B9D9FF" + aliases: + - ags + extensions: + - ".asc" + - ".ash" + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + language_id: 2 +AMPL: + type: programming + color: "#E6EFBB" + extensions: + - ".ampl" + - ".mod" + tm_scope: source.ampl + ace_mode: text + language_id: 3 +ANTLR: + type: programming + color: "#9DC3FF" + extensions: + - ".g4" + tm_scope: source.antlr + ace_mode: text + language_id: 4 +API Blueprint: + type: markup + color: "#2ACCA8" + ace_mode: markdown + extensions: + - ".apib" + tm_scope: text.html.markdown.source.gfm.apib + language_id: 5 +APL: + type: programming + color: "#5A8164" + extensions: + - ".apl" + - ".dyalog" + interpreters: + - apl + - aplx + - dyalog + tm_scope: source.apl + ace_mode: text + codemirror_mode: apl + codemirror_mime_type: text/apl + language_id: 6 +ASN.1: + type: data + extensions: + - ".asn" + - ".asn1" + tm_scope: source.asn + ace_mode: text + codemirror_mode: asn.1 + codemirror_mime_type: text/x-ttcn-asn + language_id: 7 +ASP: + type: programming + color: "#6a40fd" + tm_scope: text.html.asp + aliases: + - aspx + - aspx-vb + extensions: + - ".asp" + - ".asax" + - ".ascx" + - ".ashx" + - ".asmx" + - ".aspx" + - ".axd" + ace_mode: text + codemirror_mode: htmlembedded + codemirror_mime_type: application/x-aspx + language_id: 8 +ATS: + type: programming + color: "#1ac620" + aliases: + - ats2 + extensions: + - ".dats" + - ".hats" + - ".sats" + tm_scope: source.ats + ace_mode: ocaml + language_id: 9 +ActionScript: + type: programming + tm_scope: source.actionscript.3 + color: "#882B0F" + aliases: + - actionscript 3 + - actionscript3 + - as3 + extensions: + - ".as" + ace_mode: actionscript + language_id: 10 +Ada: + type: programming + color: "#02f88c" + extensions: + - ".adb" + - ".ada" + - ".ads" + aliases: + - ada95 + - ada2005 + tm_scope: source.ada + ace_mode: ada + language_id: 11 +Adobe Font Metrics: + type: data + tm_scope: source.afm + extensions: + - ".afm" + aliases: + - acfm + - adobe composite font metrics + - adobe multiple font metrics + - amfm + ace_mode: text + language_id: 147198098 +Agda: + type: programming + color: "#315665" + extensions: + - ".agda" + tm_scope: source.agda + ace_mode: text + language_id: 12 +Alloy: + type: programming + color: "#64C800" + extensions: + - ".als" + tm_scope: source.alloy + ace_mode: text + language_id: 13 +Alpine Abuild: + type: programming + group: Shell + aliases: + - abuild + - apkbuild + filenames: + - APKBUILD + tm_scope: source.shell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 14 +Altium Designer: + type: data + aliases: + - altium + extensions: + - ".OutJob" + - ".PcbDoc" + - ".PrjPCB" + - ".SchDoc" + tm_scope: source.ini + ace_mode: ini + language_id: 187772328 +AngelScript: + type: programming + color: "#C7D7DC" + extensions: + - ".as" + - ".angelscript" + tm_scope: source.angelscript + ace_mode: text + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + language_id: 389477596 +Ant Build System: + type: data + tm_scope: text.xml.ant + filenames: + - ant.xml + - build.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: application/xml + language_id: 15 +ApacheConf: + type: data + aliases: + - aconf + - apache + extensions: + - ".apacheconf" + - ".vhost" + filenames: + - ".htaccess" + - apache2.conf + - httpd.conf + tm_scope: source.apache-config + ace_mode: apache_conf + language_id: 16 +Apex: + type: programming + extensions: + - ".cls" + tm_scope: source.java + ace_mode: java + codemirror_mode: clike + codemirror_mime_type: text/x-java + language_id: 17 +Apollo Guidance Computer: + type: programming + group: Assembly + extensions: + - ".agc" + tm_scope: source.agc + ace_mode: assembly_x86 + language_id: 18 +AppleScript: + type: programming + aliases: + - osascript + extensions: + - ".applescript" + - ".scpt" + interpreters: + - osascript + tm_scope: source.applescript + ace_mode: applescript + color: "#101F1F" + language_id: 19 +Arc: + type: programming + color: "#aa2afe" + extensions: + - ".arc" + tm_scope: none + ace_mode: text + language_id: 20 +AsciiDoc: + type: prose + ace_mode: asciidoc + wrap: true + extensions: + - ".asciidoc" + - ".adoc" + - ".asc" + tm_scope: text.html.asciidoc + language_id: 22 +AspectJ: + type: programming + color: "#a957b0" + extensions: + - ".aj" + tm_scope: source.aspectj + ace_mode: text + language_id: 23 +Assembly: + type: programming + color: "#6E4C13" + aliases: + - asm + - nasm + extensions: + - ".asm" + - ".a51" + - ".inc" + - ".nasm" + tm_scope: source.assembly + ace_mode: assembly_x86 + language_id: 24 +Asymptote: + type: programming + color: "#4a0c0c" + extensions: + - ".asy" + interpreters: + - asy + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-kotlin + language_id: 591605007 +Augeas: + type: programming + extensions: + - ".aug" + tm_scope: none + ace_mode: text + language_id: 25 +AutoHotkey: + type: programming + color: "#6594b9" + aliases: + - ahk + extensions: + - ".ahk" + - ".ahkl" + tm_scope: source.ahk + ace_mode: autohotkey + language_id: 26 +AutoIt: + type: programming + color: "#1C3552" + aliases: + - au3 + - AutoIt3 + - AutoItScript + extensions: + - ".au3" + tm_scope: source.autoit + ace_mode: autohotkey + language_id: 27 +Awk: + type: programming + extensions: + - ".awk" + - ".auk" + - ".gawk" + - ".mawk" + - ".nawk" + interpreters: + - awk + - gawk + - mawk + - nawk + tm_scope: source.awk + ace_mode: text + language_id: 28 +Ballerina: + type: programming + extensions: + - ".bal" + tm_scope: source.ballerina + ace_mode: text + color: "#FF5000" + language_id: 720859680 +Batchfile: + type: programming + aliases: + - bat + - batch + - dosbatch + - winbatch + extensions: + - ".bat" + - ".cmd" + tm_scope: source.batchfile + ace_mode: batchfile + color: "#C1F12E" + language_id: 29 +Befunge: + type: programming + extensions: + - ".befunge" + tm_scope: source.befunge + ace_mode: text + language_id: 30 +BibTeX: + type: markup + group: TeX + extensions: + - ".bib" + tm_scope: text.bibtex + ace_mode: tex + codemirror_mode: stex + codemirror_mime_type: text/x-stex + language_id: 982188347 +Bison: + type: programming + group: Yacc + tm_scope: source.yacc + extensions: + - ".bison" + ace_mode: text + language_id: 31 +BitBake: + type: programming + tm_scope: none + extensions: + - ".bb" + ace_mode: text + language_id: 32 +Blade: + type: markup + group: HTML + extensions: + - ".blade" + - ".blade.php" + tm_scope: text.html.php.blade + ace_mode: text + language_id: 33 +BlitzBasic: + type: programming + aliases: + - b3d + - blitz3d + - blitzplus + - bplus + extensions: + - ".bb" + - ".decls" + tm_scope: source.blitzmax + ace_mode: text + language_id: 34 +BlitzMax: + type: programming + color: "#cd6400" + extensions: + - ".bmx" + aliases: + - bmax + tm_scope: source.blitzmax + ace_mode: text + language_id: 35 +Bluespec: + type: programming + extensions: + - ".bsv" + tm_scope: source.bsv + ace_mode: verilog + language_id: 36 +Boo: + type: programming + color: "#d4bec1" + extensions: + - ".boo" + ace_mode: text + tm_scope: source.boo + language_id: 37 +Brainfuck: + type: programming + color: "#2F2530" + extensions: + - ".b" + - ".bf" + tm_scope: source.bf + ace_mode: text + codemirror_mode: brainfuck + codemirror_mime_type: text/x-brainfuck + language_id: 38 +Brightscript: + type: programming + extensions: + - ".brs" + tm_scope: source.brightscript + ace_mode: text + language_id: 39 +C: + type: programming + color: "#555555" + extensions: + - ".c" + - ".cats" + - ".h" + - ".idc" + interpreters: + - tcc + tm_scope: source.c + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 41 +C#: + type: programming + ace_mode: csharp + codemirror_mode: clike + codemirror_mime_type: text/x-csharp + tm_scope: source.cs + color: "#178600" + aliases: + - csharp + extensions: + - ".cs" + - ".cake" + - ".csx" + language_id: 42 +C++: + type: programming + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + color: "#f34b7d" + aliases: + - cpp + extensions: + - ".cpp" + - ".c++" + - ".cc" + - ".cp" + - ".cxx" + - ".h" + - ".h++" + - ".hh" + - ".hpp" + - ".hxx" + - ".inc" + - ".inl" + - ".ino" + - ".ipp" + - ".re" + - ".tcc" + - ".tpp" + language_id: 43 +C-ObjDump: + type: data + extensions: + - ".c-objdump" + tm_scope: objdump.x86asm + ace_mode: assembly_x86 + language_id: 44 +C2hs Haskell: + type: programming + group: Haskell + aliases: + - c2hs + extensions: + - ".chs" + tm_scope: source.haskell + ace_mode: haskell + codemirror_mode: haskell + codemirror_mime_type: text/x-haskell + language_id: 45 +CLIPS: + type: programming + extensions: + - ".clp" + tm_scope: source.clips + ace_mode: text + language_id: 46 +CMake: + type: programming + extensions: + - ".cmake" + - ".cmake.in" + filenames: + - CMakeLists.txt + tm_scope: source.cmake + ace_mode: text + codemirror_mode: cmake + codemirror_mime_type: text/x-cmake + language_id: 47 +COBOL: + type: programming + extensions: + - ".cob" + - ".cbl" + - ".ccp" + - ".cobol" + - ".cpy" + tm_scope: source.cobol + ace_mode: cobol + codemirror_mode: cobol + codemirror_mime_type: text/x-cobol + language_id: 48 +COLLADA: + type: data + extensions: + - ".dae" + tm_scope: text.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 49 +CSON: + type: data + tm_scope: source.coffee + ace_mode: coffee + codemirror_mode: coffeescript + codemirror_mime_type: text/x-coffeescript + extensions: + - ".cson" + language_id: 424 +CSS: + type: markup + tm_scope: source.css + ace_mode: css + codemirror_mode: css + codemirror_mime_type: text/css + color: "#563d7c" + extensions: + - ".css" + language_id: 50 +CSV: + type: data + ace_mode: text + tm_scope: none + extensions: + - ".csv" + language_id: 51 +CWeb: + type: programming + extensions: + - ".w" + tm_scope: none + ace_mode: text + language_id: 657332628 +Cabal Config: + type: data + aliases: + - Cabal + extensions: + - ".cabal" + filenames: + - cabal.config + - cabal.project + ace_mode: haskell + codemirror_mode: haskell + codemirror_mime_type: text/x-haskell + tm_scope: source.cabal + language_id: 677095381 +Cap'n Proto: + type: programming + tm_scope: source.capnp + extensions: + - ".capnp" + ace_mode: text + language_id: 52 +CartoCSS: + type: programming + aliases: + - Carto + extensions: + - ".mss" + ace_mode: text + tm_scope: source.css.mss + language_id: 53 +Ceylon: + type: programming + color: "#dfa535" + extensions: + - ".ceylon" + tm_scope: source.ceylon + ace_mode: text + language_id: 54 +Chapel: + type: programming + color: "#8dc63f" + aliases: + - chpl + extensions: + - ".chpl" + tm_scope: source.chapel + ace_mode: text + language_id: 55 +Charity: + type: programming + extensions: + - ".ch" + tm_scope: none + ace_mode: text + language_id: 56 +ChucK: + type: programming + extensions: + - ".ck" + tm_scope: source.java + ace_mode: java + codemirror_mode: clike + codemirror_mime_type: text/x-java + language_id: 57 +Cirru: + type: programming + color: "#ccccff" + tm_scope: source.cirru + ace_mode: cirru + extensions: + - ".cirru" + language_id: 58 +Clarion: + type: programming + color: "#db901e" + ace_mode: text + extensions: + - ".clw" + tm_scope: source.clarion + language_id: 59 +Clean: + type: programming + color: "#3F85AF" + extensions: + - ".icl" + - ".dcl" + tm_scope: source.clean + ace_mode: text + language_id: 60 +Click: + type: programming + color: "#E4E6F3" + extensions: + - ".click" + tm_scope: source.click + ace_mode: text + language_id: 61 +Clojure: + type: programming + tm_scope: source.clojure + ace_mode: clojure + codemirror_mode: clojure + codemirror_mime_type: text/x-clojure + color: "#db5855" + extensions: + - ".clj" + - ".boot" + - ".cl2" + - ".cljc" + - ".cljs" + - ".cljs.hl" + - ".cljscm" + - ".cljx" + - ".hic" + filenames: + - riemann.config + language_id: 62 +Closure Templates: + type: markup + group: HTML + ace_mode: soy_template + codemirror_mode: soy + codemirror_mime_type: text/x-soy + aliases: + - soy + extensions: + - ".soy" + tm_scope: text.html.soy + language_id: 357046146 +Cloud Firestore Security Rules: + type: data + ace_mode: less + codemirror_mode: css + codemirror_mime_type: text/css + tm_scope: source.firestore + filenames: + - firestore.rules + language_id: 407996372 +CoNLL-U: + type: data + extensions: + - ".conllu" + - ".conll" + tm_scope: text.conllu + ace_mode: text + aliases: + - CoNLL + - CoNLL-X + language_id: 421026389 +CoffeeScript: + type: programming + tm_scope: source.coffee + ace_mode: coffee + codemirror_mode: coffeescript + codemirror_mime_type: text/x-coffeescript + color: "#244776" + aliases: + - coffee + - coffee-script + extensions: + - ".coffee" + - "._coffee" + - ".cake" + - ".cjsx" + - ".iced" + filenames: + - Cakefile + interpreters: + - coffee + language_id: 63 +ColdFusion: + type: programming + ace_mode: coldfusion + color: "#ed2cd6" + aliases: + - cfm + - cfml + - coldfusion html + extensions: + - ".cfm" + - ".cfml" + tm_scope: text.html.cfm + language_id: 64 +ColdFusion CFC: + type: programming + group: ColdFusion + ace_mode: coldfusion + aliases: + - cfc + extensions: + - ".cfc" + tm_scope: source.cfscript + language_id: 65 +Common Lisp: + type: programming + tm_scope: source.lisp + color: "#3fb68b" + aliases: + - lisp + extensions: + - ".lisp" + - ".asd" + - ".cl" + - ".l" + - ".lsp" + - ".ny" + - ".podsl" + - ".sexp" + interpreters: + - lisp + - sbcl + - ccl + - clisp + - ecl + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 66 +Common Workflow Language: + aliases: + - cwl + type: programming + ace_mode: yaml + codemirror_mode: yaml + codemirror_mime_type: text/x-yaml + extensions: + - ".cwl" + interpreters: + - cwl-runner + color: "#B5314C" + tm_scope: source.cwl + language_id: 988547172 +Component Pascal: + type: programming + color: "#B0CE4E" + extensions: + - ".cp" + - ".cps" + tm_scope: source.pascal + aliases: + - delphi + - objectpascal + ace_mode: pascal + codemirror_mode: pascal + codemirror_mime_type: text/x-pascal + language_id: 67 +Cool: + type: programming + extensions: + - ".cl" + tm_scope: source.cool + ace_mode: text + language_id: 68 +Coq: + type: programming + extensions: + - ".coq" + - ".v" + tm_scope: source.coq + ace_mode: text + language_id: 69 +Cpp-ObjDump: + type: data + extensions: + - ".cppobjdump" + - ".c++-objdump" + - ".c++objdump" + - ".cpp-objdump" + - ".cxx-objdump" + tm_scope: objdump.x86asm + aliases: + - c++-objdump + ace_mode: assembly_x86 + language_id: 70 +Creole: + type: prose + wrap: true + extensions: + - ".creole" + tm_scope: text.html.creole + ace_mode: text + language_id: 71 +Crystal: + type: programming + color: "#000100" + extensions: + - ".cr" + ace_mode: ruby + codemirror_mode: crystal + codemirror_mime_type: text/x-crystal + tm_scope: source.crystal + interpreters: + - crystal + language_id: 72 +Csound: + type: programming + aliases: + - csound-orc + extensions: + - ".orc" + - ".udo" + tm_scope: source.csound + ace_mode: csound_orchestra + language_id: 73 +Csound Document: + type: programming + aliases: + - csound-csd + extensions: + - ".csd" + tm_scope: source.csound-document + ace_mode: csound_document + language_id: 74 +Csound Score: + type: programming + aliases: + - csound-sco + extensions: + - ".sco" + tm_scope: source.csound-score + ace_mode: csound_score + language_id: 75 +Cuda: + type: programming + extensions: + - ".cu" + - ".cuh" + tm_scope: source.cuda-c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + color: "#3A4E3A" + language_id: 77 +Cycript: + type: programming + extensions: + - ".cy" + tm_scope: source.js + ace_mode: javascript + codemirror_mode: javascript + codemirror_mime_type: text/javascript + language_id: 78 +Cython: + type: programming + group: Python + extensions: + - ".pyx" + - ".pxd" + - ".pxi" + aliases: + - pyrex + tm_scope: source.cython + ace_mode: text + codemirror_mode: python + codemirror_mime_type: text/x-cython + language_id: 79 +D: + type: programming + color: "#ba595e" + extensions: + - ".d" + - ".di" + tm_scope: source.d + ace_mode: d + codemirror_mode: d + codemirror_mime_type: text/x-d + language_id: 80 +D-ObjDump: + type: data + extensions: + - ".d-objdump" + tm_scope: objdump.x86asm + ace_mode: assembly_x86 + language_id: 81 +DIGITAL Command Language: + type: programming + aliases: + - dcl + extensions: + - ".com" + tm_scope: none + ace_mode: text + language_id: 82 +DM: + type: programming + color: "#447265" + extensions: + - ".dm" + aliases: + - byond + tm_scope: source.dm + ace_mode: c_cpp + language_id: 83 +DNS Zone: + type: data + extensions: + - ".zone" + - ".arpa" + tm_scope: text.zone_file + ace_mode: text + language_id: 84 +DTrace: + type: programming + aliases: + - dtrace-script + extensions: + - ".d" + interpreters: + - dtrace + tm_scope: source.c + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 85 +Darcs Patch: + type: data + aliases: + - dpatch + extensions: + - ".darcspatch" + - ".dpatch" + tm_scope: none + ace_mode: text + language_id: 86 +Dart: + type: programming + color: "#00B4AB" + extensions: + - ".dart" + interpreters: + - dart + tm_scope: source.dart + ace_mode: dart + codemirror_mode: dart + codemirror_mime_type: application/dart + language_id: 87 +DataWeave: + type: programming + color: "#003a52" + extensions: + - ".dwl" + ace_mode: text + tm_scope: source.data-weave + language_id: 974514097 +Dhall: + type: programming + color: "#dfafff" + extensions: + - ".dhall" + tm_scope: source.haskell + ace_mode: haskell + codemirror_mode: haskell + codemirror_mime_type: text/x-haskell + language_id: 793969321 +Diff: + type: data + extensions: + - ".diff" + - ".patch" + aliases: + - udiff + tm_scope: source.diff + ace_mode: diff + codemirror_mode: diff + codemirror_mime_type: text/x-diff + language_id: 88 +Dockerfile: + type: programming + color: "#384d54" + tm_scope: source.dockerfile + extensions: + - ".dockerfile" + filenames: + - Dockerfile + ace_mode: dockerfile + codemirror_mode: dockerfile + codemirror_mime_type: text/x-dockerfile + language_id: 89 +Dogescript: + type: programming + color: "#cca760" + extensions: + - ".djs" + tm_scope: none + ace_mode: text + language_id: 90 +Dylan: + type: programming + color: "#6c616e" + extensions: + - ".dylan" + - ".dyl" + - ".intr" + - ".lid" + tm_scope: source.dylan + ace_mode: text + codemirror_mode: dylan + codemirror_mime_type: text/x-dylan + language_id: 91 +E: + type: programming + color: "#ccce35" + extensions: + - ".E" + interpreters: + - rune + tm_scope: none + ace_mode: text + language_id: 92 +EBNF: + type: data + extensions: + - ".ebnf" + tm_scope: source.ebnf + ace_mode: text + codemirror_mode: ebnf + codemirror_mime_type: text/x-ebnf + language_id: 430 +ECL: + type: programming + color: "#8a1267" + extensions: + - ".ecl" + - ".eclxml" + tm_scope: none + ace_mode: text + codemirror_mode: ecl + codemirror_mime_type: text/x-ecl + language_id: 93 +ECLiPSe: + type: programming + group: prolog + extensions: + - ".ecl" + tm_scope: source.prolog.eclipse + ace_mode: prolog + language_id: 94 +EJS: + type: markup + group: HTML + extensions: + - ".ejs" + tm_scope: text.html.js + ace_mode: ejs + language_id: 95 +EML: + type: data + extensions: + - ".eml" + - ".mbox" + tm_scope: text.eml.basic + ace_mode: text + language_id: 529653389 +EQ: + type: programming + color: "#a78649" + extensions: + - ".eq" + tm_scope: source.cs + ace_mode: csharp + codemirror_mode: clike + codemirror_mime_type: text/x-csharp + language_id: 96 +Eagle: + type: data + extensions: + - ".sch" + - ".brd" + tm_scope: text.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 97 +Easybuild: + type: data + group: Python + ace_mode: python + codemirror_mode: python + codemirror_mime_type: text/x-python + tm_scope: source.python + extensions: + - ".eb" + language_id: 342840477 +Ecere Projects: + type: data + group: JavaScript + extensions: + - ".epj" + tm_scope: source.json + ace_mode: json + codemirror_mode: javascript + codemirror_mime_type: application/json + language_id: 98 +EditorConfig: + type: data + group: INI + filenames: + - ".editorconfig" + aliases: + - editor-config + ace_mode: ini + codemirror_mode: properties + codemirror_mime_type: text/x-properties + tm_scope: source.editorconfig + language_id: 96139566 +Edje Data Collection: + type: data + extensions: + - ".edc" + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + language_id: 342840478 +Eiffel: + type: programming + color: "#946d57" + extensions: + - ".e" + tm_scope: source.eiffel + ace_mode: eiffel + codemirror_mode: eiffel + codemirror_mime_type: text/x-eiffel + language_id: 99 +Elixir: + type: programming + color: "#6e4a7e" + extensions: + - ".ex" + - ".exs" + tm_scope: source.elixir + ace_mode: elixir + filenames: + - mix.lock + interpreters: + - elixir + language_id: 100 +Elm: + type: programming + color: "#60B5CC" + extensions: + - ".elm" + tm_scope: source.elm + ace_mode: elm + codemirror_mode: elm + codemirror_mime_type: text/x-elm + language_id: 101 +Emacs Lisp: + type: programming + tm_scope: source.emacs.lisp + color: "#c065db" + aliases: + - elisp + - emacs + filenames: + - ".abbrev_defs" + - ".emacs" + - ".emacs.desktop" + - ".gnus" + - ".spacemacs" + - ".viper" + - Cask + - Project.ede + - _emacs + - abbrev_defs + extensions: + - ".el" + - ".emacs" + - ".emacs.desktop" + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 102 +EmberScript: + type: programming + color: "#FFF4F3" + extensions: + - ".em" + - ".emberscript" + tm_scope: source.coffee + ace_mode: coffee + codemirror_mode: coffeescript + codemirror_mime_type: text/x-coffeescript + language_id: 103 +Erlang: + type: programming + color: "#B83998" + extensions: + - ".erl" + - ".app.src" + - ".es" + - ".escript" + - ".hrl" + - ".xrl" + - ".yrl" + filenames: + - Emakefile + - rebar.config + - rebar.config.lock + - rebar.lock + tm_scope: source.erlang + ace_mode: erlang + codemirror_mode: erlang + codemirror_mime_type: text/x-erlang + interpreters: + - escript + language_id: 104 +F#: + type: programming + color: "#b845fc" + aliases: + - fsharp + extensions: + - ".fs" + - ".fsi" + - ".fsx" + tm_scope: source.fsharp + ace_mode: text + codemirror_mode: mllike + codemirror_mime_type: text/x-fsharp + language_id: 105 +F*: + fs_name: Fstar + type: programming + color: "#572e30" + aliases: + - fstar + extensions: + - ".fst" + tm_scope: source.fstar + ace_mode: text + language_id: 336943375 +FIGlet Font: + type: data + aliases: + - FIGfont + extensions: + - ".flf" + tm_scope: source.figfont + ace_mode: text + language_id: 686129783 +FLUX: + type: programming + color: "#88ccff" + extensions: + - ".fx" + - ".flux" + tm_scope: none + ace_mode: text + language_id: 106 +Factor: + type: programming + color: "#636746" + extensions: + - ".factor" + filenames: + - ".factor-boot-rc" + - ".factor-rc" + tm_scope: source.factor + ace_mode: text + codemirror_mode: factor + codemirror_mime_type: text/x-factor + language_id: 108 +Fancy: + type: programming + color: "#7b9db4" + extensions: + - ".fy" + - ".fancypack" + filenames: + - Fakefile + tm_scope: source.fancy + ace_mode: text + language_id: 109 +Fantom: + type: programming + color: "#14253c" + extensions: + - ".fan" + tm_scope: source.fan + ace_mode: text + language_id: 110 +Filebench WML: + type: programming + extensions: + - ".f" + tm_scope: none + ace_mode: text + language_id: 111 +Filterscript: + type: programming + group: RenderScript + extensions: + - ".fs" + tm_scope: none + ace_mode: text + language_id: 112 +Formatted: + type: data + extensions: + - ".for" + - ".eam.fs" + tm_scope: none + ace_mode: text + language_id: 113 +Forth: + type: programming + color: "#341708" + extensions: + - ".fth" + - ".4th" + - ".f" + - ".for" + - ".forth" + - ".fr" + - ".frt" + - ".fs" + tm_scope: source.forth + ace_mode: forth + codemirror_mode: forth + codemirror_mime_type: text/x-forth + language_id: 114 +Fortran: + type: programming + color: "#4d41b1" + extensions: + - ".f90" + - ".f" + - ".f03" + - ".f08" + - ".f77" + - ".f95" + - ".for" + - ".fpp" + tm_scope: source.fortran.modern + ace_mode: text + codemirror_mode: fortran + codemirror_mime_type: text/x-fortran + language_id: 107 +FreeMarker: + type: programming + color: "#0050b2" + aliases: + - ftl + extensions: + - ".ftl" + tm_scope: text.html.ftl + ace_mode: ftl + language_id: 115 +Frege: + type: programming + color: "#00cafe" + extensions: + - ".fr" + tm_scope: source.haskell + ace_mode: haskell + language_id: 116 +G-code: + type: programming + color: "#D08CF2" + extensions: + - ".g" + - ".cnc" + - ".gco" + - ".gcode" + tm_scope: source.gcode + ace_mode: gcode + language_id: 117 +GAML: + type: programming + color: "#FFC766" + extensions: + - ".gaml" + tm_scope: none + ace_mode: text + language_id: 290345951 +GAMS: + type: programming + extensions: + - ".gms" + tm_scope: none + ace_mode: text + language_id: 118 +GAP: + type: programming + extensions: + - ".g" + - ".gap" + - ".gd" + - ".gi" + - ".tst" + tm_scope: source.gap + ace_mode: text + language_id: 119 +GCC Machine Description: + type: programming + extensions: + - ".md" + tm_scope: source.lisp + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 121 +GDB: + type: programming + extensions: + - ".gdb" + - ".gdbinit" + tm_scope: source.gdb + ace_mode: text + language_id: 122 +GDScript: + type: programming + color: "#355570" + extensions: + - ".gd" + tm_scope: source.gdscript + ace_mode: text + language_id: 123 +GLSL: + type: programming + extensions: + - ".glsl" + - ".fp" + - ".frag" + - ".frg" + - ".fs" + - ".fsh" + - ".fshader" + - ".geo" + - ".geom" + - ".glslv" + - ".gshader" + - ".shader" + - ".tesc" + - ".tese" + - ".vert" + - ".vrx" + - ".vsh" + - ".vshader" + tm_scope: source.glsl + ace_mode: glsl + language_id: 124 +GN: + type: data + extensions: + - ".gn" + - ".gni" + interpreters: + - gn + filenames: + - ".gn" + tm_scope: source.gn + ace_mode: python + codemirror_mode: python + codemirror_mime_type: text/x-python + language_id: 302957008 +Game Maker Language: + type: programming + color: "#71b417" + extensions: + - ".gml" + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + language_id: 125 +Genie: + type: programming + ace_mode: text + extensions: + - ".gs" + color: "#fb855d" + tm_scope: none + language_id: 792408528 +Genshi: + type: programming + extensions: + - ".kid" + tm_scope: text.xml.genshi + aliases: + - xml+genshi + - xml+kid + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 126 +Gentoo Ebuild: + type: programming + group: Shell + extensions: + - ".ebuild" + tm_scope: source.shell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 127 +Gentoo Eclass: + type: programming + group: Shell + extensions: + - ".eclass" + tm_scope: source.shell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 128 +Gerber Image: + type: data + aliases: + - rs-274x + extensions: + - ".gbr" + - ".gbl" + - ".gbo" + - ".gbp" + - ".gbs" + - ".gko" + - ".gml" + - ".gpb" + - ".gpt" + - ".gtl" + - ".gto" + - ".gtp" + - ".gts" + interpreters: + - gerbv + - gerbview + tm_scope: source.gerber + ace_mode: text + language_id: 404627610 +Gettext Catalog: + type: prose + searchable: false + aliases: + - pot + extensions: + - ".po" + - ".pot" + tm_scope: source.po + ace_mode: text + language_id: 129 +Gherkin: + type: programming + extensions: + - ".feature" + tm_scope: text.gherkin.feature + aliases: + - cucumber + ace_mode: text + color: "#5B2063" + language_id: 76 +Git Attributes: + type: data + group: INI + aliases: + - gitattributes + filenames: + - ".gitattributes" + tm_scope: source.gitattributes + ace_mode: gitignore + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 956324166 +Git Config: + type: data + group: INI + aliases: + - gitconfig + - gitmodules + extensions: + - ".gitconfig" + filenames: + - ".gitconfig" + - ".gitmodules" + ace_mode: ini + codemirror_mode: properties + codemirror_mime_type: text/x-properties + tm_scope: source.gitconfig + language_id: 807968997 +Glyph: + type: programming + color: "#c1ac7f" + extensions: + - ".glf" + tm_scope: source.tcl + ace_mode: tcl + codemirror_mode: tcl + codemirror_mime_type: text/x-tcl + language_id: 130 +Glyph Bitmap Distribution Format: + type: data + extensions: + - ".bdf" + tm_scope: source.bdf + ace_mode: text + language_id: 997665271 +Gnuplot: + type: programming + color: "#f0a9f0" + extensions: + - ".gp" + - ".gnu" + - ".gnuplot" + - ".plot" + - ".plt" + interpreters: + - gnuplot + tm_scope: source.gnuplot + ace_mode: text + language_id: 131 +Go: + type: programming + color: "#00ADD8" + aliases: + - golang + extensions: + - ".go" + tm_scope: source.go + ace_mode: golang + codemirror_mode: go + codemirror_mime_type: text/x-go + language_id: 132 +Golo: + type: programming + color: "#88562A" + extensions: + - ".golo" + tm_scope: source.golo + ace_mode: text + language_id: 133 +Gosu: + type: programming + color: "#82937f" + extensions: + - ".gs" + - ".gst" + - ".gsx" + - ".vark" + tm_scope: source.gosu.2 + ace_mode: text + language_id: 134 +Grace: + type: programming + extensions: + - ".grace" + tm_scope: source.grace + ace_mode: text + language_id: 135 +Gradle: + type: data + extensions: + - ".gradle" + tm_scope: source.groovy.gradle + ace_mode: text + language_id: 136 +Grammatical Framework: + type: programming + aliases: + - gf + extensions: + - ".gf" + color: "#79aa7a" + tm_scope: source.gf + ace_mode: haskell + codemirror_mode: haskell + codemirror_mime_type: text/x-haskell + language_id: 137 +Graph Modeling Language: + type: data + extensions: + - ".gml" + tm_scope: none + ace_mode: text + language_id: 138 +GraphQL: + type: data + extensions: + - ".graphql" + - ".gql" + - ".graphqls" + tm_scope: source.graphql + ace_mode: text + language_id: 139 +Graphviz (DOT): + type: data + tm_scope: source.dot + extensions: + - ".dot" + - ".gv" + ace_mode: text + language_id: 140 +Groovy: + type: programming + tm_scope: source.groovy + ace_mode: groovy + codemirror_mode: groovy + codemirror_mime_type: text/x-groovy + color: "#e69f56" + extensions: + - ".groovy" + - ".grt" + - ".gtpl" + - ".gvy" + interpreters: + - groovy + filenames: + - Jenkinsfile + language_id: 142 +Groovy Server Pages: + type: programming + group: Groovy + aliases: + - gsp + - java server page + extensions: + - ".gsp" + tm_scope: text.html.jsp + ace_mode: jsp + codemirror_mode: htmlembedded + codemirror_mime_type: application/x-jsp + language_id: 143 +HAProxy: + type: data + extensions: + - ".cfg" + filenames: + - haproxy.cfg + tm_scope: source.haproxy-config + ace_mode: text + language_id: 366607477 +HCL: + type: programming + extensions: + - ".hcl" + - ".tf" + - ".tfvars" + - ".workflow" + aliases: + - terraform + ace_mode: ruby + codemirror_mode: ruby + codemirror_mime_type: text/x-ruby + tm_scope: source.terraform + language_id: 144 +HLSL: + type: programming + extensions: + - ".hlsl" + - ".cginc" + - ".fx" + - ".fxh" + - ".hlsli" + ace_mode: text + tm_scope: source.hlsl + language_id: 145 +HTML: + type: markup + tm_scope: text.html.basic + ace_mode: html + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + color: "#e34c26" + aliases: + - xhtml + extensions: + - ".html" + - ".htm" + - ".html.hl" + - ".inc" + - ".st" + - ".xht" + - ".xhtml" + language_id: 146 +HTML+Django: + type: markup + tm_scope: text.html.django + group: HTML + extensions: + - ".jinja" + - ".jinja2" + - ".mustache" + - ".njk" + aliases: + - django + - html+django/jinja + - html+jinja + - htmldjango + - njk + - nunjucks + ace_mode: django + codemirror_mode: django + codemirror_mime_type: text/x-django + language_id: 147 +HTML+ECR: + type: markup + tm_scope: text.html.ecr + group: HTML + aliases: + - ecr + extensions: + - ".ecr" + ace_mode: text + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + language_id: 148 +HTML+EEX: + type: markup + tm_scope: text.html.elixir + group: HTML + aliases: + - eex + extensions: + - ".eex" + ace_mode: text + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + language_id: 149 +HTML+ERB: + type: markup + tm_scope: text.html.erb + group: HTML + aliases: + - erb + extensions: + - ".erb" + - ".erb.deface" + ace_mode: text + codemirror_mode: htmlembedded + codemirror_mime_type: application/x-erb + language_id: 150 +HTML+PHP: + type: markup + tm_scope: text.html.php + group: HTML + extensions: + - ".phtml" + ace_mode: php + codemirror_mode: php + codemirror_mime_type: application/x-httpd-php + language_id: 151 +HTML+Razor: + type: markup + tm_scope: text.html.cshtml + group: HTML + aliases: + - razor + extensions: + - ".cshtml" + - ".razor" + ace_mode: razor + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + language_id: 479039817 +HTTP: + type: data + extensions: + - ".http" + tm_scope: source.httpspec + ace_mode: text + codemirror_mode: http + codemirror_mime_type: message/http + language_id: 152 +HXML: + type: data + ace_mode: text + extensions: + - ".hxml" + tm_scope: source.hxml + language_id: 786683730 +Hack: + type: programming + ace_mode: php + codemirror_mode: php + codemirror_mime_type: application/x-httpd-php + extensions: + - ".hack" + - ".hh" + - ".php" + tm_scope: source.hack + color: "#878787" + language_id: 153 +Haml: + group: HTML + type: markup + extensions: + - ".haml" + - ".haml.deface" + tm_scope: text.haml + ace_mode: haml + codemirror_mode: haml + codemirror_mime_type: text/x-haml + language_id: 154 +Handlebars: + type: markup + group: HTML + aliases: + - hbs + - htmlbars + extensions: + - ".handlebars" + - ".hbs" + tm_scope: text.html.handlebars + ace_mode: handlebars + language_id: 155 +Harbour: + type: programming + color: "#0e60e3" + extensions: + - ".hb" + tm_scope: source.harbour + ace_mode: text + language_id: 156 +Haskell: + type: programming + color: "#5e5086" + extensions: + - ".hs" + - ".hsc" + interpreters: + - runhaskell + tm_scope: source.haskell + ace_mode: haskell + codemirror_mode: haskell + codemirror_mime_type: text/x-haskell + language_id: 157 +Haxe: + type: programming + ace_mode: haxe + codemirror_mode: haxe + codemirror_mime_type: text/x-haxe + color: "#df7900" + extensions: + - ".hx" + - ".hxsl" + tm_scope: source.hx + language_id: 158 +HiveQL: + type: programming + extensions: + - ".q" + color: "#dce200" + tm_scope: source.hql + ace_mode: sql + language_id: 931814087 +HolyC: + type: programming + color: "#ffefaf" + extensions: + - ".hc" + tm_scope: source.hc + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 928121743 +Hy: + type: programming + ace_mode: text + color: "#7790B2" + extensions: + - ".hy" + interpreters: + - hy + aliases: + - hylang + tm_scope: source.hy + language_id: 159 +HyPhy: + type: programming + ace_mode: text + extensions: + - ".bf" + tm_scope: none + language_id: 160 +IDL: + type: programming + color: "#a3522f" + extensions: + - ".pro" + - ".dlm" + tm_scope: source.idl + ace_mode: text + codemirror_mode: idl + codemirror_mime_type: text/x-idl + language_id: 161 +IGOR Pro: + type: programming + color: "#0000cc" + extensions: + - ".ipf" + aliases: + - igor + - igorpro + tm_scope: source.igor + ace_mode: text + language_id: 162 +INI: + type: data + extensions: + - ".ini" + - ".cfg" + - ".lektorproject" + - ".prefs" + - ".pro" + - ".properties" + filenames: + - buildozer.spec + tm_scope: source.ini + aliases: + - dosini + ace_mode: ini + codemirror_mode: properties + codemirror_mime_type: text/x-properties + language_id: 163 +IRC log: + type: data + aliases: + - irc + - irc logs + extensions: + - ".irclog" + - ".weechatlog" + tm_scope: none + ace_mode: text + codemirror_mode: mirc + codemirror_mime_type: text/mirc + language_id: 164 +Idris: + type: programming + color: "#b30000" + extensions: + - ".idr" + - ".lidr" + ace_mode: text + tm_scope: source.idris + language_id: 165 +Ignore List: + type: data + group: INI + aliases: + - ignore + - gitignore + - git-ignore + extensions: + - ".gitignore" + filenames: + - ".atomignore" + - ".babelignore" + - ".bzrignore" + - ".coffeelintignore" + - ".cvsignore" + - ".dockerignore" + - ".eslintignore" + - ".gitignore" + - ".nodemonignore" + - ".npmignore" + - ".prettierignore" + - ".stylelintignore" + - ".vscodeignore" + - gitignore-global + - gitignore_global + ace_mode: gitignore + tm_scope: source.gitignore + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 74444240 +Inform 7: + type: programming + wrap: true + extensions: + - ".ni" + - ".i7x" + tm_scope: source.inform7 + aliases: + - i7 + - inform7 + ace_mode: text + language_id: 166 +Inno Setup: + type: programming + extensions: + - ".iss" + tm_scope: none + ace_mode: text + language_id: 167 +Io: + type: programming + color: "#a9188d" + extensions: + - ".io" + interpreters: + - io + tm_scope: source.io + ace_mode: io + language_id: 168 +Ioke: + type: programming + color: "#078193" + extensions: + - ".ik" + interpreters: + - ioke + tm_scope: source.ioke + ace_mode: text + language_id: 169 +Isabelle: + type: programming + color: "#FEFE00" + extensions: + - ".thy" + tm_scope: source.isabelle.theory + ace_mode: text + language_id: 170 +Isabelle ROOT: + type: programming + group: Isabelle + filenames: + - ROOT + tm_scope: source.isabelle.root + ace_mode: text + language_id: 171 +J: + type: programming + color: "#9EEDFF" + extensions: + - ".ijs" + interpreters: + - jconsole + tm_scope: source.j + ace_mode: text + language_id: 172 +JFlex: + type: programming + group: Lex + extensions: + - ".flex" + - ".jflex" + tm_scope: source.jflex + ace_mode: text + language_id: 173 +JSON: + type: data + tm_scope: source.json + ace_mode: json + codemirror_mode: javascript + codemirror_mime_type: application/json + searchable: false + extensions: + - ".json" + - ".avsc" + - ".geojson" + - ".gltf" + - ".har" + - ".ice" + - ".JSON-tmLanguage" + - ".jsonl" + - ".mcmeta" + - ".tfstate" + - ".tfstate.backup" + - ".topojson" + - ".webapp" + - ".webmanifest" + - ".yy" + - ".yyp" + filenames: + - ".arcconfig" + - ".htmlhintrc" + - ".tern-config" + - ".tern-project" + - ".watchmanconfig" + - composer.lock + - mcmod.info + language_id: 174 +JSON with Comments: + type: data + group: JSON + tm_scope: source.js + ace_mode: javascript + codemirror_mode: javascript + codemirror_mime_type: text/javascript + aliases: + - jsonc + extensions: + - ".sublime-build" + - ".sublime-commands" + - ".sublime-completions" + - ".sublime-keymap" + - ".sublime-macro" + - ".sublime-menu" + - ".sublime-mousemap" + - ".sublime-project" + - ".sublime-settings" + - ".sublime-theme" + - ".sublime-workspace" + - ".sublime_metrics" + - ".sublime_session" + filenames: + - ".babelrc" + - ".eslintrc.json" + - ".jscsrc" + - ".jshintrc" + - ".jslintrc" + - jsconfig.json + - language-configuration.json + - tsconfig.json + language_id: 423 +JSON5: + type: data + extensions: + - ".json5" + tm_scope: source.js + ace_mode: javascript + codemirror_mode: javascript + codemirror_mime_type: application/json + language_id: 175 +JSONLD: + type: data + extensions: + - ".jsonld" + tm_scope: source.js + ace_mode: javascript + codemirror_mode: javascript + codemirror_mime_type: application/json + language_id: 176 +JSONiq: + color: "#40d47e" + type: programming + ace_mode: jsoniq + codemirror_mode: javascript + codemirror_mime_type: application/json + extensions: + - ".jq" + tm_scope: source.jq + language_id: 177 +JSX: + type: programming + group: JavaScript + extensions: + - ".jsx" + tm_scope: source.js.jsx + ace_mode: javascript + codemirror_mode: jsx + codemirror_mime_type: text/jsx + language_id: 178 +Jasmin: + type: programming + ace_mode: java + extensions: + - ".j" + tm_scope: source.jasmin + language_id: 180 +Java: + type: programming + tm_scope: source.java + ace_mode: java + codemirror_mode: clike + codemirror_mime_type: text/x-java + color: "#b07219" + extensions: + - ".java" + language_id: 181 +Java Properties: + type: data + extensions: + - ".properties" + tm_scope: source.java-properties + ace_mode: properties + codemirror_mode: properties + codemirror_mime_type: text/x-properties + language_id: 519377561 +Java Server Pages: + type: programming + group: Java + aliases: + - jsp + extensions: + - ".jsp" + tm_scope: text.html.jsp + ace_mode: jsp + codemirror_mode: htmlembedded + codemirror_mime_type: application/x-jsp + language_id: 182 +JavaScript: + type: programming + tm_scope: source.js + ace_mode: javascript + codemirror_mode: javascript + codemirror_mime_type: text/javascript + color: "#f1e05a" + aliases: + - js + - node + extensions: + - ".js" + - "._js" + - ".bones" + - ".es" + - ".es6" + - ".frag" + - ".gs" + - ".jake" + - ".jsb" + - ".jscad" + - ".jsfl" + - ".jsm" + - ".jss" + - ".mjs" + - ".njs" + - ".pac" + - ".sjs" + - ".ssjs" + - ".xsjs" + - ".xsjslib" + filenames: + - Jakefile + interpreters: + - chakra + - d8 + - js + - node + - rhino + - v8 + - v8-shell + language_id: 183 +JavaScript+ERB: + type: programming + tm_scope: source.js + group: JavaScript + extensions: + - ".js.erb" + ace_mode: javascript + codemirror_mode: javascript + codemirror_mime_type: application/javascript + language_id: 914318960 +Jison: + type: programming + group: Yacc + extensions: + - ".jison" + tm_scope: source.jison + ace_mode: text + language_id: 284531423 +Jison Lex: + type: programming + group: Lex + extensions: + - ".jisonlex" + tm_scope: source.jisonlex + ace_mode: text + language_id: 406395330 +Jolie: + type: programming + extensions: + - ".ol" + - ".iol" + interpreters: + - jolie + color: "#843179" + ace_mode: text + tm_scope: source.jolie + language_id: 998078858 +Jsonnet: + color: "#0064bd" + type: programming + ace_mode: text + extensions: + - ".jsonnet" + - ".libsonnet" + tm_scope: source.jsonnet + language_id: 664885656 +Julia: + type: programming + extensions: + - ".jl" + interpreters: + - julia + color: "#a270ba" + tm_scope: source.julia + ace_mode: julia + codemirror_mode: julia + codemirror_mime_type: text/x-julia + language_id: 184 +Jupyter Notebook: + type: markup + ace_mode: json + codemirror_mode: javascript + codemirror_mime_type: application/json + tm_scope: source.json + color: "#DA5B0B" + extensions: + - ".ipynb" + filenames: + - Notebook + aliases: + - IPython Notebook + language_id: 185 +KRL: + type: programming + color: "#28430A" + extensions: + - ".krl" + tm_scope: none + ace_mode: text + language_id: 186 +KiCad Layout: + type: data + aliases: + - pcbnew + extensions: + - ".kicad_pcb" + - ".kicad_mod" + - ".kicad_wks" + filenames: + - fp-lib-table + tm_scope: source.pcb.sexp + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 187 +KiCad Legacy Layout: + type: data + extensions: + - ".brd" + tm_scope: source.pcb.board + ace_mode: text + language_id: 140848857 +KiCad Schematic: + type: data + aliases: + - eeschema schematic + extensions: + - ".sch" + tm_scope: source.pcb.schematic + ace_mode: text + language_id: 622447435 +Kit: + type: markup + ace_mode: html + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + extensions: + - ".kit" + tm_scope: text.html.basic + language_id: 188 +Kotlin: + type: programming + color: "#F18E33" + extensions: + - ".kt" + - ".ktm" + - ".kts" + tm_scope: source.kotlin + ace_mode: text + codemirror_mode: clike + codemirror_mime_type: text/x-kotlin + language_id: 189 +LFE: + type: programming + color: "#4C3023" + extensions: + - ".lfe" + tm_scope: source.lisp + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 190 +LLVM: + type: programming + extensions: + - ".ll" + tm_scope: source.llvm + ace_mode: text + color: "#185619" + language_id: 191 +LOLCODE: + type: programming + extensions: + - ".lol" + color: "#cc9900" + tm_scope: none + ace_mode: text + language_id: 192 +LSL: + type: programming + tm_scope: source.lsl + ace_mode: lsl + extensions: + - ".lsl" + - ".lslp" + interpreters: + - lsl + color: "#3d9970" + language_id: 193 +LTspice Symbol: + type: data + extensions: + - ".asy" + tm_scope: source.ltspice.symbol + ace_mode: text + codemirror_mode: spreadsheet + codemirror_mime_type: text/x-spreadsheet + language_id: 1013566805 +LabVIEW: + type: programming + extensions: + - ".lvproj" + tm_scope: text.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 194 +Lasso: + type: programming + color: "#999999" + extensions: + - ".lasso" + - ".las" + - ".lasso8" + - ".lasso9" + tm_scope: file.lasso + aliases: + - lassoscript + ace_mode: text + language_id: 195 +Latte: + type: markup + group: HTML + extensions: + - ".latte" + tm_scope: text.html.smarty + ace_mode: smarty + codemirror_mode: smarty + codemirror_mime_type: text/x-smarty + language_id: 196 +Lean: + type: programming + extensions: + - ".lean" + - ".hlean" + tm_scope: source.lean + ace_mode: text + language_id: 197 +Less: + type: markup + group: CSS + extensions: + - ".less" + tm_scope: source.css.less + ace_mode: less + codemirror_mode: css + codemirror_mime_type: text/css + language_id: 198 +Lex: + type: programming + color: "#DBCA00" + aliases: + - flex + extensions: + - ".l" + - ".lex" + tm_scope: source.lex + ace_mode: text + language_id: 199 +LilyPond: + type: programming + extensions: + - ".ly" + - ".ily" + tm_scope: source.lilypond + ace_mode: text + language_id: 200 +Limbo: + type: programming + extensions: + - ".b" + - ".m" + tm_scope: none + ace_mode: text + language_id: 201 +Linker Script: + type: data + extensions: + - ".ld" + - ".lds" + - ".x" + filenames: + - ld.script + tm_scope: none + ace_mode: text + language_id: 202 +Linux Kernel Module: + type: data + extensions: + - ".mod" + tm_scope: none + ace_mode: text + language_id: 203 +Liquid: + type: markup + extensions: + - ".liquid" + tm_scope: text.html.liquid + ace_mode: liquid + language_id: 204 +Literate Agda: + type: programming + group: Agda + extensions: + - ".lagda" + tm_scope: none + ace_mode: text + language_id: 205 +Literate CoffeeScript: + type: programming + tm_scope: source.litcoffee + group: CoffeeScript + ace_mode: text + wrap: true + aliases: + - litcoffee + extensions: + - ".litcoffee" + language_id: 206 +Literate Haskell: + type: programming + group: Haskell + aliases: + - lhaskell + - lhs + extensions: + - ".lhs" + tm_scope: text.tex.latex.haskell + ace_mode: text + codemirror_mode: haskell-literate + codemirror_mime_type: text/x-literate-haskell + language_id: 207 +LiveScript: + type: programming + color: "#499886" + aliases: + - live-script + - ls + extensions: + - ".ls" + - "._ls" + filenames: + - Slakefile + tm_scope: source.livescript + ace_mode: livescript + codemirror_mode: livescript + codemirror_mime_type: text/x-livescript + language_id: 208 +Logos: + type: programming + extensions: + - ".xm" + - ".x" + - ".xi" + ace_mode: text + tm_scope: source.logos + language_id: 209 +Logtalk: + type: programming + extensions: + - ".lgt" + - ".logtalk" + tm_scope: source.logtalk + ace_mode: text + language_id: 210 +LookML: + type: programming + ace_mode: yaml + codemirror_mode: yaml + codemirror_mime_type: text/x-yaml + color: "#652B81" + extensions: + - ".lookml" + - ".model.lkml" + - ".view.lkml" + tm_scope: source.yaml + language_id: 211 +LoomScript: + type: programming + extensions: + - ".ls" + tm_scope: source.loomscript + ace_mode: text + language_id: 212 +Lua: + type: programming + tm_scope: source.lua + ace_mode: lua + codemirror_mode: lua + codemirror_mime_type: text/x-lua + color: "#000080" + extensions: + - ".lua" + - ".fcgi" + - ".nse" + - ".p8" + - ".pd_lua" + - ".rbxs" + - ".wlua" + interpreters: + - lua + language_id: 213 +M: + type: programming + aliases: + - mumps + extensions: + - ".mumps" + - ".m" + ace_mode: text + codemirror_mode: mumps + codemirror_mime_type: text/x-mumps + language_id: 214 + tm_scope: none +M4: + type: programming + extensions: + - ".m4" + tm_scope: none + ace_mode: text + language_id: 215 +M4Sugar: + type: programming + group: M4 + aliases: + - autoconf + extensions: + - ".m4" + filenames: + - configure.ac + tm_scope: none + ace_mode: text + language_id: 216 +MATLAB: + type: programming + color: "#e16737" + aliases: + - octave + extensions: + - ".matlab" + - ".m" + tm_scope: source.matlab + ace_mode: matlab + codemirror_mode: octave + codemirror_mime_type: text/x-octave + language_id: 225 +MAXScript: + type: programming + color: "#00a6a6" + extensions: + - ".ms" + - ".mcr" + tm_scope: source.maxscript + ace_mode: text + language_id: 217 +MLIR: + type: programming + extensions: + - ".mlir" + tm_scope: source.mlir + ace_mode: text + language_id: 448253929 +MQL4: + type: programming + color: "#62A8D6" + extensions: + - ".mq4" + - ".mqh" + tm_scope: source.mql5 + ace_mode: c_cpp + language_id: 426 +MQL5: + type: programming + color: "#4A76B8" + extensions: + - ".mq5" + - ".mqh" + tm_scope: source.mql5 + ace_mode: c_cpp + language_id: 427 +MTML: + type: markup + color: "#b7e1f4" + extensions: + - ".mtml" + tm_scope: text.html.basic + ace_mode: html + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + language_id: 218 +MUF: + type: programming + group: Forth + extensions: + - ".muf" + - ".m" + tm_scope: none + ace_mode: forth + codemirror_mode: forth + codemirror_mime_type: text/x-forth + language_id: 219 +Makefile: + type: programming + color: "#427819" + aliases: + - bsdmake + - make + - mf + extensions: + - ".mak" + - ".d" + - ".make" + - ".mk" + - ".mkfile" + filenames: + - BSDmakefile + - GNUmakefile + - Kbuild + - Makefile + - Makefile.am + - Makefile.boot + - Makefile.frag + - Makefile.in + - Makefile.inc + - Makefile.wat + - makefile + - makefile.sco + - mkfile + interpreters: + - make + tm_scope: source.makefile + ace_mode: makefile + codemirror_mode: cmake + codemirror_mime_type: text/x-cmake + language_id: 220 +Mako: + type: programming + extensions: + - ".mako" + - ".mao" + tm_scope: text.html.mako + ace_mode: text + language_id: 221 +Markdown: + type: prose + aliases: + - pandoc + ace_mode: markdown + codemirror_mode: gfm + codemirror_mime_type: text/x-gfm + wrap: true + extensions: + - ".md" + - ".markdown" + - ".mdown" + - ".mdwn" + - ".mdx" + - ".mkd" + - ".mkdn" + - ".mkdown" + - ".ronn" + - ".workbook" + filenames: + - contents.lr + tm_scope: source.gfm + language_id: 222 +Marko: + group: HTML + type: markup + tm_scope: text.marko + extensions: + - ".marko" + aliases: + - markojs + ace_mode: text + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + language_id: 932782397 +Mask: + type: markup + color: "#f97732" + ace_mode: mask + extensions: + - ".mask" + tm_scope: source.mask + language_id: 223 +Mathematica: + type: programming + extensions: + - ".mathematica" + - ".cdf" + - ".m" + - ".ma" + - ".mt" + - ".nb" + - ".nbp" + - ".wl" + - ".wlt" + aliases: + - mma + tm_scope: source.mathematica + ace_mode: text + codemirror_mode: mathematica + codemirror_mime_type: text/x-mathematica + language_id: 224 +Maven POM: + type: data + tm_scope: text.xml.pom + filenames: + - pom.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 226 +Max: + type: programming + color: "#c4a79c" + aliases: + - max/msp + - maxmsp + extensions: + - ".maxpat" + - ".maxhelp" + - ".maxproj" + - ".mxt" + - ".pat" + tm_scope: source.json + ace_mode: json + codemirror_mode: javascript + codemirror_mime_type: application/json + language_id: 227 +MediaWiki: + type: prose + wrap: true + extensions: + - ".mediawiki" + - ".wiki" + tm_scope: text.html.mediawiki + ace_mode: text + language_id: 228 +Mercury: + type: programming + color: "#ff2b2b" + ace_mode: prolog + interpreters: + - mmi + extensions: + - ".m" + - ".moo" + tm_scope: source.mercury + language_id: 229 +Meson: + type: programming + color: "#007800" + filenames: + - meson.build + - meson_options.txt + tm_scope: source.meson + ace_mode: text + language_id: 799141244 +Metal: + type: programming + color: "#8f14e9" + extensions: + - ".metal" + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + language_id: 230 +MiniD: + type: programming + searchable: false + extensions: + - ".minid" + tm_scope: none + ace_mode: text + language_id: 231 +Mirah: + type: programming + color: "#c7a938" + extensions: + - ".druby" + - ".duby" + - ".mirah" + tm_scope: source.ruby + ace_mode: ruby + codemirror_mode: ruby + codemirror_mime_type: text/x-ruby + language_id: 232 +Modelica: + type: programming + extensions: + - ".mo" + tm_scope: source.modelica + ace_mode: text + codemirror_mode: modelica + codemirror_mime_type: text/x-modelica + language_id: 233 +Modula-2: + type: programming + extensions: + - ".mod" + tm_scope: source.modula2 + ace_mode: text + language_id: 234 +Modula-3: + type: programming + extensions: + - ".i3" + - ".ig" + - ".m3" + - ".mg" + color: "#223388" + ace_mode: text + tm_scope: source.modula-3 + language_id: 564743864 +Module Management System: + type: programming + extensions: + - ".mms" + - ".mmk" + filenames: + - descrip.mmk + - descrip.mms + tm_scope: none + ace_mode: text + language_id: 235 +Monkey: + type: programming + extensions: + - ".monkey" + - ".monkey2" + ace_mode: text + tm_scope: source.monkey + language_id: 236 +Moocode: + type: programming + extensions: + - ".moo" + tm_scope: none + ace_mode: text + language_id: 237 +MoonScript: + type: programming + extensions: + - ".moon" + interpreters: + - moon + tm_scope: source.moonscript + ace_mode: text + language_id: 238 +Motorola 68K Assembly: + type: programming + group: Assembly + extensions: + - ".X68" + tm_scope: source.m68k + ace_mode: assembly_x86 + language_id: 477582706 +Myghty: + type: programming + extensions: + - ".myt" + tm_scope: none + ace_mode: text + language_id: 239 +NCL: + type: programming + color: "#28431f" + extensions: + - ".ncl" + tm_scope: source.ncl + ace_mode: text + language_id: 240 +NL: + type: data + extensions: + - ".nl" + tm_scope: none + ace_mode: text + language_id: 241 +NSIS: + type: programming + extensions: + - ".nsi" + - ".nsh" + tm_scope: source.nsis + ace_mode: text + codemirror_mode: nsis + codemirror_mime_type: text/x-nsis + language_id: 242 +Nearley: + type: programming + ace_mode: text + color: "#990000" + extensions: + - ".ne" + - ".nearley" + tm_scope: source.ne + language_id: 521429430 +Nemerle: + type: programming + color: "#3d3c6e" + extensions: + - ".n" + tm_scope: source.nemerle + ace_mode: text + language_id: 243 +NetLinx: + type: programming + color: "#0aa0ff" + extensions: + - ".axs" + - ".axi" + tm_scope: source.netlinx + ace_mode: text + language_id: 244 +NetLinx+ERB: + type: programming + color: "#747faa" + extensions: + - ".axs.erb" + - ".axi.erb" + tm_scope: source.netlinx.erb + ace_mode: text + language_id: 245 +NetLogo: + type: programming + color: "#ff6375" + extensions: + - ".nlogo" + tm_scope: source.lisp + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 246 +NewLisp: + type: programming + color: "#87AED7" + extensions: + - ".nl" + - ".lisp" + - ".lsp" + interpreters: + - newlisp + tm_scope: source.lisp + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 247 +Nextflow: + type: programming + ace_mode: groovy + tm_scope: source.nextflow + color: "#3ac486" + extensions: + - ".nf" + filenames: + - nextflow.config + interpreters: + - nextflow + language_id: 506780613 +Nginx: + type: data + extensions: + - ".nginxconf" + - ".vhost" + filenames: + - nginx.conf + tm_scope: source.nginx + aliases: + - nginx configuration file + ace_mode: text + codemirror_mode: nginx + codemirror_mime_type: text/x-nginx-conf + language_id: 248 +Nim: + type: programming + color: "#37775b" + extensions: + - ".nim" + - ".nim.cfg" + - ".nimble" + - ".nimrod" + - ".nims" + filenames: + - nim.cfg + ace_mode: text + tm_scope: source.nim + language_id: 249 +Ninja: + type: data + tm_scope: source.ninja + extensions: + - ".ninja" + ace_mode: text + language_id: 250 +Nit: + type: programming + color: "#009917" + extensions: + - ".nit" + tm_scope: source.nit + ace_mode: text + language_id: 251 +Nix: + type: programming + color: "#7e7eff" + extensions: + - ".nix" + aliases: + - nixos + tm_scope: source.nix + ace_mode: nix + language_id: 252 +Nu: + type: programming + color: "#c9df40" + aliases: + - nush + extensions: + - ".nu" + filenames: + - Nukefile + tm_scope: source.nu + ace_mode: scheme + codemirror_mode: scheme + codemirror_mime_type: text/x-scheme + interpreters: + - nush + language_id: 253 +NumPy: + type: programming + group: Python + extensions: + - ".numpy" + - ".numpyw" + - ".numsc" + tm_scope: none + ace_mode: text + codemirror_mode: python + codemirror_mime_type: text/x-python + language_id: 254 +OCaml: + type: programming + ace_mode: ocaml + codemirror_mode: mllike + codemirror_mime_type: text/x-ocaml + color: "#3be133" + extensions: + - ".ml" + - ".eliom" + - ".eliomi" + - ".ml4" + - ".mli" + - ".mll" + - ".mly" + interpreters: + - ocaml + - ocamlrun + - ocamlscript + tm_scope: source.ocaml + language_id: 255 +ObjDump: + type: data + extensions: + - ".objdump" + tm_scope: objdump.x86asm + ace_mode: assembly_x86 + language_id: 256 +ObjectScript: + type: programming + extensions: + - ".cls" + language_id: 202735509 + tm_scope: source.objectscript + color: "#424893" + ace_mode: text +Objective-C: + type: programming + tm_scope: source.objc + color: "#438eff" + aliases: + - obj-c + - objc + - objectivec + extensions: + - ".m" + - ".h" + ace_mode: objectivec + codemirror_mode: clike + codemirror_mime_type: text/x-objectivec + language_id: 257 +Objective-C++: + type: programming + tm_scope: source.objc++ + color: "#6866fb" + aliases: + - obj-c++ + - objc++ + - objectivec++ + extensions: + - ".mm" + ace_mode: objectivec + codemirror_mode: clike + codemirror_mime_type: text/x-objectivec + language_id: 258 +Objective-J: + type: programming + color: "#ff0c5a" + aliases: + - obj-j + - objectivej + - objj + extensions: + - ".j" + - ".sj" + tm_scope: source.js.objj + ace_mode: text + language_id: 259 +Omgrofl: + type: programming + extensions: + - ".omgrofl" + color: "#cabbff" + tm_scope: none + ace_mode: text + language_id: 260 +Opa: + type: programming + extensions: + - ".opa" + tm_scope: source.opa + ace_mode: text + language_id: 261 +Opal: + type: programming + color: "#f7ede0" + extensions: + - ".opal" + tm_scope: source.opal + ace_mode: text + language_id: 262 +OpenCL: + type: programming + group: C + extensions: + - ".cl" + - ".opencl" + tm_scope: source.c + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 263 +OpenEdge ABL: + type: programming + aliases: + - progress + - openedge + - abl + extensions: + - ".p" + - ".cls" + - ".w" + tm_scope: source.abl + ace_mode: text + language_id: 264 +OpenRC runscript: + type: programming + group: Shell + aliases: + - openrc + interpreters: + - openrc-run + tm_scope: source.shell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 265 +OpenSCAD: + type: programming + extensions: + - ".scad" + tm_scope: source.scad + ace_mode: scad + language_id: 266 +OpenStep Property List: + type: data + extensions: + - ".plist" + tm_scope: source.plist + ace_mode: text + language_id: 598917541 +OpenType Feature File: + type: data + aliases: + - AFDKO + extensions: + - ".fea" + tm_scope: source.opentype + ace_mode: text + language_id: 374317347 +Org: + type: prose + wrap: true + extensions: + - ".org" + tm_scope: none + ace_mode: text + language_id: 267 +Ox: + type: programming + extensions: + - ".ox" + - ".oxh" + - ".oxo" + tm_scope: source.ox + ace_mode: text + language_id: 268 +Oxygene: + type: programming + color: "#cdd0e3" + extensions: + - ".oxygene" + tm_scope: none + ace_mode: text + language_id: 269 +Oz: + type: programming + color: "#fab738" + extensions: + - ".oz" + tm_scope: source.oz + ace_mode: text + codemirror_mode: oz + codemirror_mime_type: text/x-oz + language_id: 270 +P4: + type: programming + color: "#7055b5" + extensions: + - ".p4" + tm_scope: source.p4 + ace_mode: text + language_id: 348895984 +PHP: + type: programming + tm_scope: text.html.php + ace_mode: php + codemirror_mode: php + codemirror_mime_type: application/x-httpd-php + color: "#4F5D95" + extensions: + - ".php" + - ".aw" + - ".ctp" + - ".fcgi" + - ".inc" + - ".php3" + - ".php4" + - ".php5" + - ".phps" + - ".phpt" + filenames: + - ".php" + - ".php_cs" + - ".php_cs.dist" + - Phakefile + interpreters: + - php + aliases: + - inc + language_id: 272 +PLSQL: + type: programming + ace_mode: sql + codemirror_mode: sql + codemirror_mime_type: text/x-plsql + tm_scope: none + color: "#dad8d8" + extensions: + - ".pls" + - ".bdy" + - ".ddl" + - ".fnc" + - ".pck" + - ".pkb" + - ".pks" + - ".plb" + - ".plsql" + - ".prc" + - ".spc" + - ".sql" + - ".tpb" + - ".tps" + - ".trg" + - ".vw" + language_id: 273 +PLpgSQL: + type: programming + ace_mode: pgsql + codemirror_mode: sql + codemirror_mime_type: text/x-sql + tm_scope: source.sql + extensions: + - ".pgsql" + - ".sql" + language_id: 274 +POV-Ray SDL: + type: programming + aliases: + - pov-ray + - povray + extensions: + - ".pov" + - ".inc" + tm_scope: source.pov-ray sdl + ace_mode: text + language_id: 275 +Pan: + type: programming + color: "#cc0000" + extensions: + - ".pan" + tm_scope: source.pan + ace_mode: text + language_id: 276 +Papyrus: + type: programming + color: "#6600cc" + extensions: + - ".psc" + tm_scope: source.papyrus.skyrim + ace_mode: text + language_id: 277 +Parrot: + type: programming + color: "#f3ca0a" + extensions: + - ".parrot" + tm_scope: none + ace_mode: text + language_id: 278 +Parrot Assembly: + group: Parrot + type: programming + aliases: + - pasm + extensions: + - ".pasm" + interpreters: + - parrot + tm_scope: none + ace_mode: text + language_id: 279 +Parrot Internal Representation: + group: Parrot + tm_scope: source.parrot.pir + type: programming + aliases: + - pir + extensions: + - ".pir" + interpreters: + - parrot + ace_mode: text + language_id: 280 +Pascal: + type: programming + color: "#E3F171" + extensions: + - ".pas" + - ".dfm" + - ".dpr" + - ".inc" + - ".lpr" + - ".pascal" + - ".pp" + interpreters: + - instantfpc + tm_scope: source.pascal + ace_mode: pascal + codemirror_mode: pascal + codemirror_mime_type: text/x-pascal + language_id: 281 +Pawn: + type: programming + color: "#dbb284" + extensions: + - ".pwn" + - ".inc" + - ".sma" + tm_scope: source.pawn + ace_mode: text + language_id: 271 +Pep8: + type: programming + color: "#C76F5B" + extensions: + - ".pep" + ace_mode: text + tm_scope: source.pep8 + language_id: 840372442 +Perl: + type: programming + tm_scope: source.perl + ace_mode: perl + codemirror_mode: perl + codemirror_mime_type: text/x-perl + color: "#0298c3" + extensions: + - ".pl" + - ".al" + - ".cgi" + - ".fcgi" + - ".perl" + - ".ph" + - ".plx" + - ".pm" + - ".psgi" + - ".t" + filenames: + - Makefile.PL + - Rexfile + - ack + - cpanfile + interpreters: + - cperl + - perl + aliases: + - cperl + language_id: 282 +Perl 6: + type: programming + color: "#0000fb" + extensions: + - ".6pl" + - ".6pm" + - ".nqp" + - ".p6" + - ".p6l" + - ".p6m" + - ".pl" + - ".pl6" + - ".pm" + - ".pm6" + - ".t" + interpreters: + - perl6 + aliases: + - perl6 + tm_scope: source.perl6fe + ace_mode: perl + codemirror_mode: perl + codemirror_mime_type: text/x-perl + language_id: 283 +Pic: + type: markup + group: Roff + tm_scope: source.pic + extensions: + - ".pic" + - ".chem" + ace_mode: text + codemirror_mode: troff + codemirror_mime_type: text/troff + language_id: 425 +Pickle: + type: data + extensions: + - ".pkl" + tm_scope: none + ace_mode: text + language_id: 284 +PicoLisp: + type: programming + extensions: + - ".l" + interpreters: + - picolisp + - pil + tm_scope: source.lisp + ace_mode: lisp + language_id: 285 +PigLatin: + type: programming + color: "#fcd7de" + extensions: + - ".pig" + tm_scope: source.pig_latin + ace_mode: text + language_id: 286 +Pike: + type: programming + color: "#005390" + extensions: + - ".pike" + - ".pmod" + interpreters: + - pike + tm_scope: source.pike + ace_mode: text + language_id: 287 +Pod: + type: prose + ace_mode: perl + codemirror_mode: perl + codemirror_mime_type: text/x-perl + wrap: true + extensions: + - ".pod" + interpreters: + - perl + tm_scope: none + language_id: 288 +Pod 6: + type: prose + ace_mode: perl + tm_scope: source.perl6fe + wrap: true + extensions: + - ".pod" + - ".pod6" + interpreters: + - perl6 + language_id: 155357471 +PogoScript: + type: programming + color: "#d80074" + extensions: + - ".pogo" + tm_scope: source.pogoscript + ace_mode: text + language_id: 289 +Pony: + type: programming + extensions: + - ".pony" + tm_scope: source.pony + ace_mode: text + language_id: 290 +PostCSS: + type: markup + tm_scope: source.postcss + group: CSS + extensions: + - ".pcss" + ace_mode: text + language_id: 262764437 +PostScript: + type: markup + color: "#da291c" + extensions: + - ".ps" + - ".eps" + - ".pfa" + tm_scope: source.postscript + aliases: + - postscr + ace_mode: text + language_id: 291 +PowerBuilder: + type: programming + color: "#8f0f8d" + extensions: + - ".pbt" + - ".sra" + - ".sru" + - ".srw" + tm_scope: none + ace_mode: text + language_id: 292 +PowerShell: + type: programming + color: "#012456" + tm_scope: source.powershell + ace_mode: powershell + codemirror_mode: powershell + codemirror_mime_type: application/x-powershell + aliases: + - posh + - pwsh + extensions: + - ".ps1" + - ".psd1" + - ".psm1" + interpreters: + - pwsh + language_id: 293 +Processing: + type: programming + color: "#0096D8" + extensions: + - ".pde" + tm_scope: source.processing + ace_mode: text + language_id: 294 +Prolog: + type: programming + color: "#74283c" + extensions: + - ".pl" + - ".pro" + - ".prolog" + - ".yap" + interpreters: + - swipl + - yap + tm_scope: source.prolog + ace_mode: prolog + language_id: 295 +Propeller Spin: + type: programming + color: "#7fa2a7" + extensions: + - ".spin" + tm_scope: source.spin + ace_mode: text + language_id: 296 +Protocol Buffer: + type: data + aliases: + - protobuf + - Protocol Buffers + extensions: + - ".proto" + tm_scope: source.protobuf + ace_mode: protobuf + codemirror_mode: protobuf + codemirror_mime_type: text/x-protobuf + language_id: 297 +Public Key: + type: data + extensions: + - ".asc" + - ".pub" + tm_scope: none + ace_mode: text + codemirror_mode: asciiarmor + codemirror_mime_type: application/pgp + language_id: 298 +Pug: + group: HTML + type: markup + extensions: + - ".jade" + - ".pug" + tm_scope: text.jade + ace_mode: jade + codemirror_mode: pug + codemirror_mime_type: text/x-pug + language_id: 179 +Puppet: + type: programming + color: "#302B6D" + extensions: + - ".pp" + filenames: + - Modulefile + ace_mode: text + codemirror_mode: puppet + codemirror_mime_type: text/x-puppet + tm_scope: source.puppet + language_id: 299 +Pure Data: + type: data + extensions: + - ".pd" + tm_scope: none + ace_mode: text + language_id: 300 +PureBasic: + type: programming + color: "#5a6986" + extensions: + - ".pb" + - ".pbi" + tm_scope: none + ace_mode: text + language_id: 301 +PureScript: + type: programming + color: "#1D222D" + extensions: + - ".purs" + tm_scope: source.purescript + ace_mode: haskell + codemirror_mode: haskell + codemirror_mime_type: text/x-haskell + language_id: 302 +Python: + type: programming + tm_scope: source.python + ace_mode: python + codemirror_mode: python + codemirror_mime_type: text/x-python + color: "#3572A5" + extensions: + - ".py" + - ".bzl" + - ".cgi" + - ".fcgi" + - ".gyp" + - ".gypi" + - ".lmi" + - ".py3" + - ".pyde" + - ".pyi" + - ".pyp" + - ".pyt" + - ".pyw" + - ".rpy" + - ".spec" + - ".tac" + - ".wsgi" + - ".xpy" + filenames: + - ".gclient" + - BUCK + - BUILD + - BUILD.bazel + - DEPS + - SConscript + - SConstruct + - Snakefile + - WORKSPACE + - wscript + interpreters: + - python + - python2 + - python3 + aliases: + - rusthon + - python3 + language_id: 303 +Python console: + type: programming + group: Python + searchable: false + aliases: + - pycon + tm_scope: text.python.console + ace_mode: text + language_id: 428 +Python traceback: + type: data + group: Python + searchable: false + extensions: + - ".pytb" + tm_scope: text.python.traceback + ace_mode: text + language_id: 304 +QML: + type: programming + color: "#44a51c" + extensions: + - ".qml" + - ".qbs" + tm_scope: source.qml + ace_mode: text + language_id: 305 +QMake: + type: programming + extensions: + - ".pro" + - ".pri" + interpreters: + - qmake + tm_scope: source.qmake + ace_mode: text + language_id: 306 +Quake: + type: programming + filenames: + - m3makefile + - m3overrides + color: "#882233" + ace_mode: text + tm_scope: source.quake + language_id: 375265331 +R: + type: programming + color: "#198CE7" + aliases: + - R + - Rscript + - splus + extensions: + - ".r" + - ".rd" + - ".rsx" + filenames: + - ".Rprofile" + - expr-dist + interpreters: + - Rscript + tm_scope: source.r + ace_mode: r + codemirror_mode: r + codemirror_mime_type: text/x-rsrc + language_id: 307 +RAML: + type: markup + ace_mode: yaml + codemirror_mode: yaml + codemirror_mime_type: text/x-yaml + tm_scope: source.yaml + color: "#77d9fb" + extensions: + - ".raml" + language_id: 308 +RDoc: + type: prose + ace_mode: rdoc + wrap: true + extensions: + - ".rdoc" + tm_scope: text.rdoc + language_id: 309 +REALbasic: + type: programming + extensions: + - ".rbbas" + - ".rbfrm" + - ".rbmnu" + - ".rbres" + - ".rbtbar" + - ".rbuistate" + tm_scope: source.vbnet + ace_mode: text + language_id: 310 +REXX: + type: programming + aliases: + - arexx + extensions: + - ".rexx" + - ".pprx" + - ".rex" + interpreters: + - regina + - rexx + tm_scope: source.rexx + ace_mode: text + language_id: 311 +RHTML: + type: markup + group: HTML + extensions: + - ".rhtml" + tm_scope: text.html.erb + aliases: + - html+ruby + ace_mode: rhtml + codemirror_mode: htmlembedded + codemirror_mime_type: application/x-erb + language_id: 312 +RMarkdown: + type: prose + wrap: true + ace_mode: markdown + codemirror_mode: gfm + codemirror_mime_type: text/x-gfm + extensions: + - ".rmd" + tm_scope: source.gfm + language_id: 313 +RPC: + type: programming + aliases: + - rpcgen + - oncrpc + - xdr + ace_mode: c_cpp + extensions: + - ".x" + tm_scope: source.c + language_id: 1031374237 +RPM Spec: + type: data + tm_scope: source.rpm-spec + extensions: + - ".spec" + aliases: + - specfile + ace_mode: text + codemirror_mode: rpm + codemirror_mime_type: text/x-rpm-spec + language_id: 314 +RUNOFF: + type: markup + color: "#665a4e" + extensions: + - ".rnh" + - ".rno" + tm_scope: text.runoff + ace_mode: text + language_id: 315 +Racket: + type: programming + color: "#3c5caa" + extensions: + - ".rkt" + - ".rktd" + - ".rktl" + - ".scrbl" + interpreters: + - racket + tm_scope: source.racket + ace_mode: lisp + language_id: 316 +Ragel: + type: programming + color: "#9d5200" + extensions: + - ".rl" + aliases: + - ragel-rb + - ragel-ruby + tm_scope: none + ace_mode: text + language_id: 317 +Rascal: + type: programming + color: "#fffaa0" + extensions: + - ".rsc" + tm_scope: source.rascal + ace_mode: text + language_id: 173616037 +Raw token data: + type: data + aliases: + - raw + extensions: + - ".raw" + tm_scope: none + ace_mode: text + language_id: 318 +Reason: + type: programming + group: OCaml + ace_mode: rust + codemirror_mode: rust + codemirror_mime_type: text/x-rustsrc + extensions: + - ".re" + - ".rei" + interpreters: + - ocaml + tm_scope: source.reason + language_id: 869538413 +Rebol: + type: programming + color: "#358a5b" + extensions: + - ".reb" + - ".r" + - ".r2" + - ".r3" + - ".rebol" + ace_mode: text + tm_scope: source.rebol + language_id: 319 +Red: + type: programming + color: "#f50000" + extensions: + - ".red" + - ".reds" + aliases: + - red/system + tm_scope: source.red + ace_mode: text + language_id: 320 +Redcode: + type: programming + extensions: + - ".cw" + tm_scope: none + ace_mode: text + language_id: 321 +Regular Expression: + type: data + extensions: + - ".regexp" + - ".regex" + aliases: + - regexp + - regex + ace_mode: text + tm_scope: source.regexp + language_id: 363378884 +Ren'Py: + type: programming + aliases: + - renpy + color: "#ff7f7f" + extensions: + - ".rpy" + tm_scope: source.renpy + ace_mode: python + language_id: 322 +RenderScript: + type: programming + extensions: + - ".rs" + - ".rsh" + tm_scope: none + ace_mode: text + language_id: 323 +Rich Text Format: + type: markup + extensions: + - ".rtf" + tm_scope: text.rtf + ace_mode: text + language_id: 51601661 +Ring: + type: programming + color: "#2D54CB" + extensions: + - ".ring" + tm_scope: source.ring + ace_mode: text + language_id: 431 +RobotFramework: + type: programming + extensions: + - ".robot" + tm_scope: text.robot + ace_mode: text + language_id: 324 +Roff: + type: markup + color: "#ecdebe" + extensions: + - ".roff" + - ".1" + - ".1in" + - ".1m" + - ".1x" + - ".2" + - ".3" + - ".3in" + - ".3m" + - ".3p" + - ".3pm" + - ".3qt" + - ".3x" + - ".4" + - ".5" + - ".6" + - ".7" + - ".8" + - ".9" + - ".l" + - ".man" + - ".mdoc" + - ".me" + - ".ms" + - ".n" + - ".nr" + - ".rno" + - ".tmac" + filenames: + - eqnrc + - mmn + - mmt + - troffrc + - troffrc-end + tm_scope: text.roff + aliases: + - groff + - man + - manpage + - man page + - man-page + - mdoc + - nroff + - troff + ace_mode: text + codemirror_mode: troff + codemirror_mime_type: text/troff + language_id: 141 +Roff Manpage: + type: markup + group: Roff + extensions: + - ".1" + - ".1in" + - ".1m" + - ".1x" + - ".2" + - ".3" + - ".3in" + - ".3m" + - ".3p" + - ".3pm" + - ".3qt" + - ".3x" + - ".4" + - ".5" + - ".6" + - ".7" + - ".8" + - ".9" + - ".man" + - ".mdoc" + tm_scope: text.roff + ace_mode: text + codemirror_mode: troff + codemirror_mime_type: text/troff + language_id: 612669833 +Rouge: + type: programming + ace_mode: clojure + codemirror_mode: clojure + codemirror_mime_type: text/x-clojure + color: "#cc0088" + extensions: + - ".rg" + tm_scope: source.clojure + language_id: 325 +Ruby: + type: programming + tm_scope: source.ruby + ace_mode: ruby + codemirror_mode: ruby + codemirror_mime_type: text/x-ruby + color: "#701516" + aliases: + - jruby + - macruby + - rake + - rb + - rbx + extensions: + - ".rb" + - ".builder" + - ".eye" + - ".fcgi" + - ".gemspec" + - ".god" + - ".jbuilder" + - ".mspec" + - ".pluginspec" + - ".podspec" + - ".rabl" + - ".rake" + - ".rbuild" + - ".rbw" + - ".rbx" + - ".ru" + - ".ruby" + - ".spec" + - ".thor" + - ".watchr" + interpreters: + - ruby + - macruby + - rake + - jruby + - rbx + filenames: + - ".irbrc" + - ".pryrc" + - Appraisals + - Berksfile + - Brewfile + - Buildfile + - Capfile + - Dangerfile + - Deliverfile + - Fastfile + - Gemfile + - Gemfile.lock + - Guardfile + - Jarfile + - Mavenfile + - Podfile + - Puppetfile + - Rakefile + - Snapfile + - Thorfile + - Vagrantfile + - buildfile + language_id: 326 +Rust: + type: programming + color: "#dea584" + extensions: + - ".rs" + - ".rs.in" + tm_scope: source.rust + ace_mode: rust + codemirror_mode: rust + codemirror_mime_type: text/x-rustsrc + language_id: 327 +SAS: + type: programming + color: "#B34936" + extensions: + - ".sas" + tm_scope: source.sas + ace_mode: text + codemirror_mode: sas + codemirror_mime_type: text/x-sas + language_id: 328 +SCSS: + type: markup + tm_scope: source.css.scss + group: CSS + ace_mode: scss + codemirror_mode: css + codemirror_mime_type: text/x-scss + extensions: + - ".scss" + language_id: 329 +SMT: + type: programming + extensions: + - ".smt2" + - ".smt" + interpreters: + - boolector + - cvc4 + - mathsat5 + - opensmt + - smtinterpol + - smt-rat + - stp + - verit + - yices2 + - z3 + tm_scope: source.smt + ace_mode: text + language_id: 330 +SPARQL: + type: data + tm_scope: source.sparql + ace_mode: text + codemirror_mode: sparql + codemirror_mime_type: application/sparql-query + extensions: + - ".sparql" + - ".rq" + language_id: 331 +SQF: + type: programming + color: "#3F3F3F" + extensions: + - ".sqf" + - ".hqf" + tm_scope: source.sqf + ace_mode: text + language_id: 332 +SQL: + type: data + tm_scope: source.sql + ace_mode: sql + codemirror_mode: sql + codemirror_mime_type: text/x-sql + extensions: + - ".sql" + - ".cql" + - ".ddl" + - ".inc" + - ".mysql" + - ".prc" + - ".tab" + - ".udf" + - ".viw" + language_id: 333 +SQLPL: + type: programming + ace_mode: sql + codemirror_mode: sql + codemirror_mime_type: text/x-sql + tm_scope: source.sql + extensions: + - ".sql" + - ".db2" + language_id: 334 +SRecode Template: + type: markup + color: "#348a34" + tm_scope: source.lisp + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + extensions: + - ".srt" + language_id: 335 +SSH Config: + type: data + group: INI + filenames: + - ssh-config + - ssh_config + - sshconfig + - sshconfig.snip + - sshd-config + - sshd_config + ace_mode: text + tm_scope: source.ssh-config + language_id: 554920715 +STON: + type: data + group: Smalltalk + extensions: + - ".ston" + tm_scope: source.smalltalk + ace_mode: text + language_id: 336 +SVG: + type: data + extensions: + - ".svg" + tm_scope: text.xml.svg + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 337 +Sage: + type: programming + group: Python + extensions: + - ".sage" + - ".sagews" + tm_scope: source.python + ace_mode: python + codemirror_mode: python + codemirror_mime_type: text/x-python + language_id: 338 +SaltStack: + type: programming + color: "#646464" + aliases: + - saltstate + - salt + extensions: + - ".sls" + tm_scope: source.yaml.salt + ace_mode: yaml + codemirror_mode: yaml + codemirror_mime_type: text/x-yaml + language_id: 339 +Sass: + type: markup + tm_scope: source.sass + group: CSS + extensions: + - ".sass" + ace_mode: sass + codemirror_mode: sass + codemirror_mime_type: text/x-sass + language_id: 340 +Scala: + type: programming + tm_scope: source.scala + ace_mode: scala + codemirror_mode: clike + codemirror_mime_type: text/x-scala + color: "#c22d40" + extensions: + - ".scala" + - ".kojo" + - ".sbt" + - ".sc" + interpreters: + - scala + language_id: 341 +Scaml: + group: HTML + type: markup + extensions: + - ".scaml" + tm_scope: source.scaml + ace_mode: text + language_id: 342 +Scheme: + type: programming + color: "#1e4aec" + extensions: + - ".scm" + - ".sch" + - ".sld" + - ".sls" + - ".sps" + - ".ss" + interpreters: + - scheme + - guile + - bigloo + - chicken + - csi + - gosh + - r6rs + tm_scope: source.scheme + ace_mode: scheme + codemirror_mode: scheme + codemirror_mime_type: text/x-scheme + language_id: 343 +Scilab: + type: programming + extensions: + - ".sci" + - ".sce" + - ".tst" + tm_scope: source.scilab + ace_mode: text + language_id: 344 +Self: + type: programming + color: "#0579aa" + extensions: + - ".self" + tm_scope: none + ace_mode: text + language_id: 345 +ShaderLab: + type: programming + extensions: + - ".shader" + ace_mode: text + tm_scope: source.shaderlab + language_id: 664257356 +Shell: + type: programming + color: "#89e051" + aliases: + - sh + - shell-script + - bash + - zsh + extensions: + - ".sh" + - ".bash" + - ".bats" + - ".cgi" + - ".command" + - ".fcgi" + - ".ksh" + - ".sh.in" + - ".tmux" + - ".tool" + - ".zsh" + filenames: + - ".bash_aliases" + - ".bash_history" + - ".bash_logout" + - ".bash_profile" + - ".bashrc" + - ".cshrc" + - ".login" + - ".profile" + - ".zlogin" + - ".zlogout" + - ".zprofile" + - ".zshenv" + - ".zshrc" + - 9fs + - PKGBUILD + - bash_aliases + - bash_logout + - bash_profile + - bashrc + - cshrc + - gradlew + - login + - man + - profile + - zlogin + - zlogout + - zprofile + - zshenv + - zshrc + interpreters: + - ash + - bash + - dash + - ksh + - mksh + - pdksh + - rc + - sh + - zsh + tm_scope: source.shell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 346 +ShellSession: + type: programming + extensions: + - ".sh-session" + aliases: + - bash session + - console + tm_scope: text.shell-session + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 347 +Shen: + type: programming + color: "#120F14" + extensions: + - ".shen" + tm_scope: source.shen + ace_mode: text + language_id: 348 +Slash: + type: programming + color: "#007eff" + extensions: + - ".sl" + tm_scope: text.html.slash + ace_mode: text + language_id: 349 +Slice: + type: programming + color: "#003fa2" + tm_scope: source.slice + ace_mode: text + extensions: + - ".ice" + language_id: 894641667 +Slim: + group: HTML + type: markup + extensions: + - ".slim" + tm_scope: text.slim + ace_mode: text + codemirror_mode: slim + codemirror_mime_type: text/x-slim + language_id: 350 +SmPL: + type: programming + extensions: + - ".cocci" + aliases: + - coccinelle + ace_mode: text + tm_scope: source.smpl + color: "#c94949" + language_id: 164123055 +Smali: + type: programming + extensions: + - ".smali" + ace_mode: text + tm_scope: source.smali + language_id: 351 +Smalltalk: + type: programming + color: "#596706" + extensions: + - ".st" + - ".cs" + aliases: + - squeak + tm_scope: source.smalltalk + ace_mode: text + codemirror_mode: smalltalk + codemirror_mime_type: text/x-stsrc + language_id: 352 +Smarty: + type: programming + extensions: + - ".tpl" + ace_mode: smarty + codemirror_mode: smarty + codemirror_mime_type: text/x-smarty + tm_scope: text.html.smarty + language_id: 353 +Solidity: + type: programming + color: "#AA6746" + ace_mode: text + tm_scope: source.solidity + language_id: 237469032 +SourcePawn: + type: programming + color: "#5c7611" + aliases: + - sourcemod + extensions: + - ".sp" + - ".inc" + tm_scope: source.sourcepawn + ace_mode: text + language_id: 354 +Spline Font Database: + type: data + extensions: + - ".sfd" + tm_scope: text.sfd + ace_mode: yaml + language_id: 767169629 +Squirrel: + type: programming + color: "#800000" + extensions: + - ".nut" + tm_scope: source.c++ + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-c++src + language_id: 355 +Stan: + type: programming + color: "#b2011d" + extensions: + - ".stan" + ace_mode: text + tm_scope: source.stan + language_id: 356 +Standard ML: + type: programming + color: "#dc566d" + aliases: + - sml + extensions: + - ".ML" + - ".fun" + - ".sig" + - ".sml" + tm_scope: source.ml + ace_mode: text + codemirror_mode: mllike + codemirror_mime_type: text/x-ocaml + language_id: 357 +Stata: + type: programming + extensions: + - ".do" + - ".ado" + - ".doh" + - ".ihlp" + - ".mata" + - ".matah" + - ".sthlp" + tm_scope: source.stata + ace_mode: text + language_id: 358 +Stylus: + type: markup + group: CSS + extensions: + - ".styl" + tm_scope: source.stylus + ace_mode: stylus + language_id: 359 +SubRip Text: + type: data + extensions: + - ".srt" + ace_mode: text + tm_scope: text.srt + language_id: 360 +SugarSS: + type: markup + tm_scope: source.css.postcss.sugarss + group: CSS + extensions: + - ".sss" + ace_mode: text + language_id: 826404698 +SuperCollider: + type: programming + color: "#46390b" + extensions: + - ".sc" + - ".scd" + interpreters: + - sclang + - scsynth + tm_scope: source.supercollider + ace_mode: text + language_id: 361 +Svelte: + type: markup + tm_scope: source.svelte + group: HTML + ace_mode: html + codemirror_mode: htmlmixed + codemirror_mime_type: text/html + extensions: + - ".svelte" + language_id: 928734530 +Swift: + type: programming + color: "#ffac45" + extensions: + - ".swift" + tm_scope: source.swift + ace_mode: text + codemirror_mode: swift + codemirror_mime_type: text/x-swift + language_id: 362 +SystemVerilog: + type: programming + color: "#DAE1C2" + extensions: + - ".sv" + - ".svh" + - ".vh" + tm_scope: source.systemverilog + ace_mode: verilog + codemirror_mode: verilog + codemirror_mime_type: text/x-systemverilog + language_id: 363 +TI Program: + type: programming + ace_mode: text + color: "#A0AA87" + extensions: + - ".8xp" + - ".8xk" + - ".8xk.txt" + - ".8xp.txt" + language_id: 422 + tm_scope: none +TLA: + type: programming + extensions: + - ".tla" + tm_scope: source.tla + ace_mode: text + language_id: 364 +TOML: + type: data + extensions: + - ".toml" + filenames: + - Cargo.lock + - Gopkg.lock + tm_scope: source.toml + ace_mode: toml + codemirror_mode: toml + codemirror_mime_type: text/x-toml + language_id: 365 +TSQL: + type: programming + extensions: + - ".sql" + ace_mode: sql + tm_scope: source.tsql + language_id: 918334941 +TSX: + type: programming + group: TypeScript + extensions: + - ".tsx" + tm_scope: source.tsx + ace_mode: javascript + codemirror_mode: jsx + codemirror_mime_type: text/jsx + language_id: 94901924 +TXL: + type: programming + extensions: + - ".txl" + tm_scope: source.txl + ace_mode: text + language_id: 366 +Tcl: + type: programming + color: "#e4cc98" + extensions: + - ".tcl" + - ".adp" + - ".tm" + filenames: + - owh + - starfield + interpreters: + - tclsh + - wish + tm_scope: source.tcl + ace_mode: tcl + codemirror_mode: tcl + codemirror_mime_type: text/x-tcl + language_id: 367 +Tcsh: + type: programming + group: Shell + extensions: + - ".tcsh" + - ".csh" + tm_scope: source.shell + ace_mode: sh + codemirror_mode: shell + codemirror_mime_type: text/x-sh + language_id: 368 +TeX: + type: markup + color: "#3D6117" + ace_mode: tex + codemirror_mode: stex + codemirror_mime_type: text/x-stex + tm_scope: text.tex.latex + wrap: true + aliases: + - latex + extensions: + - ".tex" + - ".aux" + - ".bbx" + - ".cbx" + - ".cls" + - ".dtx" + - ".ins" + - ".lbx" + - ".ltx" + - ".mkii" + - ".mkiv" + - ".mkvi" + - ".sty" + - ".toc" + language_id: 369 +Tea: + type: markup + extensions: + - ".tea" + tm_scope: source.tea + ace_mode: text + language_id: 370 +Terra: + type: programming + extensions: + - ".t" + color: "#00004c" + tm_scope: source.terra + ace_mode: lua + codemirror_mode: lua + codemirror_mime_type: text/x-lua + interpreters: + - lua + language_id: 371 +Texinfo: + type: prose + wrap: true + extensions: + - ".texinfo" + - ".texi" + - ".txi" + ace_mode: text + tm_scope: text.texinfo + interpreters: + - makeinfo + language_id: 988020015 +Text: + type: prose + wrap: true + aliases: + - fundamental + extensions: + - ".txt" + - ".fr" + - ".nb" + - ".ncl" + - ".no" + filenames: + - COPYING + - COPYING.regex + - COPYRIGHT.regex + - FONTLOG + - INSTALL + - INSTALL.mysql + - LICENSE + - LICENSE.mysql + - NEWS + - README.1ST + - README.me + - README.mysql + - click.me + - delete.me + - go.mod + - go.sum + - keep.me + - read.me + - readme.1st + - test.me + tm_scope: none + ace_mode: text + language_id: 372 +Textile: + type: prose + ace_mode: textile + codemirror_mode: textile + codemirror_mime_type: text/x-textile + wrap: true + extensions: + - ".textile" + tm_scope: none + language_id: 373 +Thrift: + type: programming + tm_scope: source.thrift + extensions: + - ".thrift" + ace_mode: text + language_id: 374 +Turing: + type: programming + color: "#cf142b" + extensions: + - ".t" + - ".tu" + tm_scope: source.turing + ace_mode: text + language_id: 375 +Turtle: + type: data + extensions: + - ".ttl" + tm_scope: source.turtle + ace_mode: text + codemirror_mode: turtle + codemirror_mime_type: text/turtle + language_id: 376 +Twig: + type: markup + group: HTML + extensions: + - ".twig" + tm_scope: text.html.twig + ace_mode: twig + codemirror_mode: twig + codemirror_mime_type: text/x-twig + language_id: 377 +Type Language: + type: data + aliases: + - tl + extensions: + - ".tl" + tm_scope: source.tl + ace_mode: text + language_id: 632765617 +TypeScript: + type: programming + color: "#2b7489" + aliases: + - ts + interpreters: + - deno + - ts-node + extensions: + - ".ts" + tm_scope: source.ts + ace_mode: typescript + codemirror_mode: javascript + codemirror_mime_type: application/typescript + language_id: 378 +Unified Parallel C: + type: programming + group: C + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + extensions: + - ".upc" + tm_scope: source.c + language_id: 379 +Unity3D Asset: + type: data + ace_mode: yaml + codemirror_mode: yaml + codemirror_mime_type: text/x-yaml + extensions: + - ".anim" + - ".asset" + - ".mat" + - ".meta" + - ".prefab" + - ".unity" + tm_scope: source.yaml + language_id: 380 +Unix Assembly: + type: programming + group: Assembly + extensions: + - ".s" + - ".ms" + tm_scope: source.x86 + ace_mode: assembly_x86 + language_id: 120 +Uno: + type: programming + extensions: + - ".uno" + ace_mode: csharp + codemirror_mode: clike + codemirror_mime_type: text/x-csharp + tm_scope: source.cs + language_id: 381 +UnrealScript: + type: programming + color: "#a54c4d" + extensions: + - ".uc" + tm_scope: source.java + ace_mode: java + codemirror_mode: clike + codemirror_mime_type: text/x-java + language_id: 382 +UrWeb: + type: programming + aliases: + - Ur/Web + - Ur + extensions: + - ".ur" + - ".urs" + tm_scope: source.ur + ace_mode: text + language_id: 383 +V: + type: programming + color: "#5d87bd" + aliases: + - vlang + extensions: + - ".v" + tm_scope: source.v + ace_mode: golang + codemirror_mode: go + codemirror_mime_type: text/x-go + language_id: 603371597 +VCL: + type: programming + color: "#148AA8" + extensions: + - ".vcl" + tm_scope: source.varnish.vcl + ace_mode: text + language_id: 384 +VHDL: + type: programming + color: "#adb2cb" + extensions: + - ".vhdl" + - ".vhd" + - ".vhf" + - ".vhi" + - ".vho" + - ".vhs" + - ".vht" + - ".vhw" + tm_scope: source.vhdl + ace_mode: vhdl + codemirror_mode: vhdl + codemirror_mime_type: text/x-vhdl + language_id: 385 +Vala: + type: programming + color: "#fbe5cd" + extensions: + - ".vala" + - ".vapi" + tm_scope: source.vala + ace_mode: vala + language_id: 386 +Verilog: + type: programming + color: "#b2b7f8" + extensions: + - ".v" + - ".veo" + tm_scope: source.verilog + ace_mode: verilog + codemirror_mode: verilog + codemirror_mime_type: text/x-verilog + language_id: 387 +Vim script: + type: programming + color: "#199f4b" + tm_scope: source.viml + aliases: + - vim + - viml + - nvim + extensions: + - ".vim" + - ".vba" + - ".vmb" + filenames: + - ".gvimrc" + - ".nvimrc" + - ".vimrc" + - _vimrc + - gvimrc + - nvimrc + - vimrc + ace_mode: text + language_id: 388 +Visual Basic: + type: programming + color: "#945db7" + extensions: + - ".vb" + - ".bas" + - ".cls" + - ".frm" + - ".frx" + - ".vba" + - ".vbhtml" + - ".vbs" + tm_scope: source.vbnet + aliases: + - vb.net + - vbnet + ace_mode: text + codemirror_mode: vb + codemirror_mime_type: text/x-vb + language_id: 389 +Volt: + type: programming + color: "#1F1F1F" + extensions: + - ".volt" + tm_scope: source.d + ace_mode: d + codemirror_mode: d + codemirror_mime_type: text/x-d + language_id: 390 +Vue: + type: markup + color: "#2c3e50" + extensions: + - ".vue" + tm_scope: text.html.vue + ace_mode: html + language_id: 391 +Wavefront Material: + type: data + extensions: + - ".mtl" + tm_scope: source.wavefront.mtl + ace_mode: text + language_id: 392 +Wavefront Object: + type: data + extensions: + - ".obj" + tm_scope: source.wavefront.obj + ace_mode: text + language_id: 393 +Web Ontology Language: + type: data + extensions: + - ".owl" + tm_scope: text.xml + ace_mode: xml + language_id: 394 +WebAssembly: + type: programming + color: "#04133b" + extensions: + - ".wast" + - ".wat" + aliases: + - wast + - wasm + tm_scope: source.webassembly + ace_mode: lisp + codemirror_mode: commonlisp + codemirror_mime_type: text/x-common-lisp + language_id: 956556503 +WebIDL: + type: programming + extensions: + - ".webidl" + tm_scope: source.webidl + ace_mode: text + codemirror_mode: webidl + codemirror_mime_type: text/x-webidl + language_id: 395 +WebVTT: + type: data + wrap: true + extensions: + - ".vtt" + tm_scope: source.vtt + ace_mode: text + language_id: 658679714 +Windows Registry Entries: + type: data + extensions: + - ".reg" + tm_scope: source.reg + ace_mode: ini + codemirror_mode: properties + codemirror_mime_type: text/x-properties + language_id: 969674868 +Wollok: + type: programming + color: "#a23738" + extensions: + - ".wlk" + ace_mode: text + tm_scope: source.wollok + language_id: 632745969 +World of Warcraft Addon Data: + type: data + extensions: + - ".toc" + tm_scope: source.toc + ace_mode: text + language_id: 396 +X BitMap: + type: data + group: C + aliases: + - xbm + extensions: + - ".xbm" + ace_mode: c_cpp + tm_scope: source.c + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 782911107 +X Font Directory Index: + type: data + filenames: + - encodings.dir + - fonts.alias + - fonts.dir + - fonts.scale + tm_scope: source.fontdir + ace_mode: text + language_id: 208700028 +X PixMap: + type: data + group: C + aliases: + - xpm + extensions: + - ".xpm" + - ".pm" + ace_mode: c_cpp + tm_scope: source.c + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 781846279 +X10: + type: programming + aliases: + - xten + ace_mode: text + extensions: + - ".x10" + color: "#4B6BEF" + tm_scope: source.x10 + language_id: 397 +XC: + type: programming + color: "#99DA07" + extensions: + - ".xc" + tm_scope: source.xc + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 398 +XCompose: + type: data + filenames: + - ".XCompose" + - XCompose + - xcompose + tm_scope: config.xcompose + ace_mode: text + language_id: 225167241 +XML: + type: data + tm_scope: text.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + aliases: + - rss + - xsd + - wsdl + extensions: + - ".xml" + - ".adml" + - ".admx" + - ".ant" + - ".axml" + - ".builds" + - ".ccproj" + - ".ccxml" + - ".clixml" + - ".cproject" + - ".cscfg" + - ".csdef" + - ".csl" + - ".csproj" + - ".ct" + - ".depproj" + - ".dita" + - ".ditamap" + - ".ditaval" + - ".dll.config" + - ".dotsettings" + - ".filters" + - ".fsproj" + - ".fxml" + - ".glade" + - ".gml" + - ".gmx" + - ".grxml" + - ".iml" + - ".ivy" + - ".jelly" + - ".jsproj" + - ".kml" + - ".launch" + - ".mdpolicy" + - ".mjml" + - ".mm" + - ".mod" + - ".mxml" + - ".natvis" + - ".ncl" + - ".ndproj" + - ".nproj" + - ".nuspec" + - ".odd" + - ".osm" + - ".pkgproj" + - ".pluginspec" + - ".proj" + - ".props" + - ".ps1xml" + - ".psc1" + - ".pt" + - ".rdf" + - ".resx" + - ".rss" + - ".sch" + - ".scxml" + - ".sfproj" + - ".shproj" + - ".srdf" + - ".storyboard" + - ".sublime-snippet" + - ".targets" + - ".tml" + - ".ts" + - ".tsx" + - ".ui" + - ".urdf" + - ".ux" + - ".vbproj" + - ".vcxproj" + - ".vsixmanifest" + - ".vssettings" + - ".vstemplate" + - ".vxml" + - ".wixproj" + - ".workflow" + - ".wsdl" + - ".wsf" + - ".wxi" + - ".wxl" + - ".wxs" + - ".x3d" + - ".xacro" + - ".xaml" + - ".xib" + - ".xlf" + - ".xliff" + - ".xmi" + - ".xml.dist" + - ".xproj" + - ".xsd" + - ".xspec" + - ".xul" + - ".zcml" + filenames: + - ".classpath" + - ".cproject" + - ".project" + - App.config + - NuGet.config + - Settings.StyleCop + - Web.Debug.config + - Web.Release.config + - Web.config + - packages.config + language_id: 399 +XML Property List: + type: data + group: XML + extensions: + - ".plist" + - ".stTheme" + - ".tmCommand" + - ".tmLanguage" + - ".tmPreferences" + - ".tmSnippet" + - ".tmTheme" + tm_scope: text.xml.plist + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 75622871 +XPages: + type: data + extensions: + - ".xsp-config" + - ".xsp.metadata" + tm_scope: text.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 400 +XProc: + type: programming + extensions: + - ".xpl" + - ".xproc" + tm_scope: text.xml + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + language_id: 401 +XQuery: + type: programming + color: "#5232e7" + extensions: + - ".xquery" + - ".xq" + - ".xql" + - ".xqm" + - ".xqy" + ace_mode: xquery + codemirror_mode: xquery + codemirror_mime_type: application/xquery + tm_scope: source.xq + language_id: 402 +XS: + type: programming + extensions: + - ".xs" + tm_scope: source.c + ace_mode: c_cpp + codemirror_mode: clike + codemirror_mime_type: text/x-csrc + language_id: 403 +XSLT: + type: programming + aliases: + - xsl + extensions: + - ".xslt" + - ".xsl" + tm_scope: text.xml.xsl + ace_mode: xml + codemirror_mode: xml + codemirror_mime_type: text/xml + color: "#EB8CEB" + language_id: 404 +Xojo: + type: programming + extensions: + - ".xojo_code" + - ".xojo_menu" + - ".xojo_report" + - ".xojo_script" + - ".xojo_toolbar" + - ".xojo_window" + tm_scope: source.xojo + ace_mode: text + language_id: 405 +Xtend: + type: programming + extensions: + - ".xtend" + tm_scope: source.xtend + ace_mode: text + language_id: 406 +YAML: + type: data + tm_scope: source.yaml + aliases: + - yml + extensions: + - ".yml" + - ".mir" + - ".reek" + - ".rviz" + - ".sublime-syntax" + - ".syntax" + - ".yaml" + - ".yaml-tmlanguage" + - ".yml.mysql" + filenames: + - ".clang-format" + - ".clang-tidy" + - ".gemrc" + - glide.lock + ace_mode: yaml + codemirror_mode: yaml + codemirror_mime_type: text/x-yaml + language_id: 407 +YANG: + type: data + extensions: + - ".yang" + tm_scope: source.yang + ace_mode: text + language_id: 408 +YARA: + type: programming + color: "#220000" + ace_mode: text + extensions: + - ".yar" + - ".yara" + tm_scope: source.yara + language_id: 805122868 +YASnippet: + type: markup + aliases: + - snippet + - yas + color: "#32AB90" + extensions: + - ".yasnippet" + tm_scope: source.yasnippet + ace_mode: text + language_id: 378760102 +Yacc: + type: programming + extensions: + - ".y" + - ".yacc" + - ".yy" + tm_scope: source.yacc + ace_mode: text + color: "#4B6C4B" + language_id: 409 +ZAP: + type: programming + color: "#0d665e" + extensions: + - ".zap" + - ".xzap" + tm_scope: source.zap + ace_mode: text + language_id: 952972794 +ZIL: + type: programming + color: "#dc75e5" + extensions: + - ".zil" + - ".mud" + tm_scope: source.zil + ace_mode: text + language_id: 973483626 +Zeek: + type: programming + aliases: + - bro + extensions: + - ".zeek" + - ".bro" + tm_scope: source.zeek + ace_mode: text + language_id: 40 +ZenScript: + type: programming + color: "#00BCD1" + extensions: + - ".zs" + tm_scope: source.zenscript + ace_mode: text + language_id: 494938890 +Zephir: + type: programming + color: "#118f9e" + extensions: + - ".zep" + tm_scope: source.php.zephir + ace_mode: php + language_id: 410 +Zig: + type: programming + color: "#ec915c" + extensions: + - ".zig" + tm_scope: source.zig + ace_mode: text + language_id: 646424281 +Zimpl: + type: programming + extensions: + - ".zimpl" + - ".zmpl" + - ".zpl" + tm_scope: none + ace_mode: text + language_id: 411 +desktop: + type: data + extensions: + - ".desktop" + - ".desktop.in" + tm_scope: source.desktop + ace_mode: text + language_id: 412 +eC: + type: programming + color: "#913960" + extensions: + - ".ec" + - ".eh" + tm_scope: source.c.ec + ace_mode: text + language_id: 413 +edn: + type: data + ace_mode: clojure + codemirror_mode: clojure + codemirror_mime_type: text/x-clojure + extensions: + - ".edn" + tm_scope: source.clojure + language_id: 414 +fish: + type: programming + group: Shell + interpreters: + - fish + extensions: + - ".fish" + tm_scope: source.fish + ace_mode: text + language_id: 415 +mcfunction: + type: programming + color: "#E22837" + extensions: + - ".mcfunction" + tm_scope: source.mcfunction + ace_mode: text + language_id: 462488745 +mupad: + type: programming + extensions: + - ".mu" + tm_scope: source.mupad + ace_mode: text + language_id: 416 +nanorc: + type: data + group: INI + extensions: + - ".nanorc" + filenames: + - ".nanorc" + - nanorc + tm_scope: source.nanorc + ace_mode: text + language_id: 775996197 +nesC: + type: programming + color: "#94B0C7" + extensions: + - ".nc" + ace_mode: text + tm_scope: source.nesc + language_id: 417 +ooc: + type: programming + color: "#b0b77e" + extensions: + - ".ooc" + tm_scope: source.ooc + ace_mode: text + language_id: 418 +q: + type: programming + extensions: + - ".q" + tm_scope: source.q + ace_mode: text + color: "#0040cd" + language_id: 970539067 +reStructuredText: + type: prose + wrap: true + aliases: + - rst + extensions: + - ".rst" + - ".rest" + - ".rest.txt" + - ".rst.txt" + tm_scope: text.restructuredtext + ace_mode: text + codemirror_mode: rst + codemirror_mime_type: text/x-rst + language_id: 419 +sed: + type: programming + color: "#64b970" + extensions: + - ".sed" + interpreters: + - gsed + - minised + - sed + - ssed + ace_mode: text + tm_scope: source.sed + language_id: 847830017 +wdl: + type: programming + color: "#42f1f4" + extensions: + - ".wdl" + tm_scope: source.wdl + ace_mode: text + language_id: 374521672 +wisp: + type: programming + ace_mode: clojure + codemirror_mode: clojure + codemirror_mime_type: text/x-clojure + color: "#7582D1" + extensions: + - ".wisp" + tm_scope: source.clojure + language_id: 420 +xBase: + type: programming + color: "#403a40" + aliases: + - advpl + - clipper + - foxpro + extensions: + - ".prg" + - ".ch" + - ".prw" + tm_scope: source.harbour + ace_mode: text + language_id: 421 diff --git a/packages/netlify-cms-widget-code/data/languages.json b/packages/netlify-cms-widget-code/data/languages.json new file mode 100644 index 00000000..671490e3 --- /dev/null +++ b/packages/netlify-cms-widget-code/data/languages.json @@ -0,0 +1 @@ +[{"label":"AGS Script","identifiers":["ags","asc","ash"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"APL","identifiers":["apl","dyalog"],"codemirror_mode":"apl","codemirror_mime_type":"text/apl"},{"label":"ASN.1","identifiers":["asn"],"codemirror_mode":"asn.1","codemirror_mime_type":"text/x-ttcn-asn"},{"label":"ASP","identifiers":["asp","aspx","asax","ascx","ashx","asmx","axd"],"codemirror_mode":"htmlembedded","codemirror_mime_type":"application/x-aspx"},{"label":"Alpine Abuild","identifiers":["abuild","apkbuild"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"AngelScript","identifiers":["angelscript","as"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"Ant Build System","identifiers":[],"codemirror_mode":"xml","codemirror_mime_type":"application/xml"},{"label":"Apex","identifiers":["apex","cls"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-java"},{"label":"Asymptote","identifiers":["asymptote","asy"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-kotlin"},{"label":"BibTeX","identifiers":["bibtex","bib"],"codemirror_mode":"stex","codemirror_mime_type":"text/x-stex"},{"label":"Brainfuck","identifiers":["brainfuck","b","bf"],"codemirror_mode":"brainfuck","codemirror_mime_type":"text/x-brainfuck"},{"label":"C","identifiers":["c","cats","h","idc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"C#","identifiers":["csharp","cs","cake","csx"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csharp"},{"label":"C++","identifiers":["cpp","cc","cp","cxx","h","hh","hpp","hxx","inc","inl","ino","ipp","re","tcc","tpp"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"C2hs Haskell","identifiers":["chs"],"codemirror_mode":"haskell","codemirror_mime_type":"text/x-haskell"},{"label":"CMake","identifiers":["cmake"],"codemirror_mode":"cmake","codemirror_mime_type":"text/x-cmake"},{"label":"COBOL","identifiers":["cobol","cob","cbl","ccp","cpy"],"codemirror_mode":"cobol","codemirror_mime_type":"text/x-cobol"},{"label":"COLLADA","identifiers":["collada","dae"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"CSON","identifiers":["cson"],"codemirror_mode":"coffeescript","codemirror_mime_type":"text/x-coffeescript"},{"label":"CSS","identifiers":["css"],"codemirror_mode":"css","codemirror_mime_type":"text/css"},{"label":"Cabal Config","identifiers":["Cabal","cabal"],"codemirror_mode":"haskell","codemirror_mime_type":"text/x-haskell"},{"label":"ChucK","identifiers":["chuck","ck"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-java"},{"label":"Clojure","identifiers":["clojure","clj","boot","cljc","cljs","cljscm","cljx","hic"],"codemirror_mode":"clojure","codemirror_mime_type":"text/x-clojure"},{"label":"Closure Templates","identifiers":["soy"],"codemirror_mode":"soy","codemirror_mime_type":"text/x-soy"},{"label":"Cloud Firestore Security Rules","identifiers":[],"codemirror_mode":"css","codemirror_mime_type":"text/css"},{"label":"CoffeeScript","identifiers":["coffeescript","coffee","cake","cjsx","iced"],"codemirror_mode":"coffeescript","codemirror_mime_type":"text/x-coffeescript"},{"label":"Common Lisp","identifiers":["lisp","asd","cl","l","lsp","ny","podsl","sexp"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"Common Workflow Language","identifiers":["cwl"],"codemirror_mode":"yaml","codemirror_mime_type":"text/x-yaml"},{"label":"Component Pascal","identifiers":["delphi","objectpascal","cp","cps"],"codemirror_mode":"pascal","codemirror_mime_type":"text/x-pascal"},{"label":"Crystal","identifiers":["crystal","cr"],"codemirror_mode":"crystal","codemirror_mime_type":"text/x-crystal"},{"label":"Cuda","identifiers":["cuda","cu","cuh"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"Cycript","identifiers":["cycript","cy"],"codemirror_mode":"javascript","codemirror_mime_type":"text/javascript"},{"label":"Cython","identifiers":["cython","pyrex","pyx","pxd","pxi"],"codemirror_mode":"python","codemirror_mime_type":"text/x-cython"},{"label":"D","identifiers":["d","di"],"codemirror_mode":"d","codemirror_mime_type":"text/x-d"},{"label":"DTrace","identifiers":["dtrace","d"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"Dart","identifiers":["dart"],"codemirror_mode":"dart","codemirror_mime_type":"application/dart"},{"label":"Dhall","identifiers":["dhall"],"codemirror_mode":"haskell","codemirror_mime_type":"text/x-haskell"},{"label":"Diff","identifiers":["diff","udiff","patch"],"codemirror_mode":"diff","codemirror_mime_type":"text/x-diff"},{"label":"Dockerfile","identifiers":["dockerfile"],"codemirror_mode":"dockerfile","codemirror_mime_type":"text/x-dockerfile"},{"label":"Dylan","identifiers":["dylan","dyl","intr","lid"],"codemirror_mode":"dylan","codemirror_mime_type":"text/x-dylan"},{"label":"EBNF","identifiers":["ebnf"],"codemirror_mode":"ebnf","codemirror_mime_type":"text/x-ebnf"},{"label":"ECL","identifiers":["ecl","eclxml"],"codemirror_mode":"ecl","codemirror_mime_type":"text/x-ecl"},{"label":"EQ","identifiers":["eq"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csharp"},{"label":"Eagle","identifiers":["eagle","sch","brd"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"Easybuild","identifiers":["easybuild","eb"],"codemirror_mode":"python","codemirror_mime_type":"text/x-python"},{"label":"Ecere Projects","identifiers":["epj"],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"EditorConfig","identifiers":["editorconfig"],"codemirror_mode":"properties","codemirror_mime_type":"text/x-properties"},{"label":"Edje Data Collection","identifiers":["edc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"Eiffel","identifiers":["eiffel","e"],"codemirror_mode":"eiffel","codemirror_mime_type":"text/x-eiffel"},{"label":"Elm","identifiers":["elm"],"codemirror_mode":"elm","codemirror_mime_type":"text/x-elm"},{"label":"Emacs Lisp","identifiers":["elisp","emacs","el"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"EmberScript","identifiers":["emberscript","em"],"codemirror_mode":"coffeescript","codemirror_mime_type":"text/x-coffeescript"},{"label":"Erlang","identifiers":["erlang","erl","es","escript","hrl","xrl","yrl"],"codemirror_mode":"erlang","codemirror_mime_type":"text/x-erlang"},{"label":"F#","identifiers":["fsharp","fs","fsi","fsx"],"codemirror_mode":"mllike","codemirror_mime_type":"text/x-fsharp"},{"label":"Factor","identifiers":["factor"],"codemirror_mode":"factor","codemirror_mime_type":"text/x-factor"},{"label":"Forth","identifiers":["forth","fth","f","for","fr","frt","fs"],"codemirror_mode":"forth","codemirror_mime_type":"text/x-forth"},{"label":"Fortran","identifiers":["fortran","f","for","fpp"],"codemirror_mode":"fortran","codemirror_mime_type":"text/x-fortran"},{"label":"GCC Machine Description","identifiers":["md"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"GN","identifiers":["gn","gni"],"codemirror_mode":"python","codemirror_mime_type":"text/x-python"},{"label":"Game Maker Language","identifiers":["gml"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"Genshi","identifiers":["genshi","kid"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"Gentoo Ebuild","identifiers":["ebuild"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"Gentoo Eclass","identifiers":["eclass"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"Git Attributes","identifiers":["gitattributes"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"Git Config","identifiers":["gitconfig","gitmodules"],"codemirror_mode":"properties","codemirror_mime_type":"text/x-properties"},{"label":"Glyph","identifiers":["glyph","glf"],"codemirror_mode":"tcl","codemirror_mime_type":"text/x-tcl"},{"label":"Go","identifiers":["go","golang"],"codemirror_mode":"go","codemirror_mime_type":"text/x-go"},{"label":"Grammatical Framework","identifiers":["gf"],"codemirror_mode":"haskell","codemirror_mime_type":"text/x-haskell"},{"label":"Groovy","identifiers":["groovy","grt","gtpl","gvy"],"codemirror_mode":"groovy","codemirror_mime_type":"text/x-groovy"},{"label":"Groovy Server Pages","identifiers":["gsp"],"codemirror_mode":"htmlembedded","codemirror_mime_type":"application/x-jsp"},{"label":"HCL","identifiers":["hcl","terraform","tf","tfvars","workflow"],"codemirror_mode":"ruby","codemirror_mime_type":"text/x-ruby"},{"label":"HTML","identifiers":["html","xhtml","htm","inc","st","xht"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"HTML+Django","identifiers":["django","htmldjango","njk","nunjucks","jinja","mustache"],"codemirror_mode":"django","codemirror_mime_type":"text/x-django"},{"label":"HTML+ECR","identifiers":["ecr"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"HTML+EEX","identifiers":["eex"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"HTML+ERB","identifiers":["erb"],"codemirror_mode":"htmlembedded","codemirror_mime_type":"application/x-erb"},{"label":"HTML+PHP","identifiers":["phtml"],"codemirror_mode":"php","codemirror_mime_type":"application/x-httpd-php"},{"label":"HTML+Razor","identifiers":["razor","cshtml"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"HTTP","identifiers":["http"],"codemirror_mode":"http","codemirror_mime_type":"message/http"},{"label":"Hack","identifiers":["hack","hh","php"],"codemirror_mode":"php","codemirror_mime_type":"application/x-httpd-php"},{"label":"Haml","identifiers":["haml"],"codemirror_mode":"haml","codemirror_mime_type":"text/x-haml"},{"label":"Haskell","identifiers":["haskell","hs","hsc"],"codemirror_mode":"haskell","codemirror_mime_type":"text/x-haskell"},{"label":"Haxe","identifiers":["haxe","hx","hxsl"],"codemirror_mode":"haxe","codemirror_mime_type":"text/x-haxe"},{"label":"HolyC","identifiers":["holyc","hc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"IDL","identifiers":["idl","pro","dlm"],"codemirror_mode":"idl","codemirror_mime_type":"text/x-idl"},{"label":"INI","identifiers":["ini","dosini","cfg","lektorproject","prefs","pro","properties"],"codemirror_mode":"properties","codemirror_mime_type":"text/x-properties"},{"label":"IRC log","identifiers":["irc","irclog","weechatlog"],"codemirror_mode":"mirc","codemirror_mime_type":"text/mirc"},{"label":"Ignore List","identifiers":["ignore","gitignore"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"JSON","identifiers":["json","avsc","geojson","gltf","har","ice","jsonl","mcmeta","tfstate","topojson","webapp","webmanifest","yy","yyp"],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"JSON with Comments","identifiers":["jsonc"],"codemirror_mode":"javascript","codemirror_mime_type":"text/javascript"},{"label":"JSON5","identifiers":[],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"JSONLD","identifiers":["jsonld"],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"JSONiq","identifiers":["jsoniq","jq"],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"JSX","identifiers":["jsx"],"codemirror_mode":"jsx","codemirror_mime_type":"text/jsx"},{"label":"Java","identifiers":["java"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-java"},{"label":"Java Properties","identifiers":["properties"],"codemirror_mode":"properties","codemirror_mime_type":"text/x-properties"},{"label":"Java Server Pages","identifiers":["jsp"],"codemirror_mode":"htmlembedded","codemirror_mime_type":"application/x-jsp"},{"label":"JavaScript","identifiers":["javascript","js","node","bones","es","frag","gs","jake","jsb","jscad","jsfl","jsm","jss","mjs","njs","pac","sjs","ssjs","xsjs","xsjslib"],"codemirror_mode":"javascript","codemirror_mime_type":"text/javascript"},{"label":"JavaScript+ERB","identifiers":[],"codemirror_mode":"javascript","codemirror_mime_type":"application/javascript"},{"label":"Julia","identifiers":["julia","jl"],"codemirror_mode":"julia","codemirror_mime_type":"text/x-julia"},{"label":"Jupyter Notebook","identifiers":["ipynb"],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"KiCad Layout","identifiers":["pcbnew"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"Kit","identifiers":["kit"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"Kotlin","identifiers":["kotlin","kt","ktm","kts"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-kotlin"},{"label":"LFE","identifiers":["lfe"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"LTspice Symbol","identifiers":["asy"],"codemirror_mode":"spreadsheet","codemirror_mime_type":"text/x-spreadsheet"},{"label":"LabVIEW","identifiers":["labview","lvproj"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"Latte","identifiers":["latte"],"codemirror_mode":"smarty","codemirror_mime_type":"text/x-smarty"},{"label":"Less","identifiers":["less"],"codemirror_mode":"css","codemirror_mime_type":"text/css"},{"label":"Literate Haskell","identifiers":["lhaskell","lhs"],"codemirror_mode":"haskell-literate","codemirror_mime_type":"text/x-literate-haskell"},{"label":"LiveScript","identifiers":["livescript","ls"],"codemirror_mode":"livescript","codemirror_mime_type":"text/x-livescript"},{"label":"LookML","identifiers":["lookml"],"codemirror_mode":"yaml","codemirror_mime_type":"text/x-yaml"},{"label":"Lua","identifiers":["lua","fcgi","nse","rbxs","wlua"],"codemirror_mode":"lua","codemirror_mime_type":"text/x-lua"},{"label":"M","identifiers":["m","mumps"],"codemirror_mode":"mumps","codemirror_mime_type":"text/x-mumps"},{"label":"MATLAB","identifiers":["matlab","octave","m"],"codemirror_mode":"octave","codemirror_mime_type":"text/x-octave"},{"label":"MTML","identifiers":["mtml"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"MUF","identifiers":["muf","m"],"codemirror_mode":"forth","codemirror_mime_type":"text/x-forth"},{"label":"Makefile","identifiers":["makefile","bsdmake","make","mf","mak","d","mk","mkfile"],"codemirror_mode":"cmake","codemirror_mime_type":"text/x-cmake"},{"label":"Markdown","identifiers":["markdown","pandoc","md","mdown","mdwn","mdx","mkd","mkdn","mkdown","ronn","workbook"],"codemirror_mode":"gfm","codemirror_mime_type":"text/x-gfm"},{"label":"Marko","identifiers":["marko","markojs"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"Mathematica","identifiers":["mathematica","mma","cdf","m","ma","mt","nb","nbp","wl","wlt"],"codemirror_mode":"mathematica","codemirror_mime_type":"text/x-mathematica"},{"label":"Maven POM","identifiers":[],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"Max","identifiers":["max","maxmsp","maxpat","maxhelp","maxproj","mxt","pat"],"codemirror_mode":"javascript","codemirror_mime_type":"application/json"},{"label":"Metal","identifiers":["metal"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"Mirah","identifiers":["mirah","druby","duby"],"codemirror_mode":"ruby","codemirror_mime_type":"text/x-ruby"},{"label":"Modelica","identifiers":["modelica","mo"],"codemirror_mode":"modelica","codemirror_mime_type":"text/x-modelica"},{"label":"NSIS","identifiers":["nsis","nsi","nsh"],"codemirror_mode":"nsis","codemirror_mime_type":"text/x-nsis"},{"label":"NetLogo","identifiers":["netlogo","nlogo"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"NewLisp","identifiers":["newlisp","nl","lisp","lsp"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"Nginx","identifiers":["nginx","nginxconf","vhost"],"codemirror_mode":"nginx","codemirror_mime_type":"text/x-nginx-conf"},{"label":"Nu","identifiers":["nu","nush"],"codemirror_mode":"scheme","codemirror_mime_type":"text/x-scheme"},{"label":"NumPy","identifiers":["numpy","numpyw","numsc"],"codemirror_mode":"python","codemirror_mime_type":"text/x-python"},{"label":"OCaml","identifiers":["ocaml","ml","eliom","eliomi","mli","mll","mly"],"codemirror_mode":"mllike","codemirror_mime_type":"text/x-ocaml"},{"label":"Objective-C","identifiers":["objc","objectivec","m","h"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-objectivec"},{"label":"Objective-C++","identifiers":["mm"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-objectivec"},{"label":"OpenCL","identifiers":["opencl","cl"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"OpenRC runscript","identifiers":["openrc"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"Oz","identifiers":["oz"],"codemirror_mode":"oz","codemirror_mime_type":"text/x-oz"},{"label":"PHP","identifiers":["php","inc","aw","ctp","fcgi","phps","phpt"],"codemirror_mode":"php","codemirror_mime_type":"application/x-httpd-php"},{"label":"PLSQL","identifiers":["plsql","pls","bdy","ddl","fnc","pck","pkb","pks","plb","prc","spc","sql","tpb","tps","trg","vw"],"codemirror_mode":"sql","codemirror_mime_type":"text/x-plsql"},{"label":"PLpgSQL","identifiers":["plpgsql","pgsql","sql"],"codemirror_mode":"sql","codemirror_mime_type":"text/x-sql"},{"label":"Pascal","identifiers":["pascal","pas","dfm","dpr","inc","lpr","pp"],"codemirror_mode":"pascal","codemirror_mime_type":"text/x-pascal"},{"label":"Perl","identifiers":["perl","cperl","pl","al","cgi","fcgi","ph","plx","pm","psgi","t"],"codemirror_mode":"perl","codemirror_mime_type":"text/x-perl"},{"label":"Perl 6","identifiers":["nqp","pl","pm","t"],"codemirror_mode":"perl","codemirror_mime_type":"text/x-perl"},{"label":"Pic","identifiers":["pic","chem"],"codemirror_mode":"troff","codemirror_mime_type":"text/troff"},{"label":"Pod","identifiers":["pod"],"codemirror_mode":"perl","codemirror_mime_type":"text/x-perl"},{"label":"PowerShell","identifiers":["powershell","posh","pwsh"],"codemirror_mode":"powershell","codemirror_mime_type":"application/x-powershell"},{"label":"Protocol Buffer","identifiers":["protobuf","proto"],"codemirror_mode":"protobuf","codemirror_mime_type":"text/x-protobuf"},{"label":"Public Key","identifiers":["asc","pub"],"codemirror_mode":"asciiarmor","codemirror_mime_type":"application/pgp"},{"label":"Pug","identifiers":["pug","jade"],"codemirror_mode":"pug","codemirror_mime_type":"text/x-pug"},{"label":"Puppet","identifiers":["puppet","pp"],"codemirror_mode":"puppet","codemirror_mime_type":"text/x-puppet"},{"label":"PureScript","identifiers":["purescript","purs"],"codemirror_mode":"haskell","codemirror_mime_type":"text/x-haskell"},{"label":"Python","identifiers":["python","rusthon","py","bzl","cgi","fcgi","gyp","gypi","lmi","pyde","pyi","pyp","pyt","pyw","rpy","spec","tac","wsgi","xpy"],"codemirror_mode":"python","codemirror_mime_type":"text/x-python"},{"label":"R","identifiers":["r","R","Rscript","splus","rd","rsx"],"codemirror_mode":"r","codemirror_mime_type":"text/x-rsrc"},{"label":"RAML","identifiers":["raml"],"codemirror_mode":"yaml","codemirror_mime_type":"text/x-yaml"},{"label":"RHTML","identifiers":["rhtml"],"codemirror_mode":"htmlembedded","codemirror_mime_type":"application/x-erb"},{"label":"RMarkdown","identifiers":["rmarkdown","rmd"],"codemirror_mode":"gfm","codemirror_mime_type":"text/x-gfm"},{"label":"RPM Spec","identifiers":["specfile","spec"],"codemirror_mode":"rpm","codemirror_mime_type":"text/x-rpm-spec"},{"label":"Reason","identifiers":["reason","re","rei"],"codemirror_mode":"rust","codemirror_mime_type":"text/x-rustsrc"},{"label":"Roff","identifiers":["roff","groff","man","manpage","mdoc","nroff","troff","l","me","ms","n","nr","rno","tmac"],"codemirror_mode":"troff","codemirror_mime_type":"text/troff"},{"label":"Roff Manpage","identifiers":["man","mdoc"],"codemirror_mode":"troff","codemirror_mime_type":"text/troff"},{"label":"Rouge","identifiers":["rouge","rg"],"codemirror_mode":"clojure","codemirror_mime_type":"text/x-clojure"},{"label":"Ruby","identifiers":["ruby","jruby","macruby","rake","rb","rbx","builder","eye","fcgi","gemspec","god","jbuilder","mspec","pluginspec","podspec","rabl","rbuild","rbw","ru","spec","thor","watchr"],"codemirror_mode":"ruby","codemirror_mime_type":"text/x-ruby"},{"label":"Rust","identifiers":["rust","rs"],"codemirror_mode":"rust","codemirror_mime_type":"text/x-rustsrc"},{"label":"SAS","identifiers":["sas"],"codemirror_mode":"sas","codemirror_mime_type":"text/x-sas"},{"label":"SCSS","identifiers":["scss"],"codemirror_mode":"css","codemirror_mime_type":"text/x-scss"},{"label":"SPARQL","identifiers":["sparql","rq"],"codemirror_mode":"sparql","codemirror_mime_type":"application/sparql-query"},{"label":"SQL","identifiers":["sql","cql","ddl","inc","mysql","prc","tab","udf","viw"],"codemirror_mode":"sql","codemirror_mime_type":"text/x-sql"},{"label":"SQLPL","identifiers":["sqlpl","sql"],"codemirror_mode":"sql","codemirror_mime_type":"text/x-sql"},{"label":"SRecode Template","identifiers":["srt"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"SVG","identifiers":["svg"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"Sage","identifiers":["sage","sagews"],"codemirror_mode":"python","codemirror_mime_type":"text/x-python"},{"label":"SaltStack","identifiers":["saltstack","saltstate","salt","sls"],"codemirror_mode":"yaml","codemirror_mime_type":"text/x-yaml"},{"label":"Sass","identifiers":["sass"],"codemirror_mode":"sass","codemirror_mime_type":"text/x-sass"},{"label":"Scala","identifiers":["scala","kojo","sbt","sc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-scala"},{"label":"Scheme","identifiers":["scheme","scm","sch","sld","sls","sps","ss"],"codemirror_mode":"scheme","codemirror_mime_type":"text/x-scheme"},{"label":"Shell","identifiers":["shell","sh","bash","zsh","bats","cgi","command","fcgi","ksh","tmux","tool"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"ShellSession","identifiers":["shellsession","console"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"Slim","identifiers":["slim"],"codemirror_mode":"slim","codemirror_mime_type":"text/x-slim"},{"label":"Smalltalk","identifiers":["smalltalk","squeak","st","cs"],"codemirror_mode":"smalltalk","codemirror_mime_type":"text/x-stsrc"},{"label":"Smarty","identifiers":["smarty","tpl"],"codemirror_mode":"smarty","codemirror_mime_type":"text/x-smarty"},{"label":"Squirrel","identifiers":["squirrel","nut"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-c++src"},{"label":"Standard ML","identifiers":["sml","ML","fun","sig"],"codemirror_mode":"mllike","codemirror_mime_type":"text/x-ocaml"},{"label":"Svelte","identifiers":["svelte"],"codemirror_mode":"htmlmixed","codemirror_mime_type":"text/html"},{"label":"Swift","identifiers":["swift"],"codemirror_mode":"swift","codemirror_mime_type":"text/x-swift"},{"label":"SystemVerilog","identifiers":["systemverilog","sv","svh","vh"],"codemirror_mode":"verilog","codemirror_mime_type":"text/x-systemverilog"},{"label":"TOML","identifiers":["toml"],"codemirror_mode":"toml","codemirror_mime_type":"text/x-toml"},{"label":"TSX","identifiers":["tsx"],"codemirror_mode":"jsx","codemirror_mime_type":"text/jsx"},{"label":"Tcl","identifiers":["tcl","adp","tm"],"codemirror_mode":"tcl","codemirror_mime_type":"text/x-tcl"},{"label":"Tcsh","identifiers":["tcsh","csh"],"codemirror_mode":"shell","codemirror_mime_type":"text/x-sh"},{"label":"TeX","identifiers":["tex","latex","aux","bbx","cbx","cls","dtx","ins","lbx","ltx","mkii","mkiv","mkvi","sty","toc"],"codemirror_mode":"stex","codemirror_mime_type":"text/x-stex"},{"label":"Terra","identifiers":["terra","t"],"codemirror_mode":"lua","codemirror_mime_type":"text/x-lua"},{"label":"Textile","identifiers":["textile"],"codemirror_mode":"textile","codemirror_mime_type":"text/x-textile"},{"label":"Turtle","identifiers":["turtle","ttl"],"codemirror_mode":"turtle","codemirror_mime_type":"text/turtle"},{"label":"Twig","identifiers":["twig"],"codemirror_mode":"twig","codemirror_mime_type":"text/x-twig"},{"label":"TypeScript","identifiers":["typescript","ts"],"codemirror_mode":"javascript","codemirror_mime_type":"application/typescript"},{"label":"Unified Parallel C","identifiers":["upc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"Unity3D Asset","identifiers":["anim","asset","mat","meta","prefab","unity"],"codemirror_mode":"yaml","codemirror_mime_type":"text/x-yaml"},{"label":"Uno","identifiers":["uno"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csharp"},{"label":"UnrealScript","identifiers":["unrealscript","uc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-java"},{"label":"V","identifiers":["v","vlang"],"codemirror_mode":"go","codemirror_mime_type":"text/x-go"},{"label":"VHDL","identifiers":["vhdl","vhd","vhf","vhi","vho","vhs","vht","vhw"],"codemirror_mode":"vhdl","codemirror_mime_type":"text/x-vhdl"},{"label":"Verilog","identifiers":["verilog","v","veo"],"codemirror_mode":"verilog","codemirror_mime_type":"text/x-verilog"},{"label":"Visual Basic","identifiers":["vbnet","vb","bas","cls","frm","frx","vba","vbhtml","vbs"],"codemirror_mode":"vb","codemirror_mime_type":"text/x-vb"},{"label":"Volt","identifiers":["volt"],"codemirror_mode":"d","codemirror_mime_type":"text/x-d"},{"label":"WebAssembly","identifiers":["webassembly","wast","wasm","wat"],"codemirror_mode":"commonlisp","codemirror_mime_type":"text/x-common-lisp"},{"label":"WebIDL","identifiers":["webidl"],"codemirror_mode":"webidl","codemirror_mime_type":"text/x-webidl"},{"label":"Windows Registry Entries","identifiers":["reg"],"codemirror_mode":"properties","codemirror_mime_type":"text/x-properties"},{"label":"X BitMap","identifiers":["xbm"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"X PixMap","identifiers":["xpm","pm"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"XC","identifiers":["xc"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"XML","identifiers":["xml","rss","xsd","wsdl","adml","admx","ant","axml","builds","ccproj","ccxml","clixml","cproject","cscfg","csdef","csl","csproj","ct","depproj","dita","ditamap","ditaval","dotsettings","filters","fsproj","fxml","glade","gml","gmx","grxml","iml","ivy","jelly","jsproj","kml","launch","mdpolicy","mjml","mm","mod","mxml","natvis","ncl","ndproj","nproj","nuspec","odd","osm","pkgproj","pluginspec","proj","props","pt","rdf","resx","sch","scxml","sfproj","shproj","srdf","storyboard","targets","tml","ts","tsx","ui","urdf","ux","vbproj","vcxproj","vsixmanifest","vssettings","vstemplate","vxml","wixproj","workflow","wsf","wxi","wxl","wxs","xacro","xaml","xib","xlf","xliff","xmi","xproj","xspec","xul","zcml"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"XML Property List","identifiers":["plist","stTheme","tmCommand","tmLanguage","tmPreferences","tmSnippet","tmTheme"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"XPages","identifiers":["xpages"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"XProc","identifiers":["xproc","xpl"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"XQuery","identifiers":["xquery","xq","xql","xqm","xqy"],"codemirror_mode":"xquery","codemirror_mime_type":"application/xquery"},{"label":"XS","identifiers":["xs"],"codemirror_mode":"clike","codemirror_mime_type":"text/x-csrc"},{"label":"XSLT","identifiers":["xslt","xsl"],"codemirror_mode":"xml","codemirror_mime_type":"text/xml"},{"label":"YAML","identifiers":["yaml","yml","mir","reek","rviz","syntax"],"codemirror_mode":"yaml","codemirror_mime_type":"text/x-yaml"},{"label":"edn","identifiers":["edn"],"codemirror_mode":"clojure","codemirror_mime_type":"text/x-clojure"},{"label":"reStructuredText","identifiers":["restructuredtext","rst","rest"],"codemirror_mode":"rst","codemirror_mime_type":"text/x-rst"},{"label":"wisp","identifiers":["wisp"],"codemirror_mode":"clojure","codemirror_mime_type":"text/x-clojure"}] diff --git a/packages/netlify-cms-widget-code/package.json b/packages/netlify-cms-widget-code/package.json new file mode 100644 index 00000000..213d0682 --- /dev/null +++ b/packages/netlify-cms-widget-code/package.json @@ -0,0 +1,39 @@ +{ + "name": "netlify-cms-widget-code", + "description": "Widget for editing code in Netlify CMS", + "version": "1.0.0", + "homepage": "https://www.netlifycms.org/docs/widgets/#code", + "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code", + "bugs": "https://github.com/netlify/netlify-cms/issues", + "module": "dist/esm/index.js", + "main": "dist/netlify-cms-widget-code.js", + "license": "MIT", + "keywords": [ + "netlify", + "netlify-cms", + "widget", + "code", + "codemirror", + "editor", + "code editor" + ], + "sideEffects": false, + "scripts": { + "develop": "yarn build:esm --watch", + "build": "cross-env NODE_ENV=production webpack", + "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward", + "process:languages": "node ./scripts/process-languages" + }, + "peerDependencies": { + "@emotion/core": "^10.0.9", + "lodash": "^4.17.11", + "codemirror": "^5.46.0", + "react": "^16.8.4", + "netlify-cms-ui-default": "^2.6.2" + }, + "dependencies": { + "re-resizable": "^4.11.0", + "react-codemirror2": "^6.0.0", + "react-select": "^2.4.3" + } +} diff --git a/packages/netlify-cms-widget-code/scripts/process-languages.js b/packages/netlify-cms-widget-code/scripts/process-languages.js new file mode 100644 index 00000000..6ab396b3 --- /dev/null +++ b/packages/netlify-cms-widget-code/scripts/process-languages.js @@ -0,0 +1,45 @@ +const fs = require('fs-extra'); +const path = require('path'); +const yaml = require('js-yaml'); +const uniq = require('lodash/uniq'); + +const rawDataPath = '../data/languages-raw.yml'; +const outputPath = '../data/languages.json'; + +async function fetchData() { + const filePath = path.resolve(__dirname, rawDataPath); + const fileContent = await fs.readFile(filePath); + return yaml.safeLoad(fileContent); +} + +function outputData(data) { + const filePath = path.resolve(__dirname, outputPath); + return fs.writeJson(filePath, data); +} + +function transform(data) { + return Object.entries(data).reduce((acc, [label, lang]) => { + const { extensions = [], aliases = [], codemirror_mode, codemirror_mime_type } = lang; + if (codemirror_mode) { + const dotlessExtensions = extensions.map(ext => ext.slice(1)); + const identifiers = uniq( + [label.toLowerCase(), ...aliases, ...dotlessExtensions].filter(alias => { + if (!alias) { + return; + } + return !/[^a-zA-Z]/.test(alias); + }), + ); + acc.push({ label, identifiers, codemirror_mode, codemirror_mime_type }); + } + return acc; + }, []); +} + +async function process() { + const data = await fetchData(); + const transformedData = transform(data); + return outputData(transformedData); +} + +process(); diff --git a/packages/netlify-cms-widget-code/src/CodeControl.js b/packages/netlify-cms-widget-code/src/CodeControl.js new file mode 100644 index 00000000..0bf00bf0 --- /dev/null +++ b/packages/netlify-cms-widget-code/src/CodeControl.js @@ -0,0 +1,315 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { ClassNames } from '@emotion/core'; +import { Map } from 'immutable'; +import { uniq, isEqual, isEmpty } from 'lodash'; +import uuid from 'uuid/v4'; +import { UnControlled as ReactCodeMirror } from 'react-codemirror2'; +import CodeMirror from 'codemirror'; +import 'codemirror/keymap/vim'; +import 'codemirror/keymap/sublime'; +import 'codemirror/keymap/emacs'; +import codeMirrorStyles from 'codemirror/lib/codemirror.css'; +import materialTheme from 'codemirror/theme/material.css'; +import SettingsPane from './SettingsPane'; +import SettingsButton from './SettingsButton'; +import languageData from '../data/languages.json'; + +// TODO: relocate as a utility function +function getChangedProps(previous, next, keys) { + const propNames = keys || uniq(Object.keys(previous), Object.keys(next)); + const changedProps = propNames.reduce((acc, prop) => { + if (previous[prop] !== next[prop]) { + acc[prop] = next[prop]; + } + return acc; + }, {}); + if (!isEmpty(changedProps)) { + return changedProps; + } +} + +const languages = languageData.map(lang => ({ + label: lang.label, + name: lang.identifiers[0], + mode: lang.codemirror_mode, + mimeType: lang.codemirror_mime_type, +})); + +const styleString = ` + padding: 0; +`; + +const defaultLang = { name: '', mode: '', label: 'none' }; + +function valueToOption(val) { + if (typeof val === 'string') { + return { value: val, label: val }; + } + return { value: val.name, label: val.label || val.name }; +} + +const modes = languages.map(valueToOption); + +const themes = ['default', 'material']; + +const settingsPersistKeys = { + theme: 'cms.codemirror.theme', + keyMap: 'cms.codemirror.keymap', +}; + +export default class CodeControl extends React.Component { + static propTypes = { + field: ImmutablePropTypes.map.isRequired, + onChange: PropTypes.func.isRequired, + value: PropTypes.node, + forID: PropTypes.string.isRequired, + classNameWrapper: PropTypes.string.isRequired, + widget: PropTypes.object.isRequired, + }; + + keys = this.getKeys(this.props.field); + + state = { + isActive: false, + unknownLang: null, + lang: '', + keyMap: localStorage.getItem(settingsPersistKeys['keyMap']) || 'default', + settingsVisible: false, + codeMirrorKey: uuid(), + theme: localStorage.getItem(settingsPersistKeys['theme']) || themes[themes.length - 1], + lastKnownValue: this.valueIsMap() ? this.props.value?.get(this.keys.code) : this.props.value, + }; + + shouldComponentUpdate(nextProps, nextState) { + return ( + !isEqual(this.state, nextState) || this.props.classNameWrapper !== nextProps.classNameWrapper + ); + } + + componentDidMount() { + this.setState({ + lang: this.getInitialLang() || '', + }); + } + + componentDidUpdate(prevProps, prevState) { + this.updateCodeMirrorProps(prevState); + } + + updateCodeMirrorProps(prevState) { + const keys = ['lang', 'theme', 'keyMap']; + const changedProps = getChangedProps(prevState, this.state, keys); + if (changedProps) { + this.handleChangeCodeMirrorProps(changedProps); + } + } + + getLanguageByName = name => { + return languages.find(lang => lang.name === name); + }; + + getKeyMapOptions = () => { + return Object.keys(CodeMirror.keyMap) + .sort() + .filter(keyMap => ['emacs', 'vim', 'sublime', 'default'].includes(keyMap)) + .map(keyMap => ({ value: keyMap, label: keyMap })); + }; + + // This widget is not fully controlled, it only takes a value through props + // upon initialization. + getInitialLang = () => { + const { value, field } = this.props; + const lang = + (this.valueIsMap() && value && value.get(this.keys.lang)) || field.get('defaultLanguage'); + const langInfo = this.getLanguageByName(lang); + if (lang && !langInfo) { + this.setState({ unknownLang: lang }); + } + return lang; + }; + + // If `allow_language_selection` is not set, default to true. Otherwise, use + // its value. + allowLanguageSelection = + !this.props.field.has('allow_language_selection') || + !!this.props.field.get('allow_language_selection'); + + toValue = this.valueIsMap() + ? (type, value) => (this.props.value || Map()).set(this.keys[type], value) + : (type, value) => (type === 'code' ? value : this.props.value); + + // If the value is a map, keys can be customized via config. + getKeys(field) { + const defaults = { + code: 'code', + lang: 'lang', + }; + + // Force default keys if widget is an editor component code block. + if (this.props.isEditorComponent) { + return defaults; + } + + const keys = field.get('keys', Map()).toJS(); + return { ...defaults, ...keys }; + } + + // Determine if the persisted value is a map rather than a plain string. A map + // value allows both the code string and the language to be persisted. + valueIsMap() { + const { field, isEditorComponent } = this.props; + return !field.get('output_code_only') || isEditorComponent; + } + + async handleChangeCodeMirrorProps(changedProps) { + const { onChange } = this.props; + + if (changedProps.lang) { + const { mode } = this.getLanguageByName(changedProps.lang) || {}; + if (mode) { + await import(`codemirror/mode/${mode}/${mode}.js`); + } + } + + // Changing CodeMirror props requires re-initializing the + // detached/uncontrolled React CodeMirror component, so here we save and + // restore the selections and cursor position after the state change. + if (this.cm) { + const cursor = this.cm.doc.getCursor(); + const selections = this.cm.doc.listSelections(); + this.setState({ codeMirrorKey: uuid() }, () => { + this.cm.doc.setCursor(cursor); + this.cm.doc.setSelections(selections); + }); + } + + for (const key of ['theme', 'keyMap']) { + if (changedProps[key]) { + localStorage.setItem(settingsPersistKeys[key], changedProps[key]); + } + } + + // Only persist the language change if supported - requires the value to be + // a map rather than just a code string. + if (changedProps.lang && this.valueIsMap()) { + onChange(this.toValue('lang', changedProps.lang)); + } + } + + handleChange(newValue) { + const cursor = this.cm.doc.getCursor(); + const selections = this.cm.doc.listSelections(); + this.setState({ lastKnownValue: newValue }); + this.props.onChange(this.toValue('code', newValue), { cursor, selections }); + } + + showSettings = () => { + this.setState({ settingsVisible: true }); + }; + + hideSettings = () => { + if (this.state.settingsVisible) { + this.setState({ settingsVisible: false }); + } + this.cm.focus(); + }; + + handleFocus = () => { + this.hideSettings(); + this.props.setActiveStyle(); + this.setActive(); + }; + + handleBlur = () => { + this.setInactive(); + this.props.setInactiveStyle(); + }; + + setActive = () => this.setState({ isActive: true }); + setInactive = () => this.setState({ isActive: false }); + + render() { + const { classNameWrapper, forID, widget, isNewEditorComponent } = this.props; + const { lang, settingsVisible, keyMap, codeMirrorKey, theme, lastKnownValue } = this.state; + const langInfo = this.getLanguageByName(lang); + const mode = langInfo?.mimeType || langInfo?.mode; + + return ( + + {({ css, cx }) => ( +
+ {!settingsVisible && } + {settingsVisible && ( + t === theme)} + themes={themes} + keyMap={{ value: keyMap, label: keyMap }} + keyMaps={this.getKeyMapOptions()} + allowLanguageSelection={this.allowLanguageSelection} + onChangeLang={newLang => this.setState({ lang: newLang })} + onChangeTheme={newTheme => this.setState({ theme: newTheme })} + onChangeKeyMap={newKeyMap => this.setState({ keyMap: newKeyMap })} + /> + )} + { + this.cm = cm; + if (isNewEditorComponent) { + this.handleFocus(); + } + }} + value={lastKnownValue} + onChange={(editor, data, newValue) => this.handleChange(newValue)} + onFocus={this.handleFocus} + onBlur={this.handleBlur} + /> +
+ )} +
+ ); + } +} diff --git a/packages/netlify-cms-widget-code/src/CodePreview.js b/packages/netlify-cms-widget-code/src/CodePreview.js new file mode 100644 index 00000000..78bb85f6 --- /dev/null +++ b/packages/netlify-cms-widget-code/src/CodePreview.js @@ -0,0 +1,29 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Map } from 'immutable'; +import { isString } from 'lodash'; +import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +const toValue = (value, field) => { + if (isString(value)) { + return value; + } + if (Map.isMap(value)) { + return value.get(field.getIn(['keys', 'code'], 'code'), ''); + } + return ''; +}; + +const CodePreview = props => ( + +
+      {toValue(props.value, props.field)}
+    
+
+); + +CodePreview.propTypes = { + value: PropTypes.node, +}; + +export default CodePreview; diff --git a/packages/netlify-cms-widget-code/src/SettingsButton.js b/packages/netlify-cms-widget-code/src/SettingsButton.js new file mode 100644 index 00000000..1e4a9fd7 --- /dev/null +++ b/packages/netlify-cms-widget-code/src/SettingsButton.js @@ -0,0 +1,31 @@ +import React from 'react'; +import styled from '@emotion/styled'; +import { Icon, buttons, shadows } from 'netlify-cms-ui-default'; + +const StyledSettingsButton = styled.button` + ${buttons.button}; + ${buttons.default}; + ${shadows.drop}; + display: block; + position: absolute; + z-index: 100; + right: 8px; + top: 8px; + opacity: 0.8; + padding: 2px 4px; + line-height: 1; + height: auto; + + ${Icon} { + position: relative; + top: 1px; + } +`; + +const SettingsButton = ({ showClose, onClick }) => ( + + + +); + +export default SettingsButton; diff --git a/packages/netlify-cms-widget-code/src/SettingsPane.js b/packages/netlify-cms-widget-code/src/SettingsPane.js new file mode 100644 index 00000000..d077016a --- /dev/null +++ b/packages/netlify-cms-widget-code/src/SettingsPane.js @@ -0,0 +1,109 @@ +import React from 'react'; +import styled from '@emotion/styled'; +import Select from 'react-select'; +import isHotkey from 'is-hotkey'; +import { text, shadows } from 'netlify-cms-ui-default'; +import SettingsButton from './SettingsButton'; +import languageSelectStyles from './languageSelectStyles'; + +const SettingsPaneContainer = styled.div` + position: absolute; + right: 0; + width: 200px; + z-index: 10; + height: 100%; + background-color: #fff; + overflow-y: scroll; + padding: 12px; + ${shadows.drop}; +`; + +const SettingsFieldLabel = styled.label` + ${text.fieldLabel}; + font-size: 11px; + display: block; + margin-top: 8px; + margin-bottom: 2px; +`; + +const SettingsSectionTitle = styled.h3` + font-size: 14px; + margin-top: 14px; + margin-bottom: 0; + + &:first-of-type { + margin-top: 4px; + } +`; + +const SettingsSelect = ({ value, options, onChange, forID, type, autoFocus }) => ( +