src/vs/editor/browser/widget/inlineDiffMargin.ts/InlineDiffMargin/constructor
class InlineDiffMargin:	constructor(
		private readonly _viewZoneId: string,
		private readonly _marginDomNode: HTMLElement,
		public readonly editor: CodeEditorWidget,
		public readonly diff: IDiffLinesChange,
		private readonly _contextMenuService: IContextMenuService,
		private readonly _clipboardService: IClipboardService
	) {
		super();

		// make sure the diff margin shows above overlay.
		this._marginDomNode.style.zIndex = '10';

		this._diffActions = document.createElement('div');
		this._diffActions.className = Codicon.lightBulb.classNames + ' lightbulb-glyph';
		this._diffActions.style.position = 'absolute';
		const lineHeight = editor.getOption(EditorOption.lineHeight);
		const lineFeed = editor.getModel()!.getEOL();
		this._diffActions.style.right = '0px';
		this._diffActions.style.visibility = 'hidden';
		this._diffActions.style.height = `${lineHeight}px`;
		this._diffActions.style.lineHeight = `${lineHeight}px`;
		this._marginDomNode.appendChild(this._diffActions);

		const actions: Action[] = [];

		// default action
		actions.push(new Action(
			'diff.clipboard.copyDeletedContent',
			diff.originalEndLineNumber > diff.modifiedStartLineNumber
				? nls.localize('diff.clipboard.copyDeletedLinesContent.label', "Copy deleted lines")
				: nls.localize('diff.clipboard.copyDeletedLinesContent.single.label', "Copy deleted line"),
			undefined,
			true,
			async () => {
				const range = new Range(diff.originalStartLineNumber, 1, diff.originalEndLineNumber + 1, 1);
				const deletedText = diff.originalModel.getValueInRange(range);
				await this._clipboardService.writeText(deletedText);
			}
		));

		let currentLineNumberOffset = 0;
		let copyLineAction: Action | undefined = undefined;
		if (diff.originalEndLineNumber > diff.modifiedStartLineNumber) {
			copyLineAction = new Action(
				'diff.clipboard.copyDeletedLineContent',
				nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line ({0})", diff.originalStartLineNumber),
				undefined,
				true,
				async () => {
					const lineContent = diff.originalModel.getLineContent(diff.originalStartLineNumber + currentLineNumberOffset);
					await this._clipboardService.writeText(lineContent);
				}
			);

			actions.push(copyLineAction);
		}

		const readOnly = editor.getOption(EditorOption.readOnly);
		if (!readOnly) {
			actions.push(new Action('diff.inline.revertChange', nls.localize('diff.inline.revertChange.label', "Revert this change"), undefined, true, async () => {
				const range = new Range(diff.originalStartLineNumber, 1, diff.originalEndLineNumber, diff.originalModel.getLineMaxColumn(diff.originalEndLineNumber));
				const deletedText = diff.originalModel.getValueInRange(range);
				if (diff.modifiedEndLineNumber === 0) {
					// deletion only
					const column = editor.getModel()!.getLineMaxColumn(diff.modifiedStartLineNumber);
					editor.executeEdits('diffEditor', [
						{
							range: new Range(diff.modifiedStartLineNumber, column, diff.modifiedStartLineNumber, column),
							text: lineFeed + deletedText
						}
					]);
				} else {
					const column = editor.getModel()!.getLineMaxColumn(diff.modifiedEndLineNumber);
					editor.executeEdits('diffEditor', [
						{
							range: new Range(diff.modifiedStartLineNumber, 1, diff.modifiedEndLineNumber, column),
							text: deletedText
						}
					]);
				}

			}));
		}

		const showContextMenu = (x: number, y: number) => {
			this._contextMenuService.showContextMenu({
				getAnchor: () => {
					return {
						x,
						y
					};
				},
				getActions: () => {
					if (copyLineAction) {
						copyLineAction.label = nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line ({0})", diff.originalStartLineNumber + currentLineNumberOffset);
					}
					return actions;
				},
				autoSelectFirstItem: true
			});
		};

		this._register(dom.addStandardDisposableListener(this._diffActions, 'mousedown', e => {
			const { top, height } = dom.getDomNodePagePosition(this._diffActions);
			let pad = Math.floor(lineHeight / 3);
			e.preventDefault();

			showContextMenu(e.posx, top + height + pad);

		}));

		this._register(editor.onMouseMove((e: IEditorMouseEvent) => {
			if (e.target.type === MouseTargetType.CONTENT_VIEW_ZONE || e.target.type === MouseTargetType.GUTTER_VIEW_ZONE) {
				const viewZoneId = e.target.detail.viewZoneId;

				if (viewZoneId === this._viewZoneId) {
					this.visibility = true;
					currentLineNumberOffset = this._updateLightBulbPosition(this._marginDomNode, e.event.browserEvent.y, lineHeight);
				} else {
					this.visibility = false;
				}
			} else {
				this.visibility = false;
			}
		}));

		this._register(editor.onMouseDown((e: IEditorMouseEvent) => {
			if (!e.event.rightButton) {
				return;
			}

			if (e.target.type === MouseTargetType.CONTENT_VIEW_ZONE || e.target.type === MouseTargetType.GUTTER_VIEW_ZONE) {
				const viewZoneId = e.target.detail.viewZoneId;

				if (viewZoneId === this._viewZoneId) {
					e.event.preventDefault();
					currentLineNumberOffset = this._updateLightBulbPosition(this._marginDomNode, e.event.browserEvent.y, lineHeight);
					showContextMenu(e.event.posx, e.event.posy + lineHeight);
				}
			}
		}));
	}