mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Merge branch 'master' of https://github.com/microsoft/vscode
This commit is contained in:
commit
b850dfb41b
|
@ -118,6 +118,32 @@ steps:
|
|||
displayName: Run integration tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
yarn gulp "vscode-linux-x64-build-deb"
|
||||
yarn gulp "vscode-linux-x64-build-rpm"
|
||||
yarn gulp "vscode-linux-x64-prepare-snap"
|
||||
displayName: Build packages
|
||||
|
||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||
inputs:
|
||||
ConnectedServiceName: 'ESRP CodeSign'
|
||||
FolderPath: '.build/linux/rpm/x86_64'
|
||||
Pattern: '*.rpm'
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: |
|
||||
[
|
||||
{
|
||||
"keyCode": "CP-450779-Pgp",
|
||||
"operationSetCode": "LinuxSign",
|
||||
"parameters": [ ],
|
||||
"toolName": "sign",
|
||||
"toolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
SessionTimeout: 120
|
||||
displayName: Codesign rpm
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \
|
||||
|
|
|
@ -31,7 +31,6 @@ node build/azure-pipelines/common/createAsset.js "server-$PLATFORM_LINUX" archiv
|
|||
node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "x64" "$VSCODE_HOCKEYAPP_ID_LINUX64"
|
||||
|
||||
# Publish DEB
|
||||
yarn gulp "vscode-linux-x64-build-deb"
|
||||
PLATFORM_DEB="linux-deb-x64"
|
||||
DEB_ARCH="amd64"
|
||||
DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)"
|
||||
|
@ -40,7 +39,6 @@ DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME"
|
|||
node build/azure-pipelines/common/createAsset.js "$PLATFORM_DEB" package "$DEB_FILENAME" "$DEB_PATH"
|
||||
|
||||
# Publish RPM
|
||||
yarn gulp "vscode-linux-x64-build-rpm"
|
||||
PLATFORM_RPM="linux-rpm-x64"
|
||||
RPM_ARCH="x86_64"
|
||||
RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)"
|
||||
|
@ -49,8 +47,6 @@ RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
|
|||
node build/azure-pipelines/common/createAsset.js "$PLATFORM_RPM" package "$RPM_FILENAME" "$RPM_PATH"
|
||||
|
||||
# Publish Snap
|
||||
yarn gulp "vscode-linux-x64-prepare-snap"
|
||||
|
||||
# Pack snap tarball artifact, in order to preserve file perms
|
||||
mkdir -p $REPO/.build/linux/snap-tarball
|
||||
SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-x64.tar.gz"
|
||||
|
|
|
@ -45,8 +45,8 @@ export function activateMatchingTagPosition(
|
|||
isEnabled = true;
|
||||
}
|
||||
|
||||
let prevCursorCount = 0;
|
||||
let cursorCount = 0;
|
||||
let prevCursors: readonly Selection[] = [];
|
||||
let cursors: readonly Selection[] = [];
|
||||
let inMirrorMode = false;
|
||||
|
||||
function onDidChangeTextEditorSelection(event: TextEditorSelectionChangeEvent) {
|
||||
|
@ -54,67 +54,67 @@ export function activateMatchingTagPosition(
|
|||
return;
|
||||
}
|
||||
|
||||
prevCursorCount = cursorCount;
|
||||
cursorCount = event.selections.length;
|
||||
prevCursors = cursors;
|
||||
cursors = event.selections;
|
||||
|
||||
if (cursorCount === 1) {
|
||||
if (inMirrorMode && prevCursorCount === 2) {
|
||||
return;
|
||||
if (cursors.length === 1) {
|
||||
if (inMirrorMode && prevCursors.length === 2) {
|
||||
if (cursors[0].isEqual(prevCursors[0]) || cursors[0].isEqual(prevCursors[1])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (event.selections[0].isEmpty) {
|
||||
matchingTagPositionProvider(event.textEditor.document, event.selections[0].active).then(position => {
|
||||
if (position && window.activeTextEditor) {
|
||||
inMirrorMode = true;
|
||||
const newCursor = new Selection(position.line, position.character, position.line, position.character);
|
||||
window.activeTextEditor.selections = [...window.activeTextEditor.selections, newCursor];
|
||||
matchingTagPositionProvider(event.textEditor.document, event.selections[0].active).then(matchingTagPosition => {
|
||||
if (matchingTagPosition && window.activeTextEditor) {
|
||||
const charBeforeAndAfterPositionsRoughtlyEqual = isCharBeforeAndAfterPositionsRoughtlyEqual(
|
||||
event.textEditor.document,
|
||||
event.selections[0].anchor,
|
||||
new Position(matchingTagPosition.line, matchingTagPosition.character)
|
||||
);
|
||||
|
||||
if (charBeforeAndAfterPositionsRoughtlyEqual) {
|
||||
inMirrorMode = true;
|
||||
const newCursor = new Selection(
|
||||
matchingTagPosition.line,
|
||||
matchingTagPosition.character,
|
||||
matchingTagPosition.line,
|
||||
matchingTagPosition.character
|
||||
);
|
||||
window.activeTextEditor.selections = [...window.activeTextEditor.selections, newCursor];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorCount === 2 && inMirrorMode) {
|
||||
if (cursors.length === 2 && inMirrorMode) {
|
||||
// Check two cases
|
||||
if (event.selections[0].isEmpty && event.selections[1].isEmpty) {
|
||||
const charBeforePrimarySelection = getCharBefore(event.textEditor.document, event.selections[0].anchor);
|
||||
const charAfterPrimarySelection = getCharAfter(event.textEditor.document, event.selections[0].anchor);
|
||||
const charBeforeSecondarySelection = getCharBefore(event.textEditor.document, event.selections[1].anchor);
|
||||
const charAfterSecondarySelection = getCharAfter(event.textEditor.document, event.selections[1].anchor);
|
||||
const charBeforeAndAfterPositionsRoughtlyEqual = isCharBeforeAndAfterPositionsRoughtlyEqual(
|
||||
event.textEditor.document,
|
||||
event.selections[0].anchor,
|
||||
event.selections[1].anchor
|
||||
);
|
||||
|
||||
// Exit mirror mode when cursor position no longer mirror
|
||||
// Unless it's in the case of `<|></|>`
|
||||
const charBeforeBothPositionRoughlyEqual =
|
||||
charBeforePrimarySelection === charBeforeSecondarySelection ||
|
||||
(charBeforePrimarySelection === '/' && charBeforeSecondarySelection === '<') ||
|
||||
(charBeforeSecondarySelection === '/' && charBeforePrimarySelection === '<');
|
||||
const charAfterBothPositionRoughlyEqual =
|
||||
charAfterPrimarySelection === charAfterSecondarySelection ||
|
||||
(charAfterPrimarySelection === ' ' && charAfterSecondarySelection === '>') ||
|
||||
(charAfterSecondarySelection === ' ' && charAfterPrimarySelection === '>');
|
||||
|
||||
if (!charBeforeBothPositionRoughlyEqual || !charAfterBothPositionRoughlyEqual) {
|
||||
if (!charBeforeAndAfterPositionsRoughtlyEqual) {
|
||||
inMirrorMode = false;
|
||||
window.activeTextEditor!.selections = [window.activeTextEditor!.selections[0]];
|
||||
return;
|
||||
} else {
|
||||
// Need to cleanup in the case of <div |></div |>
|
||||
if (
|
||||
charBeforePrimarySelection === ' ' &&
|
||||
charAfterPrimarySelection === '>' &&
|
||||
charBeforeSecondarySelection === ' ' &&
|
||||
charAfterSecondarySelection === '>'
|
||||
shouldDoCleanupForHtmlAttributeInput(
|
||||
event.textEditor.document,
|
||||
event.selections[0].anchor,
|
||||
event.selections[1].anchor
|
||||
)
|
||||
) {
|
||||
const primaryBeforeSecondary =
|
||||
event.textEditor.document.offsetAt(event.selections[0].anchor) <
|
||||
event.textEditor.document.offsetAt(event.selections[1].anchor);
|
||||
|
||||
if (primaryBeforeSecondary) {
|
||||
inMirrorMode = false;
|
||||
const cleanupEdit = new WorkspaceEdit();
|
||||
const cleanupRange = new Range(event.selections[1].anchor.translate(0, -1), event.selections[1].anchor);
|
||||
cleanupEdit.replace(event.textEditor.document.uri, cleanupRange, '');
|
||||
window.activeTextEditor!.selections = [window.activeTextEditor!.selections[0]];
|
||||
workspace.applyEdit(cleanupEdit);
|
||||
}
|
||||
inMirrorMode = false;
|
||||
const cleanupEdit = new WorkspaceEdit();
|
||||
const cleanupRange = new Range(event.selections[1].anchor.translate(0, -1), event.selections[1].anchor);
|
||||
cleanupEdit.replace(event.textEditor.document.uri, cleanupRange, '');
|
||||
window.activeTextEditor!.selections = [window.activeTextEditor!.selections[0]];
|
||||
workspace.applyEdit(cleanupEdit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,3 +141,43 @@ function getCharAfter(document: TextDocument, position: Position) {
|
|||
|
||||
return document.getText(new Range(position, document.positionAt(offset + 1)));
|
||||
}
|
||||
|
||||
// Check if chars before and after the two positions are equal
|
||||
// For the chars before, `<` and `/` are consiered equal to handle the case of `<|></|>`
|
||||
function isCharBeforeAndAfterPositionsRoughtlyEqual(document: TextDocument, firstPos: Position, secondPos: Position) {
|
||||
const charBeforePrimarySelection = getCharBefore(document, firstPos);
|
||||
const charAfterPrimarySelection = getCharAfter(document, firstPos);
|
||||
const charBeforeSecondarySelection = getCharBefore(document, secondPos);
|
||||
const charAfterSecondarySelection = getCharAfter(document, secondPos);
|
||||
|
||||
// Exit mirror mode when cursor position no longer mirror
|
||||
// Unless it's in the case of `<|></|>`
|
||||
const charBeforeBothPositionRoughlyEqual =
|
||||
charBeforePrimarySelection === charBeforeSecondarySelection ||
|
||||
(charBeforePrimarySelection === '/' && charBeforeSecondarySelection === '<') ||
|
||||
(charBeforeSecondarySelection === '/' && charBeforePrimarySelection === '<');
|
||||
const charAfterBothPositionRoughlyEqual =
|
||||
charAfterPrimarySelection === charAfterSecondarySelection ||
|
||||
(charAfterPrimarySelection === ' ' && charAfterSecondarySelection === '>') ||
|
||||
(charAfterSecondarySelection === ' ' && charAfterPrimarySelection === '>');
|
||||
|
||||
return charBeforeBothPositionRoughlyEqual && charAfterBothPositionRoughlyEqual;
|
||||
}
|
||||
|
||||
function shouldDoCleanupForHtmlAttributeInput(document: TextDocument, firstPos: Position, secondPos: Position) {
|
||||
// Need to cleanup in the case of <div |></div |>
|
||||
const charBeforePrimarySelection = getCharBefore(document, firstPos);
|
||||
const charAfterPrimarySelection = getCharAfter(document, firstPos);
|
||||
const charBeforeSecondarySelection = getCharBefore(document, secondPos);
|
||||
const charAfterSecondarySelection = getCharAfter(document, secondPos);
|
||||
|
||||
const primaryBeforeSecondary = document.offsetAt(firstPos) < document.offsetAt(secondPos);
|
||||
|
||||
return (
|
||||
primaryBeforeSecondary &&
|
||||
charBeforePrimarySelection === ' ' &&
|
||||
charAfterPrimarySelection === '>' &&
|
||||
charBeforeSecondarySelection === ' ' &&
|
||||
charAfterSecondarySelection === '>'
|
||||
);
|
||||
}
|
||||
|
|
|
@ -274,7 +274,11 @@ export class TextAreaInput extends Disposable {
|
|||
|
||||
this._register(dom.addDisposableListener(textArea.domNode, 'compositionend', (e: CompositionEvent) => {
|
||||
this._lastTextAreaEvent = TextAreaInputEventType.compositionend;
|
||||
|
||||
// https://github.com/microsoft/monaco-editor/issues/1663
|
||||
// On iOS 13.2, Chinese system IME randomly trigger an additional compositionend event with empty data
|
||||
if (!this._isDoingComposition) {
|
||||
return;
|
||||
}
|
||||
if (compositionDataInValid(e.locale)) {
|
||||
// https://github.com/Microsoft/monaco-editor/issues/339
|
||||
const [newState, typeInput] = deduceInputFromTextAreaValue(/*couldBeEmojiInput*/false, /*couldBeTypingAtOffset0*/false);
|
||||
|
|
|
@ -33,6 +33,7 @@ import { Color } from 'vs/base/common/color';
|
|||
import { GestureEvent, EventType, Gesture } from 'vs/base/browser/touch';
|
||||
import { MinimapCharRendererFactory } from 'vs/editor/browser/viewParts/minimap/minimapCharRendererFactory';
|
||||
import { MinimapPosition } from 'vs/editor/common/model';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
|
||||
function getMinimapLineHeight(renderMinimap: RenderMinimap, scale: number): number {
|
||||
if (renderMinimap === RenderMinimap.Text) {
|
||||
|
@ -73,7 +74,7 @@ class MinimapOptions {
|
|||
|
||||
public readonly fontScale: number;
|
||||
|
||||
public readonly charRenderer: MinimapCharRenderer;
|
||||
public readonly charRenderer: () => MinimapCharRenderer;
|
||||
|
||||
/**
|
||||
* container dom node left position (in CSS px)
|
||||
|
@ -117,7 +118,7 @@ class MinimapOptions {
|
|||
const minimapOpts = options.get(EditorOption.minimap);
|
||||
this.showSlider = minimapOpts.showSlider;
|
||||
this.fontScale = Math.round(minimapOpts.scale * pixelRatio);
|
||||
this.charRenderer = MinimapCharRendererFactory.create(this.fontScale, fontInfo.fontFamily);
|
||||
this.charRenderer = once(() => MinimapCharRendererFactory.create(this.fontScale, fontInfo.fontFamily));
|
||||
this.pixelRatio = pixelRatio;
|
||||
this.typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth;
|
||||
this.lineHeight = options.get(EditorOption.lineHeight);
|
||||
|
@ -850,6 +851,11 @@ export class Minimap extends ViewPart {
|
|||
charWidth: number): void {
|
||||
const y = (lineNumber - layout.startLineNumber) * lineHeight;
|
||||
|
||||
// Skip rendering the line if it's vertically outside our viewport
|
||||
if (y + height < 0 || y > this._options.canvasOuterHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache line offset data so that it is only read once per line
|
||||
let lineIndexToXOffset = lineOffsetMap.get(lineNumber);
|
||||
const isFirstDecorationForLine = !lineIndexToXOffset;
|
||||
|
@ -900,6 +906,7 @@ export class Minimap extends ViewPart {
|
|||
|
||||
private renderLines(layout: MinimapLayout): RenderData {
|
||||
const renderMinimap = this._options.renderMinimap;
|
||||
const charRenderer = this._options.charRenderer();
|
||||
const startLineNumber = layout.startLineNumber;
|
||||
const endLineNumber = layout.endLineNumber;
|
||||
const minimapLineHeight = getMinimapLineHeight(renderMinimap, this._options.fontScale);
|
||||
|
@ -941,7 +948,7 @@ export class Minimap extends ViewPart {
|
|||
useLighterFont,
|
||||
renderMinimap,
|
||||
this._tokensColorTracker,
|
||||
this._options.charRenderer,
|
||||
charRenderer,
|
||||
dy,
|
||||
tabSize,
|
||||
lineInfo.data[lineIndex]!,
|
||||
|
|
|
@ -17,6 +17,7 @@ import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDeco
|
|||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
import { minimapWarning, minimapError } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
function MODEL_ID(resource: URI): string {
|
||||
return resource.toString();
|
||||
|
@ -205,7 +206,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
|||
color = themeColorFromId(overviewRulerWarning);
|
||||
zIndex = 20;
|
||||
minimap = {
|
||||
color,
|
||||
color: themeColorFromId(minimapWarning),
|
||||
position: MinimapPosition.Inline
|
||||
};
|
||||
break;
|
||||
|
@ -220,7 +221,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
|||
color = themeColorFromId(overviewRulerError);
|
||||
zIndex = 30;
|
||||
minimap = {
|
||||
color,
|
||||
color: themeColorFromId(minimapError),
|
||||
position: MinimapPosition.Inline
|
||||
};
|
||||
break;
|
||||
|
|
|
@ -422,6 +422,8 @@ export const overviewRulerSelectionHighlightForeground = registerColor('editorOv
|
|||
|
||||
export const minimapFindMatch = registerColor('minimap.findMatchHighlight', { light: '#d18616', dark: '#d18616', hc: '#AB5A00' }, nls.localize('minimapFindMatchHighlight', 'Minimap marker color for find matches.'), true);
|
||||
export const minimapSelection = registerColor('minimap.selectionHighlight', { light: '#ADD6FF', dark: '#264F78', hc: '#ffffff' }, nls.localize('minimapSelectionHighlight', 'Minimap marker color for the editor selection.'), true);
|
||||
export const minimapError = registerColor('minimap.errorHighlight', { dark: new Color(new RGBA(255, 18, 18, 0.7)), light: new Color(new RGBA(255, 18, 18, 0.7)), hc: new Color(new RGBA(255, 50, 50, 1)) }, nls.localize('minimapError', 'Minimap marker color for errors.'));
|
||||
export const minimapWarning = registerColor('minimap.warningHighlight', { dark: editorWarningForeground, light: editorWarningForeground, hc: editorWarningBorder }, nls.localize('overviewRuleWarning', 'Minimap marker color for warnings.'));
|
||||
|
||||
export const problemsErrorIconForeground = registerColor('problemsErrorIcon.foreground', { dark: editorErrorForeground, light: editorErrorForeground, hc: editorErrorForeground }, nls.localize('problemsErrorIconForeground', "The color used for the problems error icon."));
|
||||
export const problemsWarningIconForeground = registerColor('problemsWarningIcon.foreground', { dark: editorWarningForeground, light: editorWarningForeground, hc: editorWarningForeground }, nls.localize('problemsWarningIconForeground', "The color used for the problems warning icon."));
|
||||
|
|
|
@ -45,7 +45,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution {
|
|||
}
|
||||
|
||||
private registerCommonContributions(): void {
|
||||
this.registerLogChannel(Constants.userDataSyncLogChannelId, nls.localize('userDataSyncLog', "Configuration Sync"), this.environmentService.userDataSyncLogResource);
|
||||
this.registerLogChannel(Constants.userDataSyncLogChannelId, nls.localize('userDataSyncLog', "Sync"), this.environmentService.userDataSyncLogResource);
|
||||
this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), this.environmentService.logFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -813,6 +813,11 @@ configurationRegistry.registerConfiguration({
|
|||
type: 'number',
|
||||
default: 300,
|
||||
markdownDescription: nls.localize('search.searchOnTypeDebouncePeriod', "When `#search.searchOnType#` is enabled, controls the timeout in milliseconds between a character being typed and the search starting. Has no effect when `search.searchOnType` is disabled.")
|
||||
},
|
||||
'search.enableSearchEditorPreview': {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: nls.localize('search.enableSearchEditorPreview', "Experimental: When enabled, allows opening workspace search results in an editor.")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue