提交 238db1cb 编写于 作者: J Joao Moreno

Merge branch 'jayjun-commit-counter'

......@@ -519,6 +519,7 @@ export class Repository implements Disposable {
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)");
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
this._sourceControl.quickDiffProvider = this;
this._sourceControl.inputBox.lineWarningLength = 72;
this.disposables.push(this._sourceControl);
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes"));
......
......@@ -5782,6 +5782,11 @@ declare module 'vscode' {
* A string to show as place holder in the input box to guide the user.
*/
placeholder: string;
/**
* The warning threshold for lines in the input box.
*/
lineWarningLength: number | undefined;
}
interface QuickDiffProvider {
......
......@@ -391,4 +391,14 @@ export class MainThreadSCM implements MainThreadSCMShape {
repository.input.placeholder = placeholder;
}
$setLineWarningLength(sourceControlHandle: number, lineWarningLength: number): void {
const repository = this._repositories[sourceControlHandle];
if (!repository) {
return;
}
repository.input.lineWarningLength = lineWarningLength;
}
}
......@@ -410,6 +410,7 @@ export interface MainThreadSCMShape extends IDisposable {
$setInputBoxValue(sourceControlHandle: number, value: string): void;
$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
$setLineWarningLength(sourceControlHandle: number, lineWarningLength: number): void;
}
export type DebugSessionUUID = string;
......
......@@ -110,7 +110,7 @@ function compareResourceStates(a: vscode.SourceControlResourceState, b: vscode.S
return result;
}
export class ExtHostSCMInputBox {
export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
private _value: string = '';
......@@ -140,6 +140,17 @@ export class ExtHostSCMInputBox {
this._placeholder = placeholder;
}
private _lineWarningLength: number | undefined;
get lineWarningLength(): number | undefined {
return this._lineWarningLength;
}
set lineWarningLength(lineWarningLength: number) {
this._proxy.$setLineWarningLength(this._sourceControlHandle, lineWarningLength);
this._lineWarningLength = lineWarningLength;
}
constructor(private _proxy: MainThreadSCMShape, private _sourceControlHandle: number) {
// noop
}
......
......@@ -74,5 +74,11 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
default: 'all',
description: localize('diffDecorations', "Controls diff decorations in the editor.")
},
'scm.inputCounter': {
type: 'string',
enum: ['always', 'warn', 'off'],
default: 'warn',
description: localize('inputCounter', "Controls when to display the input counter.")
}
}
});
\ No newline at end of file
......@@ -8,7 +8,7 @@
import 'vs/css!./media/scmViewlet';
import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import Event, { Emitter, chain, mapEvent } from 'vs/base/common/event';
import Event, { Emitter, chain, mapEvent, anyEvent } from 'vs/base/common/event';
import { domEvent, stop } from 'vs/base/browser/event';
import { basename } from 'vs/base/common/paths';
import { onUnexpectedError } from 'vs/base/common/errors';
......@@ -45,7 +45,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { IMessage, InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { Command } from 'vs/editor/common/modes';
......@@ -56,6 +56,7 @@ import { format } from 'vs/base/common/strings';
import { ISpliceable, ISequence, ISplice } from 'vs/base/common/sequence';
import { firstIndex } from 'vs/base/common/arrays';
import { WorkbenchList, IListService } from 'vs/platform/list/browser/listService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
// TODO@Joao
// Need to subclass MenuItemActionItem in order to respect
......@@ -695,7 +696,8 @@ export class RepositoryPanel extends ViewletPanel {
@IWorkbenchEditorService protected editorService: IWorkbenchEditorService,
@IEditorGroupService protected editorGroupService: IEditorGroupService,
@IContextKeyService protected contextKeyService: IContextKeyService,
@IInstantiationService protected instantiationService: IInstantiationService
@IInstantiationService protected instantiationService: IInstantiationService,
@IConfigurationService protected configurationService: IConfigurationService
) {
super(repository.provider.label, {}, keybindingService, contextMenuService);
this.menus = instantiationService.createInstance(SCMMenus, repository.provider);
......@@ -753,10 +755,63 @@ export class RepositoryPanel extends ViewletPanel {
this.inputBox.setPlaceHolder(placeholder);
};
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true });
const validation = (text: string): IMessage => {
const setting = this.configurationService.getValue<'always' | 'warn' | 'off'>('scm.inputCounter');
if (setting === 'off') {
return null;
}
let position = this.inputBox.inputElement.selectionStart;
let start = 0, end;
let match: RegExpExecArray;
const regex = /\r?\n/g;
while ((match = regex.exec(text)) && position > match.index) {
start = match.index + match[0].length;
}
end = match ? match.index : text.length;
const line = text.substring(start, end);
const lineWarningLength = this.repository.input.lineWarningLength;
if (lineWarningLength === undefined) {
return {
content: localize('commitMessageInfo', "{0} characters in current line", text.length),
type: MessageType.INFO
};
}
if (line.length <= lineWarningLength) {
if (setting !== 'always') {
return null;
}
return {
content: localize('commitMessageCountdown', "{0} characters left in current line", lineWarningLength - line.length),
type: MessageType.INFO
};
} else {
return {
content: localize('commitMessageWarning', "{0} characters over {1} in current line", line.length - lineWarningLength, lineWarningLength),
type: MessageType.WARNING
};
}
};
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, {
flexibleHeight: true,
validationOptions: { validation: validation }
});
this.disposables.push(attachInputBoxStyler(this.inputBox, this.themeService));
this.disposables.push(this.inputBox);
const onKeyUp = domEvent(this.inputBox.inputElement, 'keyup');
const onMouseUp = domEvent(this.inputBox.inputElement, 'mouseup');
anyEvent<any>(onKeyUp, onMouseUp)(() => this.inputBox.validate(), null, this.disposables);
this.inputBox.value = this.repository.input.value;
this.inputBox.onDidChange(value => this.repository.input.value = value, null, this.disposables);
this.repository.input.onDidChange(value => this.inputBox.value = value, null, this.disposables);
......
......@@ -74,6 +74,8 @@ export interface ISCMInput {
placeholder: string;
readonly onDidChangePlaceholder: Event<string>;
lineWarningLength: number | undefined;
}
export interface ISCMRepository extends IDisposable {
......
......@@ -39,6 +39,8 @@ class SCMInput implements ISCMInput {
private _onDidChangePlaceholder = new Emitter<string>();
get onDidChangePlaceholder(): Event<string> { return this._onDidChangePlaceholder.event; }
public lineWarningLength: number | undefined = undefined;
}
class SCMRepository implements ISCMRepository {
......@@ -106,4 +108,4 @@ export class SCMService implements ISCMService {
return repository;
}
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册