This commit is contained in:
Martin Aeschlimann 2019-12-02 21:44:04 +01:00
commit b850dfb41b
9 changed files with 137 additions and 56 deletions

View file

@ -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)" \

View file

@ -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"

View file

@ -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 === '>'
);
}

View file

@ -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);

View file

@ -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]!,

View file

@ -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;

View file

@ -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."));

View file

@ -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);
}

View file

@ -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.")
}
}
});