vzcode 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/cli.ts +208 -0
- package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +42 -0
- package/src/client/AIAssist/AIAssistWidget/index.tsx +135 -0
- package/src/client/AIAssist/AIAssistWidget/style.scss +47 -0
- package/src/client/AIAssist/Spinner.jsx +76 -0
- package/src/client/AIAssist/formatFile.ts +27 -0
- package/src/client/AIAssist/generateFilesContext.ts +25 -0
- package/src/client/AIAssist/index.ts +2 -0
- package/src/client/AIAssist/startAIAssist.ts +95 -0
- package/src/client/App/index.tsx +152 -0
- package/src/client/App/style.scss +82 -0
- package/src/client/App/usePending.ts +51 -0
- package/src/client/App/useShareDB.ts +161 -0
- package/src/client/CodeEditor/Copilot/index.ts +74 -0
- package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +12 -0
- package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +68 -0
- package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +174 -0
- package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +79 -0
- package/src/client/CodeEditor/InteractiveWidgets/index.ts +44 -0
- package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +12 -0
- package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +20 -0
- package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +143 -0
- package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +48 -0
- package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +12 -0
- package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +25 -0
- package/src/client/CodeEditor/basicSetup.ts +73 -0
- package/src/client/CodeEditor/getOrCreateEditor.tsx +615 -0
- package/src/client/CodeEditor/index.tsx +202 -0
- package/src/client/CodeEditor/json1PresenceBroadcast.ts +41 -0
- package/src/client/CodeEditor/json1PresenceDisplay.ts +350 -0
- package/src/client/CodeEditor/rainbowBrackets.ts +122 -0
- package/src/client/CodeEditor/style.scss +156 -0
- package/src/client/CodeEditor/typescriptExtension/worker.ts +32 -0
- package/src/client/CodeErrorOverlay/index.tsx +77 -0
- package/src/client/CodeErrorOverlay/style.scss +33 -0
- package/src/client/Fonts/fonts.ts +8 -0
- package/src/client/Icons/AdjustmentSVG.tsx +19 -0
- package/src/client/Icons/BugSVG.tsx +20 -0
- package/src/client/Icons/CloseSVG.tsx +19 -0
- package/src/client/Icons/CssSVG.tsx +16 -0
- package/src/client/Icons/DirectoryArrowSVG.tsx +19 -0
- package/src/client/Icons/EditSVG.tsx +19 -0
- package/src/client/Icons/FileSVG.tsx +19 -0
- package/src/client/Icons/FolderSVG.tsx +20 -0
- package/src/client/Icons/GearSVG.tsx +16 -0
- package/src/client/Icons/HtmlSVG.tsx +16 -0
- package/src/client/Icons/JavaScriptSVG.tsx +16 -0
- package/src/client/Icons/JsonSVG.tsx +16 -0
- package/src/client/Icons/MarkdownSVG.tsx +16 -0
- package/src/client/Icons/MicOffSVG.tsx +35 -0
- package/src/client/Icons/MicSVG.tsx +25 -0
- package/src/client/Icons/NewSVG.tsx +19 -0
- package/src/client/Icons/PinSVG.tsx +14 -0
- package/src/client/Icons/PlaySVG.tsx +16 -0
- package/src/client/Icons/QuestionMarkSVG.tsx +18 -0
- package/src/client/Icons/ReactSVG.tsx +16 -0
- package/src/client/Icons/SearchSVG.tsx +20 -0
- package/src/client/Icons/SparklesSVG.tsx +23 -0
- package/src/client/Icons/SplitEditorSVG.tsx +34 -0
- package/src/client/Icons/StopSVG.tsx +15 -0
- package/src/client/Icons/SvelteSVG.tsx +16 -0
- package/src/client/Icons/TrashSVG.tsx +19 -0
- package/src/client/Icons/TypeScriptSVG.tsx +16 -0
- package/src/client/Icons/index.tsx +26 -0
- package/src/client/ImageViewer/index.tsx +91 -0
- package/src/client/ImageViewer/style.scss +41 -0
- package/src/client/PresenceNotifications/PresenceNotifications.test.ts +134 -0
- package/src/client/PresenceNotifications/index.tsx +158 -0
- package/src/client/PresenceNotifications/style.scss +17 -0
- package/src/client/RunCodeWidget/index.tsx +117 -0
- package/src/client/RunCodeWidget/style.scss +24 -0
- package/src/client/SplitPaneResizeContext.tsx +159 -0
- package/src/client/TabList/Tab.tsx +73 -0
- package/src/client/TabList/index.tsx +35 -0
- package/src/client/TabList/style.scss +51 -0
- package/src/client/VZCodeContext/index.tsx +29 -0
- package/src/client/VZCodeContext/types.ts +248 -0
- package/src/client/VZCodeContext/useVZCodeState.ts +602 -0
- package/src/client/VZKeyboardShortcutsDoc.tsx +148 -0
- package/src/client/VZLeft.tsx +28 -0
- package/src/client/VZMiddle.tsx +172 -0
- package/src/client/VZResizer/index.tsx +128 -0
- package/src/client/VZResizer/styles.scss +33 -0
- package/src/client/VZRight.tsx +113 -0
- package/src/client/VZSettings.tsx +275 -0
- package/src/client/VZSidebar/AIChat/ChatInput.tsx +243 -0
- package/src/client/VZSidebar/AIChat/DiffView.scss +136 -0
- package/src/client/VZSidebar/AIChat/DiffView.tsx +176 -0
- package/src/client/VZSidebar/AIChat/Message.tsx +79 -0
- package/src/client/VZSidebar/AIChat/MessageList.tsx +190 -0
- package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +35 -0
- package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +156 -0
- package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +19 -0
- package/src/client/VZSidebar/AIChat/index.tsx +357 -0
- package/src/client/VZSidebar/AIChat/styles.scss +646 -0
- package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +117 -0
- package/src/client/VZSidebar/CreateDirModal.tsx +111 -0
- package/src/client/VZSidebar/CreateFileModal.tsx +111 -0
- package/src/client/VZSidebar/DeleteConfirmationModal.tsx +76 -0
- package/src/client/VZSidebar/DirectoryListing.tsx +89 -0
- package/src/client/VZSidebar/EmptyState.tsx +11 -0
- package/src/client/VZSidebar/FileListing.tsx +91 -0
- package/src/client/VZSidebar/FileTypeIcon.tsx +49 -0
- package/src/client/VZSidebar/Item.tsx +237 -0
- package/src/client/VZSidebar/Listing.tsx +47 -0
- package/src/client/VZSidebar/Search.tsx +527 -0
- package/src/client/VZSidebar/VisualEditor.tsx +282 -0
- package/src/client/VZSidebar/VoiceChatModal.tsx +121 -0
- package/src/client/VZSidebar/aiCopyPaste.ts +199 -0
- package/src/client/VZSidebar/index.tsx +728 -0
- package/src/client/VZSidebar/styles.scss +612 -0
- package/src/client/VZSidebar/useDragAndDrop.tsx +408 -0
- package/src/client/bootstrap.ts +26 -0
- package/src/client/buildWorker.ts +3 -0
- package/src/client/featureFlags.ts +8 -0
- package/src/client/generateRequestId.ts +6 -0
- package/src/client/getFileTree.ts +53 -0
- package/src/client/index.ts +19 -0
- package/src/client/main.jsx +10 -0
- package/src/client/presenceColor.ts +8 -0
- package/src/client/shouldTriggerRun.ts +31 -0
- package/src/client/sortFileTree.ts +21 -0
- package/src/client/tabsSearchParameters.test.ts +79 -0
- package/src/client/tabsSearchParameters.ts +137 -0
- package/src/client/themes/index.ts +7 -0
- package/src/client/themes/themes.ts +77 -0
- package/src/client/themes/uiwImports.ts +32 -0
- package/src/client/themes/useDynamicTheme.ts +29 -0
- package/src/client/themes/vizhubTheme/colors.ts +80 -0
- package/src/client/themes/vizhubTheme/index.ts +193 -0
- package/src/client/useActions.ts +288 -0
- package/src/client/useESLint/index.ts +72 -0
- package/src/client/useESLint/worker.ts +113 -0
- package/src/client/useEditorCache.ts +35 -0
- package/src/client/useFileCRUD.ts +228 -0
- package/src/client/useKeyboardShortcuts.ts +451 -0
- package/src/client/useOpenDirectories.ts +99 -0
- package/src/client/usePresenceAutoFollow.ts +85 -0
- package/src/client/usePrettier/index.ts +178 -0
- package/src/client/usePrettier/worker.ts +109 -0
- package/src/client/useRunCode.tsx +15 -0
- package/src/client/useRuntimeError.ts +32 -0
- package/src/client/useSubmitOperation.ts +15 -0
- package/src/client/useURLSync.ts +137 -0
- package/src/client/usernameLocalStorage.ts +43 -0
- package/src/client/utils/fileExtension.ts +10 -0
- package/src/client/utils/isImageFile.ts +12 -0
- package/src/client/vzReducer/aiChatReducer.ts +44 -0
- package/src/client/vzReducer/closeTabReducer.test.ts +205 -0
- package/src/client/vzReducer/closeTabsReducer.ts +96 -0
- package/src/client/vzReducer/createInitialState.ts +38 -0
- package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +9 -0
- package/src/client/vzReducer/findPane.ts +19 -0
- package/src/client/vzReducer/index.ts +250 -0
- package/src/client/vzReducer/openTabReducer.test.ts +127 -0
- package/src/client/vzReducer/openTabReducer.ts +74 -0
- package/src/client/vzReducer/searchReducer.test.ts +292 -0
- package/src/client/vzReducer/searchReducer.ts +181 -0
- package/src/client/vzReducer/setActiveFileIdReducer.ts +28 -0
- package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +76 -0
- package/src/client/vzReducer/setIsDocOpenReducer.ts +9 -0
- package/src/client/vzReducer/setIsSettingsOpenReducer.ts +9 -0
- package/src/client/vzReducer/setThemeReducer.ts +9 -0
- package/src/client/vzReducer/setUsernameReducer.ts +9 -0
- package/src/client/vzReducer/splitCurrentPaneReducer.ts +66 -0
- package/src/client/vzReducer/toggleAutoFollowReducer.ts +12 -0
- package/src/client/vzReducer/updatePane.ts +40 -0
- package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +30 -0
- package/src/client/vzReducer/visualEditorReducer.ts +9 -0
- package/src/ot.ts +24 -0
- package/src/randomId.ts +15 -0
- package/src/reactRouterExports.ts +15 -0
- package/src/runCode.ts +27 -0
- package/src/server/aiChatHandler/aiEditing.ts +151 -0
- package/src/server/aiChatHandler/chatOperations.ts +476 -0
- package/src/server/aiChatHandler/errorHandling.ts +66 -0
- package/src/server/aiChatHandler/index.ts +199 -0
- package/src/server/aiChatHandler/llmStreaming.ts +419 -0
- package/src/server/aiChatHandler/validation.ts +24 -0
- package/src/server/computeInitialDocument.ts +220 -0
- package/src/server/config.ts +24 -0
- package/src/server/featureFlags.ts +8 -0
- package/src/server/generateAIResponse.ts +188 -0
- package/src/server/handleAIAssist.ts +53 -0
- package/src/server/handleAIChatMessage.ts +2 -0
- package/src/server/handleAICopilot.ts +97 -0
- package/src/server/index.ts +379 -0
- package/src/server/isDirectory.ts +1 -0
- package/src/server/livekit.ts +24 -0
- package/src/server/prettier.ts +115 -0
- package/src/server/setupEnv.ts +8 -0
- package/src/submitOperation.ts +25 -0
- package/src/types.ts +205 -0
- package/src/utils/fileDiff.ts +117 -0
- package/src/vite-env.d.ts +10 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { TabState } from '../types';
|
|
2
|
+
import { VizFileId, VizContent } from '@vizhub/viz-types';
|
|
3
|
+
|
|
4
|
+
// The delimiter used to separate file names in the `tabs` parameter.
|
|
5
|
+
// We need a character that is both URL-safe (does not get escaped in URLs)
|
|
6
|
+
// and is not typically found in file names, especially for JavaScript and CSS files.
|
|
7
|
+
//
|
|
8
|
+
// The following characters are not URL-safe as they get converted to escaped sequences in URLs,
|
|
9
|
+
// leading to less readable URLs:
|
|
10
|
+
// - `+` becomes `%2B`
|
|
11
|
+
// - `|` becomes `%7C`
|
|
12
|
+
// - `;` becomes `%3B`
|
|
13
|
+
// - `:` becomes `%3A`
|
|
14
|
+
// - `,` becomes `%2C`
|
|
15
|
+
// - `!` becomes `%21`
|
|
16
|
+
// - `/` becomes `%2F`
|
|
17
|
+
//
|
|
18
|
+
// The following characters, while URL-safe, are commonly used in file names,
|
|
19
|
+
// hence using them could lead to conflicts or misinterpretation:
|
|
20
|
+
// - `.` commonly used as a dot separator in file names and extensions
|
|
21
|
+
// - ` ` (space) often found in file names but can lead to issues in URLs
|
|
22
|
+
// - `-` (hyphen) frequently used in file and folder names for readability
|
|
23
|
+
// - `_` (underscore) also commonly used in file and folder names
|
|
24
|
+
//
|
|
25
|
+
// Considering the above constraints, we need a character that is both URL-safe
|
|
26
|
+
// and not typically used in file names. The following character meets these criteria:
|
|
27
|
+
// - `~` is URL-safe (remains unescaped in URLs) and is not a standard character
|
|
28
|
+
// in file names for JavaScript and CSS files, making it a suitable choice for a delimiter.
|
|
29
|
+
export const delimiter = '~';
|
|
30
|
+
|
|
31
|
+
// Gets the file id of a file with the given name.
|
|
32
|
+
// Returns null if not found.
|
|
33
|
+
const getFileId = (
|
|
34
|
+
content: VizContent,
|
|
35
|
+
fileName: string,
|
|
36
|
+
): string | null => {
|
|
37
|
+
if (content && content.files) {
|
|
38
|
+
for (const fileId of Object.keys(content.files)) {
|
|
39
|
+
const file = content.files[fileId];
|
|
40
|
+
if (file.name === fileName) {
|
|
41
|
+
return fileId;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Gets the file name of a file with the given id,
|
|
49
|
+
// guard against failure cases.
|
|
50
|
+
// Returns null if not found.
|
|
51
|
+
const getFileName = (
|
|
52
|
+
content: VizContent,
|
|
53
|
+
fileId: string,
|
|
54
|
+
): string | null => {
|
|
55
|
+
if (content && content.files) {
|
|
56
|
+
const file = content.files[fileId];
|
|
57
|
+
if (file) {
|
|
58
|
+
return file.name;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// An object representing the search parameters.
|
|
65
|
+
export type TabStateParams = {
|
|
66
|
+
file?: string;
|
|
67
|
+
tabs?: string;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Decodes the tab list and active file from the search parameters.
|
|
71
|
+
export const decodeTabs = ({
|
|
72
|
+
tabStateParams,
|
|
73
|
+
content,
|
|
74
|
+
}: {
|
|
75
|
+
tabStateParams: TabStateParams;
|
|
76
|
+
content: VizContent;
|
|
77
|
+
}): {
|
|
78
|
+
tabList: Array<TabState>;
|
|
79
|
+
activeFileId: VizFileId;
|
|
80
|
+
} => {
|
|
81
|
+
const { file, tabs } = tabStateParams;
|
|
82
|
+
const tabList: TabState[] = [];
|
|
83
|
+
|
|
84
|
+
// Decode active file
|
|
85
|
+
const activeFileId = getFileId(content, file);
|
|
86
|
+
|
|
87
|
+
// Decode tab list
|
|
88
|
+
if (tabs) {
|
|
89
|
+
tabs.split(delimiter).forEach((fileName) => {
|
|
90
|
+
const fileId = getFileId(content, fileName);
|
|
91
|
+
if (fileId) {
|
|
92
|
+
tabList.push({ fileId });
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
} else if (activeFileId) {
|
|
96
|
+
// If there's only an active file without a tab list
|
|
97
|
+
tabList.push({ fileId: activeFileId });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return { tabList, activeFileId };
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Encodes the tab list and active file into the search parameters.
|
|
104
|
+
export const encodeTabs = ({
|
|
105
|
+
tabList,
|
|
106
|
+
activeFileId,
|
|
107
|
+
content,
|
|
108
|
+
}: {
|
|
109
|
+
tabList: Array<TabState>;
|
|
110
|
+
activeFileId: VizFileId | null;
|
|
111
|
+
content: VizContent;
|
|
112
|
+
}): TabStateParams => {
|
|
113
|
+
// Get the file name of the active file
|
|
114
|
+
const activeFileName = getFileName(content, activeFileId);
|
|
115
|
+
|
|
116
|
+
const params: TabStateParams = {};
|
|
117
|
+
|
|
118
|
+
// If that's missing, no need to proceed (should never happen).
|
|
119
|
+
if (activeFileName) {
|
|
120
|
+
// In any case we set the `file` parameter.
|
|
121
|
+
params.file = activeFileName;
|
|
122
|
+
|
|
123
|
+
// We only need to encode the `tabs` parameter
|
|
124
|
+
// if there's more than one tab.
|
|
125
|
+
if (tabList.length > 1) {
|
|
126
|
+
// Set tab list
|
|
127
|
+
const tabs = tabList
|
|
128
|
+
.map((tabstate: TabState) =>
|
|
129
|
+
getFileName(content, tabstate.fileId),
|
|
130
|
+
)
|
|
131
|
+
.join(delimiter);
|
|
132
|
+
params.tabs = tabs;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return params;
|
|
137
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { oneDark } from '@codemirror/theme-one-dark';
|
|
2
|
+
|
|
3
|
+
import { vizhubTheme } from './vizhubTheme';
|
|
4
|
+
import {
|
|
5
|
+
okaidia,
|
|
6
|
+
abcdef,
|
|
7
|
+
dracula,
|
|
8
|
+
eclipse,
|
|
9
|
+
githubDark,
|
|
10
|
+
material,
|
|
11
|
+
nord,
|
|
12
|
+
xcodeLight,
|
|
13
|
+
} from './uiwImports';
|
|
14
|
+
|
|
15
|
+
// CodeMirror themes
|
|
16
|
+
export type ThemeLabel =
|
|
17
|
+
| 'abcdef'
|
|
18
|
+
| 'dracula'
|
|
19
|
+
| 'eclipse'
|
|
20
|
+
| 'material'
|
|
21
|
+
| 'nord'
|
|
22
|
+
| 'oneDark'
|
|
23
|
+
| 'okaidia'
|
|
24
|
+
| 'github'
|
|
25
|
+
| 'xcode'
|
|
26
|
+
| 'vizhub';
|
|
27
|
+
|
|
28
|
+
export type ThemeOption = {
|
|
29
|
+
value: any;
|
|
30
|
+
label: ThemeLabel;
|
|
31
|
+
};
|
|
32
|
+
// add light theme brackets to eclipse theme
|
|
33
|
+
// const modifiedEclipse = {
|
|
34
|
+
// ...eclipse,
|
|
35
|
+
// '.rainbow-bracket-red > span': {
|
|
36
|
+
// color: 'white',
|
|
37
|
+
// },
|
|
38
|
+
// '.rainbow-bracket-orange > span': {
|
|
39
|
+
// //yellow
|
|
40
|
+
// color: '#FFFFB2',
|
|
41
|
+
// },
|
|
42
|
+
// '.rainbow-bracket-yellow > span': {
|
|
43
|
+
// // orange
|
|
44
|
+
// color: '#FFB2DA',
|
|
45
|
+
// },
|
|
46
|
+
// '.rainbow-bracket-green > span': {
|
|
47
|
+
// // green
|
|
48
|
+
// color: '#B2FFB2',
|
|
49
|
+
// }
|
|
50
|
+
// };
|
|
51
|
+
export const themes: Array<ThemeOption> = [
|
|
52
|
+
{ value: abcdef, label: 'abcdef' },
|
|
53
|
+
{ value: dracula, label: 'dracula' },
|
|
54
|
+
{ value: eclipse, label: 'eclipse' },
|
|
55
|
+
{ value: material, label: 'material' },
|
|
56
|
+
{ value: nord, label: 'nord' },
|
|
57
|
+
{ value: oneDark, label: 'oneDark' },
|
|
58
|
+
{ value: okaidia, label: 'okaidia' },
|
|
59
|
+
{ value: githubDark, label: 'github' },
|
|
60
|
+
{ value: xcodeLight, label: 'xcode' },
|
|
61
|
+
{ value: vizhubTheme, label: 'vizhub' },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
// Map theme labels to theme values
|
|
65
|
+
export const themeOptionsByLabel: Record<
|
|
66
|
+
ThemeLabel,
|
|
67
|
+
ThemeOption
|
|
68
|
+
> = themes.reduce(
|
|
69
|
+
(acc, themeOption: ThemeOption) => {
|
|
70
|
+
acc[themeOption.label] = themeOption;
|
|
71
|
+
return acc;
|
|
72
|
+
},
|
|
73
|
+
{} as Record<ThemeLabel, any>,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// The default theme
|
|
77
|
+
export const defaultTheme: ThemeLabel = 'vizhub';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// These import are wreaking havoc with the build process
|
|
2
|
+
// and causing app deployments to fail.
|
|
3
|
+
// The upstream library is not configured properly in NPM.
|
|
4
|
+
// See:
|
|
5
|
+
// https://github.com/uiwjs/react-codemirror/issues/680
|
|
6
|
+
// https://github.com/scalar/scalar/issues/4222
|
|
7
|
+
// As a workaround, we need to explicitly target the ESM
|
|
8
|
+
// distribution of the library, which is not used by default
|
|
9
|
+
// because there is no "type": "module" field in the package.json
|
|
10
|
+
// of any of these `@uiw/codemirror-theme-*` packages.
|
|
11
|
+
|
|
12
|
+
import { okaidia } from '@uiw/codemirror-theme-okaidia';
|
|
13
|
+
import { abcdef } from '@uiw/codemirror-theme-abcdef';
|
|
14
|
+
import { dracula } from '@uiw/codemirror-theme-dracula';
|
|
15
|
+
import { eclipse } from '@uiw/codemirror-theme-eclipse';
|
|
16
|
+
import { githubDark } from '@uiw/codemirror-theme-github';
|
|
17
|
+
import { material } from '@uiw/codemirror-theme-material';
|
|
18
|
+
import { nord } from '@uiw/codemirror-theme-nord';
|
|
19
|
+
import { xcodeLight } from '@uiw/codemirror-theme-xcode';
|
|
20
|
+
import { createTheme } from '@uiw/codemirror-themes';
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
okaidia,
|
|
24
|
+
abcdef,
|
|
25
|
+
dracula,
|
|
26
|
+
eclipse,
|
|
27
|
+
githubDark,
|
|
28
|
+
material,
|
|
29
|
+
nord,
|
|
30
|
+
xcodeLight,
|
|
31
|
+
createTheme,
|
|
32
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { EditorCache } from '../useEditorCache';
|
|
3
|
+
import { ThemeLabel, themeOptionsByLabel } from './themes';
|
|
4
|
+
|
|
5
|
+
export const useDynamicTheme = (
|
|
6
|
+
editorCache: EditorCache,
|
|
7
|
+
theme: ThemeLabel,
|
|
8
|
+
) => {
|
|
9
|
+
const isFirstRun = useRef(true);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
// Skip the first run, since the theme is already initialized.
|
|
12
|
+
if (isFirstRun.current) {
|
|
13
|
+
isFirstRun.current = false;
|
|
14
|
+
} else {
|
|
15
|
+
// When the user changes the theme, update the theme of all editors.
|
|
16
|
+
for (const editorCacheValue of Array.from(
|
|
17
|
+
editorCache.values(),
|
|
18
|
+
)) {
|
|
19
|
+
const { editor, themeCompartment } =
|
|
20
|
+
editorCacheValue;
|
|
21
|
+
editor.dispatch({
|
|
22
|
+
effects: themeCompartment.reconfigure([
|
|
23
|
+
themeOptionsByLabel[theme].value,
|
|
24
|
+
]),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}, [theme, editorCache]);
|
|
29
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// import { hcl } from 'd3-color';
|
|
2
|
+
|
|
3
|
+
// This module defines all the colors for the VizHub theme.
|
|
4
|
+
// Ported from the CodeMirror 5 theme defined here:
|
|
5
|
+
// https://github.com/vizhub-core/vizhub-legacy/blob/01cadfb78a2611df32f981b1fd8136b70447de9e/vizhub-v2/packages/neoFrontend/src/pages/VizPage/Body/Editor/themes/vizHub.js
|
|
6
|
+
|
|
7
|
+
// This is how the colors were generated:
|
|
8
|
+
// const sidebarDark = hcl('#3d4b65');
|
|
9
|
+
// const sidebarLight = hcl('#5b677d');
|
|
10
|
+
// const luminaceDifference = sidebarLight.l - sidebarDark.l;
|
|
11
|
+
// const backgroundLuminance =
|
|
12
|
+
// sidebarDark.l - luminaceDifference * 1.1;
|
|
13
|
+
// const luminance = 90;
|
|
14
|
+
// export const backgroundColor = hcl(
|
|
15
|
+
// sidebarDark.h,
|
|
16
|
+
// sidebarDark.c,
|
|
17
|
+
// backgroundLuminance,
|
|
18
|
+
// ).formatHex();
|
|
19
|
+
// export const light = hcl(0, 0, luminance).formatHex();
|
|
20
|
+
// export const dark = hcl(
|
|
21
|
+
// sidebarDark.h,
|
|
22
|
+
// sidebarDark.c,
|
|
23
|
+
// 80,
|
|
24
|
+
// ).formatHex();
|
|
25
|
+
// console.log(
|
|
26
|
+
// JSON.stringify(
|
|
27
|
+
// {
|
|
28
|
+
// backgroundColor,
|
|
29
|
+
// light,
|
|
30
|
+
// dark,
|
|
31
|
+
// },
|
|
32
|
+
// null,
|
|
33
|
+
// 2,
|
|
34
|
+
// ),
|
|
35
|
+
// );
|
|
36
|
+
|
|
37
|
+
// These are inlined from the above code, but the code is kept around for future reference.
|
|
38
|
+
export const backgroundColor = '#202e46';
|
|
39
|
+
export const light = '#e2e2e2';
|
|
40
|
+
export const dark = '#b9c7e6';
|
|
41
|
+
|
|
42
|
+
export const lineNumbers = 'rgba(255,255,255,0.2)';
|
|
43
|
+
export const lineNumbersActive = 'rgba(255,255,255,0.5)';
|
|
44
|
+
export const selectionBackground = '#000';
|
|
45
|
+
export const selectionBackgroundMatch = 'rgba(0,0,0,0.4)';
|
|
46
|
+
export const lineHighlight = 'rgba(0,0,0,0.1)';
|
|
47
|
+
export const caretColor = 'white';
|
|
48
|
+
|
|
49
|
+
// Compute 6 colors that are evenly spaced in terms of hue
|
|
50
|
+
// Keeping this code around for future reference
|
|
51
|
+
// const rotation = 0.397;
|
|
52
|
+
// const numColors = 6;
|
|
53
|
+
// const highlightColors = Array.from(
|
|
54
|
+
// { length: numColors },
|
|
55
|
+
// (_, i) => {
|
|
56
|
+
// let t = (i / numColors + rotation) % 1;
|
|
57
|
+
// return hcl(t * 360, saturation, luminance).formatHex();
|
|
58
|
+
// },
|
|
59
|
+
// );
|
|
60
|
+
// console.log(JSON.stringify(highlightColors));
|
|
61
|
+
|
|
62
|
+
// We inline the colors here, but the code above is how they were generated.
|
|
63
|
+
const highlightColors = [
|
|
64
|
+
'#77fd8c',
|
|
65
|
+
'#00ffff',
|
|
66
|
+
'#66ecff',
|
|
67
|
+
'#ffb9ff',
|
|
68
|
+
'#ffabb3',
|
|
69
|
+
'#ffdb56',
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
export const MINT = highlightColors[0];
|
|
73
|
+
export const AQUA = highlightColors[1];
|
|
74
|
+
export const SKY = highlightColors[2];
|
|
75
|
+
export const LAVENDER = highlightColors[3];
|
|
76
|
+
export const SALMON = highlightColors[4];
|
|
77
|
+
export const GOLDENROD = highlightColors[5];
|
|
78
|
+
|
|
79
|
+
// Red that's not too bright, for errors
|
|
80
|
+
export const PANIC = '#ff2222';
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// A CodeMirror 6 theme for the VizHub syntax highlighting colors.
|
|
2
|
+
|
|
3
|
+
// Inspired by https://github.com/uiwjs/react-codemirror/blob/master/themes/vscode/src/index.ts
|
|
4
|
+
|
|
5
|
+
import { tags as t } from '@lezer/highlight';
|
|
6
|
+
import { createTheme } from '@uiw/codemirror-themes';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
// Colors for various things outside the code itself
|
|
10
|
+
backgroundColor,
|
|
11
|
+
lineHighlight,
|
|
12
|
+
light,
|
|
13
|
+
dark,
|
|
14
|
+
lineNumbers,
|
|
15
|
+
lineNumbersActive,
|
|
16
|
+
selectionBackground,
|
|
17
|
+
selectionBackgroundMatch,
|
|
18
|
+
caretColor,
|
|
19
|
+
|
|
20
|
+
// Syntax highlighting colors
|
|
21
|
+
MINT,
|
|
22
|
+
AQUA,
|
|
23
|
+
SKY,
|
|
24
|
+
LAVENDER,
|
|
25
|
+
SALMON,
|
|
26
|
+
GOLDENROD,
|
|
27
|
+
PANIC,
|
|
28
|
+
} from './colors';
|
|
29
|
+
import { EditorView } from 'codemirror';
|
|
30
|
+
|
|
31
|
+
// Use semi-bold weight for keywords and other important things
|
|
32
|
+
// const boldWeight = 'bold';
|
|
33
|
+
|
|
34
|
+
// This looks way better as we are pulling in the semi-bold font from Google Fonts
|
|
35
|
+
const boldWeight = '500';
|
|
36
|
+
|
|
37
|
+
const defaultSettingsVizhubTheme = {
|
|
38
|
+
background: backgroundColor,
|
|
39
|
+
foreground: light,
|
|
40
|
+
caret: caretColor,
|
|
41
|
+
selection: selectionBackground,
|
|
42
|
+
selectionMatch: selectionBackgroundMatch,
|
|
43
|
+
lineHighlight,
|
|
44
|
+
gutterBackground: backgroundColor,
|
|
45
|
+
gutterForeground: lineNumbers,
|
|
46
|
+
gutterActiveForeground: lineNumbersActive,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function vizhubThemeInit(options?: Partial<any>) {
|
|
50
|
+
const {
|
|
51
|
+
theme = 'dark',
|
|
52
|
+
settings = {},
|
|
53
|
+
styles = [],
|
|
54
|
+
} = options || {};
|
|
55
|
+
return [
|
|
56
|
+
createTheme({
|
|
57
|
+
theme: theme,
|
|
58
|
+
settings: {
|
|
59
|
+
...defaultSettingsVizhubTheme,
|
|
60
|
+
...settings,
|
|
61
|
+
},
|
|
62
|
+
styles: [
|
|
63
|
+
{
|
|
64
|
+
tag: [
|
|
65
|
+
t.keyword,
|
|
66
|
+
t.operatorKeyword,
|
|
67
|
+
t.modifier,
|
|
68
|
+
t.color,
|
|
69
|
+
t.constant(t.name),
|
|
70
|
+
t.standard(t.name),
|
|
71
|
+
t.standard(t.tagName),
|
|
72
|
+
t.special(t.brace),
|
|
73
|
+
t.atom,
|
|
74
|
+
t.bool,
|
|
75
|
+
t.special(t.variableName),
|
|
76
|
+
],
|
|
77
|
+
color: MINT,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
tag: [t.controlKeyword, t.moduleKeyword],
|
|
81
|
+
color: MINT,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
tag: [
|
|
85
|
+
t.name,
|
|
86
|
+
t.deleted,
|
|
87
|
+
t.character,
|
|
88
|
+
t.macroName,
|
|
89
|
+
|
|
90
|
+
t.variableName,
|
|
91
|
+
t.labelName,
|
|
92
|
+
t.definition(t.name),
|
|
93
|
+
],
|
|
94
|
+
color: AQUA,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
tag: [t.propertyName],
|
|
98
|
+
color: GOLDENROD,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
tag: t.heading,
|
|
102
|
+
fontWeight: boldWeight,
|
|
103
|
+
color: SKY,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
tag: [
|
|
107
|
+
t.typeName,
|
|
108
|
+
t.className,
|
|
109
|
+
t.tagName,
|
|
110
|
+
t.number,
|
|
111
|
+
t.changed,
|
|
112
|
+
t.annotation,
|
|
113
|
+
t.self,
|
|
114
|
+
t.namespace,
|
|
115
|
+
],
|
|
116
|
+
color: AQUA,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
tag: [
|
|
120
|
+
t.function(t.variableName),
|
|
121
|
+
t.function(t.propertyName),
|
|
122
|
+
],
|
|
123
|
+
color: AQUA,
|
|
124
|
+
},
|
|
125
|
+
{ tag: [t.number], color: SALMON },
|
|
126
|
+
{
|
|
127
|
+
tag: [
|
|
128
|
+
t.operator,
|
|
129
|
+
t.punctuation,
|
|
130
|
+
t.separator,
|
|
131
|
+
t.url,
|
|
132
|
+
t.escape,
|
|
133
|
+
t.regexp,
|
|
134
|
+
],
|
|
135
|
+
color: light,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
tag: [t.regexp],
|
|
139
|
+
color: LAVENDER,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
tag: [t.special(t.string), t.string, t.inserted],
|
|
143
|
+
color: LAVENDER,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
tag: [t.processingInstruction],
|
|
147
|
+
color: AQUA,
|
|
148
|
+
},
|
|
149
|
+
{ tag: [t.angleBracket], color: AQUA },
|
|
150
|
+
{ tag: t.strong, fontWeight: boldWeight },
|
|
151
|
+
{ tag: t.emphasis, fontStyle: 'italic' },
|
|
152
|
+
{
|
|
153
|
+
tag: t.strikethrough,
|
|
154
|
+
textDecoration: 'line-through',
|
|
155
|
+
},
|
|
156
|
+
{ tag: [t.meta, t.comment], color: dark },
|
|
157
|
+
{
|
|
158
|
+
tag: t.link,
|
|
159
|
+
color: GOLDENROD,
|
|
160
|
+
textDecoration: 'underline',
|
|
161
|
+
},
|
|
162
|
+
{ tag: t.invalid, color: PANIC },
|
|
163
|
+
// {
|
|
164
|
+
// class: 'cm-nonmatchingBracket',
|
|
165
|
+
// // color: "rede",
|
|
166
|
+
// backgroundColor: 'red', // Optional: set background color for matching brackets
|
|
167
|
+
// },
|
|
168
|
+
// {
|
|
169
|
+
// tag: t.nonmatchingBracket,
|
|
170
|
+
// color: nonMatchingBracketColor,
|
|
171
|
+
// backgroundColor: 'transparent', // Optional: set background color for non-matching brackets
|
|
172
|
+
// },
|
|
173
|
+
...styles,
|
|
174
|
+
],
|
|
175
|
+
}),
|
|
176
|
+
// Theme matching and non-matching brackets.
|
|
177
|
+
EditorView.theme(
|
|
178
|
+
{
|
|
179
|
+
'&.cm-focused .cm-matchingBracket': {
|
|
180
|
+
backgroundColor: 'transparent',
|
|
181
|
+
outline: '1px solid #888888',
|
|
182
|
+
},
|
|
183
|
+
'&.cm-focused .cm-nonmatchingBracket': {
|
|
184
|
+
backgroundColor: 'transparent',
|
|
185
|
+
outline: '1px solid #ff2222',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{ dark: true },
|
|
189
|
+
),
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export const vizhubTheme = vizhubThemeInit();
|