Skip to content

Commit

Permalink
feat: add message sort by locale's order instead of binary (#703)
Browse files Browse the repository at this point in the history
* add option to sorting message by a locale's order

Fixes #702

* Empty commit to trigger CI

---------

Co-authored-by: Alex Terehov <terales@users.noreply.github.com>
  • Loading branch information
dantman and terales committed Aug 27, 2023
1 parent 93e2c46 commit ae6972a
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 10 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"i18n-ally.keystyle": "flat",
"i18n-ally.preferredDelimiter": "_",
"i18n-ally.sortKeys": true,
"i18n-ally.sortCompare": "binary",
"i18n-ally.keepFulfilled": true,
"i18n-ally.translate.promptSource": true,
"i18n-ally.pathMatcher": "{locale}.json",
Expand Down
2 changes: 2 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"config.review_username": "Username for reviewing",
"config.show_flags": "Show flags along with locale codes",
"config.sort_keys": "Sort keys when saving to JSON/YAML",
"config.sort_compare": "Strategy for sorting keys.",
"config.sort_locale": "Locale to with if locale sort is used (will use the file's own locale if not specified)",
"config.source_language": "Source language for machine translation",
"config.tab_style": "Tab style for locale files",
"config.target_picking_strategy": "Strategy dealing with more than one locale files were found.",
Expand Down
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,19 @@
"default": false,
"description": "%config.sort_keys%"
},
"i18n-ally.sortCompare": {
"type": "string",
"enum": [
"binary",
"locale"
],
"default": "binary",
"description": "%config.sort_compare%"
},
"i18n-ally.sortLocale": {
"type": "string",
"description": "%config.sort_locale%"
},
"i18n-ally.preferredDelimiter": {
"type": "string",
"default": "-",
Expand Down
10 changes: 9 additions & 1 deletion src/core/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { workspace, extensions, ExtensionContext, commands, ConfigurationScope,
import { trimEnd, uniq } from 'lodash'
import { TagSystems } from '../tagSystems'
import { EXT_NAMESPACE, EXT_ID, EXT_LEGACY_NAMESPACE, KEY_REG_DEFAULT, KEY_REG_ALL, DEFAULT_LOCALE_COUNTRY_MAP } from '../meta'
import { KeyStyle, DirStructureAuto, TargetPickingStrategy } from '.'
import { KeyStyle, DirStructureAuto, SortCompare, TargetPickingStrategy } from '.'
import i18n from '~/i18n'
import { CaseStyles } from '~/utils/changeCase'
import { ExtractionBabelOptions, ExtractionHTMLOptions } from '~/extraction/parsers/options'
Expand Down Expand Up @@ -176,6 +176,14 @@ export class Config {
return this.getConfig<boolean>('sortKeys') || false
}

static get sortCompare(): SortCompare {
return this.getConfig<SortCompare>('sortCompare') || 'binary'
}

static get sortLocale(): string | undefined{
return this.getConfig<string>('sortLocale')
}

static get readonly(): boolean {
return this.getConfig<boolean>('readonly') || false
}
Expand Down
7 changes: 5 additions & 2 deletions src/core/loaders/LocaleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { AllyError, ErrorType } from '../Errors'
import { Analyst, Global, Config } from '..'
import { Telemetry, TelemetryKey } from '../Telemetry'
import { Loader } from './Loader'
import { ReplaceLocale, Log, applyPendingToObject, unflatten, NodeHelper, getCache, setCache } from '~/utils'
import { ReplaceLocale, Log, applyPendingToObject, unflatten, NodeHelper, getCache, setCache, getLocaleCompare } from '~/utils'
import i18n from '~/i18n'

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

await parser.save(filepath, processed, Config.sortKeys)
const compare = Config.sortCompare === 'locale'
? getLocaleCompare(Config.sortLocale, locale)
: undefined
await parser.save(filepath, processed, Config.sortKeys, compare)

if (this._files[filepath]) {
this._files[filepath].value = modified
Expand Down
2 changes: 2 additions & 0 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export interface NodeOptions {
export type DirStructureAuto = 'auto' | 'file' | 'dir'
export type DirStructure = 'file' | 'dir'

export type SortCompare = 'binary' | 'locale'

export interface Coverage {
locale: string
translated: number
Expand Down
6 changes: 3 additions & 3 deletions src/parsers/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ export abstract class Parser {
return await this.parse(raw)
}

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

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

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

parseAST(text: string): KeyInDocument[] {
return []
Expand Down
4 changes: 2 additions & 2 deletions src/parsers/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export class JsonParser extends Parser {
return JSON.parse(text)
}

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

if (sort)
return `${SortedStringify(object, { space: indent })}\n`
return `${SortedStringify(object, { space: indent, cmp: compare ? (a, b) => compare(a.key, b.key) : undefined })}\n`
else
return `${JSON.stringify(object, null, indent)}\n`
}
Expand Down
4 changes: 2 additions & 2 deletions src/parsers/yaml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ export class YamlParser extends Parser {
return YAML.load(text, Config.parserOptions?.yaml?.load) as Object
}

async dump(object: object, sort: boolean) {
async dump(object: object, sort: boolean, compare: ((x: string, y: string) => number) | undefined) {
object = JSON.parse(JSON.stringify(object))
return YAML.dump(object, {
indent: this.options.indent,
sortKeys: sort,
sortKeys: sort ? (compare ?? true) : false,
...Config.parserOptions?.yaml?.dump,
})
}
Expand Down
11 changes: 11 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,14 @@ export function abbreviateNumber(value: number): string {
result += suffixes[suffixNum]
return result
}

/**
* Get a locale aware comparison function
*/
export function getLocaleCompare(
sortLocaleSetting: string | undefined,
fileLocale: string
): (x: string, y: string) => number {
const sortLocale = sortLocaleSetting ? sortLocaleSetting : fileLocale;
return new Intl.Collator(sortLocale).compare;
}

0 comments on commit ae6972a

Please sign in to comment.