Skip to content

Commit

Permalink
Merge pull request #2414 from BetterThanTomorrow/wip/rayat/use-select…
Browse files Browse the repository at this point in the history
…ions-in-editable-document
  • Loading branch information
riotrah authored Mar 2, 2024
2 parents ce14c17 + 3cbd653 commit c888eb4
Show file tree
Hide file tree
Showing 33 changed files with 584 additions and 557 deletions.
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["esbenp.prettier-vscode", "hbenl.vscode-mocha-test-adapter"]
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changes to Calva.

## [Unreleased]

- Refactor some internal document and selection APIs in preparation for multiple selections, addressing [#610](https://github.com/BetterThanTomorrow/calva/issues/610)
- [Add default Clojure associations for file extensions `.lpy`](https://github.com/BetterThanTomorrow/calva/issues/2415)

## [2.0.414] - 2024-02-24
Expand Down
2 changes: 1 addition & 1 deletion src/api/ranges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as getText from '../util/get-text';
const wrapSelectionAndTextFunction = (
f: (document: vscode.TextDocument, position: vscode.Position) => [vscode.Range, string]
) => {
return (editor = vscode.window.activeTextEditor, position = editor?.selection?.active) => {
return (editor = vscode.window.activeTextEditor, position = editor?.selections?.[0]?.active) => {
if (editor && position && editor.document && editor.document.languageId === 'clojure') {
return f(editor.document, position);
} else {
Expand Down
26 changes: 15 additions & 11 deletions src/calva-fmt/src/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export async function indentPosition(position: vscode.Position, document: vscode
undoStopBefore: false,
})
.then((onFulfilled) => {
editor.selection = new vscode.Selection(newPosition, newPosition);
editor.selections = [new vscode.Selection(newPosition, newPosition)];
return onFulfilled;
});
} else if (delta < 0) {
Expand All @@ -43,7 +43,7 @@ export async function indentPosition(position: vscode.Position, document: vscode
undoStopBefore: false,
})
.then((onFulfilled) => {
editor.selection = new vscode.Selection(newPosition, newPosition);
editor.selections = [new vscode.Selection(newPosition, newPosition)];
return onFulfilled;
});
}
Expand Down Expand Up @@ -103,7 +103,7 @@ export async function formatPositionInfo(
extraConfig = {}
) {
const doc: vscode.TextDocument = editor.document;
const index = doc.offsetAt(editor.selection.active);
const index = doc.offsetAt(editor.selections[0].active);
const cursor = getDocument(doc).getTokenCursor(index);

const formatRange = _calculateFormatRange(extraConfig, cursor, index);
Expand Down Expand Up @@ -208,20 +208,24 @@ export async function formatPosition(
{ undoStopAfter: false, undoStopBefore: false }
)
.then((onFulfilled: boolean) => {
editor.selection = new vscode.Selection(
doc.positionAt(formattedInfo.newIndex),
doc.positionAt(formattedInfo.newIndex)
);
editor.selections = [
new vscode.Selection(
doc.positionAt(formattedInfo.newIndex),
doc.positionAt(formattedInfo.newIndex)
),
];
return onFulfilled;
});
}
if (formattedInfo) {
return new Promise((resolve, _reject) => {
if (formattedInfo.newIndex != formattedInfo.previousIndex) {
editor.selection = new vscode.Selection(
doc.positionAt(formattedInfo.newIndex),
doc.positionAt(formattedInfo.newIndex)
);
editor.selections = [
new vscode.Selection(
doc.positionAt(formattedInfo.newIndex),
doc.positionAt(formattedInfo.newIndex)
),
];
}
resolve(true);
});
Expand Down
6 changes: 3 additions & 3 deletions src/calva-fmt/src/infer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface ResultOptions {
}

export function inferParensCommand(editor: vscode.TextEditor) {
const position: vscode.Position = editor.selection.active,
const position: vscode.Position = editor.selections[0].active,
document = editor.document,
currentText = document.getText(),
r: ResultOptions = inferParens({
Expand All @@ -37,7 +37,7 @@ export function inferParensCommand(editor: vscode.TextEditor) {
}

export function indentCommand(editor: vscode.TextEditor, spacing: string, forward: boolean = true) {
const prevPosition: vscode.Position = editor.selection.active,
const prevPosition: vscode.Position = editor.selections[0].active,
document = editor.document;
let deletedText = '',
doEdit = true;
Expand Down Expand Up @@ -71,7 +71,7 @@ export function indentCommand(editor: vscode.TextEditor, spacing: string, forwar
)
.then((_onFulfilled: boolean) => {
if (doEdit) {
const position: vscode.Position = editor.selection.active,
const position: vscode.Position = editor.selections[0].active,
currentText = document.getText(),
r: ResultOptions = inferIndents({
text: currentText,
Expand Down
2 changes: 1 addition & 1 deletion src/calva-fmt/src/providers/ontype_formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class FormatOnTypeEditProvider implements vscode.OnTypeFormattingEditProv
}
const editor = util.getActiveTextEditor();

const pos = editor.selection.active;
const pos = editor.selections[0].active;
if (formatterConfig.formatOnTypeEnabled()) {
if (vscode.workspace.getConfiguration('calva.fmt').get('newIndentEngine')) {
await formatter.indentPosition(pos, document);
Expand Down
8 changes: 6 additions & 2 deletions src/clojuredocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ export function printTextToRichCommentCommand(args: { [x: string]: string }) {
async function printTextToRichComment(text: string, position?: number) {
const doc = util.getDocument({});
const mirrorDoc = docMirror.getDocument(doc);
return paredit.addRichComment(mirrorDoc, position ? position : mirrorDoc.selection.active, text);
return paredit.addRichComment(
mirrorDoc,
position ? position : mirrorDoc.selections[0].active,
text
);
}

export async function getExamplesHover(
Expand Down Expand Up @@ -175,7 +179,7 @@ async function clojureDocsLookup(
p?: vscode.Position
): Promise<DocsEntry | undefined> {
const doc = d ? d : util.getDocument({});
const position = p ? p : util.getActiveTextEditor().selection.active;
const position = p ? p : util.getActiveTextEditor().selections[0].active;
const symbol = util.getWordAtPosition(doc, position);
const [ns, _] = namespace.getNamespace(doc, p);
const session = replSession.getSession(util.getFileType(doc));
Expand Down
2 changes: 1 addition & 1 deletion src/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as config from './config';

function getText() {
const editor = vscode.window.activeTextEditor;
const selection = editor.selection;
const selection = editor.selections[0];
const doc = editor.document;
return doc.getText(
selection.active.isEqual(selection.anchor)
Expand Down
2 changes: 1 addition & 1 deletion src/cursor-doc/backspace-on-whitespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function backspaceOnWhitespace(
) {
const origIndent = getIndent(doc.model, cursor.offsetStart, config);
const onCloseToken = cursor.getToken().type === 'close';
let start = doc.selection.anchor;
let start = doc.selections[0].anchor;
let token = cursor.getToken();
if (token.type === 'ws') {
start = cursor.offsetEnd;
Expand Down
6 changes: 3 additions & 3 deletions src/cursor-doc/cursor-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type CursorContext = typeof allCursorContexts[number];
* Returns true if documentOffset is either at the first char of the token under the cursor, or
* in the whitespace between the token and the first preceding EOL, otherwise false
*/
export function isAtLineStartInclWS(doc: EditableDocument, offset = doc.selection.active) {
export function isAtLineStartInclWS(doc: EditableDocument, offset = doc.selections[0].active) {
const tokenCursor = doc.getTokenCursor(offset);
let startOfLine = false;
// only at start if we're in ws, or at the 1st char of a non-ws sexp
Expand All @@ -33,7 +33,7 @@ export function isAtLineStartInclWS(doc: EditableDocument, offset = doc.selectio
* Returns true if position is after the last char of the last lisp token on the line, including
* any trailing whitespace or EOL, otherwise false
*/
export function isAtLineEndInclWS(doc: EditableDocument, offset = doc.selection.active) {
export function isAtLineEndInclWS(doc: EditableDocument, offset = doc.selections[0].active) {
const tokenCursor = doc.getTokenCursor(offset);
if (tokenCursor.getToken().type === 'eol') {
return true;
Expand All @@ -58,7 +58,7 @@ export function isAtLineEndInclWS(doc: EditableDocument, offset = doc.selection.

export function determineContexts(
doc: EditableDocument,
offset = doc.selection.active
offset = doc.selections[0].active
): CursorContext[] {
const tokenCursor = doc.getTokenCursor(offset);
const contexts: CursorContext[] = [];
Expand Down
35 changes: 21 additions & 14 deletions src/cursor-doc/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@ export class TextLine {
}

export type ModelEditFunction = 'insertString' | 'changeRange' | 'deleteRange';

export class ModelEdit {
constructor(public editFn: ModelEditFunction, public args: any[]) {}
export type ModelEditArgs<T extends ModelEditFunction> = T extends 'insertString'
? Parameters<LineInputModel['insertString']>
: T extends 'changeRange'
? Parameters<LineInputModel['changeRange']>
: T extends 'deleteRange'
? Parameters<LineInputModel['deleteRange']>
: never;

export class ModelEdit<T extends ModelEditFunction> {
constructor(public editFn: T, public args: Readonly<ModelEditArgs<T>>) {}
}

/**
Expand Down Expand Up @@ -93,7 +100,7 @@ export type ModelEditOptions = {
undoStopBefore?: boolean;
formatDepth?: number;
skipFormat?: boolean;
selection?: ModelEditSelection;
selections?: ModelEditSelection[];
};

export interface EditableModel {
Expand All @@ -104,7 +111,7 @@ export interface EditableModel {
* For some EditableModel's these are performed as one atomic set of edits.
* @param edits
*/
edit: (edits: ModelEdit[], options: ModelEditOptions) => Thenable<boolean>;
edit: (edits: ModelEdit<ModelEditFunction>[], options: ModelEditOptions) => Thenable<boolean>;

getText: (start: number, end: number, mustBeWithin?: boolean) => string;
getLineText: (line: number) => string;
Expand All @@ -113,7 +120,7 @@ export interface EditableModel {
}

export interface EditableDocument {
selection: ModelEditSelection;
selections: ModelEditSelection[];
model: EditableModel;
selectionStack: ModelEditSelection[];
getTokenCursor: (offset?: number, previous?: boolean) => LispTokenCursor;
Expand Down Expand Up @@ -365,7 +372,7 @@ export class LineInputModel implements EditableModel {
* Doesn't need to be atomic in the LineInputModel.
* @param edits
*/
edit(edits: ModelEdit[], options: ModelEditOptions): Thenable<boolean> {
edit(edits: ModelEdit<ModelEditFunction>[], options: ModelEditOptions): Thenable<boolean> {
return new Promise((resolve, reject) => {
for (const edit of edits) {
switch (edit.editFn) {
Expand All @@ -388,8 +395,8 @@ export class LineInputModel implements EditableModel {
break;
}
}
if (this.document && options.selection) {
this.document.selection = options.selection;
if (this.document && options.selections) {
this.document.selections = options.selections;
}
resolve(true);
});
Expand Down Expand Up @@ -544,7 +551,7 @@ export class StringDocument implements EditableDocument {
}
}

selection: ModelEditSelection;
selections: ModelEditSelection[];

model: LineInputModel;

Expand All @@ -566,16 +573,16 @@ export class StringDocument implements EditableDocument {
getSelectionText: () => string;

delete() {
const p = this.selection.anchor;
const p = this.selections[0].anchor;
return this.model.edit([new ModelEdit('deleteRange', [p, 1])], {
selection: new ModelEditSelection(p),
selections: [new ModelEditSelection(p)],
});
}

backspace() {
const p = this.selection.anchor;
const p = this.selections[0].anchor;
return this.model.edit([new ModelEdit('deleteRange', [p - 1, 1])], {
selection: new ModelEditSelection(p - 1),
selections: [new ModelEditSelection(p - 1)],
});
}
}
Loading

0 comments on commit c888eb4

Please sign in to comment.