mirror of
https://github.com/microsoft/vscode.git
synced 2026-06-02 13:45:52 +01:00
Merge pull request #279680 from microsoft/benibenj/young-jaguar
Improve rename handling in inline edits
This commit is contained in:
@@ -51,6 +51,7 @@ import { StringReplacement } from '../../../../common/core/edits/stringEdit.js';
|
||||
import { OffsetRange } from '../../../../common/core/ranges/offsetRange.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { IDefaultAccountService } from '../../../../../platform/defaultAccount/common/defaultAccount.js';
|
||||
import { ModifierKeyEmitter } from '../../../../../base/browser/dom.js';
|
||||
|
||||
export class InlineCompletionsModel extends Disposable {
|
||||
private readonly _source;
|
||||
@@ -630,7 +631,7 @@ export class InlineCompletionsModel extends Disposable {
|
||||
return undefined;
|
||||
}
|
||||
const cursorAtInlineEdit = this.primaryPosition.map(cursorPos => LineRange.fromRangeInclusive(inlineEditResult.targetRange).addMargin(1, 1).contains(cursorPos.lineNumber));
|
||||
const stringEdit = inlineEditResult.action?.kind === 'edit' ? inlineEditResult.action.stringEdit : undefined;
|
||||
const stringEdit = inlineEditResult.action?.kind === 'edit' || inlineEditResult.action?.kind === 'rename' ? inlineEditResult.action.stringEdit : undefined;
|
||||
const replacements = stringEdit ? TextEdit.fromStringEdit(stringEdit, new TextModelText(this.textModel)).replacements : [];
|
||||
|
||||
const nextEditUri = (item.inlineEdit?.command?.id === 'vscode.open' || item.inlineEdit?.command?.id === '_workbench.open') &&
|
||||
@@ -904,9 +905,13 @@ export class InlineCompletionsModel extends Disposable {
|
||||
editor.pushUndoStop();
|
||||
if (isNextEditUri) {
|
||||
// Do nothing
|
||||
} else if (completion.action?.kind === 'edit') {
|
||||
} else if (completion.action?.kind === 'edit' || completion.action?.kind === 'rename') {
|
||||
const action = completion.action;
|
||||
if (action.snippetInfo) {
|
||||
if (action.kind === 'rename' && !ModifierKeyEmitter.getInstance().keyStatus.altKey) {
|
||||
await this._commandService
|
||||
.executeCommand(action.command.id, ...(action.command.arguments || []))
|
||||
.then(undefined, onUnexpectedExternalError);
|
||||
} else if (action.kind === 'edit' && action.snippetInfo) {
|
||||
const mainEdit = TextReplacement.delete(action.textReplacement.range);
|
||||
const additionalEdits = completion.additionalTextEdits.map(e => new TextReplacement(Range.lift(e.range), e.text ?? ''));
|
||||
const edit = TextEdit.fromParallelReplacementsUnsorted([mainEdit, ...additionalEdits]);
|
||||
@@ -950,12 +955,6 @@ export class InlineCompletionsModel extends Disposable {
|
||||
// Reset before invoking the command, as the command might cause a follow up trigger (which we don't want to reset).
|
||||
this.stop();
|
||||
|
||||
if (completion.renameCommand) {
|
||||
await this._commandService
|
||||
.executeCommand(completion.renameCommand.id, ...(completion.renameCommand.arguments || []))
|
||||
.then(undefined, onUnexpectedExternalError);
|
||||
}
|
||||
|
||||
if (completion.command) {
|
||||
await this._commandService
|
||||
.executeCommand(completion.command.id, ...(completion.command.arguments || []))
|
||||
|
||||
@@ -273,7 +273,7 @@ export class InlineCompletionsSource extends Disposable {
|
||||
return this._renameProcessor.proposeRenameRefactoring(this._textModel, s);
|
||||
}));
|
||||
|
||||
providerSuggestions.forEach(s => s.addPerformanceMarker('renameProcessed'));
|
||||
suggestions.forEach(s => s.addPerformanceMarker('renameProcessed'));
|
||||
|
||||
providerResult.cancelAndDispose({ kind: 'lostRace' });
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import { EndOfLinePreference, ITextModel } from '../../../../common/model.js';
|
||||
import { TextModelText } from '../../../../common/model/textModelText.js';
|
||||
import { InlineCompletionViewData, InlineCompletionViewKind } from '../view/inlineEdits/inlineEditsViewInterface.js';
|
||||
import { computeEditKind, InlineSuggestionEditKind } from './editKind.js';
|
||||
import { IInlineSuggestDataActionEdit, InlineSuggestData, InlineSuggestionList, PartialAcceptance, RenameInfo, SnippetInfo } from './provideInlineCompletions.js';
|
||||
import { IInlineSuggestDataActionEdit, IInlineSuggestDataActionRename, InlineSuggestData, InlineSuggestionList, PartialAcceptance, RenameInfo, SnippetInfo } from './provideInlineCompletions.js';
|
||||
import { singleTextRemoveCommonPrefix } from './singleTextEditHelpers.js';
|
||||
|
||||
export type InlineSuggestionItem = InlineEditItem | InlineCompletionItem;
|
||||
@@ -43,7 +43,7 @@ export namespace InlineSuggestionItem {
|
||||
}
|
||||
}
|
||||
|
||||
export type InlineSuggestionAction = IInlineSuggestionActionEdit | IInlineSuggestionActionJumpTo;
|
||||
export type InlineSuggestionAction = IInlineSuggestionActionEdit | IInlineSuggestionActionJumpTo | IInlineSuggestionActionRename;
|
||||
|
||||
export interface IInlineSuggestionActionEdit {
|
||||
kind: 'edit';
|
||||
@@ -60,6 +60,19 @@ export interface IInlineSuggestionActionJumpTo {
|
||||
uri: URI | undefined;
|
||||
}
|
||||
|
||||
export interface IInlineSuggestionActionRename {
|
||||
kind: 'rename';
|
||||
textReplacement: TextReplacement;
|
||||
stringEdit: StringEdit;
|
||||
uri: URI | undefined;
|
||||
command: Command;
|
||||
}
|
||||
|
||||
function hashInlineSuggestionAction(action: InlineSuggestionAction | undefined): string {
|
||||
const obj = action?.kind === 'rename' ? { ...action, command: action.command.id } : action;
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
|
||||
abstract class InlineSuggestionItemBase {
|
||||
constructor(
|
||||
protected readonly _data: InlineSuggestData,
|
||||
@@ -83,7 +96,7 @@ abstract class InlineSuggestionItemBase {
|
||||
if (this.hint) {
|
||||
return this.hint.range;
|
||||
}
|
||||
if (this.action?.kind === 'edit') {
|
||||
if (this.action?.kind === 'edit' || this.action?.kind === 'rename') {
|
||||
return this.action.textReplacement.range;
|
||||
} else if (this.action?.kind === 'jumpTo') {
|
||||
return Range.fromPositions(this.action.position);
|
||||
@@ -95,11 +108,10 @@ abstract class InlineSuggestionItemBase {
|
||||
public get gutterMenuLinkAction(): Command | undefined { return this._sourceInlineCompletion.gutterMenuLinkAction; }
|
||||
public get command(): Command | undefined { return this._sourceInlineCompletion.command; }
|
||||
public get supportsRename(): boolean { return this._data.supportsRename; }
|
||||
public get renameCommand(): Command | undefined { return this._data.renameCommand; }
|
||||
public get warning(): InlineCompletionWarning | undefined { return this._sourceInlineCompletion.warning; }
|
||||
public get showInlineEditMenu(): boolean { return !!this._sourceInlineCompletion.showInlineEditMenu; }
|
||||
public get hash(): string {
|
||||
return JSON.stringify(this.action);
|
||||
return hashInlineSuggestionAction(this.action);
|
||||
}
|
||||
/** @deprecated */
|
||||
public get shownCommand(): Command | undefined { return this._sourceInlineCompletion.shownCommand; }
|
||||
@@ -133,7 +145,7 @@ abstract class InlineSuggestionItemBase {
|
||||
}
|
||||
|
||||
public reportInlineEditShown(commandService: ICommandService, viewKind: InlineCompletionViewKind, viewData: InlineCompletionViewData, model: ITextModel) {
|
||||
const insertText = this.action?.kind === 'edit' ? this.action.textReplacement.text : ''; // TODO@hediet support insertText === undefined
|
||||
const insertText = this.action?.kind === 'edit' || this.action?.kind === 'rename' ? this.action.textReplacement.text : ''; // TODO@hediet support insertText === undefined
|
||||
this._data.reportInlineEditShown(commandService, insertText, viewKind, viewData, this.computeEditKind(model));
|
||||
}
|
||||
|
||||
@@ -168,8 +180,8 @@ abstract class InlineSuggestionItemBase {
|
||||
this._data.setRenameProcessingInfo(info);
|
||||
}
|
||||
|
||||
public withRename(command: Command, hint: InlineSuggestHint): InlineSuggestData {
|
||||
return this._data.withRename(command, hint);
|
||||
public withRename(renameAction: IInlineSuggestDataActionRename): InlineSuggestData {
|
||||
return this._data.withRename(renameAction);
|
||||
}
|
||||
|
||||
public addPerformanceMarker(marker: string): void {
|
||||
@@ -434,6 +446,8 @@ export class InlineEditItem extends InlineSuggestionItemBase {
|
||||
offset: textModel.getOffsetAt(data.action.position),
|
||||
uri: data.action.uri,
|
||||
};
|
||||
} else if (data.action?.kind === 'rename') {
|
||||
action = data.action;
|
||||
} else {
|
||||
action = undefined;
|
||||
if (!data.hint) {
|
||||
@@ -501,7 +515,7 @@ export class InlineEditItem extends InlineSuggestionItemBase {
|
||||
let inlineEditModelVersion = this._inlineEditModelVersion;
|
||||
let newAction: InlineSuggestionAction | undefined;
|
||||
|
||||
if (this.action?.kind === 'edit') {
|
||||
if (this.action?.kind === 'edit') { // TODO What about rename?
|
||||
edits = edits.map(innerEdit => innerEdit.applyTextModelChanges(textModelChanges));
|
||||
|
||||
if (edits.some(edit => edit.edit === undefined)) {
|
||||
@@ -573,7 +587,7 @@ export class InlineEditItem extends InlineSuggestionItemBase {
|
||||
}
|
||||
|
||||
override computeEditKind(model: ITextModel): InlineSuggestionEditKind | undefined {
|
||||
const edit = this.action?.kind === 'edit' ? this.action.stringEdit : undefined;
|
||||
const edit = this.action?.kind === 'edit' || this.action?.kind === 'rename' ? this.action.stringEdit : undefined;
|
||||
if (!edit) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Disposable, IDisposable } from '../../../../../base/common/lifecycle.js
|
||||
import { prefixedUuid } from '../../../../../base/common/uuid.js';
|
||||
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
|
||||
import { ISingleEditOperation } from '../../../../common/core/editOperation.js';
|
||||
import { StringReplacement } from '../../../../common/core/edits/stringEdit.js';
|
||||
import { StringEdit, StringReplacement } from '../../../../common/core/edits/stringEdit.js';
|
||||
import { OffsetRange } from '../../../../common/core/ranges/offsetRange.js';
|
||||
import { Position } from '../../../../common/core/position.js';
|
||||
import { Range } from '../../../../common/core/range.js';
|
||||
@@ -270,7 +270,6 @@ function toInlineSuggestData(
|
||||
context,
|
||||
inlineCompletion.isInlineEdit ?? false,
|
||||
inlineCompletion.supportsRename ?? false,
|
||||
undefined,
|
||||
requestInfo,
|
||||
providerRequestInfo,
|
||||
inlineCompletion.correlationId,
|
||||
@@ -311,7 +310,7 @@ export type InlineSuggestViewData = {
|
||||
viewKind?: InlineCompletionViewKind;
|
||||
};
|
||||
|
||||
export type IInlineSuggestDataAction = IInlineSuggestDataActionEdit | IInlineSuggestDataActionJumpTo;
|
||||
export type IInlineSuggestDataAction = IInlineSuggestDataActionEdit | IInlineSuggestDataActionJumpTo | IInlineSuggestDataActionRename;
|
||||
|
||||
export interface IInlineSuggestDataActionEdit {
|
||||
kind: 'edit';
|
||||
@@ -327,6 +326,14 @@ export interface IInlineSuggestDataActionJumpTo {
|
||||
uri: URI | undefined;
|
||||
}
|
||||
|
||||
export interface IInlineSuggestDataActionRename {
|
||||
kind: 'rename';
|
||||
textReplacement: TextReplacement;
|
||||
stringEdit: StringEdit;
|
||||
uri: URI | undefined;
|
||||
command: Command;
|
||||
}
|
||||
|
||||
export class InlineSuggestData {
|
||||
private _didShow = false;
|
||||
private _timeUntilShown: number | undefined = undefined;
|
||||
@@ -354,7 +361,6 @@ export class InlineSuggestData {
|
||||
public readonly context: InlineCompletionContext,
|
||||
public readonly isInlineEdit: boolean,
|
||||
public readonly supportsRename: boolean,
|
||||
public readonly renameCommand: Command | undefined,
|
||||
private readonly _requestInfo: InlineSuggestRequestInfo,
|
||||
private readonly _providerRequestInfo: InlineSuggestProviderRequestInfo,
|
||||
private readonly _correlationId: string | undefined,
|
||||
@@ -517,17 +523,16 @@ export class InlineSuggestData {
|
||||
this._renameInfo = info;
|
||||
}
|
||||
|
||||
public withRename(command: Command, hint: IInlineCompletionHint): InlineSuggestData {
|
||||
public withRename(renameAction: IInlineSuggestDataActionRename): InlineSuggestData {
|
||||
return new InlineSuggestData(
|
||||
undefined,
|
||||
hint,
|
||||
renameAction,
|
||||
this.hint,
|
||||
this.additionalTextEdits,
|
||||
this.sourceInlineCompletion,
|
||||
this.source,
|
||||
this.context,
|
||||
this.isInlineEdit,
|
||||
this.supportsRename,
|
||||
command,
|
||||
this._requestInfo,
|
||||
this._providerRequestInfo,
|
||||
this._correlationId,
|
||||
|
||||
@@ -14,14 +14,15 @@ import { TextEdit } from '../../../../common/core/edits/textEdit.js';
|
||||
import { Position } from '../../../../common/core/position.js';
|
||||
import { Range } from '../../../../common/core/range.js';
|
||||
import { StandardTokenType } from '../../../../common/encodedTokenAttributes.js';
|
||||
import { Command, InlineCompletionHintStyle } from '../../../../common/languages.js';
|
||||
import { Command } from '../../../../common/languages.js';
|
||||
import { ILanguageConfigurationService } from '../../../../common/languages/languageConfigurationRegistry.js';
|
||||
import { ITextModel } from '../../../../common/model.js';
|
||||
import { ILanguageFeaturesService } from '../../../../common/services/languageFeatures.js';
|
||||
import { EditSources, TextModelEditSource } from '../../../../common/textModelEditSource.js';
|
||||
import { hasProvider, prepareRename, rename } from '../../../rename/browser/rename.js';
|
||||
import { renameSymbolCommandId } from '../controller/commandIds.js';
|
||||
import { InlineSuggestHint, InlineSuggestionItem } from './inlineSuggestionItem.js';
|
||||
import { InlineSuggestionItem } from './inlineSuggestionItem.js';
|
||||
import { IInlineSuggestDataActionRename } from './provideInlineCompletions.js';
|
||||
|
||||
export type RenameEdits = {
|
||||
renames: { edits: TextEdit[]; position: Position; oldName: string; newName: string };
|
||||
@@ -258,14 +259,19 @@ export class RenameSymbolProcessor extends Disposable {
|
||||
providerId: suggestItem.source.provider.providerId,
|
||||
languageId: textModel.getLanguageId(),
|
||||
});
|
||||
const hintRange = edits.renames.edits[0].replacements[0].range;
|
||||
const label = localize('renameSymbol', "Rename '{0}' to '{1}'", oldName, newName);
|
||||
const command: Command = {
|
||||
id: renameSymbolCommandId,
|
||||
title: label,
|
||||
arguments: [textModel, position, newName, source],
|
||||
};
|
||||
const hint = InlineSuggestHint.create({ range: hintRange, content: label, style: InlineCompletionHintStyle.Code });
|
||||
return InlineSuggestionItem.create(suggestItem.withRename(command, hint), textModel);
|
||||
const renameAction: IInlineSuggestDataActionRename = {
|
||||
kind: 'rename',
|
||||
textReplacement: edit,
|
||||
stringEdit: suggestItem.action.stringEdit,
|
||||
command,
|
||||
uri: textModel.uri
|
||||
};
|
||||
return InlineSuggestionItem.create(suggestItem.withRename(renameAction), textModel);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ export class InlineEditWithChanges {
|
||||
public get lineEdit(): LineReplacement {
|
||||
if (this.action?.kind === 'jumpTo') {
|
||||
return new LineReplacement(LineRange.ofLength(this.action.position.lineNumber, 0), []);
|
||||
} else if (this.action?.kind === 'edit') {
|
||||
} else if (this.action?.kind === 'edit' || this.action?.kind === 'rename') {
|
||||
return LineReplacement.fromSingleTextEdit(this.edit!.toReplacement(this.originalText), this.originalText);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,11 +109,11 @@ export class InlineEditsView extends Disposable {
|
||||
|
||||
this._inlineCollapsedView = this._register(this._instantiationService.createInstance(InlineEditsCollapsedView,
|
||||
this._editor,
|
||||
this._model.map((m, reader) => this._uiState.read(reader)?.state?.kind === 'collapsed' ? m?.inlineEdit : undefined)
|
||||
this._model.map((m, reader) => this._uiState.read(reader)?.state?.kind === InlineCompletionViewKind.Collapsed ? m?.inlineEdit : undefined)
|
||||
));
|
||||
this._customView = this._register(this._instantiationService.createInstance(InlineEditsCustomView,
|
||||
this._editor,
|
||||
this._model.map((m, reader) => this._uiState.read(reader)?.state?.kind === 'custom' ? m?.displayLocation : undefined),
|
||||
this._model.map((m, reader) => this._uiState.read(reader)?.state?.kind === InlineCompletionViewKind.Custom ? m?.displayLocation : undefined),
|
||||
this._tabAction,
|
||||
));
|
||||
|
||||
@@ -164,10 +164,10 @@ export class InlineEditsView extends Disposable {
|
||||
equalsFn: itemsEquals(itemEquals())
|
||||
}, reader => {
|
||||
const s = this._uiState.read(reader);
|
||||
return s?.state?.kind === 'wordReplacements' ? s.state.replacements : [];
|
||||
return s?.state?.kind === InlineCompletionViewKind.WordReplacements ? s.state.replacements : [];
|
||||
});
|
||||
this._wordReplacementViews = mapObservableArrayCached(this, wordReplacements, (e, store) => {
|
||||
return store.add(this._instantiationService.createInstance(InlineEditsWordReplacementView, this._editorObs, e, this._tabAction));
|
||||
return store.add(this._instantiationService.createInstance(InlineEditsWordReplacementView, this._editorObs, e, this._model.get()?.inlineEdit.inlineCompletion.action?.kind === 'rename', this._tabAction));
|
||||
});
|
||||
this._lineReplacementView = this._register(this._instantiationService.createInstance(InlineEditsLineReplacementView,
|
||||
this._editorObs,
|
||||
@@ -426,6 +426,10 @@ export class InlineEditsView extends Disposable {
|
||||
return this._previousView!.view;
|
||||
}
|
||||
|
||||
if (model.inlineEdit.inlineCompletion.action?.kind === 'rename') {
|
||||
return InlineCompletionViewKind.WordReplacements;
|
||||
}
|
||||
|
||||
const uri = model.inlineEdit.inlineCompletion.action?.kind === 'edit' ? model.inlineEdit.inlineCompletion.action.uri : undefined;
|
||||
if (uri !== undefined) {
|
||||
return InlineCompletionViewKind.Custom;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export class InlineEditsViewAndDiffProducer extends Disposable { // TODO: This c
|
||||
|
||||
let diffEdits: TextEdit | undefined;
|
||||
|
||||
if (action?.kind === 'edit') {
|
||||
if (action?.kind === 'edit' || action?.kind === 'rename') {
|
||||
const editOffset = action.stringEdit;
|
||||
|
||||
const edits = editOffset.replacements.map(e => {
|
||||
|
||||
+62
-14
@@ -3,12 +3,14 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getWindow, n, ObserverNodeWithElement } from '../../../../../../../base/browser/dom.js';
|
||||
import { getWindow, ModifierKeyEmitter, n, ObserverNodeWithElement } from '../../../../../../../base/browser/dom.js';
|
||||
import { IMouseEvent, StandardMouseEvent } from '../../../../../../../base/browser/mouseEvent.js';
|
||||
import { renderIcon } from '../../../../../../../base/browser/ui/iconLabel/iconLabels.js';
|
||||
import { Codicon } from '../../../../../../../base/common/codicons.js';
|
||||
import { Emitter } from '../../../../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../../../../base/common/lifecycle.js';
|
||||
import { constObservable, derived, IObservable, observableValue } from '../../../../../../../base/common/observable.js';
|
||||
import { editorBackground, editorHoverForeground } from '../../../../../../../platform/theme/common/colorRegistry.js';
|
||||
import { constObservable, derived, IObservable, observableFromEvent, observableValue } from '../../../../../../../base/common/observable.js';
|
||||
import { editorBackground, editorHoverBorder, editorHoverForeground } from '../../../../../../../platform/theme/common/colorRegistry.js';
|
||||
import { asCssVariable } from '../../../../../../../platform/theme/common/colorUtils.js';
|
||||
import { ObservableCodeEditor } from '../../../../../../browser/observableCodeEditor.js';
|
||||
import { LineSource, renderLines, RenderOptions } from '../../../../../../browser/widget/diffEditor/components/diffEditorViewZones/renderLines.js';
|
||||
@@ -48,6 +50,7 @@ export class InlineEditsWordReplacementView extends Disposable implements IInlin
|
||||
private readonly _editor: ObservableCodeEditor,
|
||||
/** Must be single-line in both sides */
|
||||
private readonly _edit: TextReplacement,
|
||||
private readonly _rename: boolean,
|
||||
protected readonly _tabAction: IObservable<InlineEditTabAction>,
|
||||
@ILanguageService private readonly _languageService: ILanguageService,
|
||||
) {
|
||||
@@ -76,6 +79,7 @@ export class InlineEditsWordReplacementView extends Disposable implements IInlin
|
||||
this._line.style.width = `${res.minWidthInPx}px`;
|
||||
});
|
||||
const modifiedLineHeight = this._editor.observeLineHeightForPosition(this._edit.range.getStartPosition());
|
||||
const altPressed = observableFromEvent(this, ModifierKeyEmitter.getInstance().event, keyStatus => keyStatus?.altKey ?? ModifierKeyEmitter.getInstance().keyStatus.altKey);
|
||||
this._layout = derived(this, reader => {
|
||||
this._renderTextEffect.read(reader);
|
||||
const widgetStart = this._start.read(reader);
|
||||
@@ -94,15 +98,26 @@ export class InlineEditsWordReplacementView extends Disposable implements IInlin
|
||||
const modifiedTopOffset = 4;
|
||||
const modifiedOffset = new Point(modifiedLeftOffset, modifiedTopOffset);
|
||||
|
||||
const originalLine = Rect.fromPoints(widgetStart, widgetEnd).withHeight(lineHeight).translateX(-scrollLeft);
|
||||
const modifiedLine = Rect.fromPointSize(originalLine.getLeftBottom().add(modifiedOffset), new Point(this._edit.text.length * w, originalLine.height));
|
||||
let label = undefined;
|
||||
if (this._rename) { // TODO: make this customizable and not rename specific
|
||||
if (altPressed.read(reader)) {
|
||||
label = { content: 'Edit', icon: Codicon.edit };
|
||||
} else {
|
||||
label = { content: 'Rename', icon: Codicon.replaceAll };
|
||||
}
|
||||
}
|
||||
|
||||
const originalLine = Rect.fromPoints(widgetStart, widgetEnd).withHeight(lineHeight).translateX(-scrollLeft);
|
||||
const codeLine = Rect.fromPointSize(originalLine.getLeftBottom().add(modifiedOffset), new Point(this._edit.text.length * w, originalLine.height));
|
||||
const modifiedLine = codeLine.withWidth(codeLine.width + (label ? label.content.length * w + 8 + 4 + 12 : 0));
|
||||
const lowerBackground = modifiedLine.withLeft(originalLine.left);
|
||||
|
||||
// debugView(debugLogRects({ lowerBackground }, this._editor.editor.getContainerDomNode()), reader);
|
||||
|
||||
return {
|
||||
label,
|
||||
originalLine,
|
||||
codeLine,
|
||||
modifiedLine,
|
||||
lowerBackground,
|
||||
lineHeight,
|
||||
@@ -157,23 +172,56 @@ export class InlineEditsWordReplacementView extends Disposable implements IInlin
|
||||
style: {
|
||||
position: 'absolute',
|
||||
...rectToProps(reader => layout.read(reader).modifiedLine.withMargin(BORDER_WIDTH, 2 * BORDER_WIDTH)),
|
||||
fontFamily: this._editor.getOption(EditorOption.fontFamily),
|
||||
fontSize: this._editor.getOption(EditorOption.fontSize),
|
||||
fontWeight: this._editor.getOption(EditorOption.fontWeight),
|
||||
|
||||
width: undefined,
|
||||
pointerEvents: 'none',
|
||||
boxSizing: 'border-box',
|
||||
borderRadius: '4px',
|
||||
border: `${BORDER_WIDTH}px solid ${modifiedBorderColor}`,
|
||||
|
||||
background: asCssVariable(modifiedChangedTextOverlayColor),
|
||||
background: asCssVariable(editorBackground),
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'left',
|
||||
|
||||
outline: `2px solid ${asCssVariable(editorBackground)}`,
|
||||
}
|
||||
}, [this._line]),
|
||||
}, [
|
||||
n.div({
|
||||
style: {
|
||||
fontFamily: this._editor.getOption(EditorOption.fontFamily),
|
||||
fontSize: this._editor.getOption(EditorOption.fontSize),
|
||||
fontWeight: this._editor.getOption(EditorOption.fontWeight),
|
||||
width: rectToProps(reader => layout.read(reader).codeLine.withMargin(BORDER_WIDTH, 2 * BORDER_WIDTH)).width,
|
||||
borderRadius: layout.map(l => l.label ? '4px 0 0 4px' : '4px'),
|
||||
border: `${BORDER_WIDTH}px solid ${modifiedBorderColor}`,
|
||||
boxSizing: 'border-box',
|
||||
padding: `${BORDER_WIDTH}px`,
|
||||
|
||||
background: asCssVariable(modifiedChangedTextOverlayColor),
|
||||
display: 'flex',
|
||||
justifyContent: 'left',
|
||||
alignItems: 'center',
|
||||
}
|
||||
}, [this._line]),
|
||||
derived(this, reader => {
|
||||
const label = layout.read(reader).label;
|
||||
if (!label) {
|
||||
return undefined;
|
||||
}
|
||||
return n.div({
|
||||
style: {
|
||||
fontFamily: this._editor.getOption(EditorOption.fontFamily),
|
||||
fontSize: this._editor.getOption(EditorOption.fontSize),
|
||||
fontWeight: this._editor.getOption(EditorOption.fontWeight),
|
||||
borderRadius: '0 4px 4px 0',
|
||||
border: `${BORDER_WIDTH}px solid ${asCssVariable(editorHoverBorder)}`,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: '0 4px',
|
||||
},
|
||||
class: 'inline-edit-rename-label',
|
||||
}, [renderIcon(label.icon), label.content]);
|
||||
})
|
||||
]),
|
||||
n.div({
|
||||
style: {
|
||||
position: 'absolute',
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.go-to-label::before {
|
||||
.inline-edits-long-distance-hint-widget .go-to-label::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -12px;
|
||||
@@ -252,3 +252,8 @@
|
||||
height: 100%;
|
||||
background: linear-gradient(to left, var(--vscode-editorWidget-background) 0, transparent 12px);
|
||||
}
|
||||
|
||||
.inline-edit-rename-label .codicon {
|
||||
font-size: 12px !important;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user