Skip to content

Commit

Permalink
Implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasArvidsson committed Nov 23, 2024
1 parent 8cd7c21 commit c59b75f
Show file tree
Hide file tree
Showing 16 changed files with 282 additions and 61 deletions.
7 changes: 6 additions & 1 deletion packages/common/src/ide/PassthroughIDEBase.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { GeneralizedRange } from "../types/GeneralizedRange";
import type { NotebookEditor } from "../types/NotebookEditor";
import type { TextDocument } from "../types/TextDocument";
import type { EditableTextEditor, TextEditor } from "../types/TextEditor";
import type { Capabilities } from "./types/Capabilities";
Expand All @@ -17,9 +18,9 @@ import type {
RunMode,
WorkspaceFolder,
} from "./types/ide.types";
import type { KeyValueStore } from "./types/KeyValueStore";
import type { Messages } from "./types/Messages";
import type { QuickPickOptions } from "./types/QuickPickOptions";
import type { KeyValueStore } from "./types/KeyValueStore";

export default class PassthroughIDEBase implements IDE {
configuration: Configuration;
Expand Down Expand Up @@ -123,6 +124,10 @@ export default class PassthroughIDEBase implements IDE {
return this.original.visibleTextEditors;
}

public get visibleNotebookEditors(): NotebookEditor[] {
return this.original.visibleNotebookEditors;
}

public get cursorlessVersion(): string {
return this.original.cursorlessVersion;
}
Expand Down
6 changes: 5 additions & 1 deletion packages/common/src/ide/fake/FakeIDE.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pull } from "lodash-es";
import type { EditableTextEditor, TextEditor } from "../..";
import type { EditableTextEditor, NotebookEditor, TextEditor } from "../..";
import type { GeneralizedRange } from "../../types/GeneralizedRange";
import type { TextDocument } from "../../types/TextDocument";
import type { TextDocumentChangeEvent } from "../types/Events";
Expand Down Expand Up @@ -82,6 +82,10 @@ export class FakeIDE implements IDE {
throw Error("Not implemented");
}

get visibleNotebookEditors(): NotebookEditor[] {
throw Error("Not implemented");
}

public getEditableTextEditor(_editor: TextEditor): EditableTextEditor {
throw Error("Not implemented");
}
Expand Down
10 changes: 8 additions & 2 deletions packages/common/src/ide/types/ide.types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { URI } from "vscode-uri";
import type {
EditableTextEditor,
InputBoxOptions,
NotebookEditor,
TextDocument,
TextEditor,
} from "../..";
import type { URI } from "vscode-uri";
import type { GeneralizedRange } from "../../types/GeneralizedRange";
import type { Capabilities } from "./Capabilities";
import type { Clipboard } from "./Clipboard";
Expand All @@ -16,9 +17,9 @@ import type {
TextEditorVisibleRangesChangeEvent,
} from "./events.types";
import type { FlashDescriptor } from "./FlashDescriptor";
import type { KeyValueStore } from "./KeyValueStore";
import type { Messages } from "./Messages";
import type { QuickPickOptions } from "./QuickPickOptions";
import type { KeyValueStore } from "./KeyValueStore";

export type RunMode = "production" | "development" | "test";
export type HighlightId = string;
Expand Down Expand Up @@ -79,6 +80,11 @@ export interface IDE {
*/
readonly visibleTextEditors: TextEditor[];

/**
* The currently visible notebook editors or an empty array.
*/
readonly visibleNotebookEditors: NotebookEditor[];

/**
* The capabilities of the IDE
*/
Expand Down
6 changes: 4 additions & 2 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ export * from "./ide/types/Clipboard";
export * from "./ide/types/CommandHistoryStorage";
export * from "./ide/types/CommandId";
export * from "./ide/types/Configuration";
export * from "./ide/types/events.types";
export * from "./ide/types/Events";
export * from "./ide/types/events.types";
export * from "./ide/types/FileSystem.types";
export * from "./ide/types/FlashDescriptor";
export * from "./ide/types/Hats";
export * from "./ide/types/HatStability";
export * from "./ide/types/hatStyles.types";
export * from "./ide/types/ide.types";
export * from "./ide/types/KeyValueStore";
export * from "./ide/types/Messages";
export * from "./ide/types/Paths";
export * from "./ide/types/QuickPickOptions";
export * from "./ide/types/RawTreeSitterQueryProvider";
export * from "./ide/types/KeyValueStore";
export * from "./ide/types/TutorialContentProvider";
export * from "./ide/util/messages";
export * from "./scopeSupportFacets/languageScopeSupport";
Expand Down Expand Up @@ -66,6 +66,8 @@ export * from "./types/Edit";
export * from "./types/GeneralizedRange";
export * from "./types/HatTokenMap";
export * from "./types/InputBoxOptions";
export * from "./types/NotebookCell";
export * from "./types/NotebookEditor";
export * from "./types/Position";
export * from "./types/Range";
export * from "./types/RangeExpansionBehavior";
Expand Down
32 changes: 32 additions & 0 deletions packages/common/src/types/NotebookCell.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { TextDocument } from "./TextDocument";

export interface NotebookCell {
/**
* The index of this cell in its containing notebook. The
* index is updated when a cell is moved within its notebook. The index is `-1`
* when the cell has been removed from its notebook.
*/
readonly index: number;

/**
* The kind of this cell.
*/
readonly kind: NotebookCellKind;

/**
* The {@link TextDocument} of this cell.
*/
readonly document: TextDocument;
}

export enum NotebookCellKind {
/**
* A markup-cell is formatted source that is used for display.
*/
Markup = 1,

/**
* A code-cell.
*/
Code = 2,
}
22 changes: 22 additions & 0 deletions packages/common/src/types/NotebookEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { URI } from "vscode-uri";
import type { NotebookCell } from "./NotebookCell";

export interface NotebookEditor {
/**
* The associated uri for this document.
*
* *Note* that most documents use the `file`-scheme, which means they are files on disk. However, **not** all documents are
* saved on disk and therefore the `scheme` must be checked before trying to access the underlying file or siblings on disk.
*/
readonly uri: URI;

/**
* The number of cells in the notebook.
*/
readonly cellCount: number;

/**
* The cells of this notebook.
*/
readonly cells: NotebookCell[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import type {
SimpleEveryScopeModifier,
} from "./modifiers/scopeTypeStages/LegacyContainingSyntaxScopeStage";
import { LegacyContainingSyntaxScopeStage } from "./modifiers/scopeTypeStages/LegacyContainingSyntaxScopeStage";
import { NotebookCellStage } from "./modifiers/scopeTypeStages/NotebookCellStage";

export class ModifierStageFactoryImpl implements ModifierStageFactory {
constructor(
Expand Down Expand Up @@ -129,8 +128,6 @@ export class ModifierStageFactoryImpl implements ModifierStageFactory {
modifier: ContainingScopeModifier | EveryScopeModifier,
): ModifierStage {
switch (modifier.scopeType.type) {
case "notebookCell":
return new NotebookCellStage(modifier);
case "collectionItem":
return new ItemStage(this.languageDefinitions, this, modifier);
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export function createContinuousRangeTarget(
includeStart: boolean,
includeEnd: boolean,
): Target {
if (startTarget.editor !== endTarget.editor) {
throw Error("Continuous targets must be in the same editor");
}

if (includeStart && includeEnd && isSameType(startTarget, endTarget)) {
const richTarget = startTarget.maybeCreateRichRangeTarget(
isReversed,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import {
Range,
type Direction,
type NotebookCell,
type Position,
type ScopeType,
type TextEditor,
} from "@cursorless/common";
import type { LanguageDefinitions } from "../../../languages/LanguageDefinitions";
import { ide } from "../../../singletons/ide.singleton";
import { NotebookCellTarget } from "../../targets";
import type { TargetScope } from "./scope.types";
import type {
ScopeHandler,
ScopeIteratorRequirements,
} from "./scopeHandler.types";

export class NotebookCellScopeHandler implements ScopeHandler {
public readonly scopeType = { type: "notebookCell" } as const;
public readonly iterationScopeType = { type: "document" } as const;
public readonly includeAdjacentInEvery = false;

constructor(
private languageDefinitions: LanguageDefinitions,
_scopeType: ScopeType,
private languageId: string,
) {}

*generateScopes(
editor: TextEditor,
position: Position,
direction: Direction,
hints: ScopeIteratorRequirements,
): Iterable<TargetScope> {
const scopeHandler = this.languageDefinitions
.get(this.languageId)
?.getScopeHandler(this.scopeType);

if (scopeHandler != null) {
yield* scopeHandler.generateScopeCandidates(
editor,
position,
direction,
hints,
);
}

const nb = getNotebook(editor);

if (nb == null) {
return;
}

const { notebook, cell } = nb;

if (hints.containment === "required") {
yield createTargetScope(cell);
return;
}

const cells = (() => {
if (
hints.containment === "disallowed" ||
hints.containment === "disallowedIfStrict"
) {
return direction === "forward"
? notebook.cells.slice(cell.index + 1)
: notebook.cells.slice(0, cell.index).reverse();
}
// Every scope
if (hints.distalPosition != null) {
const searchRange = new Range(position, hints.distalPosition);
if (searchRange.isRangeEqual(editor.document.range)) {
return notebook.cells;
}
}
return direction === "forward"
? notebook.cells.slice(cell.index)
: notebook.cells.slice(0, cell.index + 1).reverse();
})();

for (const cell of cells) {
yield createTargetScope(cell);
}
}
}

function createTargetScope(cell: NotebookCell): TargetScope {
const editor = getEditor(cell);
const contentRange = editor.document.range;
return {
editor,
domain: contentRange,
getTargets: (isReversed: boolean) => [
new NotebookCellTarget({
editor,
isReversed,
contentRange,
}),
],
};
}

function getNotebook(editor: TextEditor) {
const uri = editor.document.uri.toString();
for (const notebook of ide().visibleNotebookEditors) {
for (const cell of notebook.cells) {
if (cell.document.uri.toString() === uri) {
return { notebook, cell };
}
}
}
return undefined;
}

function getEditor(cell: NotebookCell) {
for (const editor of ide().visibleTextEditors) {
if (editor.document.uri.toString() === cell.document.uri.toString()) {
return editor;
}
}
throw new Error("Editor not found notebook cell");
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CharacterScopeHandler } from "./CharacterScopeHandler";
import { DocumentScopeHandler } from "./DocumentScopeHandler";
import { IdentifierScopeHandler } from "./IdentifierScopeHandler";
import { LineScopeHandler } from "./LineScopeHandler";
import { NotebookCellScopeHandler } from "./NotebookCellScopeHandler";
import { OneOfScopeHandler } from "./OneOfScopeHandler";
import { ParagraphScopeHandler } from "./ParagraphScopeHandler";
import {
Expand Down Expand Up @@ -103,6 +104,12 @@ export class ScopeHandlerFactoryImpl implements ScopeHandlerFactory {
scopeType,
languageId,
);
case "notebookCell":
return new NotebookCellScopeHandler(
this.languageDefinitions,
scopeType,
languageId,
);
case "custom":
return scopeType.scopeHandler;
case "instance":
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
InputBoxOptions,
Listener,
Messages,
NotebookEditor,
OpenUntitledTextDocumentOptions,
QuickPickOptions,
RunMode,
Expand Down Expand Up @@ -80,6 +81,10 @@ export class TalonJsIDE implements IDE {
return this.editors;
}

get visibleNotebookEditors(): NotebookEditor[] {
return [];
}

getEditableTextEditor(editor: TextEditor): EditableTextEditor {
if (editor instanceof TalonJsEditor) {
return editor;
Expand Down
Loading

0 comments on commit c59b75f

Please sign in to comment.