mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2026-03-10 21:25:31 +00:00
Merge pull request #220 from fredsa/fixasmedit
More sensible tab/shift-tab handling
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { closeBrackets, deleteBracketPair } from "@codemirror/autocomplete";
|
||||
import { defaultKeymap, history, historyKeymap, indentWithTab, undo } from "@codemirror/commands";
|
||||
import { defaultKeymap, history, historyKeymap, undo } from "@codemirror/commands";
|
||||
import { cpp } from "@codemirror/lang-cpp";
|
||||
import { markdown } from "@codemirror/lang-markdown";
|
||||
import { bracketMatching, foldGutter, indentOnInput, indentUnit } from "@codemirror/language";
|
||||
@@ -26,6 +26,7 @@ import { isMobileDevice, ProjectView } from "./baseviews";
|
||||
import { debugHighlightTagsTooltip } from "./debug";
|
||||
import { createTextTransformFilterEffect, textTransformFilterCompartment } from "./filters";
|
||||
import { breakpointMarkers, bytes, clock, currentPcMarker, errorMarkers, offset, statusMarkers } from "./gutter";
|
||||
import { tabKeymap } from "./tabs";
|
||||
import { currentPc, errorMessages, highlightLines, showValue } from "./visuals";
|
||||
|
||||
// TODO: make this an easily toggleable debug setting.
|
||||
@@ -193,7 +194,7 @@ export class SourceEditor implements ProjectView {
|
||||
debugHighlightTags ? debugHighlightTagsTooltip : [],
|
||||
EditorState.tabSize.of(8),
|
||||
indentUnit.of(" "),
|
||||
keymap.of([indentWithTab]),
|
||||
keymap.of(tabKeymap),
|
||||
lineWrap ? EditorView.lineWrapping : [],
|
||||
|
||||
currentPc.field,
|
||||
|
||||
72
src/ide/views/tabs.ts
Normal file
72
src/ide/views/tabs.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { EditorSelection } from "@codemirror/state";
|
||||
import { EditorView, KeyBinding } from "@codemirror/view";
|
||||
|
||||
function tab(view: EditorView): boolean {
|
||||
const tabSize = view.state.tabSize;
|
||||
view.dispatch(view.state.changeByRange(sel => {
|
||||
const startLine = view.state.doc.lineAt(sel.from);
|
||||
const endLine = view.state.doc.lineAt(sel.to);
|
||||
if (sel.empty) {
|
||||
// Cursor only: insert spaces to next tab stop
|
||||
const col = sel.head - startLine.from;
|
||||
const spaces = tabSize - (col % tabSize);
|
||||
const insert = " ".repeat(spaces);
|
||||
return {
|
||||
changes: { from: sel.from, insert },
|
||||
range: EditorSelection.cursor(sel.from + spaces),
|
||||
};
|
||||
} else if (startLine.number === endLine.number) {
|
||||
// Single-line selection: replace with spaces, cursor at end of whitespace
|
||||
const col = sel.from - startLine.from;
|
||||
const spaces = tabSize - (col % tabSize);
|
||||
const insert = " ".repeat(spaces);
|
||||
return {
|
||||
changes: { from: sel.from, to: sel.to, insert },
|
||||
range: EditorSelection.cursor(sel.from + spaces),
|
||||
};
|
||||
} else {
|
||||
// Multi-line selection: move first non-ws char to next tab stop on each line
|
||||
const changes = [];
|
||||
for (let i = startLine.number; i <= endLine.number; i++) {
|
||||
const line = view.state.doc.line(i);
|
||||
const firstNonWs = line.text.search(/\S/);
|
||||
if (firstNonWs < 0) continue;
|
||||
const newCol = (Math.floor(firstNonWs / tabSize) + 1) * tabSize;
|
||||
const spaces = newCol - firstNonWs;
|
||||
changes.push({ from: line.from + firstNonWs, insert: " ".repeat(spaces) });
|
||||
}
|
||||
const changeSet = view.state.changes(changes);
|
||||
return {
|
||||
changes: changeSet,
|
||||
range: EditorSelection.range(changeSet.mapPos(sel.from), changeSet.mapPos(sel.to)),
|
||||
};
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
function shiftTab(view: EditorView): boolean {
|
||||
const tabSize = view.state.tabSize;
|
||||
const changes = [];
|
||||
const seen = new Set<number>();
|
||||
for (const sel of view.state.selection.ranges) {
|
||||
const startLine = view.state.doc.lineAt(sel.from);
|
||||
const endLine = view.state.doc.lineAt(sel.to);
|
||||
for (let i = startLine.number; i <= endLine.number; i++) {
|
||||
if (seen.has(i)) continue;
|
||||
seen.add(i);
|
||||
const line = view.state.doc.line(i);
|
||||
const firstNonWs = line.text.search(/\S/);
|
||||
if (firstNonWs <= 0) continue;
|
||||
const newCol = Math.floor((firstNonWs - 1) / tabSize) * tabSize;
|
||||
changes.push({ from: line.from + newCol, to: line.from + firstNonWs });
|
||||
}
|
||||
}
|
||||
if (changes.length) view.dispatch({ changes });
|
||||
return true;
|
||||
}
|
||||
|
||||
export const tabKeymap: KeyBinding[] = [
|
||||
{ key: "Tab", run: tab },
|
||||
{ key: "Shift-Tab", run: shiftTab },
|
||||
];
|
||||
Reference in New Issue
Block a user