Improve code editor text selection and clean up lint enablement (#37474)
1. Make the content area stretch the box, enabling text selection to start over empty space. 2. Disable linter for markdown, it can never produce lint errors, this hides the unnecessary lint gutter on markdown files. 3. Verified all languages linter enablement, all accurate. 4. Refactor `getLinterExtension` to not rely on file extensions. 5. Include jsonc/json5 extensions in regex. --- This PR was written with the help of Claude Opus 4.7 --------- Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com> Co-authored-by: Nicolas <bircni@icloud.com>
This commit is contained in:
@@ -24,6 +24,8 @@
|
|||||||
font-family: var(--fonts-monospace);
|
font-family: var(--fonts-monospace);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-editor-container .cm-editor,
|
.code-editor-container .cm-editor,
|
||||||
@@ -31,24 +33,22 @@
|
|||||||
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-editor-container .cm-content,
|
|
||||||
.code-editor-container .cm-gutter {
|
|
||||||
min-height: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-editor-container .cm-scroller {
|
.code-editor-container .cm-scroller {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
line-height: var(--line-height-code);
|
line-height: var(--line-height-code);
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-editor-container .cm-content {
|
||||||
|
align-self: stretch;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-editor-container .cm-content * {
|
.code-editor-container .cm-content * {
|
||||||
caret-color: inherit;
|
caret-color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-editor-container .cm-content {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-editor-container .cm-cursor,
|
.code-editor-container .cm-cursor,
|
||||||
.code-editor-container .cm-dropCursor {
|
.code-editor-container .cm-dropCursor {
|
||||||
border-left-color: var(--color-caret);
|
border-left-color: var(--color-caret);
|
||||||
@@ -341,6 +341,8 @@
|
|||||||
.code-editor-container {
|
.code-editor-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-command-palette {
|
.cm-command-palette {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type {PaletteCommand} from './command-palette.ts';
|
|||||||
import {contextMenu, collectSymbols, selectAllOccurrences} from './context-menu.ts';
|
import {contextMenu, collectSymbols, selectAllOccurrences} from './context-menu.ts';
|
||||||
import {createJsonLinter, createSyntaxErrorLinter} from './linter.ts';
|
import {createJsonLinter, createSyntaxErrorLinter} from './linter.ts';
|
||||||
import {clickableUrls, goToDefinitionAt, trimTrailingWhitespaceFromView} from './utils.ts';
|
import {clickableUrls, goToDefinitionAt, trimTrailingWhitespaceFromView} from './utils.ts';
|
||||||
import type {LanguageDescription} from '@codemirror/language';
|
import type {LanguageDescription, LanguageSupport} from '@codemirror/language';
|
||||||
import type {Compartment, Extension} from '@codemirror/state';
|
import type {Compartment, Extension} from '@codemirror/state';
|
||||||
import type {EditorView, ViewUpdate} from '@codemirror/view';
|
import type {EditorView, ViewUpdate} from '@codemirror/view';
|
||||||
|
|
||||||
@@ -295,16 +295,19 @@ export async function createCodeEditor(textarea: HTMLTextAreaElement, filenameIn
|
|||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// files that are JSONC despite having a .json extension
|
// files that the JSON parser is too strict for (comments, trailing commas)
|
||||||
const jsoncFilesRegex = /^([jt]sconfig.*|devcontainer)\.json$/;
|
const jsoncFilesRegex = /^([jt]sconfig.*|devcontainer)\.json$|\.(jsonc|json5)$/i;
|
||||||
|
|
||||||
async function getLinterExtension(cm: CodemirrorModules, filename: string, loadedLang: {language: unknown} | null): Promise<Extension> {
|
async function getLinterExtension(cm: CodemirrorModules, filename: string, loadedLang: LanguageSupport | null): Promise<Extension> {
|
||||||
const ext = extname(filename).toLowerCase();
|
if (!loadedLang) return [];
|
||||||
if (ext === '.json' || ext === '.map') {
|
const lang = loadedLang.language;
|
||||||
|
// StreamLanguage (legacy modes) don't produce Lezer error nodes
|
||||||
|
if (lang instanceof cm.language.StreamLanguage) return [];
|
||||||
|
if (lang.name === 'json') {
|
||||||
return jsoncFilesRegex.test(filename) ? [] : [cm.lint.lintGutter(), await createJsonLinter(cm)];
|
return jsoncFilesRegex.test(filename) ? [] : [cm.lint.lintGutter(), await createJsonLinter(cm)];
|
||||||
}
|
}
|
||||||
// StreamLanguage (legacy modes) don't produce Lezer error nodes
|
// markdown's parser emits no error nodes, and nested code-fence overlays aren't traversed
|
||||||
if (!loadedLang || loadedLang.language instanceof cm.language.StreamLanguage) return [];
|
if (lang.name === 'markdown') return [];
|
||||||
return [cm.lint.lintGutter(), createSyntaxErrorLinter(cm)];
|
return [cm.lint.lintGutter(), createSyntaxErrorLinter(cm)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user