🐛 Fixed the issue of highlightActiveLine and selected background color conflicts
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
|||||||
drawSelection,
|
drawSelection,
|
||||||
dropCursor,
|
dropCursor,
|
||||||
EditorView,
|
EditorView,
|
||||||
|
highlightActiveLine,
|
||||||
highlightActiveLineGutter,
|
highlightActiveLineGutter,
|
||||||
highlightSpecialChars,
|
highlightSpecialChars,
|
||||||
keymap,
|
keymap,
|
||||||
@@ -12,22 +13,17 @@ import {
|
|||||||
rectangularSelection,
|
rectangularSelection,
|
||||||
} from '@codemirror/view';
|
} from '@codemirror/view';
|
||||||
import {Compartment, EditorState, Extension} from '@codemirror/state';
|
import {Compartment, EditorState, Extension} from '@codemirror/state';
|
||||||
import {baseDark} from "@/editor/theme/base-dark";
|
import {baseDark, customHighlightActiveLine} from "@/editor/theme/base-dark";
|
||||||
import {
|
import {
|
||||||
bracketMatching,
|
bracketMatching,
|
||||||
defaultHighlightStyle,
|
defaultHighlightStyle,
|
||||||
foldGutter,
|
foldGutter,
|
||||||
foldKeymap,
|
foldKeymap,
|
||||||
indentOnInput,
|
indentOnInput,
|
||||||
syntaxHighlighting,
|
indentUnit,
|
||||||
indentUnit
|
syntaxHighlighting
|
||||||
} from '@codemirror/language';
|
} from '@codemirror/language';
|
||||||
import {
|
import {defaultKeymap, history, historyKeymap, indentSelection,} from '@codemirror/commands';
|
||||||
defaultKeymap,
|
|
||||||
history,
|
|
||||||
historyKeymap,
|
|
||||||
indentSelection,
|
|
||||||
} from '@codemirror/commands';
|
|
||||||
import {highlightSelectionMatches, searchKeymap} from '@codemirror/search';
|
import {highlightSelectionMatches, searchKeymap} from '@codemirror/search';
|
||||||
import {autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap} from '@codemirror/autocomplete';
|
import {autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap} from '@codemirror/autocomplete';
|
||||||
import {lintKeymap} from '@codemirror/lint';
|
import {lintKeymap} from '@codemirror/lint';
|
||||||
@@ -55,7 +51,7 @@ const handleWheel = (event: WheelEvent) => {
|
|||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
// 阻止默认行为(防止页面缩放)
|
// 阻止默认行为(防止页面缩放)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
// 根据滚轮方向增大或减小字体
|
// 根据滚轮方向增大或减小字体
|
||||||
if (event.deltaY < 0) {
|
if (event.deltaY < 0) {
|
||||||
// 向上滚动,增大字体
|
// 向上滚动,增大字体
|
||||||
@@ -73,26 +69,26 @@ const tabHandler = (view: EditorView): boolean => {
|
|||||||
if (!view.state.selection.main.empty) {
|
if (!view.state.selection.main.empty) {
|
||||||
return indentSelection(view);
|
return indentSelection(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前的tabSize值
|
// 获取当前的tabSize值
|
||||||
const currentTabSize = editorStore.tabSize;
|
const currentTabSize = editorStore.tabSize;
|
||||||
// 创建相应数量的空格
|
// 创建相应数量的空格
|
||||||
const spaces = ' '.repeat(currentTabSize);
|
const spaces = ' '.repeat(currentTabSize);
|
||||||
|
|
||||||
// 在光标位置插入空格
|
// 在光标位置插入空格
|
||||||
const { state, dispatch } = view;
|
const {state, dispatch} = view;
|
||||||
dispatch(state.update(state.replaceSelection(spaces), { scrollIntoView: true }));
|
dispatch(state.update(state.replaceSelection(spaces), {scrollIntoView: true}));
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取Tab相关的扩展
|
// 获取Tab相关的扩展
|
||||||
const getTabExtensions = (): Extension[] => {
|
const getTabExtensions = (): Extension[] => {
|
||||||
const extensions: Extension[] = [];
|
const extensions: Extension[] = [];
|
||||||
|
|
||||||
// 设置缩进单位
|
// 设置缩进单位
|
||||||
const tabSize = editorStore.tabSize;
|
const tabSize = editorStore.tabSize;
|
||||||
extensions.push(tabSizeCompartment.of(indentUnit.of(' '.repeat(tabSize))));
|
extensions.push(tabSizeCompartment.of(indentUnit.of(' '.repeat(tabSize))));
|
||||||
|
|
||||||
// 如果启用了Tab缩进,添加自定义Tab键映射
|
// 如果启用了Tab缩进,添加自定义Tab键映射
|
||||||
if (editorStore.enableTabIndent) {
|
if (editorStore.enableTabIndent) {
|
||||||
extensions.push(tabKeyCompartment.of(keymap.of([{
|
extensions.push(tabKeyCompartment.of(keymap.of([{
|
||||||
@@ -102,7 +98,7 @@ const getTabExtensions = (): Extension[] => {
|
|||||||
} else {
|
} else {
|
||||||
extensions.push(tabKeyCompartment.of([]));
|
extensions.push(tabKeyCompartment.of([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return extensions;
|
return extensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -130,6 +126,8 @@ const createEditor = () => {
|
|||||||
rectangularSelection(),
|
rectangularSelection(),
|
||||||
crosshairCursor(),
|
crosshairCursor(),
|
||||||
highlightSelectionMatches(),
|
highlightSelectionMatches(),
|
||||||
|
customHighlightActiveLine,
|
||||||
|
highlightActiveLine(),
|
||||||
keymap.of([
|
keymap.of([
|
||||||
...closeBracketsKeymap,
|
...closeBracketsKeymap,
|
||||||
...defaultKeymap,
|
...defaultKeymap,
|
||||||
@@ -156,13 +154,13 @@ const createEditor = () => {
|
|||||||
state,
|
state,
|
||||||
parent: editorElement.value
|
parent: editorElement.value
|
||||||
});
|
});
|
||||||
|
|
||||||
// 将编辑器实例保存到store
|
// 将编辑器实例保存到store
|
||||||
editorStore.setEditorView(view);
|
editorStore.setEditorView(view);
|
||||||
|
|
||||||
// 初始化统计
|
// 初始化统计
|
||||||
updateStats();
|
updateStats();
|
||||||
|
|
||||||
// 应用初始字体大小
|
// 应用初始字体大小
|
||||||
editorStore.applyFontSize();
|
editorStore.applyFontSize();
|
||||||
};
|
};
|
||||||
@@ -170,12 +168,12 @@ const createEditor = () => {
|
|||||||
// 更新统计信息
|
// 更新统计信息
|
||||||
const updateStats = () => {
|
const updateStats = () => {
|
||||||
if (!editorStore.editorView) return;
|
if (!editorStore.editorView) return;
|
||||||
|
|
||||||
const view = editorStore.editorView;
|
const view = editorStore.editorView;
|
||||||
const state = view.state;
|
const state = view.state;
|
||||||
const doc = state.doc;
|
const doc = state.doc;
|
||||||
const text = doc.toString();
|
const text = doc.toString();
|
||||||
|
|
||||||
// 计算选中的字符数
|
// 计算选中的字符数
|
||||||
let selectedChars = 0;
|
let selectedChars = 0;
|
||||||
const selections = state.selection;
|
const selections = state.selection;
|
||||||
@@ -185,7 +183,7 @@ const updateStats = () => {
|
|||||||
selectedChars += range.to - range.from;
|
selectedChars += range.to - range.from;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editorStore.updateDocumentStats({
|
editorStore.updateDocumentStats({
|
||||||
lines: doc.lines,
|
lines: doc.lines,
|
||||||
characters: text.length,
|
characters: text.length,
|
||||||
@@ -196,22 +194,22 @@ const updateStats = () => {
|
|||||||
// 动态更新Tab配置,不需要重建编辑器
|
// 动态更新Tab配置,不需要重建编辑器
|
||||||
const updateTabConfig = () => {
|
const updateTabConfig = () => {
|
||||||
if (!editorStore.editorView) return;
|
if (!editorStore.editorView) return;
|
||||||
|
|
||||||
// 更新Tab大小配置
|
// 更新Tab大小配置
|
||||||
const tabSize = editorStore.tabSize;
|
const tabSize = editorStore.tabSize;
|
||||||
|
|
||||||
const view = editorStore.editorView;
|
const view = editorStore.editorView;
|
||||||
|
|
||||||
// 更新indentUnit配置
|
// 更新indentUnit配置
|
||||||
view.dispatch({
|
view.dispatch({
|
||||||
effects: tabSizeCompartment.reconfigure(indentUnit.of(' '.repeat(tabSize)))
|
effects: tabSizeCompartment.reconfigure(indentUnit.of(' '.repeat(tabSize)))
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新Tab键映射
|
// 更新Tab键映射
|
||||||
const tabKeymap = editorStore.enableTabIndent
|
const tabKeymap = editorStore.enableTabIndent
|
||||||
? keymap.of([{ key: "Tab", run: tabHandler }])
|
? keymap.of([{key: "Tab", run: tabHandler}])
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
view.dispatch({
|
view.dispatch({
|
||||||
effects: tabKeyCompartment.reconfigure(tabKeymap)
|
effects: tabKeyCompartment.reconfigure(tabKeymap)
|
||||||
});
|
});
|
||||||
@@ -220,7 +218,7 @@ const updateTabConfig = () => {
|
|||||||
// 重新配置编辑器(仅在必要时完全重建)
|
// 重新配置编辑器(仅在必要时完全重建)
|
||||||
const reconfigureEditor = () => {
|
const reconfigureEditor = () => {
|
||||||
if (!editorStore.editorView) return;
|
if (!editorStore.editorView) return;
|
||||||
|
|
||||||
// 尝试动态更新配置
|
// 尝试动态更新配置
|
||||||
updateTabConfig();
|
updateTabConfig();
|
||||||
};
|
};
|
||||||
@@ -237,10 +235,10 @@ watch(() => editorStore.enableTabIndent, () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 创建编辑器
|
// 创建编辑器
|
||||||
createEditor();
|
createEditor();
|
||||||
|
|
||||||
// 添加滚轮事件监听
|
// 添加滚轮事件监听
|
||||||
if (editorElement.value) {
|
if (editorElement.value) {
|
||||||
editorElement.value.addEventListener('wheel', handleWheel, { passive: false });
|
editorElement.value.addEventListener('wheel', handleWheel, {passive: false});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -249,7 +247,7 @@ onBeforeUnmount(() => {
|
|||||||
if (editorElement.value) {
|
if (editorElement.value) {
|
||||||
editorElement.value.removeEventListener('wheel', handleWheel);
|
editorElement.value.removeEventListener('wheel', handleWheel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editorStore.editorView) {
|
if (editorStore.editorView) {
|
||||||
editorStore.editorView.destroy();
|
editorStore.editorView.destroy();
|
||||||
editorStore.setEditorView(null);
|
editorStore.setEditorView(null);
|
||||||
|
@@ -9,10 +9,11 @@ export const config = {
|
|||||||
background: '#252B37',
|
background: '#252B37',
|
||||||
foreground: '#9BB586',
|
foreground: '#9BB586',
|
||||||
selection: '#1A5888',
|
selection: '#1A5888',
|
||||||
|
selectionMatch: 'rgba(26, 88, 136, 0.5)',
|
||||||
cursor: '#F8F8F2',
|
cursor: '#F8F8F2',
|
||||||
dropdownBackground: '#282A36',
|
dropdownBackground: '#282A36',
|
||||||
dropdownBorder: '#191A21',
|
dropdownBorder: '#191A21',
|
||||||
activeLine: '#2E333F',
|
activeLine: 'rgba(46, 51, 63, 0.6)',
|
||||||
lineNumber: '#676d7c',
|
lineNumber: '#676d7c',
|
||||||
lineNumberActive: '#F8F8F2',
|
lineNumberActive: '#F8F8F2',
|
||||||
lineNumberBackground: '#212731',
|
lineNumberBackground: '#212731',
|
||||||
@@ -42,7 +43,10 @@ export const draculaTheme = EditorView.theme({
|
|||||||
'.cm-content': {caretColor: config.cursor},
|
'.cm-content': {caretColor: config.cursor},
|
||||||
|
|
||||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
|
||||||
|
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
|
||||||
|
backgroundColor: `${config.selection} !important`
|
||||||
|
},
|
||||||
|
|
||||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||||
@@ -57,7 +61,11 @@ export const draculaTheme = EditorView.theme({
|
|||||||
},
|
},
|
||||||
|
|
||||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
|
||||||
|
'.cm-selectionMatch': {
|
||||||
|
backgroundColor: `${config.selectionMatch} !important`,
|
||||||
|
borderRadius: '2px'
|
||||||
|
},
|
||||||
|
|
||||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||||
backgroundColor: config.matchingBracket,
|
backgroundColor: config.matchingBracket,
|
||||||
@@ -123,6 +131,12 @@ export const draculaHighlightStyle = HighlightStyle.define([
|
|||||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
export const customHighlightActiveLine = EditorView.theme({
|
||||||
|
'.cm-activeLine': {
|
||||||
|
backgroundColor: config.activeLine,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
export const baseDark: Extension = [
|
export const baseDark: Extension = [
|
||||||
draculaTheme,
|
draculaTheme,
|
||||||
syntaxHighlighting(draculaHighlightStyle),
|
syntaxHighlighting(draculaHighlightStyle),
|
||||||
|
Reference in New Issue
Block a user