Skip to content

Commit ae6972a

Browse files
dantmanterales
andauthored
feat: add message sort by locale's order instead of binary (#703)
* add option to sorting message by a locale's order Fixes #702 * Empty commit to trigger CI --------- Co-authored-by: Alex Terehov <[email protected]>
1 parent 93e2c46 commit ae6972a

File tree

10 files changed

+50
-10
lines changed

10 files changed

+50
-10
lines changed

.vscode/settings.json

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"i18n-ally.keystyle": "flat",
3232
"i18n-ally.preferredDelimiter": "_",
3333
"i18n-ally.sortKeys": true,
34+
"i18n-ally.sortCompare": "binary",
3435
"i18n-ally.keepFulfilled": true,
3536
"i18n-ally.translate.promptSource": true,
3637
"i18n-ally.pathMatcher": "{locale}.json",

locales/en.json

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989
"config.review_username": "Username for reviewing",
9090
"config.show_flags": "Show flags along with locale codes",
9191
"config.sort_keys": "Sort keys when saving to JSON/YAML",
92+
"config.sort_compare": "Strategy for sorting keys.",
93+
"config.sort_locale": "Locale to with if locale sort is used (will use the file's own locale if not specified)",
9294
"config.source_language": "Source language for machine translation",
9395
"config.tab_style": "Tab style for locale files",
9496
"config.target_picking_strategy": "Strategy dealing with more than one locale files were found.",

package.json

+13
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,19 @@
869869
"default": false,
870870
"description": "%config.sort_keys%"
871871
},
872+
"i18n-ally.sortCompare": {
873+
"type": "string",
874+
"enum": [
875+
"binary",
876+
"locale"
877+
],
878+
"default": "binary",
879+
"description": "%config.sort_compare%"
880+
},
881+
"i18n-ally.sortLocale": {
882+
"type": "string",
883+
"description": "%config.sort_locale%"
884+
},
872885
"i18n-ally.preferredDelimiter": {
873886
"type": "string",
874887
"default": "-",

src/core/Config.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { workspace, extensions, ExtensionContext, commands, ConfigurationScope,
44
import { trimEnd, uniq } from 'lodash'
55
import { TagSystems } from '../tagSystems'
66
import { EXT_NAMESPACE, EXT_ID, EXT_LEGACY_NAMESPACE, KEY_REG_DEFAULT, KEY_REG_ALL, DEFAULT_LOCALE_COUNTRY_MAP } from '../meta'
7-
import { KeyStyle, DirStructureAuto, TargetPickingStrategy } from '.'
7+
import { KeyStyle, DirStructureAuto, SortCompare, TargetPickingStrategy } from '.'
88
import i18n from '~/i18n'
99
import { CaseStyles } from '~/utils/changeCase'
1010
import { ExtractionBabelOptions, ExtractionHTMLOptions } from '~/extraction/parsers/options'
@@ -176,6 +176,14 @@ export class Config {
176176
return this.getConfig<boolean>('sortKeys') || false
177177
}
178178

179+
static get sortCompare(): SortCompare {
180+
return this.getConfig<SortCompare>('sortCompare') || 'binary'
181+
}
182+
183+
static get sortLocale(): string | undefined{
184+
return this.getConfig<string>('sortLocale')
185+
}
186+
179187
static get readonly(): boolean {
180188
return this.getConfig<boolean>('readonly') || false
181189
}

src/core/loaders/LocaleLoader.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { AllyError, ErrorType } from '../Errors'
1111
import { Analyst, Global, Config } from '..'
1212
import { Telemetry, TelemetryKey } from '../Telemetry'
1313
import { Loader } from './Loader'
14-
import { ReplaceLocale, Log, applyPendingToObject, unflatten, NodeHelper, getCache, setCache } from '~/utils'
14+
import { ReplaceLocale, Log, applyPendingToObject, unflatten, NodeHelper, getCache, setCache, getLocaleCompare } from '~/utils'
1515
import i18n from '~/i18n'
1616

1717
const THROTTLE_DELAY = 1500
@@ -325,7 +325,10 @@ export class LocaleLoader extends Loader {
325325
const processingContext = { locale, targetFile: filepath }
326326
const processed = this.deprocessData(modified, processingContext)
327327

328-
await parser.save(filepath, processed, Config.sortKeys)
328+
const compare = Config.sortCompare === 'locale'
329+
? getLocaleCompare(Config.sortLocale, locale)
330+
: undefined
331+
await parser.save(filepath, processed, Config.sortKeys, compare)
329332

330333
if (this._files[filepath]) {
331334
this._files[filepath].value = modified

src/core/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ export interface NodeOptions {
7777
export type DirStructureAuto = 'auto' | 'file' | 'dir'
7878
export type DirStructure = 'file' | 'dir'
7979

80+
export type SortCompare = 'binary' | 'locale'
81+
8082
export interface Coverage {
8183
locale: string
8284
translated: number

src/parsers/base.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ export abstract class Parser {
3636
return await this.parse(raw)
3737
}
3838

39-
async save(filepath: string, object: object, sort: boolean) {
40-
const text = await this.dump(object, sort)
39+
async save(filepath: string, object: object, sort: boolean, compare: ((x: string, y: string) => number) | undefined) {
40+
const text = await this.dump(object, sort, compare)
4141
await File.write(filepath, text)
4242
}
4343

4444
abstract parse(text: string): Promise<object>
4545

46-
abstract dump(object: object, sort: boolean): Promise<string>
46+
abstract dump(object: object, sort: boolean, compare: ((x: string, y: string) => number) | undefined): Promise<string>
4747

4848
parseAST(text: string): KeyInDocument[] {
4949
return []

src/parsers/json.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ export class JsonParser extends Parser {
1616
return JSON.parse(text)
1717
}
1818

19-
async dump(object: object, sort: boolean) {
19+
async dump(object: object, sort: boolean, compare: ((x: string, y: string) => number) | undefined) {
2020
const indent = this.options.tab === '\t' ? this.options.tab : this.options.indent
2121

2222
if (sort)
23-
return `${SortedStringify(object, { space: indent })}\n`
23+
return `${SortedStringify(object, { space: indent, cmp: compare ? (a, b) => compare(a.key, b.key) : undefined })}\n`
2424
else
2525
return `${JSON.stringify(object, null, indent)}\n`
2626
}

src/parsers/yaml.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ export class YamlParser extends Parser {
1515
return YAML.load(text, Config.parserOptions?.yaml?.load) as Object
1616
}
1717

18-
async dump(object: object, sort: boolean) {
18+
async dump(object: object, sort: boolean, compare: ((x: string, y: string) => number) | undefined) {
1919
object = JSON.parse(JSON.stringify(object))
2020
return YAML.dump(object, {
2121
indent: this.options.indent,
22-
sortKeys: sort,
22+
sortKeys: sort ? (compare ?? true) : false,
2323
...Config.parserOptions?.yaml?.dump,
2424
})
2525
}

src/utils/utils.ts

+11
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,14 @@ export function abbreviateNumber(value: number): string {
9696
result += suffixes[suffixNum]
9797
return result
9898
}
99+
100+
/**
101+
* Get a locale aware comparison function
102+
*/
103+
export function getLocaleCompare(
104+
sortLocaleSetting: string | undefined,
105+
fileLocale: string
106+
): (x: string, y: string) => number {
107+
const sortLocale = sortLocaleSetting ? sortLocaleSetting : fileLocale;
108+
return new Intl.Collator(sortLocale).compare;
109+
}

0 commit comments

Comments
 (0)