vscode#DecorationOptions TypeScript Examples

The following examples show how to use vscode#DecorationOptions. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: decoration-utils.ts    From vscode-code-review with MIT License 7 votes vote down vote up
/**
   * Highlight a matching review comment with decorations an underline decoration
   *
   * @param csvEntries The selection to highlight
   * @param editor The editor to work on
   * @return all highlighting decorations
   */
  underlineDecoration(csvEntries: CsvEntry[], editor: TextEditor): void {
    const decorationOptions: DecorationOptions[] = [];

    // build decoration options for each comment block
    csvEntries.forEach((entry) => {
      // iterate over multi-selections
      rangesFromStringDefinition(entry.lines).forEach((range: Range) => {
        decorationOptions.push({ range });
      });
    });

    editor.setDecorations(this.decorationDeclarationType, decorationOptions);
  }
Example #2
Source File: decoration-utils.ts    From vscode-code-review with MIT License 7 votes vote down vote up
/**
   * Highlight a matching review comment with an icon next to the start of the selection on the right
   *
   * @param csvEntries The selection to highlight
   * @param editor The editor to work on
   * @return all highlighting decorations
   */
  commentIconDecoration(csvEntries: CsvEntry[], editor: TextEditor): void {
    const decorationOptions: DecorationOptions[] = [];

    // build decoration options for each comment block
    csvEntries.forEach((entry) => {
      // iterate over multi-selections
      rangesFromStringDefinition(entry.lines).forEach((range: Range) => {
        decorationOptions.push({
          range: new Range(
            new Position(range.start.line, EDITOR_MAX_LETTER),
            new Position(range.start.line, EDITOR_MAX_LETTER),
          ),
        });
      });
    });
    editor.setDecorations(this.commentDecorationType, decorationOptions);
  }
Example #3
Source File: counterExamplesView.ts    From ide-vscode with MIT License 6 votes vote down vote up
private static createDecorator(counterExample: ICounterExampleItem): DecorationOptions {
    const contentText = Object.entries(counterExample.variables)
      .map(([ name, value ]) => `${name} = ${value}`)
      .join(' ');
    // TODO earlier versions showed a warning that there are references present.
    const line = counterExample.position.line;
    return {
      range: new Range(
        new Position(line, counterExample.position.character + 1),
        new Position(line, Number.MAX_VALUE)
      ),
      renderOptions: {
        after: { contentText }
      }
    };
  }
Example #4
Source File: LineHistory.ts    From vscode-realtime-debugging with GNU General Public License v3.0 6 votes vote down vote up
private updateDecorations() {
		for (const editor of window.visibleTextEditors) {
			const entry = this.map.get(editor.document.uri.toString());
			if (!entry) {
				editor.setDecorations(this.decorationType, []);
				continue;
			}

			editor.setDecorations(
				this.decorationType,
				[...entry.lines.values()].map((history) => {
					const range = editor.document.lineAt(history.line).range;
					const hoverMessage = new MarkdownString();
					hoverMessage.isTrusted = true;
					for (const h of history.history.slice().reverse()) {
						hoverMessage.appendMarkdown(`* ${h}`);
					}
					/*const params = encodeURIComponent(
						JSON.stringify({ stepId: o.id } as RunCmdIdArgs)
					);*/
					/*hoverMessage.appendMarkdown(
						`* [Run Step '${o.id}'](command:${runCmdId}?${params})`
					);*/

					return {
						range,
						renderOptions: {
							after: {
								contentText: history.history[0],
							},
						},
						hoverMessage,
					} as DecorationOptions;
				})
			);
		}
	}
Example #5
Source File: annotationProvider.ts    From vscode-inline-parameters with MIT License 6 votes vote down vote up
public static parameterAnnotation(
        message: string,
        range: Range
    ): DecorationOptions {
        return {
            range,
            renderOptions: {
                before: {
                    contentText: message,
                    color: new ThemeColor("inlineparameters.annotationForeground"),
                    backgroundColor: new ThemeColor("inlineparameters.annotationBackground"),
                    fontStyle: workspace.getConfiguration("inline-parameters").get("fontStyle"),
                    fontWeight: workspace.getConfiguration("inline-parameters").get("fontWeight"),
                    textDecoration: `;
                        font-size: ${workspace.getConfiguration("inline-parameters").get("fontSize")};
                        margin: ${workspace.getConfiguration("inline-parameters").get("margin")};
                        padding: ${workspace.getConfiguration("inline-parameters").get("padding")};
                        border-radius: ${workspace.getConfiguration("inline-parameters").get("borderRadius")};
                        border: ${workspace.getConfiguration("inline-parameters").get("border")};
                        vertical-align: middle;
                    `,
                },
            } as DecorationInstanceRenderOptions,
        } as DecorationOptions
    }
Example #6
Source File: decoration-utils.test.ts    From vscode-code-review with MIT License 5 votes vote down vote up
suite('Decoration Utils', () => {
  let editorStub: TextEditor;
  let lastSetDecorationConf: TextEditorDecorationType | undefined;
  let lastSetDecorationSelection!: Selection[] | DecorationOptions[] | undefined;
  beforeEach(() => {
    editorStub = ({
      selections: [new Selection(new Position(0, 1), new Position(2, 6))],
      setDecorations: (conf: TextEditorDecorationType, selection: Selection[]) => {
        lastSetDecorationConf = conf;
        lastSetDecorationSelection = selection;
      },
    } as unknown) as TextEditor;
  });

  afterEach(() => {
    lastSetDecorationConf = undefined;
    lastSetDecorationSelection = undefined;
  });

  suite('underlineDecoration', () => {
    test('should underline comments', () => {
      const contextStub = {
        asAbsolutePath: (p) => p,
      } as ExtensionContext;
      const deco = new Decorations(contextStub);

      const csvEntries = [{ lines: '1:0-3:4|9:0-11:3' } as CsvEntry, { lines: '17:3-19:2' } as CsvEntry];
      const decoration = deco.underlineDecoration(csvEntries, editorStub);
      const decorationOptions = lastSetDecorationSelection as DecorationOptions[];

      assert.ok(deco);
      assert.deepStrictEqual(lastSetDecorationConf, deco.decorationDeclarationType);

      assert.strictEqual(decorationOptions[0].range.start.line, 0);
      assert.strictEqual(decorationOptions[0].range.start.character, 0);
      assert.strictEqual(decorationOptions[0].range.end.line, 2);
      assert.strictEqual(decorationOptions[0].range.end.character, 4);

      assert.strictEqual(decorationOptions[1].range.start.line, 8);
      assert.strictEqual(decorationOptions[1].range.start.character, 0);
      assert.strictEqual(decorationOptions[1].range.end.line, 10);
      assert.strictEqual(decorationOptions[1].range.end.character, 3);

      assert.strictEqual(decorationOptions[2].range.start.line, 16);
      assert.strictEqual(decorationOptions[2].range.start.character, 3);
      assert.strictEqual(decorationOptions[2].range.end.line, 18);
      assert.strictEqual(decorationOptions[2].range.end.character, 2);
    });
  });

  suite('commentIconDecoration', () => {
    test('should underline comments', () => {
      const contextStub = {
        asAbsolutePath: (p) => p,
      } as ExtensionContext;
      const deco = new Decorations(contextStub);

      const csvEntries = [{ lines: '1:0-3:4|9:0-11:3' } as CsvEntry, { lines: '17:3-19:2' } as CsvEntry];
      const decoration = deco.commentIconDecoration(csvEntries, editorStub);
      const decorationOptions = lastSetDecorationSelection as DecorationOptions[];

      assert.ok(deco);
      assert.deepStrictEqual(lastSetDecorationConf, deco.commentDecorationType);

      assert.strictEqual(decorationOptions[0].range.start.line, 0);
      assert.strictEqual(decorationOptions[0].range.start.character, 1024);
      assert.strictEqual(decorationOptions[0].range.end.line, 0);
      assert.strictEqual(decorationOptions[0].range.end.character, 1024);

      assert.strictEqual(decorationOptions[1].range.start.line, 8);
      assert.strictEqual(decorationOptions[1].range.start.character, 1024);
      assert.strictEqual(decorationOptions[1].range.end.line, 8);
      assert.strictEqual(decorationOptions[1].range.end.character, 1024);

      assert.strictEqual(decorationOptions[2].range.start.line, 16);
      assert.strictEqual(decorationOptions[2].range.start.character, 1024);
      assert.strictEqual(decorationOptions[2].range.end.line, 16);
      assert.strictEqual(decorationOptions[2].range.end.character, 1024);
    });
  });

  suite('colorizedBackgroundDecoration', () => {
    test('should colorize the given selection with decoration', () => {
      const selections = [new Range(new Position(2, 5), new Position(2, 5))];
      const decoration = colorizedBackgroundDecoration(selections, editorStub, '#fdfdfd');
      assert.ok(decoration);
      assert.deepStrictEqual(lastSetDecorationConf, decoration);
      assert.deepStrictEqual(lastSetDecorationSelection, selections);
    });
  });
});
Example #7
Source File: ghostDiagnosticsView.ts    From ide-vscode with MIT License 5 votes vote down vote up
private static createDecorator(diagnostic: Diagnostic): DecorationOptions {
    return {
      range: toVsRange(diagnostic.range),
      hoverMessage: diagnostic.message
    };
  }
Example #8
Source File: windowDecorations.ts    From dendron with GNU Affero General Public License v3.0 4 votes vote down vote up
// see [[Decorations|dendron://dendron.docs/pkg.plugin-core.ref.decorations]] for further docs
export async function updateDecorations(editor: TextEditor): Promise<{
  allDecorations?: Map<TextEditorDecorationType, DecorationOptions[]>;
  allWarnings?: Diagnostic[];
}> {
  try {
    const ctx = "updateDecorations";
    const engine = ExtensionProvider.getEngine();
    if (
      ConfigUtils.getWorkspace(engine.config).enableEditorDecorations === false
    ) {
      // Explicitly disabled, stop here.
      return {};
    }

    // Only show decorations & warnings for notes
    let note: NoteProps | undefined;
    try {
      note = ExtensionProvider.getWSUtils().getNoteFromDocument(
        editor.document
      );
      if (_.isUndefined(note)) return {};
    } catch (error) {
      Logger.info({
        ctx,
        msg: "Unable to check if decorations should be updated",
        error,
      });
      return {};
    }
    // Only decorate visible ranges, of which there could be multiple if the document is open in multiple tabs
    const inputRanges = VSCodeUtils.mergeOverlappingRanges(
      editor.visibleRanges.map((range) =>
        VSCodeUtils.padRange({
          range,
          padding: VISIBLE_RANGE_MARGIN,
          zeroCharacter: true,
        })
      )
    );

    const ranges = inputRanges.map((range) => {
      return {
        range: VSCodeUtils.toPlainRange(range),
        text: editor.document.getText(range),
      };
    });
    const out = await engine.getDecorations({
      id: note.id,
      ranges,
      text: editor.document.getText(),
    });

    if (
      debouncedUpdateDecorations.states.get(
        updateDecorationsKeyFunction(editor)
      ) === "trailing"
    ) {
      // There's another execution that has already been called after this was
      // run. That means these results are stale. If existing lines have shifted
      // up or down since this function execution was started, setting the
      // decorations now will place the decorations at bad positions in the
      // document. On the other hand, if we do nothing VSCode will smartly move
      // those decorations to their new locations. With another execution
      // already scheduled, it's better to just wait for those decorations to
      // come in.
      return {};
    }
    const { data, error } = out;
    Logger.info({
      ctx,
      payload: {
        error,
        decorationsLength: data?.decorations?.length,
        diagnosticsLength: data?.diagnostics?.length,
      },
    });

    const vscodeDecorations = data?.decorations
      ?.map(mapDecoration)
      .filter(isNotUndefined);
    if (vscodeDecorations === undefined) return {};
    const activeDecorations = mapValues(
      groupBy(vscodeDecorations, (decoration) => decoration.type),
      (decorations) => decorations.map((item) => item.decoration)
    );

    for (const [type, decorations] of activeDecorations.entries()) {
      editor.setDecorations(type, decorations);
    }

    // Clear out any old decorations left over from last pass
    for (const type of _.values(EDITOR_DECORATION_TYPES)) {
      if (!activeDecorations.has(type)) {
        editor.setDecorations(type, []);
      }
    }

    const allWarnings =
      data?.diagnostics?.map((diagnostic) => {
        const diagnosticObject = new Diagnostic(
          VSCodeUtils.toRangeObject(diagnostic.range),
          diagnostic.message,
          diagnostic.severity
        );
        diagnosticObject.code = diagnostic.code;
        return diagnosticObject;
      }) || [];
    delayedFrontmatterWarning(editor.document.uri, allWarnings);

    return {
      allDecorations: activeDecorations,
      allWarnings,
    };
  } catch (err) {
    Sentry.captureException(err);
    throw err;
  }
}
Example #9
Source File: decorations.ts    From vscode-todo-md with MIT License 4 votes vote down vote up
/**
 * Actually update the editor decorations
 */
export function doUpdateEditorDecorations(editor: TextEditor) {
	const completedDecorationRanges: Range[] = [];
	const tagsDecorationOptions: DecorationOptions[] = [];
	const priorityADecorationRanges: Range[] = [];
	const priorityBDecorationRanges: Range[] = [];
	const priorityCDecorationRanges: Range[] = [];
	const priorityDDecorationRanges: Range[] = [];
	const priorityEDecorationRanges: Range[] = [];
	const priorityFDecorationRanges: Range[] = [];
	const tagsDelimiterDecorationRanges: Range[] = [];
	const tagWithDelimiterDecorationRanges: Range[] = [];
	const specialtagDecorationRanges: Range[] = [];
	const projectDecorationRanges: Range[] = [];
	const contextDecorationRanges: Range[] = [];
	const notDueDecorationRanges: Range[] = [];
	const dueDecorationRanges: Range[] = [];
	const overdueDecorationOptions: DecorationOptions[] = [];
	const invalidDueDateDecorationRanges: Range[] = [];
	const closestDueDateDecorationOptions: DecorationOptions[] = [];
	const nestedTasksDecorationOptions: DecorationOptions[] = [];
	const nestedTasksPieOptions: DecorationOptions[] = [];

	forEachTask(task => {
		// When decoration have `isWholeLine` range can be empty / wouldn't matter
		const emptyRange = new Range(task.lineNumber, 0, task.lineNumber, 0);// TODO: move outside?
		if (task.done) {
			completedDecorationRanges.push(emptyRange);
		}
		if (task.tagsRange) {
			if (!Global.userSpecifiedAdvancedTagDecorations) {
				for (let i = 0; i < task.tags.length; i++) {
					let contentText: string | undefined = undefined;
					if ($config.tagCounterBadgeEnabled) {
						contentText = String($state.tagsForTreeView.find(tag => tag.title === task.tags[i])?.tasks.length || '');
					}
					tagsDecorationOptions.push({
						range: task.tagsRange[i],
						renderOptions: {
							after: {
								contentText,
							},
						},
					});
				}
				tagsDelimiterDecorationRanges.push(...task.tagsDelimiterRanges!);// if `tagsRange` exists - `tagsDelimiterRanges` also exists
			} else {
				// User has advanced decorations. Include tag symbol in decoration range.
				tagWithDelimiterDecorationRanges.push(...task.tagsRange.map(range => new Range(range.start.line, range.start.character - 1, range.end.line, range.end.character)));
			}
		}
		if (task.priorityRange) {
			switch (task.priority) {
				case 'A': priorityADecorationRanges.push(task.priorityRange); break;
				case 'B': priorityBDecorationRanges.push(task.priorityRange); break;
				case 'C': priorityCDecorationRanges.push(task.priorityRange); break;
				case 'D': priorityDDecorationRanges.push(task.priorityRange); break;
				case 'E': priorityEDecorationRanges.push(task.priorityRange); break;
				default: priorityFDecorationRanges.push(task.priorityRange);
			}
		}
		if (task.specialTagRanges.length) {
			specialtagDecorationRanges.push(...task.specialTagRanges);
		}
		if (task.contextRanges && task.contextRanges.length) {
			contextDecorationRanges.push(...task.contextRanges);
		}
		if (task.projectRanges && task.projectRanges.length) {
			projectDecorationRanges.push(...task.projectRanges);
		}
		if (task.due) {
			const due = task.due;
			const dueRange = task.dueRange!;// if due exists - dueRange exists too
			if (due.isDue === DueState.Due) {
				dueDecorationRanges.push(dueRange);
			} else if (due.isDue === DueState.NotDue) {
				notDueDecorationRanges.push(dueRange);
			} else if (due.isDue === DueState.Overdue) {
				overdueDecorationOptions.push({
					range: dueRange,
					renderOptions: {
						after: {
							contentText: `${due.overdueInDays}d`,
						},
					},
				});
				if (task.overdueRange) {
					specialtagDecorationRanges.push(task.overdueRange);
				}
			} else if (due.isDue === DueState.Invalid) {
				invalidDueDateDecorationRanges.push(dueRange);
			}
			if (due.isDue === DueState.NotDue && due.closestDueDateInTheFuture) {
				closestDueDateDecorationOptions.push({
					range: dueRange,
					renderOptions: {
						after: {
							contentText: makeClosestDueDateDecoration(task),
						},
					},
				});
			}
		}
		if (task.subtasks.length) {
			let numberOfSubtasks = 0;
			let numberOfCompletedSubtasks = 0;
			forEachTask(subtask => {
				numberOfSubtasks++;
				if (subtask.done) {
					numberOfCompletedSubtasks++;
				}
			}, task.subtasks);
			nestedTasksDecorationOptions.push({
				range: emptyRange,
				renderOptions: {
					after: {
						contentText: `${numberOfCompletedSubtasks}/${numberOfSubtasks}`,
					},
				},
			});
			nestedTasksPieOptions.push({
				range: emptyRange,
				renderOptions: {
					after: {
						contentIconPath: svgToUri(createPieProgressSvg($state.editorLineHeight, numberOfCompletedSubtasks, numberOfSubtasks)),
					},
				},
			});
		}
	});

	editor.setDecorations(Global.completedTaskDecorationType, completedDecorationRanges);
	editor.setDecorations(Global.tagsDecorationType, tagsDecorationOptions);
	editor.setDecorations(Global.tagWithDelimiterDecorationType, tagWithDelimiterDecorationRanges);
	editor.setDecorations(Global.tagsDelimiterDecorationType, tagsDelimiterDecorationRanges);
	editor.setDecorations(Global.specialTagDecorationType, specialtagDecorationRanges);
	editor.setDecorations(Global.priorityADecorationType, priorityADecorationRanges);
	editor.setDecorations(Global.priorityBDecorationType, priorityBDecorationRanges);
	editor.setDecorations(Global.priorityCDecorationType, priorityCDecorationRanges);
	editor.setDecorations(Global.priorityDDecorationType, priorityDDecorationRanges);
	editor.setDecorations(Global.priorityEDecorationType, priorityEDecorationRanges);
	editor.setDecorations(Global.priorityFDecorationType, priorityFDecorationRanges);
	editor.setDecorations(Global.projectDecorationType, projectDecorationRanges);
	editor.setDecorations(Global.contextDecorationType, contextDecorationRanges);
	editor.setDecorations(Global.notDueDecorationType, notDueDecorationRanges);
	editor.setDecorations(Global.dueDecorationType, dueDecorationRanges);
	editor.setDecorations(Global.overdueDecorationType, overdueDecorationOptions);
	editor.setDecorations(Global.invalidDueDateDecorationType, invalidDueDateDecorationRanges);
	editor.setDecorations(Global.closestDueDateDecorationType, closestDueDateDecorationOptions);
	editor.setDecorations(Global.nestedTasksCountDecorationType, nestedTasksDecorationOptions);
	editor.setDecorations(Global.nestedTasksPieDecorationType, nestedTasksPieOptions);
	editor.setDecorations(Global.commentDecorationType, $state.commentLines);
}