Unified and context diff syntax highlighting (#26)

This commit is contained in:
Matouš Kučera
2024-11-27 00:29:27 +01:00
committed by GitHub
parent 60c15956b8
commit 8936a95ef9
5 changed files with 105 additions and 50 deletions

View File

@@ -17,7 +17,8 @@ import themes, { Theme } from '../style/themes';
import type { editor } from 'monaco-editor'; import type { editor } from 'monaco-editor';
import { ResetFunction } from './Editor'; import { ResetFunction } from './Editor';
import { logLanguage } from '../util/log-language'; import { logLanguage } from '../util/languages/log';
import { diffLanguage } from '../util/languages/diff';
import * as monaco from 'monaco-editor'; import * as monaco from 'monaco-editor';
import { loader } from '@monaco-editor/react'; import { loader } from '@monaco-editor/react';
@@ -68,6 +69,8 @@ export default function EditorTextArea({
monaco.languages.register({ id: 'log' }); monaco.languages.register({ id: 'log' });
monaco.languages.setMonarchTokensProvider('log', logLanguage); monaco.languages.setMonarchTokensProvider('log', logLanguage);
monaco.languages.register({ id: 'diff' });
monaco.languages.setMonarchTokensProvider('diff', diffLanguage);
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({ monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: true, noSemanticValidation: true,

View File

@@ -64,6 +64,9 @@ const themes: Themes = {
logWarning: '#d29922', // yellow.3 logWarning: '#d29922', // yellow.3
logDate: '#33B3AE', // teal.3 logDate: '#33B3AE', // teal.3
logException: '#f8e3a1', // yellow.0 logException: '#f8e3a1', // yellow.0
diffMeta: '#33B3AE', // teal.3
diffAddition: '#3fb950', // green.3
diffDeletion: '#f85149', // red.4
}, },
}), }),
}, },
@@ -100,6 +103,9 @@ const themes: Themes = {
logWarning: '#d4a72c', // yellow.3 logWarning: '#d4a72c', // yellow.3
logDate: '#136061', // teal.6 logDate: '#136061', // teal.6
logException: '#7d4e00', // yellow.6 logException: '#7d4e00', // yellow.6
diffMeta: '#136061', // teal.6
diffAddition: '#2da44e', // green.4
diffDeletion: '#cf222e', // red.5
}, },
}), }),
}, },
@@ -114,12 +120,15 @@ const themes: Themes = {
color: '#586e75', color: '#586e75',
backgroundColor: '#44475a', backgroundColor: '#44475a',
}, },
editor: addLogColors(dracula as editor.IStandaloneThemeData, { editor: addExtraColors(dracula as editor.IStandaloneThemeData, {
info: '#50FA7B', // green logInfo: '#50FA7B', // green
error: '#FF5555', // red logError: '#FF5555', // red
warning: '#FFB86C', // orange logWarning: '#FFB86C', // orange
date: '#BD93F9', // purple logDate: '#BD93F9', // purple
exception: '#F1FA8C', // yellow logException: '#F1FA8C', // yellow
diffMeta: '#BD93F9', // purple
diffAddition: '#50FA7B', // green
diffDeletion: '#FF5555', // red
}), }),
}, },
'monokai': { 'monokai': {
@@ -133,12 +142,15 @@ const themes: Themes = {
color: '#49483E', color: '#49483E',
backgroundColor: '#3E3D32', backgroundColor: '#3E3D32',
}, },
editor: addLogColors(monokai as editor.IStandaloneThemeData, { editor: addExtraColors(monokai as editor.IStandaloneThemeData, {
info: '#a6e22e', // green logInfo: '#a6e22e', // green
error: '#f92672', // red logError: '#f92672', // red
warning: '#fd971f', // orange logWarning: '#fd971f', // orange
date: '#AB9DF2', // purple logDate: '#AB9DF2', // purple
exception: '#F1FA8C', // yellow logException: '#F1FA8C', // yellow
diffMeta: '#AB9DF2', // purple
diffAddition: '#a6e22e', // green
diffDeletion: '#f92672', // red
}), }),
}, },
'solarized': { 'solarized': {
@@ -152,12 +164,15 @@ const themes: Themes = {
color: '#93a1a1', // base1 color: '#93a1a1', // base1
backgroundColor: '#073642', // base02 backgroundColor: '#073642', // base02
}, },
editor: addLogColors(solarizedDark as editor.IStandaloneThemeData, { editor: addExtraColors(solarizedDark as editor.IStandaloneThemeData, {
info: '#268bd2', // blue logInfo: '#268bd2', // blue
error: '#dc322f', // red logError: '#dc322f', // red
warning: '#b58900', // yellow logWarning: '#b58900', // yellow
date: '#2aa198', // cyan logDate: '#2aa198', // cyan
exception: '#859900', // green logException: '#859900', // green
diffMeta: '#2aa198', // cyan
diffAddition: '#859900', // green
diffDeletion: '#dc322f', // red
}), }),
}, },
'solarized-light': { 'solarized-light': {
@@ -171,18 +186,32 @@ const themes: Themes = {
color: '#586e75', // base01 color: '#586e75', // base01
backgroundColor: '#eee8d5', // base2 backgroundColor: '#eee8d5', // base2
}, },
editor: addLogColors(solarizedLight as editor.IStandaloneThemeData, { editor: addExtraColors(solarizedLight as editor.IStandaloneThemeData, {
info: '#268bd2', // blue logInfo: '#268bd2', // blue
error: '#dc322f', // red logError: '#dc322f', // red
warning: '#b58900', // yellow logWarning: '#b58900', // yellow
date: '#2aa198', // cyan logDate: '#2aa198', // cyan
exception: '#859900', // green logException: '#859900', // green
diffMeta: '#2aa198', // cyan
diffAddition: '#859900', // green
diffDeletion: '#dc322f', // red
}), }),
}, },
}; };
export default themes; export default themes;
interface ExtraColors {
logInfo: Color;
logError: Color;
logWarning: Color;
logDate: Color;
logException: Color;
diffMeta: Color;
diffAddition: Color;
diffDeletion: Color;
}
interface MonacoThemeProps { interface MonacoThemeProps {
base: 'vs' | 'vs-dark'; base: 'vs' | 'vs-dark';
colors: { colors: {
@@ -198,12 +227,7 @@ interface MonacoThemeProps {
keyword: Color; keyword: Color;
type: Color; type: Color;
variable: Color; variable: Color;
logInfo: Color; } & ExtraColors;
logError: Color;
logWarning: Color;
logDate: Color;
logException: Color;
};
} }
export function makeMonacoTheme( export function makeMonacoTheme(
@@ -246,6 +270,9 @@ export function makeMonacoTheme(
{ token: 'warning.log', foreground: colors.logWarning }, { token: 'warning.log', foreground: colors.logWarning },
{ token: 'date.log', foreground: colors.logDate }, { token: 'date.log', foreground: colors.logDate },
{ token: 'exception.log', foreground: colors.logException }, { token: 'exception.log', foreground: colors.logException },
{ token: 'meta.diff', foreground: colors.diffMeta },
{ token: 'addition.diff', foreground: colors.diffAddition },
{ token: 'deletion.diff', foreground: colors.diffDeletion },
], ],
colors: { colors: {
'editor.background': `#${colors.background}`, 'editor.background': `#${colors.background}`,
@@ -254,28 +281,23 @@ export function makeMonacoTheme(
}; };
} }
interface LogColors { export function addExtraColors(
info: Color;
error: Color;
warning: Color;
date: Color;
exception: Color;
}
export function addLogColors(
theme: editor.IStandaloneThemeData, theme: editor.IStandaloneThemeData,
logColors: LogColors extraColors: ExtraColors
): editor.IStandaloneThemeData { ): editor.IStandaloneThemeData {
const colors = Object.fromEntries( const colors = Object.fromEntries(
Object.entries(logColors).map(([key, color]) => [key, color.substring(1)]) Object.entries(extraColors).map(([key, color]) => [key, color.substring(1)])
) as Record<keyof LogColors, string>; ) as Record<keyof ExtraColors, string>;
theme.rules.push( theme.rules.push(
...[ ...[
{ token: 'info.log', foreground: colors.info }, { token: 'info.log', foreground: colors.logInfo },
{ token: 'error.log', foreground: colors.error, fontStyle: 'bold' }, { token: 'error.log', foreground: colors.logError, fontStyle: 'bold' },
{ token: 'warning.log', foreground: colors.warning }, { token: 'warning.log', foreground: colors.logWarning },
{ token: 'date.log', foreground: colors.date }, { token: 'date.log', foreground: colors.logDate },
{ token: 'exception.log', foreground: colors.exception }, { token: 'exception.log', foreground: colors.logException },
{ token: 'meta.diff', foreground: colors.diffMeta },
{ token: 'addition.diff', foreground: colors.diffAddition },
{ token: 'deletion.diff', foreground: colors.diffDeletion },
] ]
); );
return theme; return theme;

View File

@@ -17,10 +17,10 @@ export const languages = {
'go', 'go',
'lua', 'lua',
'swift', 'swift',
'c' 'c',
], ],
web: ['html', 'css', 'scss', 'php', 'graphql'], web: ['html', 'css', 'scss', 'php', 'graphql'],
misc: ['dockerfile', 'markdown', 'proto'], misc: ['diff', 'dockerfile', 'markdown', 'proto'],
}; };
export const languageIds = Object.values(languages).flat(1); export const languageIds = Object.values(languages).flat(1);

View File

@@ -0,0 +1,30 @@
import { languages } from 'monaco-editor';
export const diffLanguage: languages.IMonarchLanguage = {
defaultToken: '',
tokenizer: {
root: [
// Meta lines (e.g., @@ -1,2 +3,4 @@)
[/@@@ +-\d+,\d+ +\+\d+,\d+ +@@@/, 'meta'],
[/^\*\*\* +\d+,\d+ +\*\*\*\*$/, 'meta'],
[/^--- +\d+,\d+ +----$/, 'meta'],
// Comments
[/Index: .*/, 'comment'],
[/^index.*/, 'comment'],
[/={3,}/, 'comment'],
[/^-{3}.*/, 'comment'],
[/^\*{3} .*/, 'comment'],
[/^\+{3}.*/, 'comment'],
[/^diff --git.*/, 'comment'],
[/^\*{15}$/, 'comment'],
// Additions
[/^\+.*/, 'addition'],
[/^!.*/, 'addition'],
// Deletions
[/^-.*/, 'deletion'],
],
},
};