未验证 提交 eeca0eb7 编写于 作者: D Daniel Imms 提交者: GitHub

Merge branch 'master' into tyriar/46696_terminal_env

{
newReleaseLabel: 'new release',
newReleaseColor: '006b75',
daysAfterRelease: 5,
perform: true
}
......@@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: 'JacksonKearl/vscode-triage-github-actions'
ref: v9
ref: v10
- name: Run Commands
uses: ./commands
with:
......
......@@ -11,7 +11,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: 'JacksonKearl/vscode-triage-github-actions'
ref: v9
ref: v10
- name: Run CopyCat (JacksonKearl/testissues)
uses: ./copycat
with:
......
......@@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: 'JacksonKearl/vscode-triage-github-actions'
ref: v9
ref: v10
- name: Run Locker
uses: ./locker
with:
......
......@@ -11,7 +11,7 @@ jobs:
uses: actions/checkout@v2
with:
repository: 'JacksonKearl/vscode-triage-github-actions'
ref: v9
ref: v10
- name: Run Needs Version Info
uses: ./needs-more-info
with:
......
name: New Release
on:
issues:
types: [opened]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
with:
repository: 'JacksonKearl/vscode-triage-github-actions'
ref: v10
- name: Run New Release
uses: ./new-release
with:
token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}}
label: new release
labelColor: "006b75"
labelDescription: Issues found in a recent release of VS Code
days: 5
......@@ -93,7 +93,6 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series(
resources: vscodeResources,
loaderConfig: common.loaderConfig(nodeModules),
out: 'out-vscode',
inlineAmdImages: true,
bundleInfo: undefined
})
));
......
......@@ -6,7 +6,6 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.minifyTask = exports.optimizeTask = exports.loaderConfig = void 0;
const es = require("event-stream");
const fs = require("fs");
const gulp = require("gulp");
const concat = require("gulp-concat");
const minifyCSS = require("gulp-cssnano");
......@@ -134,14 +133,6 @@ function optimizeTask(opts) {
if (err || !result) {
return bundlesStream.emit('error', JSON.stringify(err));
}
if (opts.inlineAmdImages) {
try {
result = inlineAmdImages(src, result);
}
catch (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
}
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
const filteredResources = resources.slice();
......@@ -177,39 +168,6 @@ function optimizeTask(opts) {
};
}
exports.optimizeTask = optimizeTask;
function inlineAmdImages(src, result) {
for (const outputFile of result.files) {
for (const sourceFile of outputFile.sources) {
if (sourceFile.path && /\.js$/.test(sourceFile.path)) {
sourceFile.contents = sourceFile.contents.replace(/\([^.]+\.registerAndGetAmdImageURL\(([^)]+)\)\)/g, (_, m0) => {
let imagePath = m0;
// remove `` or ''
if ((imagePath.charAt(0) === '`' && imagePath.charAt(imagePath.length - 1) === '`')
|| (imagePath.charAt(0) === '\'' && imagePath.charAt(imagePath.length - 1) === '\'')) {
imagePath = imagePath.substr(1, imagePath.length - 2);
}
if (!/\.(png|svg)$/.test(imagePath)) {
console.log(`original: ${_}`);
return _;
}
const repoLocation = path.join(src, imagePath);
const absoluteLocation = path.join(REPO_ROOT_PATH, repoLocation);
if (!fs.existsSync(absoluteLocation)) {
const message = `Invalid amd image url in file ${sourceFile.path}: ${imagePath}`;
console.log(message);
throw new Error(message);
}
const fileContents = fs.readFileSync(absoluteLocation);
const mime = /\.svg$/.test(imagePath) ? 'image/svg+xml' : 'image/png';
// Mark the file as inlined so we don't ship it by itself
result.cssInlinedResources.push(repoLocation);
return `("data:${mime};base64,${fileContents.toString('base64')}")`;
});
}
}
}
return result;
}
/**
* Wrap around uglify and allow the preserveComments function
* to have a file "context" to include our copyright only once per file.
......
......@@ -6,7 +6,6 @@
'use strict';
import * as es from 'event-stream';
import * as fs from 'fs';
import * as gulp from 'gulp';
import * as concat from 'gulp-concat';
import * as minifyCSS from 'gulp-cssnano';
......@@ -160,10 +159,6 @@ export interface IOptimizeTaskOpts {
* (emit bundleInfo.json file)
*/
bundleInfo: boolean;
/**
* replace calls to `registerAndGetAmdImageURL` with data uris
*/
inlineAmdImages: boolean;
/**
* (out folder name)
*/
......@@ -197,14 +192,6 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err || !result) { return bundlesStream.emit('error', JSON.stringify(err)); }
if (opts.inlineAmdImages) {
try {
result = inlineAmdImages(src, result);
} catch (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
}
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
......@@ -249,42 +236,6 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
};
}
function inlineAmdImages(src: string, result: bundle.IBundleResult): bundle.IBundleResult {
for (const outputFile of result.files) {
for (const sourceFile of outputFile.sources) {
if (sourceFile.path && /\.js$/.test(sourceFile.path)) {
sourceFile.contents = sourceFile.contents.replace(/\([^.]+\.registerAndGetAmdImageURL\(([^)]+)\)\)/g, (_, m0) => {
let imagePath = m0;
// remove `` or ''
if ((imagePath.charAt(0) === '`' && imagePath.charAt(imagePath.length - 1) === '`')
|| (imagePath.charAt(0) === '\'' && imagePath.charAt(imagePath.length - 1) === '\'')) {
imagePath = imagePath.substr(1, imagePath.length - 2);
}
if (!/\.(png|svg)$/.test(imagePath)) {
console.log(`original: ${_}`);
return _;
}
const repoLocation = path.join(src, imagePath);
const absoluteLocation = path.join(REPO_ROOT_PATH, repoLocation);
if (!fs.existsSync(absoluteLocation)) {
const message = `Invalid amd image url in file ${sourceFile.path}: ${imagePath}`;
console.log(message);
throw new Error(message);
}
const fileContents = fs.readFileSync(absoluteLocation);
const mime = /\.svg$/.test(imagePath) ? 'image/svg+xml' : 'image/png';
// Mark the file as inlined so we don't ship it by itself
result.cssInlinedResources.push(repoLocation);
return `("data:${mime};base64,${fileContents.toString('base64')}")`;
});
}
}
}
return result;
}
declare class FileWithCopyright extends VinylFile {
public __hasOurCopyright: boolean;
}
......
......@@ -202,7 +202,7 @@ class Label {
const l = label[i];
const id = options?.domId && `${options?.domId}_${i}`;
dom.append(this.container, dom.$('a.label-name', { id, 'data-icon-label-count': label.length, 'data-icon-label-index': i }, l));
dom.append(this.container, dom.$('a.label-name', { id, 'data-icon-label-count': label.length, 'data-icon-label-index': i, 'role': 'treeitem' }, l));
if (i < label.length - 1) {
dom.append(this.container, dom.$('span.label-separator', undefined, options?.separator || '/'));
......@@ -270,7 +270,7 @@ class LabelWithHighlights {
const m = matches ? matches[i] : undefined;
const id = options?.domId && `${options?.domId}_${i}`;
const name = dom.$('a.label-name', { id, 'data-icon-label-count': label.length, 'data-icon-label-index': i });
const name = dom.$('a.label-name', { id, 'data-icon-label-count': label.length, 'data-icon-label-index': i, 'role': 'treeitem' });
const highlightedLabel = new HighlightedLabel(dom.append(this.container, name), this.supportCodicons);
highlightedLabel.set(l, m, options?.title, options?.labelEscapeNewLines);
......
......@@ -12,12 +12,3 @@ export function getPathFromAmdModule(requirefn: typeof require, relativePath: st
export function getUriFromAmdModule(requirefn: typeof require, relativePath: string): URI {
return URI.parse(requirefn.toUrl(relativePath));
}
/**
* Reference a resource that might be inlined.
* Do not inline icons that will be used by the native mac touchbar.
* Do not rename this method unless you adopt the build scripts.
*/
export function registerAndGetAmdImageURL(absolutePath: string): string {
return require.toUrl(absolutePath);
}
......@@ -663,6 +663,7 @@ export class DropDownMenuActionViewItem extends ExtensionActionViewItem {
export function getContextMenuActions(menuService: IMenuService, contextKeyService: IContextKeyService, instantiationService: IInstantiationService, extension: IExtension | undefined | null): ExtensionAction[][] {
const scopedContextKeyService = contextKeyService.createScoped();
if (extension) {
scopedContextKeyService.createKey<string>('extension', extension.identifier.id);
scopedContextKeyService.createKey<boolean>('isBuiltinExtension', extension.type === ExtensionType.System);
scopedContextKeyService.createKey<boolean>('extensionHasConfiguration', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.configuration);
if (extension.state === ExtensionState.Installed) {
......
......@@ -22,6 +22,7 @@ export const EXECUTE_CELL_COMMAND_ID = 'workbench.notebook.cell.execute';
// Cell sizing related
export const CELL_MARGIN = 20;
export const CELL_RUN_GUTTER = 32; // TODO should be dynamic based on execution order width, and runnable enablement
export const EDITOR_TOP_MARGIN = 8;
export const EDITOR_TOP_PADDING = 8;
export const EDITOR_BOTTOM_PADDING = 8;
export const EDITOR_TOOLBAR_HEIGHT = 22;
......
......@@ -321,7 +321,7 @@ registerAction2(class extends Action2 {
});
}
async run(accessor: ServicesAccessor): Promise<void> {
async run(accessor: ServicesAccessor, context?: INotebookCellActionContext): Promise<void> {
return changeActiveCellToKind(CellKind.Markdown, accessor);
}
});
......@@ -384,7 +384,7 @@ async function changeActiveCellToKind(kind: CellKind, accessor: ServicesAccessor
return;
}
editor.focusNotebookCell(newCell, false);
editor.focusNotebookCell(newCell, true);
editor.deleteNotebookCell(activeCell);
}
......
......@@ -155,7 +155,7 @@ export interface INotebookEditor {
/**
* Layout the cell with a new height
*/
layoutNotebookCell(cell: ICellViewModel, height: number): void;
layoutNotebookCell(cell: ICellViewModel, height: number): Promise<void>;
/**
* Render the output in webview layer
......
......@@ -335,6 +335,14 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
const viewState = this.loadTextEditorViewState(input);
this.notebookViewModel.restoreEditorViewState(viewState);
if (viewState?.scrollPosition !== undefined) {
this.list!.scrollTop = viewState!.scrollPosition.top;
this.list!.scrollLeft = viewState!.scrollPosition.left;
} else {
this.list!.scrollTop = 0;
this.list!.scrollLeft = 0;
}
this.localStore.add(this.eventDispatcher.onDidChangeMetadata((e) => {
this.editorEditable?.set(e.source.editable);
}));
......@@ -409,6 +417,10 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
private saveTextEditorViewState(input: NotebookEditorInput): void {
if (this.group && this.notebookViewModel) {
const state = this.notebookViewModel.saveEditorViewState();
if (this.list) {
state.scrollPosition = { left: this.list.scrollLeft, top: this.list.scrollTop };
}
this.editorMemento.saveEditorState(this.group, input.resource, state);
}
}
......@@ -552,7 +564,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
//#endregion
//#region Cell operations
layoutNotebookCell(cell: ICellViewModel, height: number) {
async layoutNotebookCell(cell: ICellViewModel, height: number): Promise<void> {
let relayout = (cell: ICellViewModel, height: number) => {
let index = this.notebookViewModel!.getViewCellIndex(cell);
if (index >= 0) {
......@@ -560,9 +572,13 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
}
};
let r: () => void;
DOM.scheduleAtNextAnimationFrame(() => {
relayout(cell, height);
r();
});
return new Promise(resolve => { r = resolve; });
}
async insertNotebookCell(cell: ICellViewModel, type: CellKind, direction: 'above' | 'below', initialText: string = ''): Promise<void> {
......@@ -577,9 +593,13 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
newCell.editState = CellEditState.Editing;
}
let r: () => void;
DOM.scheduleAtNextAnimationFrame(() => {
this.list?.revealInCenterIfOutsideViewport(insertIndex);
r();
});
return new Promise(resolve => { r = resolve; });
}
async deleteNotebookCell(cell: ICellViewModel): Promise<void> {
......@@ -588,26 +608,30 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
this.notebookViewModel!.deleteCell(index, true);
}
moveCellDown(cell: ICellViewModel): void {
async moveCellDown(cell: ICellViewModel): Promise<void> {
const index = this.notebookViewModel!.getViewCellIndex(cell);
const newIdx = index + 1;
this.moveCellToIndex(index, newIdx);
return this.moveCellToIndex(index, newIdx);
}
moveCellUp(cell: ICellViewModel): void {
async moveCellUp(cell: ICellViewModel): Promise<void> {
const index = this.notebookViewModel!.getViewCellIndex(cell);
const newIdx = index - 1;
this.moveCellToIndex(index, newIdx);
return this.moveCellToIndex(index, newIdx);
}
private moveCellToIndex(index: number, newIdx: number): void {
private async moveCellToIndex(index: number, newIdx: number): Promise<void> {
if (!this.notebookViewModel!.moveCellToIdx(index, newIdx, true)) {
return;
}
let r: () => void;
DOM.scheduleAtNextAnimationFrame(() => {
this.list?.revealInCenterIfOutsideViewport(index + 1);
r();
});
return new Promise(resolve => { r = resolve; });
}
editNotebookCell(cell: CellViewModel): void {
......@@ -805,6 +829,7 @@ registerThemingParticipant((theme, collector) => {
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .output { margin: 0px ${CELL_MARGIN}px 0px ${CELL_MARGIN + CELL_RUN_GUTTER}px }`);
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .cell .cell-editor-container { width: calc(100% - ${CELL_RUN_GUTTER}px); }`);
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .cell .markdown-editor-container { margin-left: ${CELL_RUN_GUTTER}px; }`);
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .monaco-list-row > div.cell.markdown { padding-left: ${CELL_RUN_GUTTER}px; }`);
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .cell .run-button-container { width: ${CELL_RUN_GUTTER}px; }`);
});
......@@ -306,6 +306,10 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
}
private _revealInternal(index: number, ignoreIfInsideViewport: boolean, revealPosition: CellRevealPosition) {
if (index >= this.view.length) {
return;
}
const scrollTop = this.view.getScrollTop();
const wrapperBottom = scrollTop + this.view.renderHeight;
const elementTop = this.view.elementTop(index);
......
......@@ -179,7 +179,8 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
renderTemplate(container: HTMLElement): CellRenderTemplate {
const codeInnerContent = document.createElement('div');
DOM.addClasses(codeInnerContent, 'cell', 'code');
codeInnerContent.style.display = 'none';
const editorContainer = DOM.append(codeInnerContent, $('.markdown-editor-container'));
editorContainer.style.display = 'none';
const disposables = new DisposableStore();
const toolbar = this.createToolbar(container);
......@@ -196,7 +197,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
return {
container: container,
cellContainer: innerContent,
editingContainer: codeInnerContent,
editingContainer: editorContainer,
disposables,
toolbar,
toJSON: () => { return {}; }
......
......@@ -13,6 +13,8 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { raceCancellation } from 'vs/base/common/async';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { EDITOR_TOP_PADDING, EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { ITextModel } from 'vs/editor/common/model';
import { IDimension } from 'vs/base/browser/dom';
export class StatefullMarkdownCell extends Disposable {
private editor: CodeEditorWidget | null = null;
......@@ -22,9 +24,9 @@ export class StatefullMarkdownCell extends Disposable {
private localDisposables: DisposableStore;
constructor(
notebookEditor: INotebookEditor,
public viewCell: MarkdownCellViewModel,
templateData: CellRenderTemplate,
private notebookEditor: INotebookEditor,
private viewCell: MarkdownCellViewModel,
private templateData: CellRenderTemplate,
editorOptions: IEditorOptions,
instantiationService: IInstantiationService
) {
......@@ -50,6 +52,8 @@ export class StatefullMarkdownCell extends Disposable {
if (notebookEditor.getActiveCell() === viewCell) {
this.editor!.focus();
}
this.bindEditorListeners(this.editor!.getModel()!);
} else {
this.editingContainer!.style.display = 'block';
this.editingContainer!.innerHTML = '';
......@@ -61,7 +65,6 @@ export class StatefullMarkdownCell extends Disposable {
}
}, {});
const cts = new CancellationTokenSource();
this._register({ dispose() { cts.dispose(true); } });
raceCancellation(viewCell.resolveTextModel(), cts.token).then(model => {
......@@ -86,71 +89,15 @@ export class StatefullMarkdownCell extends Disposable {
viewCell.attachTextEditor(this.editor!);
this.localDisposables.add(model.onDidChangeContent(() => {
viewCell.setText(model.getLinesContent());
let clientHeight = this.cellContainer.clientHeight;
this.cellContainer.innerHTML = '';
let renderedHTML = viewCell.getHTML();
if (renderedHTML) {
this.cellContainer.appendChild(renderedHTML);
clientHeight = this.cellContainer.clientHeight;
}
notebookEditor.layoutNotebookCell(viewCell, this.editor!.getContentHeight() + 32 + clientHeight);
}));
if (viewCell.editState === CellEditState.Editing) {
this.editor!.focus();
}
});
this.localDisposables.add(this.editor.onDidContentSizeChange(e => {
let viewLayout = this.editor!.getLayoutInfo();
if (e.contentHeightChanged) {
this.editor!.layout(
{
width: viewLayout.width,
height: e.contentHeight
}
);
const clientHeight = this.cellContainer.clientHeight;
notebookEditor.layoutNotebookCell(viewCell, e.contentHeight + 32 + clientHeight);
}
}));
let cellWidthResizeObserver = getResizesObserver(templateData.editingContainer!, {
width: width,
height: totalHeight
}, () => {
let newWidth = cellWidthResizeObserver.getWidth();
let realContentHeight = this.editor!.getContentHeight();
let layoutInfo = this.editor!.getLayoutInfo();
// the dimension generated by the resize observer are float numbers, let's round it a bit to avoid relayout.
if (newWidth < layoutInfo.width - 0.3 || layoutInfo.width + 0.3 < newWidth) {
this.editor!.layout(
{
width: newWidth,
height: realContentHeight
}
);
}
this.bindEditorListeners(model, {
width: width,
height: totalHeight
});
});
cellWidthResizeObserver.startObserving();
this.localDisposables.add(cellWidthResizeObserver);
let markdownRenderer = viewCell.getMarkdownRenderer();
this.cellContainer.innerHTML = '';
let renderedHTML = viewCell.getHTML();
if (renderedHTML) {
this.cellContainer.appendChild(renderedHTML);
this.localDisposables.add(markdownRenderer.onDidUpdateRender(() => {
const clientHeight = this.cellContainer.clientHeight;
notebookEditor.layoutNotebookCell(viewCell, clientHeight);
}));
}
}
const clientHeight = this.cellContainer.clientHeight;
......@@ -204,6 +151,66 @@ export class StatefullMarkdownCell extends Disposable {
viewUpdate();
}
bindEditorListeners(model: ITextModel, dimension?: IDimension) {
this.localDisposables.add(model.onDidChangeContent(() => {
this.viewCell.setText(model.getLinesContent());
let clientHeight = this.cellContainer.clientHeight;
this.cellContainer.innerHTML = '';
let renderedHTML = this.viewCell.getHTML();
if (renderedHTML) {
this.cellContainer.appendChild(renderedHTML);
clientHeight = this.cellContainer.clientHeight;
}
this.notebookEditor.layoutNotebookCell(this.viewCell, this.editor!.getContentHeight() + 32 + clientHeight);
}));
this.localDisposables.add(this.editor!.onDidContentSizeChange(e => {
let viewLayout = this.editor!.getLayoutInfo();
if (e.contentHeightChanged) {
this.editor!.layout(
{
width: viewLayout.width,
height: e.contentHeight
}
);
const clientHeight = this.cellContainer.clientHeight;
this.notebookEditor.layoutNotebookCell(this.viewCell, e.contentHeight + 32 + clientHeight);
}
}));
let cellWidthResizeObserver = getResizesObserver(this.templateData.editingContainer!, dimension, () => {
let newWidth = cellWidthResizeObserver.getWidth();
let realContentHeight = this.editor!.getContentHeight();
let layoutInfo = this.editor!.getLayoutInfo();
// the dimension generated by the resize observer are float numbers, let's round it a bit to avoid relayout.
if (newWidth < layoutInfo.width - 0.3 || layoutInfo.width + 0.3 < newWidth) {
this.editor!.layout(
{
width: newWidth,
height: realContentHeight
}
);
}
});
cellWidthResizeObserver.startObserving();
this.localDisposables.add(cellWidthResizeObserver);
let markdownRenderer = this.viewCell.getMarkdownRenderer();
this.cellContainer.innerHTML = '';
let renderedHTML = this.viewCell.getHTML();
if (renderedHTML) {
this.cellContainer.appendChild(renderedHTML);
this.localDisposables.add(markdownRenderer.onDidUpdateRender(() => {
const clientHeight = this.cellContainer.clientHeight;
this.notebookEditor.layoutNotebookCell(this.viewCell, clientHeight);
}));
}
}
dispose() {
this.viewCell.detachTextEditor();
super.dispose();
......
......@@ -12,7 +12,7 @@ import { ICellViewModel, CellFindMatch, MarkdownCellLayoutInfo, MarkdownCellLayo
import { MarkdownRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/mdRenderer';
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
import { CellKind, ICell } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CELL_MARGIN } from 'vs/workbench/contrib/notebook/browser/constants';
import { CELL_MARGIN, CELL_RUN_GUTTER } from 'vs/workbench/contrib/notebook/browser/constants';
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
export class MarkdownCellViewModel extends BaseCellViewModel implements ICellViewModel {
......@@ -55,7 +55,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
layoutChange(state: MarkdownCellLayoutChangeEvent) {
// recompute
const editorWidth = state.outerWidth !== undefined ? state.outerWidth - CELL_MARGIN * 2 : 0;
const editorWidth = state.outerWidth !== undefined ? state.outerWidth - CELL_MARGIN * 2 - CELL_RUN_GUTTER : 0;
this._layoutInfo = {
fontInfo: state.font || null,
......
......@@ -25,6 +25,7 @@ import { NotebookEventDispatcher, NotebookMetadataChangedEvent } from 'vs/workbe
export interface INotebookEditorViewState {
editingCells: { [key: number]: boolean };
editorViewStates: { [key: number]: editorCommon.ICodeEditorViewState | null };
scrollPosition?: { left: number; top: number; };
}
export interface ICellModelDecorations {
......
......@@ -314,8 +314,19 @@
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-overrides {
opacity: 0.5;
opacity: 0.9;
font-style: italic;
margin-right: 4px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-ignored {
opacity: 0.9;
font-style: italic;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-ignored .codicon {
vertical-align: text-top;
padding-left: 1px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-overrides a.modified-scope {
......
......@@ -50,6 +50,7 @@ import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
import { IUserDataSyncEnablementService, getDefaultIgnoredSettings } from 'vs/platform/userDataSync/common/userDataSync';
import { CodiconLabel } from 'vs/base/browser/ui/codiconLabel/codiconLabel';
const $ = DOM.$;
......@@ -204,6 +205,7 @@ interface ISettingItemTemplate<T = any> extends IDisposableTemplate {
controlElement: HTMLElement;
deprecationWarningElement: HTMLElement;
otherOverridesElement: HTMLElement;
syncIgnoredElement: HTMLElement;
toolbar: ToolBar;
elementDisposables: IDisposable[];
}
......@@ -300,6 +302,10 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
private readonly _onDidFocusSetting = this._register(new Emitter<SettingsTreeSettingElement>());
readonly onDidFocusSetting: Event<SettingsTreeSettingElement> = this._onDidFocusSetting.event;
private ignoredSettings: string[];
private readonly _onDidChangeIgnoredSettings = this._register(new Emitter<void>());
readonly onDidChangeIgnoredSettings: Event<void> = this._onDidChangeIgnoredSettings.event;
// Put common injections back here
constructor(
private readonly settingActions: IAction[],
......@@ -311,8 +317,17 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
@ICommandService protected readonly _commandService: ICommandService,
@IContextMenuService protected readonly _contextMenuService: IContextMenuService,
@IKeybindingService protected readonly _keybindingService: IKeybindingService,
@IConfigurationService protected readonly _configService: IConfigurationService,
) {
super();
this.ignoredSettings = getIgnoredSettings(getDefaultIgnoredSettings(), this._configService);
this._register(this._configService.onDidChangeConfiguration(e => {
if (e.affectedKeys.includes('sync.ignoredSettings')) {
this.ignoredSettings = getIgnoredSettings(getDefaultIgnoredSettings(), this._configService);
this._onDidChangeIgnoredSettings.fire();
}
}));
}
renderTemplate(container: HTMLElement): any {
......@@ -323,6 +338,14 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
throw new Error('to override');
}
protected createSyncIgnoredElement(container: HTMLElement): HTMLElement {
const syncIgnoredElement = DOM.append(container, $('span.setting-item-ignored'));
const syncIgnoredLabel = new CodiconLabel(syncIgnoredElement);
syncIgnoredLabel.text = `($(eye-closed) ${localize('extensionSyncIgnoredLabel', 'Sync: Ignored')})`;
return syncIgnoredElement;
}
protected renderCommonTemplate(tree: any, _container: HTMLElement, typeClass: string): ISettingItemTemplate {
DOM.addClass(_container, 'setting-item');
DOM.addClass(_container, 'setting-item-' + typeClass);
......@@ -333,6 +356,8 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
const categoryElement = DOM.append(labelCategoryContainer, $('span.setting-item-category'));
const labelElement = DOM.append(labelCategoryContainer, $('span.setting-item-label'));
const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides'));
const syncIgnoredElement = this.createSyncIgnoredElement(titleElement);
const descriptionElement = DOM.append(container, $('.setting-item-description'));
const modifiedIndicatorElement = DOM.append(container, $('.setting-item-modified-indicator'));
modifiedIndicatorElement.title = localize('modified', "Modified");
......@@ -358,6 +383,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
controlElement,
deprecationWarningElement,
otherOverridesElement,
syncIgnoredElement,
toolbar
};
......@@ -447,8 +473,10 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
template.descriptionElement.id = baseId + '_setting_description';
template.otherOverridesElement.innerHTML = '';
template.otherOverridesElement.style.display = 'none';
if (element.overriddenScopeList.length) {
template.otherOverridesElement.style.display = 'inline';
const otherOverridesLabel = element.isConfigured ?
localize('alsoConfiguredIn', "Also modified in") :
localize('configuredIn', "Modified in");
......@@ -482,6 +510,14 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
DOM.toggleClass(template.containerElement, 'is-deprecated', !!deprecationText);
this.renderValue(element, <ISettingItemTemplate>template, onChange);
const update = () => {
template.syncIgnoredElement.style.display = this.ignoredSettings.includes(element.setting.key) ? 'inline' : 'none';
};
update();
template.elementDisposables.push(this.onDidChangeIgnoredSettings(() => {
update();
}));
}
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: DisposableStore): HTMLElement {
......@@ -1085,6 +1121,7 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
const categoryElement = DOM.append(titleElement, $('span.setting-item-category'));
const labelElement = DOM.append(titleElement, $('span.setting-item-label'));
const otherOverridesElement = DOM.append(titleElement, $('span.setting-item-overrides'));
const syncIgnoredElement = this.createSyncIgnoredElement(titleElement);
const descriptionAndValueElement = DOM.append(container, $('.setting-item-value-description'));
const controlElement = DOM.append(descriptionAndValueElement, $('.setting-item-bool-control'));
......@@ -1138,6 +1175,7 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
descriptionElement,
deprecationWarningElement,
otherOverridesElement,
syncIgnoredElement,
toolbar
};
......
......@@ -692,6 +692,7 @@ export class RepositoryPane extends ViewPane {
const label = binding ? binding.getLabel() : (platform.isMacintosh ? 'Cmd+Enter' : 'Ctrl+Enter');
const placeholderText = format(this.repository.input.placeholder, label);
this.inputEditor.updateOptions({ ariaLabel: placeholderText });
placeholderTextContainer.textContent = placeholderText;
};
......
......@@ -111,7 +111,7 @@ export class TerminalService implements ITerminalService {
this._activeTabIndex = 0;
this._isShuttingDown = false;
this._findState = new FindReplaceState();
lifecycleService.onBeforeShutdown(async event => event.veto(await this._onBeforeShutdown()));
lifecycleService.onBeforeShutdown(async event => event.veto(this._onBeforeShutdown()));
lifecycleService.onShutdown(() => this._onShutdown());
if (this._terminalNativeService) {
this._terminalNativeService.onOpenFileRequest(e => this._onOpenFileRequest(e));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册