/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Emitter } from '../../../base/common/event.js'; import { Disposable } from '../../../base/common/lifecycle.js'; import { Range } from '../../common/core/range.js'; export class GhostText { constructor(lineNumber, parts, additionalReservedLineCount = 0) { this.lineNumber = lineNumber; this.parts = parts; this.additionalReservedLineCount = additionalReservedLineCount; } renderForScreenReader(lineText) { if (this.parts.length === 0) { return ''; } const lastPart = this.parts[this.parts.length - 1]; const cappedLineText = lineText.substr(0, lastPart.column - 1); const text = applyEdits(cappedLineText, this.parts.map(p => ({ range: { startLineNumber: 1, endLineNumber: 1, startColumn: p.column, endColumn: p.column }, text: p.lines.join('\n') }))); return text.substring(this.parts[0].column - 1); } } class PositionOffsetTransformer { constructor(text) { this.lineStartOffsetByLineIdx = []; this.lineStartOffsetByLineIdx.push(0); for (let i = 0; i < text.length; i++) { if (text.charAt(i) === '\n') { this.lineStartOffsetByLineIdx.push(i + 1); } } } getOffset(position) { return this.lineStartOffsetByLineIdx[position.lineNumber - 1] + position.column - 1; } } function applyEdits(text, edits) { const transformer = new PositionOffsetTransformer(text); const offsetEdits = edits.map(e => { const range = Range.lift(e.range); return ({ startOffset: transformer.getOffset(range.getStartPosition()), endOffset: transformer.getOffset(range.getEndPosition()), text: e.text }); }); offsetEdits.sort((a, b) => b.startOffset - a.startOffset); for (const edit of offsetEdits) { text = text.substring(0, edit.startOffset) + edit.text + text.substring(edit.endOffset); } return text; } export class GhostTextPart { constructor(column, lines, /** * Indicates if this part is a preview of an inline suggestion when a suggestion is previewed. */ preview) { this.column = column; this.lines = lines; this.preview = preview; } } export class BaseGhostTextWidgetModel extends Disposable { constructor(editor) { super(); this.editor = editor; this._expanded = undefined; this.onDidChangeEmitter = new Emitter(); this.onDidChange = this.onDidChangeEmitter.event; this._register(editor.onDidChangeConfiguration((e) => { if (e.hasChanged(105 /* suggest */) && this._expanded === undefined) { this.onDidChangeEmitter.fire(); } })); } setExpanded(expanded) { this._expanded = true; this.onDidChangeEmitter.fire(); } }