Skip to content

Commit

Permalink
Dispose of decorations (#307)
Browse files Browse the repository at this point in the history
* Dispose of decorations

* Ad more documentation

* Remove extra spaces
  • Loading branch information
pokey committed Nov 8, 2021
1 parent 6543066 commit a6bdb3a
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 49 deletions.
20 changes: 14 additions & 6 deletions src/core/Decorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
DEFAULT_HAT_HEIGHT_EM,
DEFAULT_VERTICAL_OFFSET_EM,
} from "./shapeAdjustments";
import { Graph } from "../typings/Types";

export type DecorationMap = {
[k in HatStyleName]?: vscode.TextEditorDecorationType;
Expand All @@ -35,11 +36,9 @@ export default class Decorations {
hatStyleMap!: Record<HatStyleName, HatStyle>;
hatStyleNames!: HatStyleName[];

constructor(
fontMeasurements: FontMeasurements,
private extensionPath: string
) {
this.constructDecorations(fontMeasurements);
constructor(private graph: Graph) {
this.constructDecorations(graph.fontMeasurements);
graph.extensionContext.subscriptions.push(this);
}

destroyDecorations() {
Expand Down Expand Up @@ -209,7 +208,12 @@ export default class Decorations {
scaleFactor: number,
hatVerticalOffsetEm: number
) {
const iconPath = join(this.extensionPath, "images", "hats", `${shape}.svg`);
const iconPath = join(
this.graph.extensionContext.extensionPath,
"images",
"hats",
`${shape}.svg`
);
const rawSvg = readFileSync(iconPath, "utf8");
const { characterWidth, characterHeight, fontSize } = fontMeasurements;

Expand Down Expand Up @@ -272,4 +276,8 @@ export default class Decorations {

return { originalViewBoxHeight, originalViewBoxWidth };
}

dispose() {
this.destroyDecorations();
}
}
9 changes: 5 additions & 4 deletions src/core/FontMeasurements.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as vscode from "vscode";
import { Graph } from "../typings/Types";

/**
* Contains measurements for the user's font
Expand All @@ -17,24 +18,24 @@ export default class FontMeasurements {
*/
characterHeight!: number;

constructor(private context: vscode.ExtensionContext) {}
constructor(private graph: Graph) {}

clearCache() {
this.context.globalState.update("fontRatios", undefined);
this.graph.extensionContext.globalState.update("fontRatios", undefined);
}

async calculate() {
const fontFamily = getFontFamily();
let widthRatio, heightRatio;
let fontRatiosCache = this.context.globalState.get<{
let fontRatiosCache = this.graph.extensionContext.globalState.get<{
widthRatio: number;
heightRatio: number;
fontFamily: string;
}>("fontRatios");

if (fontRatiosCache == null || fontRatiosCache.fontFamily !== fontFamily) {
const fontRatios = await getFontRatios();
this.context.globalState.update("fontRatios", {
this.graph.extensionContext.globalState.update("fontRatios", {
...fontRatios,
fontFamily,
});
Expand Down
51 changes: 37 additions & 14 deletions src/core/editStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import {
DecorationRangeBehavior,
window,
} from "vscode";
import { Graph } from "../typings/Types";

export class EditStyle {
token: TextEditorDecorationType;
line: TextEditorDecorationType;

constructor(colorName: string) {
constructor(colorName: EditStyleThemeColorName) {
const options = {
backgroundColor: new ThemeColor(`cursorless.${colorName}`),
rangeBehavior: DecorationRangeBehavior.ClosedClosed,
Expand All @@ -20,20 +21,42 @@ export class EditStyle {
isWholeLine: true,
});
}

dispose() {
this.token.dispose();
this.line.dispose();
}
}

export class EditStyles {
pendingDelete: EditStyle;
referenced: EditStyle;
pendingModification0: EditStyle;
pendingModification1: EditStyle;
justAdded: EditStyle;

constructor() {
this.pendingDelete = new EditStyle("pendingDeleteBackground");
this.justAdded = new EditStyle("justAddedBackground");
this.referenced = new EditStyle("referencedBackground");
this.pendingModification0 = new EditStyle("pendingModification0Background");
this.pendingModification1 = new EditStyle("pendingModification1Background");
const EDIT_STYLE_NAMES = [
"pendingDelete",
"referenced",
"pendingModification0",
"pendingModification1",
"justAdded",
] as const;

type EditStyleName = typeof EDIT_STYLE_NAMES[number];
type EditStyleThemeColorName = `${EditStyleName}Background`;

export class EditStyles implements Record<EditStyleName, EditStyle> {
pendingDelete!: EditStyle;
referenced!: EditStyle;
pendingModification0!: EditStyle;
pendingModification1!: EditStyle;
justAdded!: EditStyle;

constructor(graph: Graph) {
EDIT_STYLE_NAMES.forEach((editStyleName) => {
this[editStyleName] = new EditStyle(`${editStyleName}Background`);
});

graph.extensionContext.subscriptions.push(this);
}

dispose() {
EDIT_STYLE_NAMES.forEach((editStyleName) => {
this[editStyleName].dispose();
});
}
}
28 changes: 9 additions & 19 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,34 @@
import * as vscode from "vscode";
import { addDecorationsToEditors } from "./util/addDecorationsToEditor";
import { DECORATION_DEBOUNCE_DELAY } from "./core/constants";
import Decorations from "./core/Decorations";
import graphFactories from "./util/graphFactories";
import inferFullTargets from "./core/inferFullTargets";
import processTargets from "./processTargets";
import FontMeasurements from "./core/FontMeasurements";
import {
ActionType,
Graph,
PartialTarget,
ProcessedTargetsContext,
} from "./typings/Types";
import { Graph, PartialTarget, ProcessedTargetsContext } from "./typings/Types";
import makeGraph, { FactoryMap } from "./util/makeGraph";
import { logBranchTypes } from "./util/debug";
import { TestCase } from "./testUtil/TestCase";
import { ThatMark } from "./core/ThatMark";
import { TestCaseRecorder } from "./testUtil/TestCaseRecorder";
import { getParseTreeApi } from "./util/getExtensionApi";
import { canonicalizeAndValidateCommand } from "./util/canonicalizeAndValidateCommand";
import canonicalizeActionName from "./util/canonicalizeActionName";

export async function activate(context: vscode.ExtensionContext) {
const fontMeasurements = new FontMeasurements(context);
await fontMeasurements.calculate();
const decorations = new Decorations(fontMeasurements, context.extensionPath);

const { getNodeAtLocation } = await getParseTreeApi();

var isActive = vscode.workspace
.getConfiguration("cursorless")
.get<boolean>("showOnStart")!;

function clearEditorDecorations(editor: vscode.TextEditor) {
decorations.decorations.forEach(({ decoration }) => {
graph.decorations.decorations.forEach(({ decoration }) => {
editor.setDecorations(decoration, []);
});
}

function addDecorations() {
if (isActive) {
addDecorationsToEditors(graph.navigationMap, decorations);
addDecorationsToEditors(graph.navigationMap, graph.decorations);
} else {
vscode.window.visibleTextEditors.forEach(clearEditorDecorations);
graph.navigationMap.clear();
Expand Down Expand Up @@ -72,7 +60,7 @@ export async function activate(context: vscode.ExtensionContext) {
const recomputeDecorationStylesDisposable = vscode.commands.registerCommand(
"cursorless.recomputeDecorationStyles",
() => {
fontMeasurements.clearCache();
graph.fontMeasurements.clearCache();
recomputeDecorationStyles();
}
);
Expand All @@ -82,6 +70,8 @@ export async function activate(context: vscode.ExtensionContext) {
extensionContext: () => context,
} as FactoryMap<Graph>);
graph.snippets.init();
await graph.fontMeasurements.calculate();

const thatMark = new ThatMark();
const sourceMark = new ThatMark();
const testCaseRecorder = new TestCaseRecorder(context);
Expand Down Expand Up @@ -248,9 +238,9 @@ export async function activate(context: vscode.ExtensionContext) {
}

const recomputeDecorationStyles = async () => {
decorations.destroyDecorations();
await fontMeasurements.calculate();
decorations.constructDecorations(fontMeasurements);
graph.decorations.destroyDecorations();
await graph.fontMeasurements.calculate();
graph.decorations.constructDecorations(graph.fontMeasurements);
addDecorations();
};

Expand Down
23 changes: 23 additions & 0 deletions src/typings/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import NavigationMap from "../core/NavigationMap";
import { Snippets } from "../core/Snippets";
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
import { FullRangeInfo } from "./updateSelections";
import Decorations from "../core/Decorations";
import FontMeasurements from "../core/FontMeasurements";

/**
* A token within a text editor, including the current display line of the token
Expand Down Expand Up @@ -46,6 +48,7 @@ export interface LineNumberPosition {
lineNumber: number;
isRelative: boolean;
}

export interface LineNumber {
type: "lineNumber";
anchor: LineNumberPosition;
Expand All @@ -60,6 +63,7 @@ export type Mark =
// | LastCursorPosition Not implemented yet
| DecoratedSymbol
| LineNumber;

export type Delimiter =
| "angleBrackets"
| "backtickQuotes"
Expand Down Expand Up @@ -97,19 +101,22 @@ export type ScopeType =
| "xmlElement"
| "xmlEndTag"
| "xmlStartTag";

export type SubTokenType = "word" | "character";

export interface SurroundingPairModifier {
type: "surroundingPair";
delimiter: Delimiter | null;
delimitersOnly: boolean;
}

export interface ContainingScopeModifier {
type: "containingScope";
scopeType: ScopeType;
valueOnly?: boolean;
includeSiblings?: boolean;
}

export interface SubTokenModifier {
type: "subpiece";
pieceType: SubTokenType;
Expand All @@ -118,15 +125,19 @@ export interface SubTokenModifier {
excludeAnchor?: boolean;
excludeActive?: boolean;
}

export interface MatchingPairSymbolModifier {
type: "matchingPairSymbol";
}

export interface IdentityModifier {
type: "identity";
}

export interface HeadModifier {
type: "head";
}

export interface TailModifier {
type: "tail";
}
Expand All @@ -143,7 +154,9 @@ export type Modifier =
export type SelectionType =
// | "character" Not implemented
"token" | "line" | "notebookCell" | "paragraph" | "document";

export type Position = "before" | "after" | "contents";

export type InsideOutsideType = "inside" | "outside" | null;

export interface PartialPrimitiveTarget {
Expand Down Expand Up @@ -354,6 +367,16 @@ export interface Graph {
* as the document changes
*/
readonly rangeUpdater: RangeUpdater;

/**
* Responsible for all the hat styles
*/
readonly decorations: Decorations;

/**
* Takes measurements of the user's font
*/
readonly fontMeasurements: FontMeasurements;
}

export type NodeMatcherValue = {
Expand Down
27 changes: 21 additions & 6 deletions src/util/graphFactories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,28 @@ import { FactoryMap } from "./makeGraph";
import NavigationMap from "../core/NavigationMap";
import { Snippets } from "../core/Snippets";
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
import Decorations from "../core/Decorations";
import FontMeasurements from "../core/FontMeasurements";

const graphFactories: Partial<FactoryMap<Graph>> = {
actions: (graph: Graph) => new Actions(graph),
editStyles: () => new EditStyles(),
navigationMap: (graph: Graph) => new NavigationMap(graph),
snippets: (graph: Graph) => new Snippets(graph),
rangeUpdater: (graph: Graph) => new RangeUpdater(graph),
type ConstructorMap<T> = {
[P in keyof T]: new (t: T) => T[P];
};

const graphConstructors: Partial<ConstructorMap<Graph>> = {
actions: Actions,
editStyles: EditStyles,
navigationMap: NavigationMap,
decorations: Decorations,
fontMeasurements: FontMeasurements,
snippets: Snippets,
rangeUpdater: RangeUpdater,
};

const graphFactories: Partial<FactoryMap<Graph>> = Object.fromEntries(
Object.entries(graphConstructors).map(([key, constructor]) => [
key,
(graph: Graph) => new constructor(graph),
])
);

export default graphFactories;

0 comments on commit a6bdb3a

Please sign in to comment.