Skip to content

Commit

Permalink
feat: add autocompletion (#41)
Browse files Browse the repository at this point in the history
* update codemirror dependencies
* update dark theme
* add custom keymap
* add ladle to inspect components
  • Loading branch information
janstuemmel authored Nov 30, 2022
1 parent 3f8858a commit 5f7edbe
Show file tree
Hide file tree
Showing 8 changed files with 15,543 additions and 9,643 deletions.
24,815 changes: 15,214 additions & 9,601 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"lint": "eslint . --cache",
"type-check": "tsc --noEmit",
"clean": "rimraf dist",
"ladle": "ladle serve",
"watch": "./scripts/build.ts --watch",
"build": "./scripts/build.ts --minify",
"bundle": "run-s clean build ext:build:firefox ext:build:chrome",
Expand All @@ -20,10 +21,13 @@
},
"dependencies": {
"@blueprintjs/core": "^4.5.1",
"@codemirror/language": "^6.2.0",
"@codemirror/autocomplete": "^6.3.4",
"@codemirror/commands": "^6.1.2",
"@codemirror/language": "^6.3.1",
"@codemirror/legacy-modes": "^6.1.0",
"@codemirror/view": "^6.0.2",
"@uiw/react-codemirror": "^4.10.4",
"@codemirror/theme-one-dark": "^6.1.0",
"@codemirror/view": "^6.6.0",
"@uiw/react-codemirror": "^4.15.1",
"buffer": "^6.0.3",
"colortranslator": "^1.9.2",
"js-ini": "^1.5.1",
Expand All @@ -36,6 +40,7 @@
},
"devDependencies": {
"@faker-js/faker": "^7.3.0",
"@ladle/react": "^2.4.5",
"@types/chrome": "^0.0.202",
"@types/jest": "^28.1.4",
"@types/lodash": "^4.14.182",
Expand Down
150 changes: 150 additions & 0 deletions src/common/const/cssColors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
export default {
aliceblue: "#f0f8ff",
antiquewhite: "#faebd7",
aqua: "#00ffff",
aquamarine: "#7fffd4",
azure: "#f0ffff",
beige: "#f5f5dc",
bisque: "#ffe4c4",
black: "#000000",
blanchedalmond: "#ffebcd",
blue: "#0000ff",
blueviolet: "#8a2be2",
brown: "#a52a2a",
burlywood: "#deb887",
cadetblue: "#5f9ea0",
chartreuse: "#7fff00",
chocolate: "#d2691e",
coral: "#ff7f50",
cornflowerblue: "#6495ed",
cornsilk: "#fff8dc",
crimson: "#dc143c",
cyan: "#00ffff",
darkblue: "#00008b",
darkcyan: "#008b8b",
darkgoldenrod: "#b8860b",
darkgray: "#a9a9a9",
darkgreen: "#006400",
darkgrey: "#a9a9a9",
darkkhaki: "#bdb76b",
darkmagenta: "#8b008b",
darkolivegreen: "#556b2f",
darkorange: "#ff8c00",
darkorchid: "#9932cc",
darkred: "#8b0000",
darksalmon: "#e9967a",
darkseagreen: "#8fbc8f",
darkslateblue: "#483d8b",
darkslategray: "#2f4f4f",
darkslategrey: "#2f4f4f",
darkturquoise: "#00ced1",
darkviolet: "#9400d3",
deeppink: "#ff1493",
deepskyblue: "#00bfff",
dimgray: "#696969",
dimgrey: "#696969",
dodgerblue: "#1e90ff",
firebrick: "#b22222",
floralwhite: "#fffaf0",
forestgreen: "#228b22",
fuchsia: "#ff00ff",
gainsboro: "#dcdcdc",
ghostwhite: "#f8f8ff",
goldenrod: "#daa520",
gold: "#ffd700",
gray: "#808080",
green: "#008000",
greenyellow: "#adff2f",
grey: "#808080",
honeydew: "#f0fff0",
hotpink: "#ff69b4",
indianred: "#cd5c5c",
indigo: "#4b0082",
ivory: "#fffff0",
khaki: "#f0e68c",
lavenderblush: "#fff0f5",
lavender: "#e6e6fa",
lawngreen: "#7cfc00",
lemonchiffon: "#fffacd",
lightblue: "#add8e6",
lightcoral: "#f08080",
lightcyan: "#e0ffff",
lightgoldenrodyellow: "#fafad2",
lightgray: "#d3d3d3",
lightgreen: "#90ee90",
lightgrey: "#d3d3d3",
lightpink: "#ffb6c1",
lightsalmon: "#ffa07a",
lightseagreen: "#20b2aa",
lightskyblue: "#87cefa",
lightslategray: "#778899",
lightslategrey: "#778899",
lightsteelblue: "#b0c4de",
lightyellow: "#ffffe0",
lime: "#00ff00",
limegreen: "#32cd32",
linen: "#faf0e6",
magenta: "#ff00ff",
maroon: "#800000",
mediumaquamarine: "#66cdaa",
mediumblue: "#0000cd",
mediumorchid: "#ba55d3",
mediumpurple: "#9370db",
mediumseagreen: "#3cb371",
mediumslateblue: "#7b68ee",
mediumspringgreen: "#00fa9a",
mediumturquoise: "#48d1cc",
mediumvioletred: "#c71585",
midnightblue: "#191970",
mintcream: "#f5fffa",
mistyrose: "#ffe4e1",
moccasin: "#ffe4b5",
navajowhite: "#ffdead",
navy: "#000080",
oldlace: "#fdf5e6",
olive: "#808000",
olivedrab: "#6b8e23",
orange: "#ffa500",
orangered: "#ff4500",
orchid: "#da70d6",
palegoldenrod: "#eee8aa",
palegreen: "#98fb98",
paleturquoise: "#afeeee",
palevioletred: "#db7093",
papayawhip: "#ffefd5",
peachpuff: "#ffdab9",
peru: "#cd853f",
pink: "#ffc0cb",
plum: "#dda0dd",
powderblue: "#b0e0e6",
purple: "#800080",
rebeccapurple: "#663399",
red: "#ff0000",
rosybrown: "#bc8f8f",
royalblue: "#4169e1",
saddlebrown: "#8b4513",
salmon: "#fa8072",
sandybrown: "#f4a460",
seagreen: "#2e8b57",
seashell: "#fff5ee",
sienna: "#a0522d",
silver: "#c0c0c0",
skyblue: "#87ceeb",
slateblue: "#6a5acd",
slategray: "#708090",
slategrey: "#708090",
snow: "#fffafa",
springgreen: "#00ff7f",
steelblue: "#4682b4",
tan: "#d2b48c",
teal: "#008080",
thistle: "#d8bfd8",
tomato: "#ff6347",
turquoise: "#40e0d0",
violet: "#ee82ee",
wheat: "#f5deb3",
white: "#ffffff",
whitesmoke: "#f5f5f5",
yellow: "#ffff00",
yellowgreen: "#9acd32"
};
22 changes: 22 additions & 0 deletions src/options/editor/Editor.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from "react";
import { useLadleContext } from '@ladle/react';

import Editor from "./Editor";
import '../options.scss';

const TEST_VALUE = `[test]
aws_account_id = 11234
color =
region = `;

export const EditorWithText = () => {
const { globalState } = useLadleContext();
return (
<Editor
height="400px"
value={TEST_VALUE}
theme={globalState.theme == 'dark' ? 'dark' : 'light'}
/>
);
};

54 changes: 54 additions & 0 deletions src/options/editor/Editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import CodeMirror from '@uiw/react-codemirror';
import { StreamLanguage } from '@codemirror/language';
import { toml } from '@codemirror/legacy-modes/mode/toml';
import { autocompletion } from '@codemirror/autocomplete';
import { oneDark } from '@codemirror/theme-one-dark';
import { keymap } from '@codemirror/view';
import {
copyLineDown,
deleteLine,
} from '@codemirror/commands';

import {
completeValue,
completeKey,
showCompletionForCompletedKey,
} from './plugins/autocomplete';

type EditorProps = {
theme?: 'light' | 'dark'
height?: string
value?: string
onChange?: (val: string) => void
onSave?: () => boolean
}

export default ({
theme = 'light',
height = '100vh',
value = '',
onChange = () => {},
onSave = () => true,
}: EditorProps) =>
<CodeMirror
value={value}
height={height}
theme={theme == 'light' ? 'light' : oneDark}
onChange={onChange}
extensions={[
StreamLanguage.define(toml),
keymap.of([
{ key: 'Ctrl-s', run: onSave, preventDefault: true },
{ key: 'Ctrl-Shift-d', run: copyLineDown, preventDefault: true },
{ key: 'Ctrl-x', run: deleteLine, preventDefault: true },
]),
autocompletion({
override: [
completeKey,
completeValue,
],
}),
showCompletionForCompletedKey,
]}
/>;
82 changes: 82 additions & 0 deletions src/options/editor/plugins/autocomplete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
closeCompletion,
Completion,
CompletionContext,
CompletionResult,
startCompletion,
} from '@codemirror/autocomplete';
import { EditorView } from '@codemirror/view';

import { availableRegions } from '../../../common/config/availableRegions';
import colors from '../../../common/const/cssColors';

const getOptions = (key: string): Completion[] => {
switch (key) {
case 'region':
return availableRegions.map((r): Completion => ({
label: r,
type: 'constant',
}));
case 'color':
return Object.keys(colors).map((c): Completion => ({
label: c,
type: 'constant',
info: () => {
const color = document.createElement('div');
color.style.backgroundColor = c;
color.style.width = '40px';
color.style.height = '20px';
return color;
}
}));
case 'key':
return [
{ label: 'aws_account_id', apply: 'aws_account_id = ', type: 'keyword' },
{ label: 'role_name', apply: 'role_name = ', type: 'keyword' },
{ label: 'role_arn', apply: 'role_arn = ', type: 'keyword' },
{ label: 'color', apply: 'color = ', type: 'keyword' },
{ label: 'group', apply: 'group = ', type: 'keyword' },
{ label: 'region', apply: 'region = ', type: 'keyword' },
] as Completion[];
default:
return [];
}
};

// fixes the codemirror behaviour when a completion is applied
// the next completion dialog is not shown
export const showCompletionForCompletedKey = EditorView.updateListener.of(({ state, view, docChanged }) => {
const currentLineNumber = state.doc.lineAt(state.selection.main.head).number;
const line = state.doc.line(currentLineNumber).text;
const match = line.match(/^(region|color)\s*=\s$/);
if (docChanged && match) {
closeCompletion(view);
startCompletion(view);
}
});

export const completeValue = (
context: CompletionContext
): CompletionResult | null => {
const re = /^(region|color)\s*=\s*([\w-]*)$/;
const word = context.matchBefore(re);
const match = word?.text.match(re);
if (!word || !match || word.from == word.to) return null;
return {
from: word.to - match[2].length,
options: getOptions(match[1]),
filter: true,
};
};

export const completeKey = (
context: CompletionContext
): CompletionResult | null => {
const word = context.matchBefore(/^\w+/);
if (!word) return null;
return {
from: word.from,
options: getOptions('key'),
filter: true,
};
};
18 changes: 0 additions & 18 deletions src/options/keymap.ts

This file was deleted.

Loading

0 comments on commit 5f7edbe

Please sign in to comment.