ソースを参照

Adds Strings.pluralize

main
Eric Amodio 6年前
コミット
867001dc60
10個のファイルの変更64行の追加57行の削除
  1. +2
    -1
      src/annotations/annotations.ts
  2. +9
    -21
      src/git/models/branch.ts
  3. +24
    -16
      src/git/models/status.ts
  4. +12
    -0
      src/system/string.ts
  5. +1
    -2
      src/views/nodes/comparisonResultsNode.ts
  6. +2
    -1
      src/views/nodes/statusFileCommitsNode.ts
  7. +1
    -1
      src/views/nodes/statusFilesNode.ts
  8. +1
    -1
      src/views/nodes/statusFilesResultsNode.ts
  9. +7
    -10
      src/views/nodes/statusUpstreamNode.ts
  10. +5
    -4
      src/views/resultsExplorer.ts

+ 2
- 1
src/annotations/annotations.ts ファイルの表示

@ -51,6 +51,7 @@ const defaultHeatmapHotColor = '#f66a0a';
const defaultHeatmapColdColor = '#0a60f6';
const escapeMarkdownRegEx = /[`\>\#\*\_\-\+\.]/g;
// const sampleMarkdown = '## message `not code` *not important* _no underline_ \n> don\'t quote me \n- don\'t list me \n+ don\'t list me \n1. don\'t list me \nnot h1 \n=== \nnot h2 \n---\n***\n---\n___';
const markdownHeaderReplacement = `${GlyphChars.ZeroWidthSpace}===`;
let computedHeatmapColor: {
color: string;
@ -154,7 +155,7 @@ export class Annotations {
// Escape markdown
.replace(escapeMarkdownRegEx, '\\$&')
// Escape markdown header (since the above regex won't match it)
.replace(/^===/gm, `${GlyphChars.ZeroWidthSpace}===`)
.replace(/^===/gm, markdownHeaderReplacement)
// Keep under the same block-quote
.replace(/\n/g, ' \n');
message = `\n\n> ${message}`;

+ 9
- 21
src/git/models/branch.ts ファイルの表示

@ -1,4 +1,4 @@
import { GlyphChars } from '../../constants';
import { GitStatus } from './status';
'use strict';
@ -63,26 +63,14 @@ export class GitBranch {
return undefined;
}
getTrackingStatus(options: { empty?: string; expand?: boolean; prefix?: string; separator?: string } = {}): string {
options = { empty: '', prefix: '', separator: ' ', ...options };
if (this.tracking === undefined || (this.state.behind === 0 && this.state.ahead === 0)) return options.empty!;
if (options.expand) {
let status = '';
if (this.state.behind) {
status += `${this.state.behind} ${this.state.behind === 1 ? 'commit' : 'commits'} behind`;
}
if (this.state.ahead) {
status += `${status === '' ? '' : options.separator}${this.state.ahead} ${
this.state.ahead === 1 ? 'commit' : 'commits'
} ahead`;
}
return `${options.prefix}${status}`;
}
return `${options.prefix}${this.state.behind}${GlyphChars.ArrowDown}${options.separator}${this.state.ahead}${
GlyphChars.ArrowUp
}`;
getTrackingStatus(options?: {
empty?: string;
expand?: boolean;
prefix?: string;
separator?: string;
suffix?: string;
}): string {
return GitStatus.getUpstreamStatus(this.tracking, this.state, options);
}
isValid(): boolean {

+ 24
- 16
src/git/models/status.ts ファイルの表示

@ -57,17 +57,19 @@ export class GitStatus {
if (options.expand) {
let status = '';
if (this._diff.added) {
status += `${this._diff.added} ${this._diff.added === 1 ? 'file' : 'files'} added`;
status += `${Strings.pluralize('file', this._diff.added)} added`;
}
if (this._diff.changed) {
status += `${status === '' ? '' : options.separator}${this._diff.changed} ${
this._diff.changed === 1 ? 'file' : 'files'
} changed`;
status += `${status === '' ? '' : options.separator}${this._diff.changed} ${Strings.pluralize(
'file',
this._diff.changed
)} changed`;
}
if (this._diff.deleted) {
status += `${status === '' ? '' : options.separator}${this._diff.deleted} ${
this._diff.deleted === 1 ? 'file' : 'files'
} deleted`;
status += `${status === '' ? '' : options.separator}${this._diff.deleted} ${Strings.pluralize(
'file',
this._diff.deleted
)} deleted`;
}
return `${options.prefix}${status}`;
}
@ -77,24 +79,30 @@ export class GitStatus {
}`;
}
getUpstreamStatus(options: { empty?: string; expand?: boolean; prefix?: string; separator?: string } = {}): string {
getUpstreamStatus(options: { empty?: string; expand?: boolean; prefix?: string; separator?: string }): string {
return GitStatus.getUpstreamStatus(this.upstream, this.state, options);
}
static getUpstreamStatus(
upstream: string | undefined,
state: { ahead: number; behind: number },
options: { empty?: string; expand?: boolean; prefix?: string; separator?: string } = {}
): string {
options = { empty: '', prefix: '', separator: ' ', ...options };
if (this.upstream === undefined || (this.state.behind === 0 && this.state.ahead === 0)) return options.empty!;
if (upstream === undefined || (state.behind === 0 && state.ahead === 0)) return options.empty!;
if (options.expand) {
let status = '';
if (this.state.behind) {
status += `${this.state.behind} ${this.state.behind === 1 ? 'commit' : 'commits'} behind`;
if (state.behind) {
status += `${Strings.pluralize('commit', state.behind)} behind`;
}
if (this.state.ahead) {
status += `${status === '' ? '' : options.separator}${this.state.ahead} ${
this.state.ahead === 1 ? 'commit' : 'commits'
} ahead`;
if (state.ahead) {
status += `${status === '' ? '' : options.separator}${Strings.pluralize('commit', state.ahead)} ahead`;
}
return `${options.prefix}${status}`;
}
return `${options.prefix}${this.state.behind}${GlyphChars.ArrowDown}${options.separator}${this.state.ahead}${
return `${options.prefix}${state.behind}${GlyphChars.ArrowDown}${options.separator}${state.ahead}${
GlyphChars.ArrowUp
}`;
}

+ 12
- 0
src/system/string.ts ファイルの表示

@ -108,6 +108,18 @@ export namespace Strings {
return s;
}
export function pluralize(
s: string,
count: number,
options?: { number?: string; plural?: string; suffix?: string; zero?: string }
) {
if (options === undefined) return `${count} ${s}${count === 1 ? '' : 's'}`;
return `${count === 0 ? options.zero || count : options.number || count} ${
count === 1 ? s : options.plural || `${s}${options.suffix}`
}`;
}
// Removes \ / : * ? " < > | and C0 and C1 control codes
const illegalCharsForFSRegEx = /[\\/:*?"<>|\x00-\x1f\x80-\x9f]/g;

+ 1
- 2
src/views/nodes/comparisonResultsNode.ts ファイルの表示

@ -30,8 +30,7 @@ export class ComparisonResultsNode extends ExplorerNode {
const count = log !== undefined ? log.count : 0;
const truncated = log !== undefined ? log.truncated : false;
if (count === 1) return `1 commit`;
return `${count === 0 ? 'No' : `${count}${truncated ? '+' : ''}`} commits`;
return Strings.pluralize('commit', count, { number: truncated ? `${count}+` : undefined, zero: 'No' });
};
this.children = [

+ 2
- 1
src/views/nodes/statusFileCommitsNode.ts ファイルの表示

@ -12,6 +12,7 @@ import {
IStatusFormatOptions,
StatusFileFormatter
} from '../../gitService';
import { Strings } from '../../system';
import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode';
import { Explorer, ExplorerNode, ResourceType } from './explorerNode';
@ -145,7 +146,7 @@ export class StatusFileCommitsNode extends ExplorerNode {
}
if (commits > 0) {
changedIn.push(`${commits} ${commits === 1 ? 'commit' : 'commits'}`);
changedIn.push(Strings.pluralize('commit', commits));
}
if (changedIn.length > 2) {

+ 1
- 1
src/views/nodes/statusFilesNode.ts ファイルの表示

@ -222,7 +222,7 @@ export class StatusFilesNode extends ExplorerNode {
}
}
const label = `${files} ${files === 1 ? 'file' : 'files'} changed`;
const label = `${Strings.pluralize('file', files)} changed`;
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
item.id = this.id;
item.contextValue = ResourceType.StatusFiles;

+ 1
- 1
src/views/nodes/statusFilesResultsNode.ts ファイルの表示

@ -69,7 +69,7 @@ export class StatusFilesResultsNode extends ExplorerNode {
const diff = await Container.git.getDiffStatus(this.uri.repoPath!, this.ref1, this.ref2);
const count = diff !== undefined ? diff.length : 0;
const label = `${count === 0 ? 'No' : count} ${count === 1 ? 'file' : 'files'} changed`;
const label = `${Strings.pluralize('file', count, { zero: 'No' })} changed`;
this._cache = {
label: label,

+ 7
- 10
src/views/nodes/statusUpstreamNode.ts ファイルの表示

@ -2,7 +2,7 @@
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Container } from '../../container';
import { GitStatus, GitUri } from '../../gitService';
import { Iterables } from '../../system';
import { Iterables, Strings } from '../../system';
import { CommitNode } from './commitNode';
import { Explorer, ExplorerNode, ResourceType } from './explorerNode';
@ -49,20 +49,17 @@ export class StatusUpstreamNode extends ExplorerNode {
}
async getTreeItem(): Promise<TreeItem> {
const label =
this.direction === 'ahead'
? `${this.status.state.ahead} ${this.status.state.ahead === 1 ? 'commit' : 'commits'} (ahead of ${
this.status.upstream
})`
: `${this.status.state.behind} ${this.status.state.behind === 1 ? 'commit' : 'commits'} (behind ${
this.status.upstream
})`;
const ahead = this.direction === 'ahead';
const label = ahead
? `${Strings.pluralize('commit', this.status.state.ahead)} ahead`
: `${Strings.pluralize('commit', this.status.state.behind)} behind`;
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
item.id = this.id;
item.contextValue = ResourceType.StatusUpstream;
item.tooltip = `${label}${ahead ? ' of ' : ''}${this.status.upstream}`;
const iconSuffix = this.direction === 'ahead' ? 'upload' : 'download';
const iconSuffix = ahead ? 'upload' : 'download';
item.iconPath = {
dark: Container.context.asAbsolutePath(`images/dark/icon-${iconSuffix}.svg`),
light: Container.context.asAbsolutePath(`images/light/icon-${iconSuffix}.svg`)

+ 5
- 4
src/views/resultsExplorer.ts ファイルの表示

@ -237,10 +237,11 @@ export class ResultsExplorer implements TreeDataProvider, Disposab
results.repoPath}`;
}
if (count === 1) return `1 ${resultsType.singular} for ${resultsLabel.label}${repository}`;
return `${count === 0 ? 'No' : `${count}${truncated ? '+' : ''}`} ${resultsType.plural} for ${
resultsLabel.label
}${repository}`;
return `${Strings.pluralize(resultsType.singular, count, {
number: truncated ? `${count}+` : undefined,
plural: resultsType.plural,
zero: 'No'
})} for ${resultsLabel.label}${repository}`;
};
this.showResults(

読み込み中…
キャンセル
保存