From 0fa9792718d77e153020e4be982db279094644a5 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 5 Feb 2025 15:26:13 +1000 Subject: [PATCH 01/61] feat(windows): mutex used to check download process Using the KeymanMutex wrapper to check if a download process is occuring if it isn't and we are in the downloading state this means the download process exited early. We can then clean up any downloaded files and reset the statemachine and check for updates again. --- .../main/Keyman.System.UpdateStateMachine.pas | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index a09a9e5068..5f8d91a959 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -118,6 +118,7 @@ uses GlobalProxySettings, kmint, keymanapi_TLB, + KeymanMutex, Keyman.System.KeymanSentryClient, Keyman.System.DownloadUpdate, Keyman.System.RemoteUpdateCheck, @@ -753,12 +754,21 @@ procedure DownloadingState.Enter; var DownloadResult: Boolean; RetryCount: Integer; + FMutex: TKeymanMutex; begin // Enter DownloadingState bucStateContext.SetRegistryState(usDownloading); RetryCount := 0; DownloadResult := False; + FMutex := TKeymanMutex.Create('KeymanDownloading'); + // Should be impossible but just exit anyway and let the process current + // downloading process finish. + if not FMutex.MutexOwned then + begin + FreeAndNil(FMutex); + Exit; + end; while (not DownloadResult) and (RetryCount < 3) do begin @@ -767,6 +777,8 @@ begin Inc(RetryCount); end; + FreeAndNil(FMutex); + if (not DownloadResult) then begin // Failed three times in this process; return to the @@ -807,14 +819,38 @@ begin end; function DownloadingState.HandleKmShell; +var + FMutex: TKeymanMutex; begin - // Downloading state, in other process, so continue + // Check to ensure a download process is running if not + // clean up return to the the idle state and check for updates + FMutex := TKeymanMutex.Create('KeymanDownloading'); + if FMutex.MutexOwned then + begin + bucStateContext.RemoveCachedFiles; + FreeAndNil(FMutex); + ChangeState(IdleState); + bucStateContext.CurrentState.HandleCheck; + end; + FreeAndNil(FMutex); + // Downloading state, in another process, so continue to execute kmshell Result := kmShellContinue; end; procedure DownloadingState.HandleDownload; +var + FMutex: TKeymanMutex; begin - // Enter Already Downloading + // If downloading process is not running clean files and return to idle + FMutex := TKeymanMutex.Create('KeymanDownloading'); + if FMutex.MutexOwned then + begin + bucStateContext.RemoveCachedFiles; + FreeAndNil(FMutex); + ChangeState(IdleState); + bucStateContext.CurrentState.HandleCheck; + end; + FreeAndNil(FMutex); end; procedure DownloadingState.HandleAbort; From 01690ed483f248595c7ff457fc7f4d95f3b05562 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 10 Feb 2025 10:05:14 +1000 Subject: [PATCH 02/61] feat(windows): remove redunant FreeAndNil --- .../main/Keyman.System.UpdateStateMachine.pas | 77 +++++++++++-------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index 5f8d91a959..b1d4193a35 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -761,24 +761,28 @@ begin RetryCount := 0; DownloadResult := False; - FMutex := TKeymanMutex.Create('KeymanDownloading'); - // Should be impossible but just exit anyway and let the process current - // downloading process finish. - if not FMutex.MutexOwned then - begin + FMutex := nil; + + try + FMutex := TKeymanMutex.Create('KeymanDownloading'); + // Should be impossible but just exit anyway and let the process current + // downloading process finish. + if not FMutex.MutexOwned then + begin + Exit; + end; + + while (not DownloadResult) and (RetryCount < 3) do + begin + DownloadResult := DownloadUpdatesBackground; + if not DownloadResult then + Inc(RetryCount); + end; + + finally FreeAndNil(FMutex); - Exit; end; - while (not DownloadResult) and (RetryCount < 3) do - begin - DownloadResult := DownloadUpdatesBackground; - if not DownloadResult then - Inc(RetryCount); - end; - - FreeAndNil(FMutex); - if (not DownloadResult) then begin // Failed three times in this process; return to the @@ -822,35 +826,46 @@ function DownloadingState.HandleKmShell; var FMutex: TKeymanMutex; begin + FMutex := nil; + // Whether already downloading in another process or download has failed and + // this function has clean up and force a restart, kmshell should continue processing + Result := kmShellContinue; // Check to ensure a download process is running if not // clean up return to the the idle state and check for updates - FMutex := TKeymanMutex.Create('KeymanDownloading'); - if FMutex.MutexOwned then - begin - bucStateContext.RemoveCachedFiles; + try + FMutex := TKeymanMutex.Create('KeymanDownloading'); + if FMutex.MutexOwned then + begin + bucStateContext.RemoveCachedFiles; + FreeAndNil(FMutex); // Mutex must be freed before changing state + ChangeState(IdleState); + bucStateContext.CurrentState.HandleCheck; + Exit; + end; + finally FreeAndNil(FMutex); - ChangeState(IdleState); - bucStateContext.CurrentState.HandleCheck; end; - FreeAndNil(FMutex); - // Downloading state, in another process, so continue to execute kmshell - Result := kmShellContinue; end; procedure DownloadingState.HandleDownload; var FMutex: TKeymanMutex; begin + FMutex := nil; // If downloading process is not running clean files and return to idle - FMutex := TKeymanMutex.Create('KeymanDownloading'); - if FMutex.MutexOwned then - begin - bucStateContext.RemoveCachedFiles; + try + FMutex := TKeymanMutex.Create('KeymanDownloading'); + if FMutex.MutexOwned then + begin + bucStateContext.RemoveCachedFiles; + FreeAndNil(FMutex); // Mutex must be freed before changing state + ChangeState(IdleState); + bucStateContext.CurrentState.HandleCheck; + Exit; + end; + finally FreeAndNil(FMutex); - ChangeState(IdleState); - bucStateContext.CurrentState.HandleCheck; end; - FreeAndNil(FMutex); end; procedure DownloadingState.HandleAbort; From 8281e328c9a9cfe6abbb1d5bd000aa0eca113194 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:37:59 +1000 Subject: [PATCH 03/61] feat(windows): review changes --- .../main/Keyman.System.UpdateStateMachine.pas | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index 53c9e71b19..e79dd299c4 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -132,6 +132,7 @@ const SPackageUpgradeFilename = 'upgrade_packages.inf'; kmShellContinue = 0; kmShellExit = 1; + KeymanDownloadMutexName = 'KeymanDownloading'; { State Class Memebers } @@ -759,25 +760,21 @@ begin // Enter DownloadingState bucStateContext.SetRegistryState(usDownloading); - RetryCount := 0; - DownloadResult := False; - FMutex := nil; + FMutex := TKeymanMutex.Create(KeymanDownloadMutexName); try - FMutex := TKeymanMutex.Create('KeymanDownloading'); // Should be impossible but just exit anyway and let the process current // downloading process finish. - if not FMutex.MutexOwned then + if not FMutex.TakeOwnership then begin Exit; end; - while (not DownloadResult) and (RetryCount < 3) do - begin + RetryCount := 0; + repeat DownloadResult := DownloadUpdatesBackground; - if not DownloadResult then - Inc(RetryCount); - end; + Inc(RetryCount); + until DownloadResult or (RetryCount = 3); finally FreeAndNil(FMutex); @@ -824,21 +821,19 @@ function DownloadingState.HandleKmShell; var FMutex: TKeymanMutex; begin - FMutex := nil; // Whether already downloading in another process or download has failed and // this function has clean up and force a restart, kmshell should continue processing Result := kmShellContinue; // Check to ensure a download process is running if not // clean up return to the the idle state and check for updates + FMutex := TKeymanMutex.Create(KeymanDownloadMutexName); try - FMutex := TKeymanMutex.Create('KeymanDownloading'); - if FMutex.MutexOwned then + if FMutex.TakeOwnership then begin bucStateContext.RemoveCachedFiles; - FreeAndNil(FMutex); // Mutex must be freed before changing state + FMutex.ReleaseOwnership; // Mutex must be freed before changing state ChangeState(IdleState); bucStateContext.CurrentState.HandleCheck; - Exit; end; finally FreeAndNil(FMutex); @@ -849,17 +844,15 @@ procedure DownloadingState.HandleDownload; var FMutex: TKeymanMutex; begin - FMutex := nil; // If downloading process is not running clean files and return to idle + FMutex := TKeymanMutex.Create(KeymanDownloadMutexName); try - FMutex := TKeymanMutex.Create('KeymanDownloading'); - if FMutex.MutexOwned then + if FMutex.TakeOwnership then begin bucStateContext.RemoveCachedFiles; - FreeAndNil(FMutex); // Mutex must be freed before changing state + FMutex.ReleaseOwnership; // Mutex must be freed before changing state ChangeState(IdleState); bucStateContext.CurrentState.HandleCheck; - Exit; end; finally FreeAndNil(FMutex); From b2fbfaf8cfe4cbd98686ee8e762abfc699b69734 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 10 Feb 2025 15:45:34 +0700 Subject: [PATCH 04/61] fix: use tier and version from branch when merging history from another branch Fixes: #13138 --- resources/build/version/src/fixupHistory.ts | 23 ++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/resources/build/version/src/fixupHistory.ts b/resources/build/version/src/fixupHistory.ts index a8ceda3c50..1d6a290957 100644 --- a/resources/build/version/src/fixupHistory.ts +++ b/resources/build/version/src/fixupHistory.ts @@ -6,6 +6,7 @@ import { GitHub } from '@actions/github'; import { readFileSync, writeFileSync } from 'fs'; import { gt } from 'semver'; import { reportHistory } from './reportHistory.js'; +import { spawnChild } from './util/spawnAwait.js'; interface PRInformation { title: string; @@ -16,16 +17,28 @@ interface PRInformation { // splitPullsIntoHistory // ------------------------------------------------------------------------------------ -const splicePullsIntoHistory = async (pulls: PRInformation[]): Promise<{count: number, pulls: number[]}> => { +const splicePullsIntoHistory = async (pulls: PRInformation[], base?: string): Promise<{count: number, pulls: number[]}> => { let currentPulls: number[] = []; // - // Get current version and history from VERSION.md and TIER.md + // Get current version and history from VERSION.md and TIER.md. This may not + // yet be committed, so read the details from the worktree. // - const version = readFileSync('./VERSION.md', 'utf8').trim(); - const tier = readFileSync('./TIER.md', 'utf8').trim(); + let version = readFileSync('./VERSION.md', 'utf8').trim(); + let tier = readFileSync('./TIER.md', 'utf8').trim(); + + if(base) { + // If we are merging history from another branch, we need to use the data + // from that branch. In this case, we must assume that the version and tier + // data are definitely already committed. + const currentBase = (await spawnChild('git', ['branch', '--show-current'])).trim(); + if(currentBase != base) { + version = (await spawnChild('git', ['show', base+':VERSION.md'])).trim(); + tier = (await spawnChild('git', ['show', base+':TIER.md'])).trim(); + } + } //logInfo(`VERSION="${version}"`); // @@ -208,7 +221,7 @@ export const fixupHistory = async ( // Splice these into HISTORY.md // - const historyResult = await splicePullsIntoHistory(pulls); + const historyResult = await splicePullsIntoHistory(pulls, base); // // Write a comment to GitHub for each of the pulls From ec2373acd534e25410aff6897755c26029642346 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 10 Feb 2025 16:30:20 +0100 Subject: [PATCH 05/61] fix(linux): start system service when switching keyboards This change fixes #13171 where we failed to output after the first keypress because the keyman system service had to be started. This change introduces a new method `Ping` that we call to force keyman-system-service to be started. Fixes: #13171 --- .../src/KeymanSystemServiceClient.cpp | 25 +++++++++++++++++++ .../src/KeymanSystemServiceClient.h | 1 + linux/ibus-keyman/src/engine.c | 2 ++ .../src/KeymanSystemService.cpp | 11 ++++++++ .../src/com.keyman.SystemService1.System.xml | 8 ++++++ 5 files changed, 47 insertions(+) diff --git a/linux/ibus-keyman/src/KeymanSystemServiceClient.cpp b/linux/ibus-keyman/src/KeymanSystemServiceClient.cpp index b411e808f7..928d929dd0 100644 --- a/linux/ibus-keyman/src/KeymanSystemServiceClient.cpp +++ b/linux/ibus-keyman/src/KeymanSystemServiceClient.cpp @@ -25,6 +25,7 @@ public: void SetCapsLockIndicator(guint32 capsLock); gint32 GetCapsLockIndicator(); void CallOrderedOutputSentinel(); + void Ping(); }; KeymanSystemServiceClient::KeymanSystemServiceClient() { @@ -111,6 +112,23 @@ KeymanSystemServiceClient::CallOrderedOutputSentinel() { } } +void KeymanSystemServiceClient::Ping() { + if (!bus) { + // we already reported the error in the c'tor, so just return + return; + } + + sd_bus_error *error = NULL; + int result = sd_bus_call_method(bus, KEYMAN_BUS_NAME, KEYMAN_OBJECT_PATH, + KEYMAN_INTERFACE_NAME, "Ping", error, &msg, ""); + if (result < 0) { + g_error("%s: Failed to call method Ping: %s. %s. %s.", + __FUNCTION__, strerror(-result), error ? error->name : "-", error ? error->message : "-"); + sd_bus_error_free(error); + return; + } +} + void set_capslock_indicator(guint32 capsLock) { KeymanSystemServiceClient client; @@ -128,3 +146,10 @@ call_ordered_output_sentinel() { KeymanSystemServiceClient client; client.CallOrderedOutputSentinel(); } + +void +ping_keyman_system_service() { + g_message("%s: Pinging keyman-system-service", __FUNCTION__); + KeymanSystemServiceClient client; + client.Ping(); +} diff --git a/linux/ibus-keyman/src/KeymanSystemServiceClient.h b/linux/ibus-keyman/src/KeymanSystemServiceClient.h index bf5766434f..a10cab4717 100644 --- a/linux/ibus-keyman/src/KeymanSystemServiceClient.h +++ b/linux/ibus-keyman/src/KeymanSystemServiceClient.h @@ -10,6 +10,7 @@ extern "C" { void set_capslock_indicator(guint32 capsLockState); gint32 get_capslock_indicator(); void call_ordered_output_sentinel(); +void ping_keyman_system_service(); #ifdef __cplusplus } diff --git a/linux/ibus-keyman/src/engine.c b/linux/ibus-keyman/src/engine.c index 29d1be00d2..c4511ee3b2 100644 --- a/linux/ibus-keyman/src/engine.c +++ b/linux/ibus-keyman/src/engine.c @@ -553,6 +553,8 @@ ibus_keyman_engine_constructor( return NULL; } + ping_keyman_system_service(); + set_context_if_needed(engine); return (GObject *) keyman; diff --git a/linux/keyman-system-service/src/KeymanSystemService.cpp b/linux/keyman-system-service/src/KeymanSystemService.cpp index 5e5b4f6e3e..56d1e558b3 100644 --- a/linux/keyman-system-service/src/KeymanSystemService.cpp +++ b/linux/keyman-system-service/src/KeymanSystemService.cpp @@ -76,11 +76,22 @@ on_call_ordered_output_sentinel( return sd_bus_reply_method_return(msg, ""); } +static int32_t +on_ping( + sd_bus_message *msg, + void *user_data, + sd_bus_error *ret_error +) { + *ret_error = SD_BUS_ERROR_NULL; + return sd_bus_reply_method_return(msg, "s", "pong"); +} + static const sd_bus_vtable system_service_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_METHOD("SetCapsLockIndicator", "b", "", on_set_caps_lock_indicator, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("GetCapsLockIndicator", "", "b", on_get_caps_lock_indicator, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("CallOrderedOutputSentinel", "", "", on_call_ordered_output_sentinel, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Ping", "", "s", on_ping, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END }; diff --git a/linux/keyman-system-service/src/com.keyman.SystemService1.System.xml b/linux/keyman-system-service/src/com.keyman.SystemService1.System.xml index b93bcffa3a..70ca44cba2 100644 --- a/linux/keyman-system-service/src/com.keyman.SystemService1.System.xml +++ b/linux/keyman-system-service/src/com.keyman.SystemService1.System.xml @@ -34,5 +34,13 @@ + + + + From b59bb6d4def218c8a528aeec1f92ff6088199511 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 10 Feb 2025 12:12:12 -0600 Subject: [PATCH 06/61] =?UTF-8?q?feat(developer):=20serialize=20KMXPlus=20?= =?UTF-8?q?into=20XML=20=F0=9F=8D=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry pick of #12969 > feat(developer): serialize KMXPlus (back) into XML 🗼 (cherry picked from commit f93c45c9e8257805035ee0321a5e6e0fbcf5fe06 #12969) Fixes: #12874 --- common/web/types/src/kmx/kmx-plus/kmx-plus.ts | 21 +- .../src/common/web/utils/src/xml-utils.ts | 7 + developer/src/kmc-ldml/src/compiler/keys.ts | 24 +- .../kmc-ldml/src/compiler/section-compiler.ts | 16 + developer/src/kmc-ldml/src/compiler/tran.ts | 7 + developer/src/kmc-ldml/src/compiler/vars.ts | 2 +- developer/src/kmc-ldml/src/util/serialize.ts | 273 ++++++++++++++++++ .../src/kmc-ldml/test/compiler-e2e.tests.ts | 29 ++ .../test/fixtures/basic-serialized.xml | 42 +++ .../src/kmc-ldml/test/helpers/compareXml.ts | 25 ++ developer/src/kmc-ldml/test/tsconfig.json | 2 +- 11 files changed, 431 insertions(+), 17 deletions(-) create mode 100644 developer/src/kmc-ldml/src/util/serialize.ts create mode 100644 developer/src/kmc-ldml/test/fixtures/basic-serialized.xml create mode 100644 developer/src/kmc-ldml/test/helpers/compareXml.ts diff --git a/common/web/types/src/kmx/kmx-plus/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus/kmx-plus.ts index d0de2989d0..24538c0108 100644 --- a/common/web/types/src/kmx/kmx-plus/kmx-plus.ts +++ b/common/web/types/src/kmx/kmx-plus/kmx-plus.ts @@ -385,15 +385,11 @@ export class UnicodeSetItem extends VarsItem { }; export class SetVarItem extends VarsItem { - constructor(id: string, value: string[], sections: DependencySections, rawItems: string[]) { + constructor(id: string, value: string[], sections: DependencySections) { super(id, value.join(' '), sections); this.items = sections.elem.allocElementString(sections, value); - this.rawItems = rawItems; } - // element string array - items: ElementString; - // like items, but with unprocessed marker strings - rawItems: string[]; + items: ElementString; // element string array valid() : boolean { return !!this.items; } @@ -409,10 +405,12 @@ export class StringVarItem extends VarsItem { // 'tran' export class TranTransform { - from: StrsItem; - to: StrsItem; - mapFrom: StrsItem; // var name - mapTo: StrsItem; // var name + from: StrsItem; // "from" computed regex string + to: StrsItem; // "to" (replacement) computed regex string + mapFrom: StrsItem; // var name for map + mapTo: StrsItem; // var name for map + _from?: string; // Not part of binary file: for use in the XML serializer. If present, sets the from= attribute for XML. + _to?: string; // Not part of binary file: for use in the XML serializer. If present, sets the to= attribute for XML. } export class TranGroup { @@ -424,6 +422,9 @@ export class TranGroup { export class TranReorder { elements: ElementString; before: ElementString; + _before?: string; // Not part of binary file: for use in the XML serializer. If present, sets the before= attribute for XML. + _from?: string; // Not part of binary file: for use in the XML serializer. If present, sets the from= attribute for XML. + _order?: string; // Not part of binary file: for use in the XML serializer. If present, sets the order= attribute for XML. }; export class Tran extends Section { diff --git a/developer/src/common/web/utils/src/xml-utils.ts b/developer/src/common/web/utils/src/xml-utils.ts index 022328ff94..69a039aa00 100644 --- a/developer/src/common/web/utils/src/xml-utils.ts +++ b/developer/src/common/web/utils/src/xml-utils.ts @@ -114,6 +114,13 @@ const GENERATOR_OPTIONS: KeymanXMLOptionsBag = { textNodeName: '_', suppressEmptyNode: true, }, + keyboard3: { + attributeNamePrefix: '$', + ignoreAttributes: false, + format: true, + textNodeName: '_', + suppressEmptyNode: true, + }, }; /** wrapper for XML parsing support */ diff --git a/developer/src/kmc-ldml/src/compiler/keys.ts b/developer/src/kmc-ldml/src/compiler/keys.ts index e341f3ac87..d86d7e2bf5 100644 --- a/developer/src/kmc-ldml/src/compiler/keys.ts +++ b/developer/src/kmc-ldml/src/compiler/keys.ts @@ -15,8 +15,9 @@ import { SubstitutionUse, Substitutions } from './substitution-tracker.js'; /** reserved name for the special gap key. space is not allowed in key ids. */ const reserved_gap = "gap (reserved)"; - export class KeysCompiler extends SectionCompiler { + /** keys that are of a reserved type */ + public static RESERVED_KEY = Symbol('Reserved Key'); static validateSubstitutions( keyboard: LDMLKeyboard.LKKeyboard, st: Substitutions @@ -222,6 +223,19 @@ export class KeysCompiler extends SectionCompiler { /** count of reserved keys, for tests */ public static readonly reserved_count = KeysCompiler.reserved_keys.length; + /** mark as reserved */ + private static asReserved(k : KeysKeys) : KeysKeys { + const o = k as any; + o[KeysCompiler.RESERVED_KEY] = true; + return k; + } + + /** true if a reserved key */ + public static isReserved(k : KeysKeys) : boolean { + const o = k as any; + return !!o[KeysCompiler.RESERVED_KEY]; + } + /** load up all reserved keys */ getReservedKeys(sections: KMXPlus.DependencySections) : Map { const r = new Map(); @@ -231,7 +245,7 @@ export class KeysCompiler extends SectionCompiler { const no_list = sections.list.allocList([], {}, sections); // now add the reserved key(s). - r.set(reserved_gap, { + r.set(reserved_gap, KeysCompiler.asReserved({ flags: constants.keys_key_flags_gap | constants.keys_key_flags_extend, id: sections.strs.allocString(reserved_gap), flicks: '', @@ -241,7 +255,7 @@ export class KeysCompiler extends SectionCompiler { switch: no_string, to: no_string, width: 10.0, // 10 * .1 - }); + })); if (r.size !== KeysCompiler.reserved_count) { throw Error(`Internal Error: KeysCompiler.reserved_count=${KeysCompiler.reserved_count} != ${r.size} actual reserved keys.`); @@ -357,7 +371,7 @@ export class KeysCompiler extends SectionCompiler { flags |= constants.keys_key_flags_extend; } const width = Math.ceil((key.width || 1) * 10.0); // default, width=1 - sect.keys.push({ + sect.keys.push(SectionCompiler.copySymbols({ flags, flicks: flickId, id, @@ -367,7 +381,7 @@ export class KeysCompiler extends SectionCompiler { switch: keySwitch, // 'switch' is a reserved word to, width, - }); + }, key)); } } diff --git a/developer/src/kmc-ldml/src/compiler/section-compiler.ts b/developer/src/kmc-ldml/src/compiler/section-compiler.ts index e33eda1086..dd83a9deda 100644 --- a/developer/src/kmc-ldml/src/compiler/section-compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/section-compiler.ts @@ -55,4 +55,20 @@ export abstract class SectionCompiler { ]); return defaults; } + + /** + * Copy symbols from 'from' onto 'onto' + * This is used to propagate special symbols such as ImportStatus + * and XML + * @param onto object to copy onto + * @param from source for symbols + * @returns the onto object + */ + public static copySymbols(onto: T, from: any) : T { + const o = onto as any; + for (const sym of Object.getOwnPropertySymbols(from)) { + o[sym] = from[sym]; + } + return onto; + } } diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index e8d7b9eb37..1a91e8d382 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -138,6 +138,9 @@ export abstract class TransformCompiler result.substituteMarkerString(v, false)); - result.sets.push(new SetVarItem(id, cookedItems, sections, rawItems)); + result.sets.push(new SetVarItem(id, cookedItems, sections)); } addUnicodeSet(result: Vars, e: LDMLKeyboard.LKUSet, sections: DependencySections): void { const { id } = e; diff --git a/developer/src/kmc-ldml/src/util/serialize.ts b/developer/src/kmc-ldml/src/util/serialize.ts new file mode 100644 index 0000000000..ee02abadcc --- /dev/null +++ b/developer/src/kmc-ldml/src/util/serialize.ts @@ -0,0 +1,273 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * This module contains routines for serializing from a KMXPlus file into XML. + */ + +import { KMXPlus } from "@keymanapp/common-types"; +import { KeymanXMLWriter, LDMLKeyboard } from "@keymanapp/developer-utils"; +import { constants } from "@keymanapp/ldml-keyboard-constants"; +import { KeysCompiler } from "../compiler/keys.js"; + +/** + * Serialize a KMXPlusFile back to XML. + * This is implemented for the LDML editor to be able to mutate LDML (XML) content by: + * 1. reading the original XML + * 2. compiling to KMXPlusFile + * 3. modifying the KMXPlusFile + * 4. serializing back to XML + * + * There are limitations: + * - TODO-LDML-EDITOR: Transforms would not be serialized properly, due to + * regex munging around markers and such. + * + * To work around this, fields with underscores such as _from and _to are added to + * the KMXPlusFile classes. These provide hints as to what the output XML should be, + * and are populated by the tran compiler. + * + * - TODO-LDML-EDITOR: Comments, whitespace, etc. are not preserved by this + * approach. Updates to the XML parsing will support this, see #10622. + * + * @param kmx input KMXPlusFile + * @returns XML String + */ +export function kmxToXml(kmx: KMXPlus.KMXPlusFile): string { + const writer = new KeymanXMLWriter("keyboard3"); + const { kmxplus } = kmx; + const { + // sect, + bksp, + disp, + // elem, + keys, + layr, + // list, + loca, + meta, + // strs, + tran, + // uset, + vars, + } = kmxplus; + const data = { + keyboard3: { + ...getRootAttributes(), + ...getLocales(), + version: getVersion(), + info: getInfo(), + ...getDisplays(), + ...getKeys(), + ...getFlicks(), + ...getLayers(), + ...getVariables(), + ...getTransforms(), + } + }; + + return writer.write(data); + + function getRootAttributes() { + return { + '$xmlns': `https://schemas.unicode.org/cldr/${constants.cldr_version_latest}/keyboard3`, + '$locale': kmx.kmxplus.loca.locales[0].value, + '$conformsTo': constants.cldr_version_latest, + }; + } + + function getLocales() { + if (loca?.locales?.length < 2) { + return {}; // no additional locales + } else { + return { + locales: + loca.locales.map(({ value }) => ({ '$id': value })), + } + } + } + + function getInfo() { + return { + '$author': meta.author.value, + '$name': meta.name.value, + '$layout': meta.layout.value, + '$indicator': meta.indicator.value, + }; + } + + function getVersion() { + return { '$number': kmx.kmxplus.meta.version.value }; + } + + function getDisplays() { + const displays = { + display: disp?.disps.map(disp => getDisplay(disp)) || [], + ...getDisplaySettings(), + }; + if (displays?.display?.length || displays?.displayOptions) { + return { displays } + } else { + return {}; + } + } + + function stringToAttr(attr: string, s?: KMXPlus.StrsItem, override?: string) { + if (override) return asAttr(attr, override); + if (!s || !s?.value?.length) return {}; + return Object.fromEntries([[`\$${attr}`, s.value]]); + } + + function asAttr(attr: string, s?: any) { + if (s === undefined) return {}; + return Object.fromEntries([[`\$${attr}`, s]]); + } + + function numberToAttr(attr: string, s?: number) { + if (s === undefined) return {}; + return Object.fromEntries([[`\$${attr}`, s.toString()]]); + } + + function getDisplay(disp: KMXPlus.DispItem) { + return { + ...stringToAttr('output', disp?.to), + ...stringToAttr('keyId', disp?.id), + ...stringToAttr('display', disp?.display), + }; + } + + function getDisplaySettings() { + if (!disp?.baseCharacter?.value) return {}; + return { + displayOptions: { + '$baseCharacter': disp?.baseCharacter?.value, + } + }; + } + + function getKeys() { + if (!keys?.keys?.length) { + return {}; + } + return { + keys: { + key: keys.keys + // skip reserved keys (gap) + .filter((key: KMXPlus.KeysKeys) => + !KeysCompiler.isReserved(key) && + !LDMLKeyboard.ImportStatus.isImpliedImport(key)) + .map((key: KMXPlus.KeysKeys) => ({ + ...stringToAttr('id', key.id), + ...stringToAttr('output', key.to), + ...asAttr('longPressKeyIds', key?.longPress?.join(' ') || undefined), + })), + }, + }; + } + + function getFlicks() { + // skip the null flicks + if (keys?.flicks?.length < 2) { + return {}; + } + return { + flicks: { + // keys.key.. + } + }; + } + + function getLayers() { + if (!layr?.lists?.length) { + return {}; + } + return { + layers: layr.lists.map(({ hardware, minDeviceWidth, layers }) => ({ + ...stringToAttr('formId', hardware), + ...numberToAttr('minDeviceWidth', minDeviceWidth), + layer: layers.map(({ id, mod, rows }) => ({ + ...stringToAttr('id', id), + ...asAttr('modifiers', modToString(mod)), + row: rows.map(({ keys }) => ({ + ...asAttr('keys', keys.map(({ value }) => value).join(' ')), + })), + })), + })), + }; + } + + function getVariables() { + if (!vars?.strings.length && !vars?.sets.length && !vars?.usets.length) { + return {}; + } + function varToObj(v: KMXPlus.VarsItem): any { + const { id, value } = v; + return { + ...stringToAttr('id', id), + ...stringToAttr('value', value), + }; + } + function varsToArray(vars: KMXPlus.VarsItem[]): any[] { + return vars.map(varToObj); + } + const { strings, sets, usets } = vars; + + return { + variables: { + string: varsToArray(strings), + set: varsToArray(sets), + uset: varsToArray(usets), + }, + }; + } + + function getTransforms() { + return { + transforms: [ + ...getTransformType("simple", tran), + ...getTransformType("backspace", bksp), + ], + }; + } + + /** NB: Bksp is a child class of Tran */ + function getTransformType(type: string, t: KMXPlus.Tran) { + if (!t?.groups?.length) { + return []; + } + const { groups } = t; + return [{ + ...asAttr('type', type), + transformGroup: groups.map((group) => { + if (group.type === constants.tran_group_type_transform) { + return { + transform: group.transforms.map(({from, to, _from, _to}) => ({ + ...stringToAttr('from', from, _from), + ...stringToAttr('to', to, _to), + })), + }; + } else if(group.type === constants.tran_group_type_reorder) { + return { + reorder: group.reorders.map(({before, elements, _before, _from, _order}) => ({ + ...asAttr('before', _before || before.toString()), + ...asAttr('from', _from || elements.toString()), + ...asAttr('order', _order), + })), + }; + } else { + throw Error(`Invalid tran.group.type ${group.type}`); + } + }), + }]; + } +} + + +/** convert a keys_mod value to a space-separated string list */ +function modToString(mod: number) { + // first try exact match + const matches: string[] = []; + for (const [name, value] of constants.keys_mod_map.entries()) { + if (mod === value) return name; // exact match + if (mod & value) matches.push(name); + } + return matches.sort().join(' '); +} diff --git a/developer/src/kmc-ldml/test/compiler-e2e.tests.ts b/developer/src/kmc-ldml/test/compiler-e2e.tests.ts index 1f87e55a22..c1bafeedb2 100644 --- a/developer/src/kmc-ldml/test/compiler-e2e.tests.ts +++ b/developer/src/kmc-ldml/test/compiler-e2e.tests.ts @@ -3,7 +3,10 @@ import {assert} from 'chai'; import hextobin from '@keymanapp/hextobin'; import { KMXBuilder } from '@keymanapp/developer-utils'; import {checkMessages, compileKeyboard, compilerTestCallbacks, compilerTestOptions, makePathToFixture} from './helpers/index.js'; +import { compareXml } from './helpers/compareXml.js'; import { LdmlKeyboardCompiler } from '../src/compiler/compiler.js'; +import { kmxToXml } from '../src/util/serialize.js'; +import { writeFileSync } from 'node:fs'; /** Overall compiler tests */ describe('compiler-tests', function() { @@ -35,8 +38,34 @@ describe('compiler-tests', function() { let expected = await hextobin(binaryFilename, undefined, {silent:true}); assert.deepEqual(code, expected); + + // now output it again as XML + const outputFilename = makePathToFixture('basic-serialized.xml'); + const asXml = kmxToXml(kmx); + writeFileSync(outputFilename, asXml, 'utf-8'); + }); + it('should-serialize-kmx', async function() { + this.timeout(4000); + // Let's build basic.xml + // It should match basic.kmx (built from basic.txt) + + const inputFilename = makePathToFixture('basic.xml'); + + // Compile the keyboard + const kmx = await compileKeyboard(inputFilename, {...compilerTestOptions, saveDebug: true, shouldAddCompilerVersion: false}); + assert.isNotNull(kmx); + + // now output it as XML + const outputFilename = makePathToFixture('basic-serialized.xml'); + const asXml = kmxToXml(kmx); + writeFileSync(outputFilename, asXml, 'utf-8'); + + compareXml(outputFilename, inputFilename); + }); + + it('should handle non existent files', async () => { const filename = 'DOES_NOT_EXIST.xml'; const k = new LdmlKeyboardCompiler(); diff --git a/developer/src/kmc-ldml/test/fixtures/basic-serialized.xml b/developer/src/kmc-ldml/test/fixtures/basic-serialized.xml new file mode 100644 index 0000000000..aa570fd6f0 --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/basic-serialized.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/helpers/compareXml.ts b/developer/src/kmc-ldml/test/helpers/compareXml.ts new file mode 100644 index 0000000000..f245da51a9 --- /dev/null +++ b/developer/src/kmc-ldml/test/helpers/compareXml.ts @@ -0,0 +1,25 @@ +import {assert} from 'chai'; +import {readFileSync} from 'node:fs'; +import { KeymanXMLReader } from "@keymanapp/developer-utils"; + +/** + * + * @param actual path to actual XML + * @param expect path to expected XML + * @param mutator optional function that will be applied to the parsed object + */ +export function compareXml(actual : string, expect: string, mutator?: (input: any) => any) { + if (!mutator) { + // no-op + mutator = (x: any) => x; + } + const reader = new KeymanXMLReader('keyboard3'); + + const actualStr = readFileSync(actual, 'utf-8'); + const expectStr = readFileSync(expect, 'utf-8'); + + const actualParsed = mutator(reader.parse(actualStr)); + const expectParsed = mutator(reader.parse(expectStr)); + + assert.deepEqual(actualParsed, expectParsed); +} diff --git a/developer/src/kmc-ldml/test/tsconfig.json b/developer/src/kmc-ldml/test/tsconfig.json index 354f5235f1..5f6d6e93b6 100644 --- a/developer/src/kmc-ldml/test/tsconfig.json +++ b/developer/src/kmc-ldml/test/tsconfig.json @@ -10,7 +10,7 @@ }, "include": [ "**/*.tests.ts", - "./helpers/index.ts" + "./helpers/*.ts", ], "references": [ { "path": "../../../../common/web/keyman-version" }, From 9a33a26d5ccbb3a4c1368646e5f466aad8cb3c93 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 10 Feb 2025 12:35:25 -0600 Subject: [PATCH 07/61] feat(developer): preserve CLDR version on serialize Fixes: #12874 --- developer/src/kmc-ldml/src/util/serialize.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/developer/src/kmc-ldml/src/util/serialize.ts b/developer/src/kmc-ldml/src/util/serialize.ts index ee02abadcc..2a7391d0c6 100644 --- a/developer/src/kmc-ldml/src/util/serialize.ts +++ b/developer/src/kmc-ldml/src/util/serialize.ts @@ -67,10 +67,11 @@ export function kmxToXml(kmx: KMXPlus.KMXPlusFile): string { return writer.write(data); function getRootAttributes() { + const conform = meta.conform.value; return { - '$xmlns': `https://schemas.unicode.org/cldr/${constants.cldr_version_latest}/keyboard3`, + '$xmlns': `https://schemas.unicode.org/cldr/${conform}/keyboard3`, '$locale': kmx.kmxplus.loca.locales[0].value, - '$conformsTo': constants.cldr_version_latest, + '$conformsTo': conform, }; } From 7ac190fc1be846ce0433f8bf976e01d59eeb3fb5 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:47:14 +1000 Subject: [PATCH 08/61] feat(windows): commit review suggestion Co-authored-by: Eberhard Beilharz --- .../desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index e79dd299c4..dcb6f5a6d6 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -774,7 +774,7 @@ begin repeat DownloadResult := DownloadUpdatesBackground; Inc(RetryCount); - until DownloadResult or (RetryCount = 3); + until DownloadResult or (RetryCount >= 3); finally FreeAndNil(FMutex); From fa45fd88e52e05d0de1c18dcfaf9f43bda0a5740 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:54:58 +1000 Subject: [PATCH 09/61] feat(windows): release ownership of mutex successful download Added a release of ownership for the mutex download after in the successuful download case --- .../desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas index dcb6f5a6d6..afce261cfa 100644 --- a/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas +++ b/windows/src/desktop/kmshell/main/Keyman.System.UpdateStateMachine.pas @@ -775,7 +775,7 @@ begin DownloadResult := DownloadUpdatesBackground; Inc(RetryCount); until DownloadResult or (RetryCount >= 3); - + FMutex.ReleaseOwnership; finally FreeAndNil(FMutex); end; From a530775b65954e4efbfd31c414b794e8548eccb6 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 11 Feb 2025 14:04:34 +0700 Subject: [PATCH 10/61] chore: establish 18.0 beta --- HISTORY.md | 4 ++++ TIER.md | 2 +- VERSION.md | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ca5fe2101f..4486c583d4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 18.0.189 beta 2025-02-11 + +* chore: move to beta + ## 18.0.188 alpha 2025-02-10 * fix(windows): check the params status flag equals ucrsUpdateReady before attempting to download the keyman setup file (#13154) diff --git a/TIER.md b/TIER.md index 4a58007052..65b2df87f7 100644 --- a/TIER.md +++ b/TIER.md @@ -1 +1 @@ -alpha +beta diff --git a/VERSION.md b/VERSION.md index b9cdf8a8b6..a5872e474d 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.189 \ No newline at end of file +18.0.190 \ No newline at end of file From 0c85008cae10ed9cabbadd33b2a01a8abd193e7c Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 11 Feb 2025 02:36:16 -0500 Subject: [PATCH 11/61] auto: increment beta version to 18.0.191 --- HISTORY.md | 8 ++++++++ VERSION.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 4486c583d4..297952a566 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,13 @@ # Keyman Version History +## 18.0.190 beta 2025-02-11 + +* fix(developer): bundle ttfmeta library internally with kmc-keyboard-info (#11631) +* fix(developer): support Windows and Unicode names in .ttf (#11633) +* chore(developer): increase timeout for kmc-ldml compiler test (#11635) +* chore(common): deps: update eslint typescript plugins (#11842) +* refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168) + ## 18.0.189 beta 2025-02-11 * chore: move to beta diff --git a/VERSION.md b/VERSION.md index a5872e474d..ba4e96bd1d 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.190 \ No newline at end of file +18.0.191 \ No newline at end of file From af3756dd9258b1f941de21aa3c25855c3c700dfb Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 11 Feb 2025 19:24:22 +0100 Subject: [PATCH 12/61] chore(linux): remove support of Ubuntu 20.04 Focal Ubuntu 20.04 Focal will reach EOL in April and GitHub removes the runner images, so we no longer will be able to build packages for Focal. --- .github/workflows/deb-packaging.yml | 2 +- linux/scripts/launchpad.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 52c485aa65..bf1bfca2fa 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -116,7 +116,7 @@ jobs: strategy: fail-fast: true matrix: - dist: [focal, jammy, noble, oracular] + dist: [jammy, noble, oracular] steps: - name: Checkout diff --git a/linux/scripts/launchpad.sh b/linux/scripts/launchpad.sh index 98ab9238f0..4b89980994 100755 --- a/linux/scripts/launchpad.sh +++ b/linux/scripts/launchpad.sh @@ -33,7 +33,7 @@ else fi echo "ppa: ${ppa}" -distributions="${DIST:-focal jammy noble oracular plucky}" +distributions="${DIST:-jammy noble oracular plucky}" packageversion="${PACKAGEVERSION:-1~sil1}" BASEDIR=$(pwd) From de79efb8fb6ec989556f84115b845ff072a5384d Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 11 Feb 2025 19:56:19 +0100 Subject: [PATCH 13/61] chore(linux): update actions/cache to non-deprecated version Our previous version of actions/cache will stop working at the end of February. This change updates to the latest version. https://github.com/actions/cache/discussions/1510 --- .github/workflows/api-verification.yml | 2 +- .github/workflows/deb-packaging.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api-verification.yml b/.github/workflows/api-verification.yml index 443adb471f..8f37141c08 100644 --- a/.github/workflows/api-verification.yml +++ b/.github/workflows/api-verification.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Restore artifacts - uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: | artifacts diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 52c485aa65..bc21de4623 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -315,7 +315,7 @@ jobs: echo "GIT_USER=${{ github.event.client_payload.user }}" >> artifacts/env - name: Cache artifacts - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: | artifacts From 9491202e5b7a8909dc34291d17eed72138070fe7 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 11 Feb 2025 19:35:19 +0100 Subject: [PATCH 14/61] chore(linux): update branch that's used for Debian packaging Use the `beta` branch while we're in Beta. --- linux/debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/debian/control b/linux/debian/control index fbe7066f5c..e6bc47bdb8 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -43,8 +43,8 @@ Build-Depends: xserver-xephyr, xvfb, Standards-Version: 4.7.0 -Vcs-Git: https://github.com/keymanapp/keyman.git -b stable-17.0 [linux/debian] -Vcs-Browser: https://github.com/keymanapp/keyman/tree/stable-17.0/linux/debian +Vcs-Git: https://github.com/keymanapp/keyman.git -b beta [linux/debian] +Vcs-Browser: https://github.com/keymanapp/keyman/tree/beta/linux/debian Homepage: https://www.keyman.com Rules-Requires-Root: binary-targets From c2225b84312b2f342b6b383abb6da741307bc25b Mon Sep 17 00:00:00 2001 From: Shawn Schantz Date: Wed, 12 Feb 2025 10:43:17 +0700 Subject: [PATCH 15/61] chore(mac): update whats new for Keyman 18 Fixes: #13184 --- mac/docs/help/about/whatsnew.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mac/docs/help/about/whatsnew.md b/mac/docs/help/about/whatsnew.md index 73ccb4d49b..627ef1a5b0 100644 --- a/mac/docs/help/about/whatsnew.md +++ b/mac/docs/help/about/whatsnew.md @@ -2,4 +2,10 @@ title: What's New in Keyman 18.0 for macOS --- -Here are some of the new features we have added to Keyman 18.0 for macOS: +Here are some significant changes to Keyman 18.0 for macOS: + +* Minimum supported version of macOS is 10.13 High Sierra. +* Improved handling of Option key and how it relates to Alt key in Keyman keyboards (#12458) +* Keyman keyboards are now stored in the preferred location, `/Library/Application Support`, instead of `/Documents` (#12106) +* Removed 'Use Verbose console Logging' option and use Apple unified logging system instead (#12431) +* Removed 'Always Show OSK' option and automatically remember OSK window state instead (#12355) \ No newline at end of file From 24c27d364b400078e16fc4267f0140bc33f92b3f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 12 Feb 2025 10:51:22 +0700 Subject: [PATCH 16/61] docs(developer): update what's new for 18.0 Fixes: #13180 --- developer/docs/help/whats-new.md | 54 ++++++++++---------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/developer/docs/help/whats-new.md b/developer/docs/help/whats-new.md index d1dce092c3..b91430b167 100644 --- a/developer/docs/help/whats-new.md +++ b/developer/docs/help/whats-new.md @@ -2,42 +2,20 @@ title: What's new in Keyman Developer 18.0 --- -Keyman Developer 17 has a number of significant changes: +Keyman Developer 18 has a number of significant changes: -* `kmcomp` has been removed and replaced with `kmc`. Learn more in our [kmcomp migration guide](reference/kmc/cli/kmcomp-migration). - -* Windows installer packages should now be built with - `kmc build windows-package-installer` and can no longer be built within - the Keyman Developer IDE. More details on how to use this are in the - [`kmc` reference documentation](reference/kmc/cli/reference#toc-kmc-build-windows-package-installer-additional-options). - -* `.keyboard_info` files are now generated entirely from the package and - keyboard files. Extra fields are available in packages for license file, - welcome file, typing examples, related packages (including deprecated - packages), and additional font files. Keyboards in the Keyman Cloud - keyboard repository have already been updated; if you are an author of - one of these keyboards, you should pull the changes from the repository - before submitting future updates. - -* Keyboard project files (.kpj) now have a new format which does not list - individual files, but instead includes all files in the same folder and - subfolders relative to the project file. This prevents projects from - including unrelated files, and reduces the number of files that change - when keyboards are updated. - -* Keyman Developer will now open each project in a new window, allowing - the user to rapidly switch between multiple projects at the same time. - -* The Keyman Keyboard and Lexical Model Cloud repositories have new build - scripts which run `kmc`. These run much, much faster than previously! - -* The [`&displayMap`](/developer/language/reference/displaymap) store allows - keyboard developers to specify a font mapping to PUA for the On Screen - Keyboard and Touch Layout to resolve diacritic rendering issues. - -* Keyman Developer has been updated to support Unicode 15.1. - -* Additional non-printing characters have been added to the Touch Layout Editor. - -* Virtual keys in output of rules have never worked properly or been officially - supported; Keyman Developer will now warn if you attempt to use this pattern. +* Updated to Unicode 16.0 (#12393) +* Improve automatic detection of minimum Keyman version for a keyboard during + compilation (#11981, 311982, #11965, #11957) +* Generate keyboards and lexical models from templates, with `kmc generate` + (#11014) +* Clone existing keyboard and lexical model projects, both from local file + system and also from any open source online Keyman keyboard in Keyman Cloud or + GitHub, with `kmc copy` and New Project dialogs (#12555, #12586, #13076) +* Support extending existing `&displaymap` data files when adding new characters + (#12622) +* Font settings for on screen keyboards are now kept consistent with package + metadata during compilation (#12949) +* New npm module @keymanapp/langtags makes langtags.json easily accessible + (#13046) +* Compiler messages now have links to additional documentation (#13156) From 343df5d5eb38d8263a15d184e0add226c44fdbe7 Mon Sep 17 00:00:00 2001 From: Shawn Schantz Date: Wed, 12 Feb 2025 10:53:26 +0700 Subject: [PATCH 17/61] chore(ios): update whats new for Keyman 18 Fixes: #13182 --- ios/docs/help/about/whatsnew.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/docs/help/about/whatsnew.md b/ios/docs/help/about/whatsnew.md index aa4cf6b333..e5338030f2 100644 --- a/ios/docs/help/about/whatsnew.md +++ b/ios/docs/help/about/whatsnew.md @@ -1,8 +1,8 @@ --- title: What's New in Keyman 18.0 for iPhone and iPad --- -Here are some of the new features we have added to Keyman for iPhone and iPad 18.0: +Here are some significant changes to Keyman for iPhone and iPad 18.0: -Additional changes: - -* Performance improvements +* Minimum supported version of iOS is 13.0. +* Predictive text and on screen keyboard startup performance improvements (#11784, #11264, #11265) +* Keyboard size can now be adjusted to your preference (#12571) \ No newline at end of file From 6b6b2f9a1d9ecdc5fd0d31f61af1960951e1bb5e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 12 Feb 2025 06:12:05 +0100 Subject: [PATCH 18/61] chore: Update developer/docs/help/whats-new.md Co-authored-by: Darcy Wong --- developer/docs/help/whats-new.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/docs/help/whats-new.md b/developer/docs/help/whats-new.md index b91430b167..d941d0e917 100644 --- a/developer/docs/help/whats-new.md +++ b/developer/docs/help/whats-new.md @@ -6,7 +6,7 @@ Keyman Developer 18 has a number of significant changes: * Updated to Unicode 16.0 (#12393) * Improve automatic detection of minimum Keyman version for a keyboard during - compilation (#11981, 311982, #11965, #11957) + compilation (#11981, #11982, #11965, #11957) * Generate keyboards and lexical models from templates, with `kmc generate` (#11014) * Clone existing keyboard and lexical model projects, both from local file From 29c46bcfe2f37608b3c81af52097126e870cbd6e Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 12 Feb 2025 11:32:37 +0100 Subject: [PATCH 19/61] chore(linux): update minimum version --- docs/build/linux-ubuntu.md | 2 +- docs/minimum-versions.md | 2 +- linux/docs/help/common/index.md | 4 ++-- resources/build/minimum-versions.inc.sh | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index 0f531acb59..9c0b195474 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -23,7 +23,7 @@ The following projects **cannot** be built on Linux: ### System Requirements -- Minimum Ubuntu version: Ubuntu 20.04 +- Minimum Ubuntu version: Ubuntu 22.04 Other Linux distributions will also work if appropriate dependencies are installed. diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md index 174f4b518e..3b270f48a4 100644 --- a/docs/minimum-versions.md +++ b/docs/minimum-versions.md @@ -53,7 +53,7 @@ https://help.keyman.com/developer/engine/android/latest-version/ | KEYMAN_MIN_TARGET_VERSION_ANDROID_CHROME | 53.0 | | KEYMAN_MIN_TARGET_VERSION_IOS | 12.2 | | KEYMAN_MIN_TARGET_VERSION_MAC | 10.13 | -| KEYMAN_MIN_TARGET_VERSION_UBUNTU | 20.04 | +| KEYMAN_MIN_TARGET_VERSION_UBUNTU | 22.04 | | KEYMAN_MIN_TARGET_VERSION_WEB_CHROME | 95.0 | | KEYMAN_MIN_TARGET_VERSION_WEB_FIREFOX | 79.0 | | KEYMAN_MIN_TARGET_VERSION_WEB_OPERA | 47.0 | diff --git a/linux/docs/help/common/index.md b/linux/docs/help/common/index.md index b2d606b38d..a7f9e786bf 100644 --- a/linux/docs/help/common/index.md +++ b/linux/docs/help/common/index.md @@ -59,8 +59,8 @@ no on-screen keyboard for Wayland that works with Keyman. **A.** Keyman runs on Debian, Ubuntu, Wasta Linux and can be compiled to run from source in most distributions. -**Note:** Ubuntu versions before Ubuntu 20.04 LTS are no longer supported with -Keyman 17. If you are still running an older version and require Keyman you'll +**Note:** Ubuntu versions before Ubuntu 22.04 LTS are no longer supported with +Keyman 18. If you are still running an older version and require Keyman you'll have to install an older Keyman version. ## Q. Will my existing Windows Keyman keyboard work with Keyman for Linux? diff --git a/resources/build/minimum-versions.inc.sh b/resources/build/minimum-versions.inc.sh index 41a7c3690f..9fb46cd492 100644 --- a/resources/build/minimum-versions.inc.sh +++ b/resources/build/minimum-versions.inc.sh @@ -14,7 +14,7 @@ KEYMAN_MIN_TARGET_VERSION_ANDROID=5.0 # Lollipop KEYMAN_MIN_TARGET_VERSION_IOS=12.2 # iOS 12.2 KEYMAN_MIN_TARGET_VERSION_WINDOWS=10 # Windows 10 KEYMAN_MIN_TARGET_VERSION_MAC=10.13 # MacOS 10.13 (High Sierra) -KEYMAN_MIN_TARGET_VERSION_UBUNTU=20.04 # Ubuntu 20.04 Focal +KEYMAN_MIN_TARGET_VERSION_UBUNTU=22.04 # Ubuntu 22.04 Jammy KEYMAN_MIN_TARGET_VERSION_ANDROID_CHROME=53.0 # min version of Chrome for Keyman for Android # Target web browsers for KeymanWeb -- we do not have polyfills for From d03b8e0e9ab7903d06b51a0acd52d7fa97141874 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 12 Feb 2025 11:47:21 +0100 Subject: [PATCH 20/61] docs(linux): update `welcome.md` --- linux/docs/help/about/welcome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/docs/help/about/welcome.md b/linux/docs/help/about/welcome.md index eacc8c449c..dfd410b46e 100644 --- a/linux/docs/help/about/welcome.md +++ b/linux/docs/help/about/welcome.md @@ -6,6 +6,6 @@ Thank you for installing Keyman for Linux. Whether you're a new or returning use ## What is Keyman for Linux? -Keyman for Linux makes it possible to type in over 1,000 languages in any Linux application. +Keyman for Linux makes it possible to type in over 2,000 languages in any Linux application. [Click here](../start/) to get started. From bbc3142c3c05a7c8c4d0a35f6f74303a2e4fc679 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 12 Feb 2025 18:01:21 +0100 Subject: [PATCH 21/61] docs(linux): update what's new for 18.0 Fixes: #13183 --- linux/docs/help/about/whatsnew.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/linux/docs/help/about/whatsnew.md b/linux/docs/help/about/whatsnew.md index 4a4d5a30e1..35edaa60ab 100644 --- a/linux/docs/help/about/whatsnew.md +++ b/linux/docs/help/about/whatsnew.md @@ -2,4 +2,12 @@ title: What's New in Keyman 18.0 for Linux --- -Here are some of the new features we have added to Keyman for Linux 18.0: +Here are some significant changes to Keyman for Linux 18.0: + +- Minimum supported Ubuntu version is now 22.04 Jammy LTS. +- Other supported versions are Ubuntu 24.04 Noble LTS and + Ubuntu 24.10 Oracular. Users that are running an older version of + Ubuntu will have to continue using an older Keyman version. +- Keyman no longer requires a patched version of ibus as Keyman now uses + a system service to manage keystroke order (#11535). +- Added support for simulation of AltGr (right Alt) with Ctrl+Alt (#11852) From 28c81f7440268dd015783391f73ef5f2265b42dd Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 12 Feb 2025 13:03:55 -0500 Subject: [PATCH 22/61] auto: increment beta version to 18.0.192 --- HISTORY.md | 12 ++++++++++++ VERSION.md | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 297952a566..8520b89814 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,17 @@ # Keyman Version History +## 18.0.191 beta 2025-02-12 + +* feat(windows): handle a hard windows reset occurring while downloading updated keyman files (#13128) +* docs(developer): update what's new for 18.0 (#13198) +* chore(mac): update whats new for Keyman 18 (#13197) +* chore(ios): update whats new for Keyman 18 (#13199) +* fix: use tier and version from branch when merging history from another branch (#13170) +* fix(linux): start system service when switching keyboards (#13172) +* chore(linux): update actions/cache to non-deprecated version (#13193) +* chore(linux): update branch that's used for Debian packaging (#13192) +* chore(linux): remove support of Ubuntu 20.04 Focal (#13202) + ## 18.0.190 beta 2025-02-11 * fix(developer): bundle ttfmeta library internally with kmc-keyboard-info (#11631) diff --git a/VERSION.md b/VERSION.md index ba4e96bd1d..60181cc347 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.191 \ No newline at end of file +18.0.192 \ No newline at end of file From 0cd393a2e92308be202e34a44444289513214830 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:45:09 +1000 Subject: [PATCH 23/61] docs(windows): whats new keyman 18.0 for windows --- windows/docs/help/about/whatsnew.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/windows/docs/help/about/whatsnew.md b/windows/docs/help/about/whatsnew.md index 4f11c82ec2..c4173bf2fc 100644 --- a/windows/docs/help/about/whatsnew.md +++ b/windows/docs/help/about/whatsnew.md @@ -4,6 +4,11 @@ title: What's New in Keyman 18.0 for Windows Here are some of the new features we have added to Keyman 18.0 for Windows: +- Minimum supported version of Windows is 10.0 +- Updates to Keyman are now applied before Keyman starts for the first time in a session, so Windows no longer needs to be restarted (#10041) +- Keyman no longer adds a desktop shortcut when it is installed (#11401) +- Added an option to make Right Alt and Right Control also work for keyboard switching hotkeys if preferred (#11471) + ## Related Topics - [Version History](history) From a5fde7d3522e48db1f1a28f1485dca71fc685e40 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 13 Feb 2025 10:35:35 +0700 Subject: [PATCH 24/61] chore(common): Fix 17.0.335 tier in HISTORY.md --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8520b89814..5a5b197557 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1336,7 +1336,7 @@ * chore(common): move to 18.0 alpha (#10713) * chore: move to 18.0 alpha -## 17.0.335 alpha 2025-02-06 +## 17.0.335 stable 2025-02-06 * fix(android): improve resource-update tool handling of host Activity's closure (#13057) * fix(ios): prevent message-handler collision (#13058) From 0bff2d8ff6361a13a4543390b48a228f29d0fbf0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 13 Feb 2025 13:52:27 +0100 Subject: [PATCH 25/61] Update TIER.md --- TIER.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TIER.md b/TIER.md index 65b2df87f7..4a58007052 100644 --- a/TIER.md +++ b/TIER.md @@ -1 +1 @@ -beta +alpha From 965aee64f8c6b1cf1efc42d05ad6a54ad85ca2f0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 13 Feb 2025 13:52:57 +0100 Subject: [PATCH 26/61] Update VERSION.md From 017afe810048a938429b9b82a0d04defbb716015 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Thu, 13 Feb 2025 13:01:27 -0500 Subject: [PATCH 27/61] auto: increment master version to 19.0.4 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 544a275dea..eeff3d2866 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 19.0.3 alpha 2025-02-13 + +* docs: update keyboard processor build source (#13221) +* chore(linux): additional code cleanup after Focal removal (#13206) + ## 19.0.2 alpha 2025-02-12 * chore(linux): remove support of Ubuntu 20.04 Focal (#13203) diff --git a/VERSION.md b/VERSION.md index dd7d796646..2a33de40df 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.3 \ No newline at end of file +19.0.4 \ No newline at end of file From 296e1bbad416e22644162302b430ee63a8d72cf7 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 14 Feb 2025 05:51:35 +0700 Subject: [PATCH 28/61] feat(windows): hack in some fun features for kmdevlink This was an evening activity scratching itches on kmdevlink's 'Open Issue' dialog. The search box now supports three different types of strings: 1. `[[repo]#]num` -> open issue/PR #num in repo (if repo omitted, will use 'keyman'): * `13235` or `#13235` or `keyman#13235` -> opens PR #13235 * `keyman.com#545` -> opens PR keymanapp/keyman.com#545 * `api#172` -> opens PR keymanapp/api.keyman.com#172 2. `[[repo]#]searchtext` -> any non-numeric string does an issue search: * `label:ios/ font` -> opens an issue search for 'ios/' label and 'font' in keymanapp/keyman repo * `api#db` -> opens an issue search for 'db' in keymanapp/api.keyman.com repo 3. `[[repo]#]` -> opens issue list for repo (keymanapp/keyman if repo is omitted, or empty box) A second feature is construction of a HTML snippet of our usual short-form links to issues/PRs for Google Docs. Note that this dialog does not check if the target is an issue or PR, it just builds a link to the issue URL and lets GitHub redirect to PR. To use this, just type the `[[repo]#]num` format into the search field and click the Copy button. --- windows/src/support/kmdevlink/UfrmMain.pas | 28 ++-- .../support/kmdevlink/UfrmOpenCRMRecord.dfm | 27 ++-- .../support/kmdevlink/UfrmOpenCRMRecord.pas | 139 ++++++++++++++++-- 3 files changed, 163 insertions(+), 31 deletions(-) diff --git a/windows/src/support/kmdevlink/UfrmMain.pas b/windows/src/support/kmdevlink/UfrmMain.pas index 141596c4ca..6dcf14f575 100644 --- a/windows/src/support/kmdevlink/UfrmMain.pas +++ b/windows/src/support/kmdevlink/UfrmMain.pas @@ -12,7 +12,9 @@ uses const SStatusSiteURL = 'https://status.keyman.com'; - SSearchURL = 'https://github.com/keymanapp/%s/issues/%s'; + SOpenIssueURL = 'https://github.com/keymanapp/%s/issues/%d'; + SOpenAllIssuesURL = 'https://github.com/keymanapp/%s/issues'; + SIssueSearchURL = 'https://github.com/keymanapp/%s/issues?q=state%%3Aopen%%20%s'; SAddIssueURL = 'https://github.com/keymanapp/keyman/issues/new'; type @@ -81,6 +83,7 @@ var implementation uses + System.NetEncoding, ErrorControlledRegistry, ShellApi, UfrmCharacterIdentifier, @@ -228,8 +231,8 @@ end; procedure TfrmMain.cmdOpenIssueOrPRClick(Sender: TObject); var - parts: TArray; - repo, number: string; + URL: string; + iq: TIssueQuery; begin with TfrmOpenCRMRecord.Create(Self) do try @@ -240,20 +243,21 @@ begin Free; end; - parts := CustomerText.Split(['#']); - if Length(parts) = 1 then + iq := SearchTextToQuery(CustomerText); + if iq.searchString <> '' then begin - repo := 'keyman'; - number := parts[0]; + URL := Format(SIssueSearchURL, [iq.repo, TNetEncoding.URL.Encode(iq.searchString)]); + end + else if iq.issueNumber > 0 then + begin + URL := Format(SOpenIssueURL, [iq.repo, iq.issueNumber]); end else begin - repo := parts[0]; - if repo = '' then repo := 'keyman' else repo := RepoShortNameToFullName(repo); - - number := parts[1]; + URL := Format(SOpenAllIssuesURL, [iq.repo]); end; - if not TUtilExecute.URL(Format(SSearchURL, [repo, number])) then // I3349 + + if not TUtilExecute.URL(URL) then // I3349 ShowMessage(SysErrorMessage(GetLastError)); end; diff --git a/windows/src/support/kmdevlink/UfrmOpenCRMRecord.dfm b/windows/src/support/kmdevlink/UfrmOpenCRMRecord.dfm index 1914b23468..69f9f1dd3f 100644 --- a/windows/src/support/kmdevlink/UfrmOpenCRMRecord.dfm +++ b/windows/src/support/kmdevlink/UfrmOpenCRMRecord.dfm @@ -20,9 +20,9 @@ object frmOpenCRMRecord: TfrmOpenCRMRecord object TntLabel1: TLabel Left = 20 Top = 20 - Width = 62 + Width = 115 Height = 19 - Caption = '&Issue/PR' + Caption = '&Issue/PR/Search' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -16 @@ -45,9 +45,9 @@ object frmOpenCRMRecord: TfrmOpenCRMRecord ParentFont = False end object editSearchFor: TEdit - Left = 108 + Left = 156 Top = 17 - Width = 341 + Width = 293 Height = 27 Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -66,7 +66,7 @@ object frmOpenCRMRecord: TfrmOpenCRMRecord Caption = 'OK' Default = True ModalResult = 1 - TabOrder = 1 + TabOrder = 3 end object cmdCancel: TButton Left = 240 @@ -76,12 +76,12 @@ object frmOpenCRMRecord: TfrmOpenCRMRecord Cancel = True Caption = 'Cancel' ModalResult = 2 - TabOrder = 2 + TabOrder = 4 end object cbRepository: TComboBox - Left = 108 + Left = 156 Top = 69 - Width = 341 + Width = 293 Height = 27 Style = csDropDownList Font.Charset = DEFAULT_CHARSET @@ -90,7 +90,16 @@ object frmOpenCRMRecord: TfrmOpenCRMRecord Font.Name = 'Tahoma' Font.Style = [] ParentFont = False - TabOrder = 3 + TabOrder = 1 OnClick = cbRepositoryClick end + object cmdCopyHTML: TButton + Left = 156 + Top = 110 + Width = 159 + Height = 25 + Caption = 'Copy short form as &HTML link' + TabOrder = 2 + OnClick = cmdCopyHTMLClick + end end diff --git a/windows/src/support/kmdevlink/UfrmOpenCRMRecord.pas b/windows/src/support/kmdevlink/UfrmOpenCRMRecord.pas index e0fcf2fb74..3ca8cfedbd 100644 --- a/windows/src/support/kmdevlink/UfrmOpenCRMRecord.pas +++ b/windows/src/support/kmdevlink/UfrmOpenCRMRecord.pas @@ -17,9 +17,11 @@ type cmdCancel: TButton; lblRepo: TLabel; cbRepository: TComboBox; + cmdCopyHTML: TButton; procedure cbRepositoryClick(Sender: TObject); procedure editSearchForChange(Sender: TObject); procedure FormCreate(Sender: TObject); + procedure cmdCopyHTMLClick(Sender: TObject); private Changing: Boolean; function GetSearchText: WideString; @@ -33,8 +35,21 @@ type function RepoFullNameToShortName(name: string): string; function RepoShortNameToFullName(name: string): string; + +type + TIssueQuery = record + searchString: string; + repo: string; + issueNumber: Integer; + end; + +function SearchTextToQuery(s: string): TIssueQuery; + implementation +uses + Vcl.Clipbrd; + {$R *.dfm} const repos: TArray> = [ @@ -74,28 +89,131 @@ begin Result := name; end; +function SearchTextToQuery(s: string): TIssueQuery; +var + parts: TArray; +begin + Result.repo := 'keyman'; + Result.issueNumber := 0; + Result.searchString := ''; + + s := s.Trim; + parts := s.Split(['#']); + if Length(parts) = 0 then + begin + Exit; + end + else if Length(parts) = 1 then + begin + Result.issueNumber := StrToIntDef(s, 0); + if IntToStr(Result.issueNumber) <> s then + begin + Result.issueNumber := 0; + Result.searchString := s; + end; + end + else + begin + Result.repo := RepoShortNameToFullName(parts[0]); + Result.issueNumber := StrToIntDef(parts[1], 0); + if IntToStr(Result.issueNumber) <> parts[1] then + begin + Result.issueNumber := 0; + Result.searchString := parts[1]; + end; + end; +end; + +type + TMyClipboard = class(TClipboard); + +procedure TfrmOpenCRMRecord.cmdCopyHTMLClick(Sender: TObject); +var + c: TMyClipboard; + m: TMemoryStream; + ss: TStream; + displayRepo, html, s: string; + iq: TIssueQuery; + CF_HTML: UINT; + header: string; +const + // https://learn.microsoft.com/en-us/windows/win32/dataxchg/html-clipboard-format + // yeesh what a format + header_template = + 'Version:0.9'#$D#$A+ + 'StartHTML:%0.09d'#$D#$A+ + 'EndHTML:%0.09d'#$D#$A+ + 'StartFragment:%0.09d'#$D#$A+ + 'EndFragment:%0.09d'#$D#$A; + start_fragment = ''; + end_fragment = ''; + context_start = ''#$D#$A''#$D#$A; + context_end = #$D#$A''#$D#$A''; +begin + iq := SearchTextToQuery(SearchText); + if iq.repo = 'keyman' then + displayRepo := '' + else + displayRepo := iq.repo; + html := Format('%2:s#%1:d', [ + iq.repo, iq.issueNumber, displayRepo + ]); + + // Warning, this will go sadly badly with non-ascii letters + // because I am lazily not using UTF8Strings at this point + + header := Format(header_template, [0,0,0,0]); + s := Format(header_template, [ + header.Length, + header.Length + context_start.Length + start_fragment.Length + html.Length + end_fragment.Length + context_end.Length, + header.Length + context_start.Length + start_fragment.Length, + header.Length + context_start.Length + start_fragment.Length + html.Length + ]) + context_start + start_fragment + html + end_fragment + context_end + #0; + + ss := TStringStream.Create(s, TEncoding.UTF8); + try + CF_HTML := RegisterClipboardFormat('HTML Format'); + m := TMemoryStream.Create; + try + m.CopyFrom(ss, 0); + c := TMyClipboard(Clipboard); // access protected members yay delphi + c.SetBuffer(CF_HTML, m.Memory^, m.Size); + finally + m.Free; + end; + finally + ss.Free; + end; +end; + procedure TfrmOpenCRMRecord.editSearchForChange(Sender: TObject); var - s: string; - parts: TArray; - repo: string; + iq: TIssueQuery; begin if Changing then Exit; Changing := True; - s := editSearchFor.Text; - parts := s.Split(['#']); - if Length(parts) = 1 then + iq := SearchTextToQuery(SearchText); + + if iq.searchString <> '' then begin - cbRepository.ItemIndex := cbRepository.Items.IndexOf('keyman'); + cmdCopyHTML.Enabled := False; + cmdOK.Caption := '&Search'; + end + else if iq.issueNumber > 0 then + begin + cmdCopyHTML.Enabled := True; + cmdOK.Caption := '&Open issue'; end else begin - repo := RepoShortNameToFullName(parts[0]); - cbRepository.ItemIndex := cbRepository.Items.IndexOf(repo); + cmdCopyHTML.Enabled := False; + cmdOK.Caption := '&All issues'; end; + cbRepository.ItemIndex := cbRepository.Items.IndexOf(iq.repo); + Changing := False; end; @@ -106,11 +224,12 @@ begin for i := 0 to High(repos) do cbRepository.Items.Add(repos[i][0]); cbRepository.ItemIndex := cbRepository.Items.IndexOf('keyman'); + editSearchForChange(nil); end; function TfrmOpenCRMRecord.GetSearchText: WideString; begin - Result := editSearchFor.Text; + Result := Trim(editSearchFor.Text); end; procedure TfrmOpenCRMRecord.cbRepositoryClick(Sender: TObject); From d6e7c0b9d1c6a19d3cd8fd971abdae7e0bc8f2b7 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 14 Feb 2025 07:45:28 +0700 Subject: [PATCH 29/61] chore: Revert "Merge branch 'master' into beta" This reverts commit fae3932e15dd2e4e2790f1382a78b096e2e7ce69, reversing changes made to 793daddb48c6c11eb6beb3632cbd6351a9396fa8. --- HISTORY.md | 9 ------ VERSION.md | 2 +- android/docs/engine/guides/in-app/index.md | 6 ++-- android/docs/engine/index.md | 2 +- android/docs/engine/whatsnew.md | 7 ++++- android/docs/help/about/whatsnew.md | 7 +++-- android/docs/help/index.md | 2 +- developer/docs/help/index.md | 4 +-- developer/docs/help/whats-new.md | 20 +++++++++++-- developer/src/kmc/src/kmlmp.ts | 2 +- docs/build/linux-ubuntu.md | 2 +- docs/linux/README.md | 2 +- docs/minimum-versions.md | 2 +- docs/minimum-versions.md.in | 2 +- ios/docs/engine/index.md | 2 +- ios/docs/help/about/whatsnew.md | 7 +++-- ios/docs/help/index.md | 2 +- linux/debian/control | 4 +-- linux/debian/rules | 5 +++- linux/docs/help/about/whatsnew.md | 12 ++++++-- linux/docs/help/index.md | 2 +- linux/ibus-keyman/src/keymanutil.c | 5 ++-- linux/ibus-keyman/src/test/keymanutil.tests.c | 30 ++++++++++++++----- .../keyman_config/downloadkeyboard.py | 7 ++++- .../keyman_config/install_window.py | 7 ++++- .../keyman_config/keyboard_options_view.py | 7 ++++- linux/keyman-config/keyman_config/welcome.py | 6 +++- mac/docs/help/about/whatsnew.md | 10 +++++-- mac/docs/help/index.md | 2 +- resources/build/minimum-versions.inc.sh | 2 +- web/docs/engine/guide/index.md | 6 ++-- web/docs/engine/index.md | 12 ++++---- web/docs/engine/reference/core/version.md | 2 +- web/docs/engine/reference/index.md | 2 +- web/docs/engine/whats-new.md | 2 +- windows/docs/engine/api/index.md | 6 ++-- windows/docs/engine/index.md | 4 +-- windows/docs/help/about/whatsnew.md | 4 +-- windows/docs/help/index.md | 2 +- 39 files changed, 145 insertions(+), 74 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c88caba4e5..5a5b197557 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,14 +1,5 @@ # Keyman Version History -## 19.0.2 alpha 2025-02-12 - -* chore(linux): remove support of Ubuntu 20.04 Focal (#13203) - -## 19.0.1 alpha 2025-02-11 - -* refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168) -* chore: increment to alpha 19.0 (#13187) - ## 18.0.191 beta 2025-02-12 * feat(windows): handle a hard windows reset occurring while downloading updated keyman files (#13128) diff --git a/VERSION.md b/VERSION.md index 25720f44a6..60181cc347 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.3 +18.0.192 \ No newline at end of file diff --git a/android/docs/engine/guides/in-app/index.md b/android/docs/engine/guides/in-app/index.md index 538094ddbb..d788e267bb 100644 --- a/android/docs/engine/guides/in-app/index.md +++ b/android/docs/engine/guides/in-app/index.md @@ -6,8 +6,8 @@ Keyman Engine for Android allows you to use any Keyman touch keyboard in your An system keyboard app for purchase in the Play Store.
This guide will walk you through the steps for creating your first Android app with Keyman Engine for Android. -If you are not familiar with Android development, you will find the -[Android Developer online training](https://developer.android.com/training/index.html) an invaluable +If you are not familiar with Android development, you will find the +[Android Developer online training](https://developer.android.com/training/index.html) an invaluable resource, and working through some of their tutorials first will help you with the rest of this guide. ### 1. Install Free Tools @@ -131,5 +131,5 @@ And there you have it: your first Keyman Engine for Android app! ## See Also * [Guide: Build a system keyboard app](../system-keyboard/) * [Keyman Developer Documentation](/developer/17.0/) -* [Keyman Engine for Android Documentation](/developer/engine/android/19.0/) +* [Keyman Engine for Android Documentation](/developer/engine/android/18.0/) * [Android Developer Home](https://developer.android.com/index.html) diff --git a/android/docs/engine/index.md b/android/docs/engine/index.md index 38f255592b..fa549e4b34 100644 --- a/android/docs/engine/index.md +++ b/android/docs/engine/index.md @@ -4,7 +4,7 @@ title: Keyman Engine for Android ## Overview -Keyman Engine for Android 19.0 is a Java library for Android 5.0 and later versions which enables a fully customisable keyboard layout, both within an app and system-wide. +Keyman Engine for Android 18.0 is a Java library for Android 5.0 and later versions which enables a fully customisable keyboard layout, both within an app and system-wide. Keyboard layouts for Keyman Engine can be created with [Keyman Developer](/developer/17.0), and a [library of existing keyboard layouts](http://keyman.com/developer/keymanweb/keyboards) is also available.

diff --git a/android/docs/engine/whatsnew.md b/android/docs/engine/whatsnew.md index 5d6f717f8a..af3f8932d6 100644 --- a/android/docs/engine/whatsnew.md +++ b/android/docs/engine/whatsnew.md @@ -1,6 +1,11 @@ --- -title: What's New in Keyman Engine 19.0 for Android +title: What's New in Keyman Engine 18.0 for Android --- +## Keyman Engine for Android Breaking Changes: ## + +* Change package name from `com.tavultesoft.kmea` to `com.keyman.engine` #7881 +* Update to Java 11 #8543 + ## See Also * [Keyman Engine for Android Documentation](index) \ No newline at end of file diff --git a/android/docs/help/about/whatsnew.md b/android/docs/help/about/whatsnew.md index d0ca85e93f..0f0e891e42 100644 --- a/android/docs/help/about/whatsnew.md +++ b/android/docs/help/about/whatsnew.md @@ -1,6 +1,9 @@ --- -title: What's New in Keyman 19.0 for Android +title: What's New in Keyman 18.0 for Android --- -Here are some of the new features we have added to Keyman 19.0 for Android: +Here are some of the new features we have added to Keyman 18.0 for Android: +* New menu to adjust longpress delay time (#12170, #12185) +* Support localizations for right-to-left languages (#12215) +* Handle additional actions for ENTER key (#12125, #12315) diff --git a/android/docs/help/index.md b/android/docs/help/index.md index 360af91e6d..62df93195b 100644 --- a/android/docs/help/index.md +++ b/android/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Android 19.0 Help +title: Keyman for Android 18.0 Help --- ## [About Keyman](about/) diff --git a/developer/docs/help/index.md b/developer/docs/help/index.md index d7fbc4098d..9e9c250abb 100644 --- a/developer/docs/help/index.md +++ b/developer/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman Developer 19.0 User Guide +title: Keyman Developer 18.0 User Guide --- Need help using Keyman Developer to create your keyboard layouts? You'll @@ -8,7 +8,7 @@ and tutorials, and full reference information. ## Guides and Tutorials - [What is Keyman Developer?](guides/intro) -- [What's new in 19.0](whats-new) +- [What's new in 18.0](whats-new) - [Developing Keyman keyboard layouts](guides/develop) - [Testing Keyman keyboards](guides/test) - [Distributing Keyman keyboards](guides/distribute) diff --git a/developer/docs/help/whats-new.md b/developer/docs/help/whats-new.md index 1005476c3d..d941d0e917 100644 --- a/developer/docs/help/whats-new.md +++ b/developer/docs/help/whats-new.md @@ -1,5 +1,21 @@ --- -title: What's new in Keyman Developer 19.0 +title: What's new in Keyman Developer 18.0 --- -Keyman Developer 19 has the following significant changes: +Keyman Developer 18 has a number of significant changes: + +* Updated to Unicode 16.0 (#12393) +* Improve automatic detection of minimum Keyman version for a keyboard during + compilation (#11981, #11982, #11965, #11957) +* Generate keyboards and lexical models from templates, with `kmc generate` + (#11014) +* Clone existing keyboard and lexical model projects, both from local file + system and also from any open source online Keyman keyboard in Keyman Cloud or + GitHub, with `kmc copy` and New Project dialogs (#12555, #12586, #13076) +* Support extending existing `&displaymap` data files when adding new characters + (#12622) +* Font settings for on screen keyboards are now kept consistent with package + metadata during compilation (#12949) +* New npm module @keymanapp/langtags makes langtags.json easily accessible + (#13046) +* Compiler messages now have links to additional documentation (#13156) diff --git a/developer/src/kmc/src/kmlmp.ts b/developer/src/kmc/src/kmlmp.ts index a1346ac0d3..bb0cda5e53 100644 --- a/developer/src/kmc/src/kmlmp.ts +++ b/developer/src/kmc/src/kmlmp.ts @@ -3,7 +3,7 @@ * kmlmp - Keyman Lexical Model Package Compiler */ -// Note: this is a deprecated package and will be removed in Keyman 19.0 +// Note: this is a deprecated package and will be removed in Keyman 18.0 import { Command } from 'commander'; import { KmpCompiler } from '@keymanapp/kmc-package'; diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index 98e15185bf..9c0b195474 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -113,7 +113,7 @@ All dependencies are already installed if you followed the instructions under Keyman Core can be built with the `core/build.sh` script. -- [Building Keyman Core](../../core/docs/BUILDING.md) +- [Building Keyman Core](../../core/doc/BUILDING.md) ## Keyman for Linux diff --git a/docs/linux/README.md b/docs/linux/README.md index 64ef6c967f..80c1a78434 100644 --- a/docs/linux/README.md +++ b/docs/linux/README.md @@ -147,7 +147,7 @@ Run `ibus restart` after installing any of them. Keyman tries to activate the keyboard automatically. If you want to activate it for a different language, you can do so by following the steps below. -#### GNOME3 (Ubuntu default) +#### GNOME3 (focal and bionic default, also newer Ubuntu versions) - Click the connection/sound/shutdown section in the top right. Then the tools icon for Settings. diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md index 4f67d5a626..3b270f48a4 100644 --- a/docs/minimum-versions.md +++ b/docs/minimum-versions.md @@ -4,7 +4,7 @@ title: Keyman Minimum Versions Changes in [minimum-versions.inc.sh](minimum-versions.inc.sh) should manually be propagated to the linked help files below: -## Keyman 19.0 +## Keyman 18.0 Target Operating System and Platform Versions diff --git a/docs/minimum-versions.md.in b/docs/minimum-versions.md.in index 41a664d454..ffe508e12f 100644 --- a/docs/minimum-versions.md.in +++ b/docs/minimum-versions.md.in @@ -4,7 +4,7 @@ title: Keyman Minimum Versions Changes in [minimum-versions.inc.sh](minimum-versions.inc.sh) should manually be propagated to the linked help files below: -## Keyman 19.0 +## Keyman 18.0 Target Operating System and Platform Versions diff --git a/ios/docs/engine/index.md b/ios/docs/engine/index.md index bdba88b741..b87af4e260 100644 --- a/ios/docs/engine/index.md +++ b/ios/docs/engine/index.md @@ -4,7 +4,7 @@ title: Keyman for iPhone and iPad Developer Support ## Overview -The Keyman Engine for iPhone and iPad 19.0 SDK is designed to provide +The Keyman Engine for iPhone and iPad 18.0 SDK is designed to provide advanced international keyboard support to iOS apps. As a developer, you simply need to use (or subclass) TextView or diff --git a/ios/docs/help/about/whatsnew.md b/ios/docs/help/about/whatsnew.md index b123b1f23c..e5338030f2 100644 --- a/ios/docs/help/about/whatsnew.md +++ b/ios/docs/help/about/whatsnew.md @@ -1,5 +1,8 @@ --- -title: What's New in Keyman 19.0 for iPhone and iPad +title: What's New in Keyman 18.0 for iPhone and iPad --- +Here are some significant changes to Keyman for iPhone and iPad 18.0: -Here are some of the new features we have added to Keyman for iPhone and iPad 19.0: +* Minimum supported version of iOS is 13.0. +* Predictive text and on screen keyboard startup performance improvements (#11784, #11264, #11265) +* Keyboard size can now be adjusted to your preference (#12571) \ No newline at end of file diff --git a/ios/docs/help/index.md b/ios/docs/help/index.md index cd0f81300e..994bbbda9e 100644 --- a/ios/docs/help/index.md +++ b/ios/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for iPhone and iPad 19.0 Help +title: Keyman for iPhone and iPad 18.0 Help --- ## [About Keyman](about/) diff --git a/linux/debian/control b/linux/debian/control index 7e71df1b7b..e6bc47bdb8 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -10,7 +10,7 @@ Build-Depends: debhelper-compat (= 12), dh-python, gawk, - gir1.2-webkit2-4.1, + gir1.2-webkit2-4.1 | gir1.2-webkit2-4.0, ibus, libevdev-dev, libgtk-3-dev, @@ -88,7 +88,7 @@ Architecture: all Depends: dbus-x11, dconf-cli, - gir1.2-webkit2-4.1, + gir1.2-webkit2-4.1 | gir1.2-webkit2-4.0, keyman-engine, python3-bs4, python3-fonttools, diff --git a/linux/debian/rules b/linux/debian/rules index 5138b58330..8da37f40e4 100755 --- a/linux/debian/rules +++ b/linux/debian/rules @@ -66,7 +66,10 @@ override_dh_auto_install: rm $(CURDIR)/debian/keyman/usr/share/locale/*.po* # Don't call `build.sh install` - dh_auto_install does some extra smarts dh_auto_install --sourcedir=linux/keyman-config --buildsystem=pybuild $@ - dh $@ --with-python3 --with bash-completion + # Unfortunately bash-completion 2.10 (focal) doesn't yet provide dh-sequence-bash-completion, + # which we could add as build-dependency, so we'll have to explicitly call + # dh_bash_completion here instead of using `dh $@ --with-python3 --with bash-completion` + dh_bash-completion -O--buildsystem=pybuild dh_python3 -O--buildsystem=pybuild override_dh_missing: diff --git a/linux/docs/help/about/whatsnew.md b/linux/docs/help/about/whatsnew.md index 5521261b96..35edaa60ab 100644 --- a/linux/docs/help/about/whatsnew.md +++ b/linux/docs/help/about/whatsnew.md @@ -1,5 +1,13 @@ --- -title: What's New in Keyman 19.0 for Linux +title: What's New in Keyman 18.0 for Linux --- -Here are some of the new features we have added to Keyman for Linux 19.0: +Here are some significant changes to Keyman for Linux 18.0: + +- Minimum supported Ubuntu version is now 22.04 Jammy LTS. +- Other supported versions are Ubuntu 24.04 Noble LTS and + Ubuntu 24.10 Oracular. Users that are running an older version of + Ubuntu will have to continue using an older Keyman version. +- Keyman no longer requires a patched version of ibus as Keyman now uses + a system service to manage keystroke order (#11535). +- Added support for simulation of AltGr (right Alt) with Ctrl+Alt (#11852) diff --git a/linux/docs/help/index.md b/linux/docs/help/index.md index 329c66f69b..58d245063a 100644 --- a/linux/docs/help/index.md +++ b/linux/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Linux 19.0 Help +title: Keyman for Linux 18.0 Help --- Need help using Keyman for Linux? In time, this product documentation will grow and explain frequently asked questions. diff --git a/linux/ibus-keyman/src/keymanutil.c b/linux/ibus-keyman/src/keymanutil.c index 4bb0ac4078..9f48f0ffce 100644 --- a/linux/ibus-keyman/src/keymanutil.c +++ b/linux/ibus-keyman/src/keymanutil.c @@ -649,8 +649,9 @@ _ptr_array_new_from_array( } // `g_ptr_array_new_from_null_terminated_array` is only available in GLib 2.76, but we're still -// stuck to 2.72 (Ubuntu 22.04 Jammy). Therefore we copy the implementation here (slightly -// simplified). Once we're past 2.76 we can use the GLib method directly. +// stuck to 2.64 (Ubuntu 20.04 Focal) and 2.72 (Ubuntu 22.04 Jammy). Therefore we +// copy the implementation here (slightly simplified). Once we're past 2.76 we can use the GLib method +// directly. GPtrArray * _g_ptr_array_new_from_null_terminated_array( gpointer *data, diff --git a/linux/ibus-keyman/src/test/keymanutil.tests.c b/linux/ibus-keyman/src/test/keymanutil.tests.c index 56965a41ad..13636857d8 100644 --- a/linux/ibus-keyman/src/test/keymanutil.tests.c +++ b/linux/ibus-keyman/src/test/keymanutil.tests.c @@ -123,6 +123,22 @@ _free_tst_kb_data(add_keyboard_data* kb_data) { G_DEFINE_AUTOPTR_CLEANUP_FUNC(add_keyboard_data, _free_tst_kb_data) +// Newer glib versions have g_assert_cmpstrv which would allow to do +// g_assert_cmpstrv(result, keyboards); +// but unfortunately Ubuntu 20.04 Focal doesn't have that, so we roll +// our own +void +_kmn_assert_cmpstrv(gchar** result, gchar** expected) { + g_assert_nonnull(result); + g_assert_nonnull(expected); + int i = 0; + for (; result[i] && expected[i]; i++) { + g_assert_cmpstr(result[i], ==, expected[i]); + } + g_assert_null(result[i]); + g_assert_null(expected[i]); +} + //---------------------------------------------------------------------------------------------- void test_keyman_put_keyboard_options_todconf__invalid() { @@ -510,7 +526,7 @@ test_keyman_set_custom_keyboards__new_key() { // Verify g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); - g_assert_cmpstrv(result, keyboards); + _kmn_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -530,7 +546,7 @@ test_keyman_set_custom_keyboards__overwrite_key() { // Verify g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); - g_assert_cmpstrv(result, keyboards); + _kmn_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -549,7 +565,7 @@ test_keyman_set_custom_keyboards__delete_key_NULL() { g_auto(GStrv) result = _get_tst_kbds_key(); gchar* expected[] = {NULL}; g_assert_nonnull(result); - g_assert_cmpstrv(result, expected); + _kmn_assert_cmpstrv(result, expected); // Cleanup _delete_tst_kbds_key(); @@ -569,7 +585,7 @@ test_keyman_set_custom_keyboards__delete_key_empty_array() { // Verify g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); - g_assert_cmpstrv(result, keyboards); + _kmn_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -588,7 +604,7 @@ test_keyman_set_custom_keyboards__invalid_values() { g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); gchar* expected[] = {"fr:/tmp/test/test.kmx", NULL}; - g_assert_cmpstrv(result, expected); + _kmn_assert_cmpstrv(result, expected); // Cleanup _delete_tst_kbds_key(); @@ -606,7 +622,7 @@ test_keyman_get_custom_keyboards__value() { // Verify g_assert_nonnull(result); - g_assert_cmpstrv(result, keyboards); + _kmn_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -624,7 +640,7 @@ test_keyman_get_custom_keyboards__invalid_values() { // Verify gchar* expected[] = {"fr:/tmp/test/test.kmx", NULL}; g_assert_nonnull(result); - g_assert_cmpstrv(result, expected); + _kmn_assert_cmpstrv(result, expected); // Cleanup _delete_tst_kbds_key(); diff --git a/linux/keyman-config/keyman_config/downloadkeyboard.py b/linux/keyman-config/keyman_config/downloadkeyboard.py index ca3b091f92..42ff74308d 100755 --- a/linux/keyman-config/keyman_config/downloadkeyboard.py +++ b/linux/keyman-config/keyman_config/downloadkeyboard.py @@ -7,7 +7,12 @@ import urllib.parse import gi gi.require_version('Gtk', '3.0') -gi.require_version('WebKit2', '4.1') +try: + gi.require_version('WebKit2', '4.1') +except ValueError: + # TODO: Remove once we drop support for Ubuntu 20.04 Focal + gi.require_version('WebKit2', '4.0') + from gi.repository import Gtk, WebKit2 from keyman_config import KeymanComUrl, _, __releaseversion__, __tier__ diff --git a/linux/keyman-config/keyman_config/install_window.py b/linux/keyman-config/keyman_config/install_window.py index 1342dd44f6..dda242c7e1 100755 --- a/linux/keyman-config/keyman_config/install_window.py +++ b/linux/keyman-config/keyman_config/install_window.py @@ -15,7 +15,12 @@ import packaging.version import gi gi.require_version('Gtk', '3.0') -gi.require_version('WebKit2', '4.1') +try: + gi.require_version('WebKit2', '4.1') +except ValueError: + # TODO: Remove once we drop support for Ubuntu 20.04 Focal + gi.require_version('WebKit2', '4.0') + from gi.repository import Gtk, WebKit2 from keyman_config import _, secure_lookup diff --git a/linux/keyman-config/keyman_config/keyboard_options_view.py b/linux/keyman-config/keyman_config/keyboard_options_view.py index 38499a558a..795386d7bf 100644 --- a/linux/keyman-config/keyman_config/keyboard_options_view.py +++ b/linux/keyman-config/keyman_config/keyboard_options_view.py @@ -8,7 +8,12 @@ from urllib.parse import parse_qsl, urlencode import gi gi.require_version('Gtk', '3.0') -gi.require_version('WebKit2', '4.1') +try: + gi.require_version('WebKit2', '4.1') +except ValueError: + # TODO: Remove once we drop support for Ubuntu 20.04 Focal + gi.require_version('WebKit2', '4.0') + from gi.repository import Gtk, WebKit2 from keyman_config import _ diff --git a/linux/keyman-config/keyman_config/welcome.py b/linux/keyman-config/keyman_config/welcome.py index a14d747c6a..af001ea464 100644 --- a/linux/keyman-config/keyman_config/welcome.py +++ b/linux/keyman-config/keyman_config/welcome.py @@ -7,7 +7,11 @@ import webbrowser import gi gi.require_version('Gtk', '3.0') -gi.require_version('WebKit2', '4.1') +try: + gi.require_version('WebKit2', '4.1') +except ValueError: + # TODO: Remove once we drop support for Ubuntu 20.04 Focal + gi.require_version('WebKit2', '4.0') from gi.repository import Gtk, WebKit2 from keyman_config import _ diff --git a/mac/docs/help/about/whatsnew.md b/mac/docs/help/about/whatsnew.md index 8cc29bdadb..627ef1a5b0 100644 --- a/mac/docs/help/about/whatsnew.md +++ b/mac/docs/help/about/whatsnew.md @@ -1,5 +1,11 @@ --- -title: What's New in Keyman 19.0 for macOS +title: What's New in Keyman 18.0 for macOS --- -Here are some of the new features we have added to Keyman 19.0 for macOS: +Here are some significant changes to Keyman 18.0 for macOS: + +* Minimum supported version of macOS is 10.13 High Sierra. +* Improved handling of Option key and how it relates to Alt key in Keyman keyboards (#12458) +* Keyman keyboards are now stored in the preferred location, `/Library/Application Support`, instead of `/Documents` (#12106) +* Removed 'Use Verbose console Logging' option and use Apple unified logging system instead (#12431) +* Removed 'Always Show OSK' option and automatically remember OSK window state instead (#12355) \ No newline at end of file diff --git a/mac/docs/help/index.md b/mac/docs/help/index.md index 12397a903d..aa507a531e 100644 --- a/mac/docs/help/index.md +++ b/mac/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman 19.0 for macOS Help +title: Keyman 18.0 for macOS Help --- Need help using Keyman for macOS? You'll find everything you need here, including product documentation, diff --git a/resources/build/minimum-versions.inc.sh b/resources/build/minimum-versions.inc.sh index 2e1a2914b1..9fb46cd492 100644 --- a/resources/build/minimum-versions.inc.sh +++ b/resources/build/minimum-versions.inc.sh @@ -1,4 +1,4 @@ -# Required minimum versions as of Keyman 19.0 +# Required minimum versions as of Keyman 18.0 # # This is a list of minimum, maximum, and specific versions of any external # components or dependencies found in Keyman. diff --git a/web/docs/engine/guide/index.md b/web/docs/engine/guide/index.md index 4f59a4ebf0..26e2e42b47 100644 --- a/web/docs/engine/guide/index.md +++ b/web/docs/engine/guide/index.md @@ -1,8 +1,8 @@ --- -title: KeymanWeb - The Guide +title: KeymanWeb 18.0 - The Guide --- -Welcome to the guide for using KeymanWeb. +Welcome to the guide for using KeymanWeb 18.0. - [Getting Started with Keyman Web](get-started) - [User Interface Design](user-interface-design) @@ -10,4 +10,4 @@ Welcome to the guide for using KeymanWeb. - [Installing Keyboards](adding-keyboards) - [Additional Examples](examples/) -[Return to the main KeymanWeb page](../) \ No newline at end of file +[Return to the main KeymanWeb 18.0 page](../) \ No newline at end of file diff --git a/web/docs/engine/index.md b/web/docs/engine/index.md index 5515112f88..63d14e2fd1 100644 --- a/web/docs/engine/index.md +++ b/web/docs/engine/index.md @@ -1,27 +1,27 @@ --- -title: Keyman Engine for Web 19.0 Developer Help +title: Keyman Engine for Web 18.0 Developer Help --- -Keyman Engine for Web 19.0 is the current version of KeymanWeb and +Keyman Engine for Web 18.0 is the current version of KeymanWeb and supports touch devices with custom touch-layouts as well as desktop computer browsers. [Download](https://keyman.com/developer/keymanweb/) -: Downloading Keyman Engine for Web +: Downloading Keyman Engine for Web 18.0 [Guide](guide/) -: Keyman Engine for Web Guide +: Keyman Engine for Web 18.0 Guide [Reference](reference) -: Keyman Engine for Web Developer Reference +: Keyman Engine for Web 18.0 Developer Reference [What's New](whats-new) -: What's new in Keyman Engine for Web 19.0 +: What's new in Keyman Engine for Web 18.0 diff --git a/web/docs/engine/reference/core/version.md b/web/docs/engine/reference/core/version.md index 40b9db4529..7df0978ac8 100644 --- a/web/docs/engine/reference/core/version.md +++ b/web/docs/engine/reference/core/version.md @@ -22,7 +22,7 @@ Read only ### Return Value -`'19.0'` (for KeymanWeb 19.0) +`'18.0'` (for KeymanWeb 18.0) ## Description diff --git a/web/docs/engine/reference/index.md b/web/docs/engine/reference/index.md index f6e5a3a8de..74d83c3931 100644 --- a/web/docs/engine/reference/index.md +++ b/web/docs/engine/reference/index.md @@ -1,5 +1,5 @@ --- -title: KeymanWeb Reference +title: KeymanWeb 18.0 Reference --- [KeymanWeb Overview](overview) diff --git a/web/docs/engine/whats-new.md b/web/docs/engine/whats-new.md index e220fb9c13..49fa337fe0 100644 --- a/web/docs/engine/whats-new.md +++ b/web/docs/engine/whats-new.md @@ -1,3 +1,3 @@ --- -title: What's New in KeymanWeb 19.0 +title: What's New in KeymanWeb 18.0 --- diff --git a/windows/docs/engine/api/index.md b/windows/docs/engine/api/index.md index f95332c45a..7032aa0cd2 100644 --- a/windows/docs/engine/api/index.md +++ b/windows/docs/engine/api/index.md @@ -1,13 +1,13 @@ --- -title: Keyman Engine for Windows API +title: Keyman Engine for Windows 18.0 API --- ## Introduction -The Keyman Engine for Windows API is implemented in COM. It can be +The Keyman Engine for Windows 18.0 API is implemented in COM. It can be instantiated with `CreateObject("keymanapi.Keyman")`. -> [!Note] +> [!Note] > This documentation applies to Keyman Engine for Windows versions 14.0 and up. ## Interface Hierarchy diff --git a/windows/docs/engine/index.md b/windows/docs/engine/index.md index 0687433412..acdd77d877 100644 --- a/windows/docs/engine/index.md +++ b/windows/docs/engine/index.md @@ -1,8 +1,8 @@ --- -title: Keyman Engine for Windows +title: Keyman Engine for Windows 18.0 --- -Keyman Engine for Windows gives you the tools to build a customised +Keyman Engine for Windows 18.0 gives you the tools to build a customised desktop keyboarding product for Windows. **Note:** This documentation applies to Keyman Engine for Windows diff --git a/windows/docs/help/about/whatsnew.md b/windows/docs/help/about/whatsnew.md index 723530e09c..c4173bf2fc 100644 --- a/windows/docs/help/about/whatsnew.md +++ b/windows/docs/help/about/whatsnew.md @@ -1,8 +1,8 @@ --- -title: What's New in Keyman 19.0 for Windows +title: What's New in Keyman 18.0 for Windows --- -Here are some of the new features we have added to Keyman 19.0 for Windows: +Here are some of the new features we have added to Keyman 18.0 for Windows: - Minimum supported version of Windows is 10.0 - Updates to Keyman are now applied before Keyman starts for the first time in a session, so Windows no longer needs to be restarted (#10041) diff --git a/windows/docs/help/index.md b/windows/docs/help/index.md index 231ed5fc7d..c7cccc7695 100644 --- a/windows/docs/help/index.md +++ b/windows/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Windows 19.0 Help +title: Keyman for Windows 18.0 Help --- Need help using Keyman for Windows? You'll find everything you need here, including product documentation, From b9e95b927213e431a4a480f07f35a74497251023 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 14 Feb 2025 07:45:35 +0700 Subject: [PATCH 30/61] chore: Revert "Update TIER.md" This reverts commit 0bff2d8ff6361a13a4543390b48a228f29d0fbf0. --- TIER.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TIER.md b/TIER.md index 4a58007052..65b2df87f7 100644 --- a/TIER.md +++ b/TIER.md @@ -1 +1 @@ -alpha +beta From 901edd63b9efe0fd9170efbe4fcdbe08423d72e6 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 14 Feb 2025 08:44:32 +0700 Subject: [PATCH 31/61] chore: Revert "chore: Revert "Merge branch 'master' into beta"" This reverts commit d6e7c0b9d1c6a19d3cd8fd971abdae7e0bc8f2b7. --- HISTORY.md | 5 ++++ VERSION.md | 2 +- android/docs/engine/guides/in-app/index.md | 6 ++-- android/docs/engine/index.md | 2 +- android/docs/engine/whatsnew.md | 7 +---- android/docs/help/about/whatsnew.md | 7 ++--- android/docs/help/index.md | 2 +- developer/docs/help/index.md | 4 +-- developer/docs/help/whats-new.md | 20 ++----------- developer/src/kmc/src/kmlmp.ts | 2 +- docs/build/linux-ubuntu.md | 2 +- docs/linux/README.md | 2 +- docs/minimum-versions.md | 2 +- docs/minimum-versions.md.in | 2 +- ios/docs/engine/index.md | 2 +- ios/docs/help/about/whatsnew.md | 7 ++--- ios/docs/help/index.md | 2 +- linux/debian/control | 4 +-- linux/debian/rules | 5 +--- linux/docs/help/about/whatsnew.md | 12 ++------ linux/docs/help/index.md | 2 +- linux/ibus-keyman/src/keymanutil.c | 5 ++-- linux/ibus-keyman/src/test/keymanutil.tests.c | 30 +++++-------------- .../keyman_config/downloadkeyboard.py | 7 +---- .../keyman_config/install_window.py | 7 +---- .../keyman_config/keyboard_options_view.py | 7 +---- linux/keyman-config/keyman_config/welcome.py | 6 +--- mac/docs/help/about/whatsnew.md | 10 ++----- mac/docs/help/index.md | 2 +- resources/build/minimum-versions.inc.sh | 2 +- web/docs/engine/guide/index.md | 6 ++-- web/docs/engine/index.md | 12 ++++---- web/docs/engine/reference/core/version.md | 2 +- web/docs/engine/reference/index.md | 2 +- web/docs/engine/whats-new.md | 2 +- windows/docs/engine/api/index.md | 6 ++-- windows/docs/engine/index.md | 4 +-- windows/docs/help/about/whatsnew.md | 4 +-- windows/docs/help/index.md | 2 +- 39 files changed, 70 insertions(+), 145 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6536a429ed..65f6c3beb9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,11 @@ * chore(linux): remove support of Ubuntu 20.04 Focal (#13203) +## 19.0.1 alpha 2025-02-11 + +* refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168) +* chore: increment to alpha 19.0 (#13187) + ## 18.0.191 beta 2025-02-12 * feat(windows): handle a hard windows reset occurring while downloading updated keyman files (#13128) diff --git a/VERSION.md b/VERSION.md index 2a33de40df..fe09f0b0b9 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.4 \ No newline at end of file +19.0.4 diff --git a/android/docs/engine/guides/in-app/index.md b/android/docs/engine/guides/in-app/index.md index d788e267bb..538094ddbb 100644 --- a/android/docs/engine/guides/in-app/index.md +++ b/android/docs/engine/guides/in-app/index.md @@ -6,8 +6,8 @@ Keyman Engine for Android allows you to use any Keyman touch keyboard in your An system keyboard app for purchase in the Play Store.
This guide will walk you through the steps for creating your first Android app with Keyman Engine for Android. -If you are not familiar with Android development, you will find the -[Android Developer online training](https://developer.android.com/training/index.html) an invaluable +If you are not familiar with Android development, you will find the +[Android Developer online training](https://developer.android.com/training/index.html) an invaluable resource, and working through some of their tutorials first will help you with the rest of this guide. ### 1. Install Free Tools @@ -131,5 +131,5 @@ And there you have it: your first Keyman Engine for Android app! ## See Also * [Guide: Build a system keyboard app](../system-keyboard/) * [Keyman Developer Documentation](/developer/17.0/) -* [Keyman Engine for Android Documentation](/developer/engine/android/18.0/) +* [Keyman Engine for Android Documentation](/developer/engine/android/19.0/) * [Android Developer Home](https://developer.android.com/index.html) diff --git a/android/docs/engine/index.md b/android/docs/engine/index.md index fa549e4b34..38f255592b 100644 --- a/android/docs/engine/index.md +++ b/android/docs/engine/index.md @@ -4,7 +4,7 @@ title: Keyman Engine for Android ## Overview -Keyman Engine for Android 18.0 is a Java library for Android 5.0 and later versions which enables a fully customisable keyboard layout, both within an app and system-wide. +Keyman Engine for Android 19.0 is a Java library for Android 5.0 and later versions which enables a fully customisable keyboard layout, both within an app and system-wide. Keyboard layouts for Keyman Engine can be created with [Keyman Developer](/developer/17.0), and a [library of existing keyboard layouts](http://keyman.com/developer/keymanweb/keyboards) is also available.

diff --git a/android/docs/engine/whatsnew.md b/android/docs/engine/whatsnew.md index af3f8932d6..5d6f717f8a 100644 --- a/android/docs/engine/whatsnew.md +++ b/android/docs/engine/whatsnew.md @@ -1,11 +1,6 @@ --- -title: What's New in Keyman Engine 18.0 for Android +title: What's New in Keyman Engine 19.0 for Android --- -## Keyman Engine for Android Breaking Changes: ## - -* Change package name from `com.tavultesoft.kmea` to `com.keyman.engine` #7881 -* Update to Java 11 #8543 - ## See Also * [Keyman Engine for Android Documentation](index) \ No newline at end of file diff --git a/android/docs/help/about/whatsnew.md b/android/docs/help/about/whatsnew.md index 0f0e891e42..d0ca85e93f 100644 --- a/android/docs/help/about/whatsnew.md +++ b/android/docs/help/about/whatsnew.md @@ -1,9 +1,6 @@ --- -title: What's New in Keyman 18.0 for Android +title: What's New in Keyman 19.0 for Android --- -Here are some of the new features we have added to Keyman 18.0 for Android: +Here are some of the new features we have added to Keyman 19.0 for Android: -* New menu to adjust longpress delay time (#12170, #12185) -* Support localizations for right-to-left languages (#12215) -* Handle additional actions for ENTER key (#12125, #12315) diff --git a/android/docs/help/index.md b/android/docs/help/index.md index 62df93195b..360af91e6d 100644 --- a/android/docs/help/index.md +++ b/android/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Android 18.0 Help +title: Keyman for Android 19.0 Help --- ## [About Keyman](about/) diff --git a/developer/docs/help/index.md b/developer/docs/help/index.md index 9e9c250abb..d7fbc4098d 100644 --- a/developer/docs/help/index.md +++ b/developer/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman Developer 18.0 User Guide +title: Keyman Developer 19.0 User Guide --- Need help using Keyman Developer to create your keyboard layouts? You'll @@ -8,7 +8,7 @@ and tutorials, and full reference information. ## Guides and Tutorials - [What is Keyman Developer?](guides/intro) -- [What's new in 18.0](whats-new) +- [What's new in 19.0](whats-new) - [Developing Keyman keyboard layouts](guides/develop) - [Testing Keyman keyboards](guides/test) - [Distributing Keyman keyboards](guides/distribute) diff --git a/developer/docs/help/whats-new.md b/developer/docs/help/whats-new.md index d941d0e917..1005476c3d 100644 --- a/developer/docs/help/whats-new.md +++ b/developer/docs/help/whats-new.md @@ -1,21 +1,5 @@ --- -title: What's new in Keyman Developer 18.0 +title: What's new in Keyman Developer 19.0 --- -Keyman Developer 18 has a number of significant changes: - -* Updated to Unicode 16.0 (#12393) -* Improve automatic detection of minimum Keyman version for a keyboard during - compilation (#11981, #11982, #11965, #11957) -* Generate keyboards and lexical models from templates, with `kmc generate` - (#11014) -* Clone existing keyboard and lexical model projects, both from local file - system and also from any open source online Keyman keyboard in Keyman Cloud or - GitHub, with `kmc copy` and New Project dialogs (#12555, #12586, #13076) -* Support extending existing `&displaymap` data files when adding new characters - (#12622) -* Font settings for on screen keyboards are now kept consistent with package - metadata during compilation (#12949) -* New npm module @keymanapp/langtags makes langtags.json easily accessible - (#13046) -* Compiler messages now have links to additional documentation (#13156) +Keyman Developer 19 has the following significant changes: diff --git a/developer/src/kmc/src/kmlmp.ts b/developer/src/kmc/src/kmlmp.ts index bb0cda5e53..a1346ac0d3 100644 --- a/developer/src/kmc/src/kmlmp.ts +++ b/developer/src/kmc/src/kmlmp.ts @@ -3,7 +3,7 @@ * kmlmp - Keyman Lexical Model Package Compiler */ -// Note: this is a deprecated package and will be removed in Keyman 18.0 +// Note: this is a deprecated package and will be removed in Keyman 19.0 import { Command } from 'commander'; import { KmpCompiler } from '@keymanapp/kmc-package'; diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index 9c0b195474..98e15185bf 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -113,7 +113,7 @@ All dependencies are already installed if you followed the instructions under Keyman Core can be built with the `core/build.sh` script. -- [Building Keyman Core](../../core/doc/BUILDING.md) +- [Building Keyman Core](../../core/docs/BUILDING.md) ## Keyman for Linux diff --git a/docs/linux/README.md b/docs/linux/README.md index 80c1a78434..64ef6c967f 100644 --- a/docs/linux/README.md +++ b/docs/linux/README.md @@ -147,7 +147,7 @@ Run `ibus restart` after installing any of them. Keyman tries to activate the keyboard automatically. If you want to activate it for a different language, you can do so by following the steps below. -#### GNOME3 (focal and bionic default, also newer Ubuntu versions) +#### GNOME3 (Ubuntu default) - Click the connection/sound/shutdown section in the top right. Then the tools icon for Settings. diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md index 3b270f48a4..4f67d5a626 100644 --- a/docs/minimum-versions.md +++ b/docs/minimum-versions.md @@ -4,7 +4,7 @@ title: Keyman Minimum Versions Changes in [minimum-versions.inc.sh](minimum-versions.inc.sh) should manually be propagated to the linked help files below: -## Keyman 18.0 +## Keyman 19.0 Target Operating System and Platform Versions diff --git a/docs/minimum-versions.md.in b/docs/minimum-versions.md.in index ffe508e12f..41a664d454 100644 --- a/docs/minimum-versions.md.in +++ b/docs/minimum-versions.md.in @@ -4,7 +4,7 @@ title: Keyman Minimum Versions Changes in [minimum-versions.inc.sh](minimum-versions.inc.sh) should manually be propagated to the linked help files below: -## Keyman 18.0 +## Keyman 19.0 Target Operating System and Platform Versions diff --git a/ios/docs/engine/index.md b/ios/docs/engine/index.md index b87af4e260..bdba88b741 100644 --- a/ios/docs/engine/index.md +++ b/ios/docs/engine/index.md @@ -4,7 +4,7 @@ title: Keyman for iPhone and iPad Developer Support ## Overview -The Keyman Engine for iPhone and iPad 18.0 SDK is designed to provide +The Keyman Engine for iPhone and iPad 19.0 SDK is designed to provide advanced international keyboard support to iOS apps. As a developer, you simply need to use (or subclass) TextView or diff --git a/ios/docs/help/about/whatsnew.md b/ios/docs/help/about/whatsnew.md index e5338030f2..b123b1f23c 100644 --- a/ios/docs/help/about/whatsnew.md +++ b/ios/docs/help/about/whatsnew.md @@ -1,8 +1,5 @@ --- -title: What's New in Keyman 18.0 for iPhone and iPad +title: What's New in Keyman 19.0 for iPhone and iPad --- -Here are some significant changes to Keyman for iPhone and iPad 18.0: -* Minimum supported version of iOS is 13.0. -* Predictive text and on screen keyboard startup performance improvements (#11784, #11264, #11265) -* Keyboard size can now be adjusted to your preference (#12571) \ No newline at end of file +Here are some of the new features we have added to Keyman for iPhone and iPad 19.0: diff --git a/ios/docs/help/index.md b/ios/docs/help/index.md index 994bbbda9e..cd0f81300e 100644 --- a/ios/docs/help/index.md +++ b/ios/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for iPhone and iPad 18.0 Help +title: Keyman for iPhone and iPad 19.0 Help --- ## [About Keyman](about/) diff --git a/linux/debian/control b/linux/debian/control index e6bc47bdb8..7e71df1b7b 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -10,7 +10,7 @@ Build-Depends: debhelper-compat (= 12), dh-python, gawk, - gir1.2-webkit2-4.1 | gir1.2-webkit2-4.0, + gir1.2-webkit2-4.1, ibus, libevdev-dev, libgtk-3-dev, @@ -88,7 +88,7 @@ Architecture: all Depends: dbus-x11, dconf-cli, - gir1.2-webkit2-4.1 | gir1.2-webkit2-4.0, + gir1.2-webkit2-4.1, keyman-engine, python3-bs4, python3-fonttools, diff --git a/linux/debian/rules b/linux/debian/rules index 8da37f40e4..5138b58330 100755 --- a/linux/debian/rules +++ b/linux/debian/rules @@ -66,10 +66,7 @@ override_dh_auto_install: rm $(CURDIR)/debian/keyman/usr/share/locale/*.po* # Don't call `build.sh install` - dh_auto_install does some extra smarts dh_auto_install --sourcedir=linux/keyman-config --buildsystem=pybuild $@ - # Unfortunately bash-completion 2.10 (focal) doesn't yet provide dh-sequence-bash-completion, - # which we could add as build-dependency, so we'll have to explicitly call - # dh_bash_completion here instead of using `dh $@ --with-python3 --with bash-completion` - dh_bash-completion -O--buildsystem=pybuild + dh $@ --with-python3 --with bash-completion dh_python3 -O--buildsystem=pybuild override_dh_missing: diff --git a/linux/docs/help/about/whatsnew.md b/linux/docs/help/about/whatsnew.md index 35edaa60ab..5521261b96 100644 --- a/linux/docs/help/about/whatsnew.md +++ b/linux/docs/help/about/whatsnew.md @@ -1,13 +1,5 @@ --- -title: What's New in Keyman 18.0 for Linux +title: What's New in Keyman 19.0 for Linux --- -Here are some significant changes to Keyman for Linux 18.0: - -- Minimum supported Ubuntu version is now 22.04 Jammy LTS. -- Other supported versions are Ubuntu 24.04 Noble LTS and - Ubuntu 24.10 Oracular. Users that are running an older version of - Ubuntu will have to continue using an older Keyman version. -- Keyman no longer requires a patched version of ibus as Keyman now uses - a system service to manage keystroke order (#11535). -- Added support for simulation of AltGr (right Alt) with Ctrl+Alt (#11852) +Here are some of the new features we have added to Keyman for Linux 19.0: diff --git a/linux/docs/help/index.md b/linux/docs/help/index.md index 58d245063a..329c66f69b 100644 --- a/linux/docs/help/index.md +++ b/linux/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Linux 18.0 Help +title: Keyman for Linux 19.0 Help --- Need help using Keyman for Linux? In time, this product documentation will grow and explain frequently asked questions. diff --git a/linux/ibus-keyman/src/keymanutil.c b/linux/ibus-keyman/src/keymanutil.c index 9f48f0ffce..4bb0ac4078 100644 --- a/linux/ibus-keyman/src/keymanutil.c +++ b/linux/ibus-keyman/src/keymanutil.c @@ -649,9 +649,8 @@ _ptr_array_new_from_array( } // `g_ptr_array_new_from_null_terminated_array` is only available in GLib 2.76, but we're still -// stuck to 2.64 (Ubuntu 20.04 Focal) and 2.72 (Ubuntu 22.04 Jammy). Therefore we -// copy the implementation here (slightly simplified). Once we're past 2.76 we can use the GLib method -// directly. +// stuck to 2.72 (Ubuntu 22.04 Jammy). Therefore we copy the implementation here (slightly +// simplified). Once we're past 2.76 we can use the GLib method directly. GPtrArray * _g_ptr_array_new_from_null_terminated_array( gpointer *data, diff --git a/linux/ibus-keyman/src/test/keymanutil.tests.c b/linux/ibus-keyman/src/test/keymanutil.tests.c index 13636857d8..56965a41ad 100644 --- a/linux/ibus-keyman/src/test/keymanutil.tests.c +++ b/linux/ibus-keyman/src/test/keymanutil.tests.c @@ -123,22 +123,6 @@ _free_tst_kb_data(add_keyboard_data* kb_data) { G_DEFINE_AUTOPTR_CLEANUP_FUNC(add_keyboard_data, _free_tst_kb_data) -// Newer glib versions have g_assert_cmpstrv which would allow to do -// g_assert_cmpstrv(result, keyboards); -// but unfortunately Ubuntu 20.04 Focal doesn't have that, so we roll -// our own -void -_kmn_assert_cmpstrv(gchar** result, gchar** expected) { - g_assert_nonnull(result); - g_assert_nonnull(expected); - int i = 0; - for (; result[i] && expected[i]; i++) { - g_assert_cmpstr(result[i], ==, expected[i]); - } - g_assert_null(result[i]); - g_assert_null(expected[i]); -} - //---------------------------------------------------------------------------------------------- void test_keyman_put_keyboard_options_todconf__invalid() { @@ -526,7 +510,7 @@ test_keyman_set_custom_keyboards__new_key() { // Verify g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); - _kmn_assert_cmpstrv(result, keyboards); + g_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -546,7 +530,7 @@ test_keyman_set_custom_keyboards__overwrite_key() { // Verify g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); - _kmn_assert_cmpstrv(result, keyboards); + g_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -565,7 +549,7 @@ test_keyman_set_custom_keyboards__delete_key_NULL() { g_auto(GStrv) result = _get_tst_kbds_key(); gchar* expected[] = {NULL}; g_assert_nonnull(result); - _kmn_assert_cmpstrv(result, expected); + g_assert_cmpstrv(result, expected); // Cleanup _delete_tst_kbds_key(); @@ -585,7 +569,7 @@ test_keyman_set_custom_keyboards__delete_key_empty_array() { // Verify g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); - _kmn_assert_cmpstrv(result, keyboards); + g_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -604,7 +588,7 @@ test_keyman_set_custom_keyboards__invalid_values() { g_auto(GStrv) result = _get_tst_kbds_key(); g_assert_nonnull(result); gchar* expected[] = {"fr:/tmp/test/test.kmx", NULL}; - _kmn_assert_cmpstrv(result, expected); + g_assert_cmpstrv(result, expected); // Cleanup _delete_tst_kbds_key(); @@ -622,7 +606,7 @@ test_keyman_get_custom_keyboards__value() { // Verify g_assert_nonnull(result); - _kmn_assert_cmpstrv(result, keyboards); + g_assert_cmpstrv(result, keyboards); // Cleanup _delete_tst_kbds_key(); @@ -640,7 +624,7 @@ test_keyman_get_custom_keyboards__invalid_values() { // Verify gchar* expected[] = {"fr:/tmp/test/test.kmx", NULL}; g_assert_nonnull(result); - _kmn_assert_cmpstrv(result, expected); + g_assert_cmpstrv(result, expected); // Cleanup _delete_tst_kbds_key(); diff --git a/linux/keyman-config/keyman_config/downloadkeyboard.py b/linux/keyman-config/keyman_config/downloadkeyboard.py index 42ff74308d..ca3b091f92 100755 --- a/linux/keyman-config/keyman_config/downloadkeyboard.py +++ b/linux/keyman-config/keyman_config/downloadkeyboard.py @@ -7,12 +7,7 @@ import urllib.parse import gi gi.require_version('Gtk', '3.0') -try: - gi.require_version('WebKit2', '4.1') -except ValueError: - # TODO: Remove once we drop support for Ubuntu 20.04 Focal - gi.require_version('WebKit2', '4.0') - +gi.require_version('WebKit2', '4.1') from gi.repository import Gtk, WebKit2 from keyman_config import KeymanComUrl, _, __releaseversion__, __tier__ diff --git a/linux/keyman-config/keyman_config/install_window.py b/linux/keyman-config/keyman_config/install_window.py index dda242c7e1..1342dd44f6 100755 --- a/linux/keyman-config/keyman_config/install_window.py +++ b/linux/keyman-config/keyman_config/install_window.py @@ -15,12 +15,7 @@ import packaging.version import gi gi.require_version('Gtk', '3.0') -try: - gi.require_version('WebKit2', '4.1') -except ValueError: - # TODO: Remove once we drop support for Ubuntu 20.04 Focal - gi.require_version('WebKit2', '4.0') - +gi.require_version('WebKit2', '4.1') from gi.repository import Gtk, WebKit2 from keyman_config import _, secure_lookup diff --git a/linux/keyman-config/keyman_config/keyboard_options_view.py b/linux/keyman-config/keyman_config/keyboard_options_view.py index 795386d7bf..38499a558a 100644 --- a/linux/keyman-config/keyman_config/keyboard_options_view.py +++ b/linux/keyman-config/keyman_config/keyboard_options_view.py @@ -8,12 +8,7 @@ from urllib.parse import parse_qsl, urlencode import gi gi.require_version('Gtk', '3.0') -try: - gi.require_version('WebKit2', '4.1') -except ValueError: - # TODO: Remove once we drop support for Ubuntu 20.04 Focal - gi.require_version('WebKit2', '4.0') - +gi.require_version('WebKit2', '4.1') from gi.repository import Gtk, WebKit2 from keyman_config import _ diff --git a/linux/keyman-config/keyman_config/welcome.py b/linux/keyman-config/keyman_config/welcome.py index af001ea464..a14d747c6a 100644 --- a/linux/keyman-config/keyman_config/welcome.py +++ b/linux/keyman-config/keyman_config/welcome.py @@ -7,11 +7,7 @@ import webbrowser import gi gi.require_version('Gtk', '3.0') -try: - gi.require_version('WebKit2', '4.1') -except ValueError: - # TODO: Remove once we drop support for Ubuntu 20.04 Focal - gi.require_version('WebKit2', '4.0') +gi.require_version('WebKit2', '4.1') from gi.repository import Gtk, WebKit2 from keyman_config import _ diff --git a/mac/docs/help/about/whatsnew.md b/mac/docs/help/about/whatsnew.md index 627ef1a5b0..8cc29bdadb 100644 --- a/mac/docs/help/about/whatsnew.md +++ b/mac/docs/help/about/whatsnew.md @@ -1,11 +1,5 @@ --- -title: What's New in Keyman 18.0 for macOS +title: What's New in Keyman 19.0 for macOS --- -Here are some significant changes to Keyman 18.0 for macOS: - -* Minimum supported version of macOS is 10.13 High Sierra. -* Improved handling of Option key and how it relates to Alt key in Keyman keyboards (#12458) -* Keyman keyboards are now stored in the preferred location, `/Library/Application Support`, instead of `/Documents` (#12106) -* Removed 'Use Verbose console Logging' option and use Apple unified logging system instead (#12431) -* Removed 'Always Show OSK' option and automatically remember OSK window state instead (#12355) \ No newline at end of file +Here are some of the new features we have added to Keyman 19.0 for macOS: diff --git a/mac/docs/help/index.md b/mac/docs/help/index.md index aa507a531e..12397a903d 100644 --- a/mac/docs/help/index.md +++ b/mac/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman 18.0 for macOS Help +title: Keyman 19.0 for macOS Help --- Need help using Keyman for macOS? You'll find everything you need here, including product documentation, diff --git a/resources/build/minimum-versions.inc.sh b/resources/build/minimum-versions.inc.sh index 9fb46cd492..2e1a2914b1 100644 --- a/resources/build/minimum-versions.inc.sh +++ b/resources/build/minimum-versions.inc.sh @@ -1,4 +1,4 @@ -# Required minimum versions as of Keyman 18.0 +# Required minimum versions as of Keyman 19.0 # # This is a list of minimum, maximum, and specific versions of any external # components or dependencies found in Keyman. diff --git a/web/docs/engine/guide/index.md b/web/docs/engine/guide/index.md index 26e2e42b47..4f59a4ebf0 100644 --- a/web/docs/engine/guide/index.md +++ b/web/docs/engine/guide/index.md @@ -1,8 +1,8 @@ --- -title: KeymanWeb 18.0 - The Guide +title: KeymanWeb - The Guide --- -Welcome to the guide for using KeymanWeb 18.0. +Welcome to the guide for using KeymanWeb. - [Getting Started with Keyman Web](get-started) - [User Interface Design](user-interface-design) @@ -10,4 +10,4 @@ Welcome to the guide for using KeymanWeb 18.0. - [Installing Keyboards](adding-keyboards) - [Additional Examples](examples/) -[Return to the main KeymanWeb 18.0 page](../) \ No newline at end of file +[Return to the main KeymanWeb page](../) \ No newline at end of file diff --git a/web/docs/engine/index.md b/web/docs/engine/index.md index 63d14e2fd1..5515112f88 100644 --- a/web/docs/engine/index.md +++ b/web/docs/engine/index.md @@ -1,27 +1,27 @@ --- -title: Keyman Engine for Web 18.0 Developer Help +title: Keyman Engine for Web 19.0 Developer Help --- -Keyman Engine for Web 18.0 is the current version of KeymanWeb and +Keyman Engine for Web 19.0 is the current version of KeymanWeb and supports touch devices with custom touch-layouts as well as desktop computer browsers. [Download](https://keyman.com/developer/keymanweb/) -: Downloading Keyman Engine for Web 18.0 +: Downloading Keyman Engine for Web [Guide](guide/) -: Keyman Engine for Web 18.0 Guide +: Keyman Engine for Web Guide [Reference](reference) -: Keyman Engine for Web 18.0 Developer Reference +: Keyman Engine for Web Developer Reference [What's New](whats-new) -: What's new in Keyman Engine for Web 18.0 +: What's new in Keyman Engine for Web 19.0 diff --git a/web/docs/engine/reference/core/version.md b/web/docs/engine/reference/core/version.md index 7df0978ac8..40b9db4529 100644 --- a/web/docs/engine/reference/core/version.md +++ b/web/docs/engine/reference/core/version.md @@ -22,7 +22,7 @@ Read only ### Return Value -`'18.0'` (for KeymanWeb 18.0) +`'19.0'` (for KeymanWeb 19.0) ## Description diff --git a/web/docs/engine/reference/index.md b/web/docs/engine/reference/index.md index 74d83c3931..f6e5a3a8de 100644 --- a/web/docs/engine/reference/index.md +++ b/web/docs/engine/reference/index.md @@ -1,5 +1,5 @@ --- -title: KeymanWeb 18.0 Reference +title: KeymanWeb Reference --- [KeymanWeb Overview](overview) diff --git a/web/docs/engine/whats-new.md b/web/docs/engine/whats-new.md index 49fa337fe0..e220fb9c13 100644 --- a/web/docs/engine/whats-new.md +++ b/web/docs/engine/whats-new.md @@ -1,3 +1,3 @@ --- -title: What's New in KeymanWeb 18.0 +title: What's New in KeymanWeb 19.0 --- diff --git a/windows/docs/engine/api/index.md b/windows/docs/engine/api/index.md index 7032aa0cd2..f95332c45a 100644 --- a/windows/docs/engine/api/index.md +++ b/windows/docs/engine/api/index.md @@ -1,13 +1,13 @@ --- -title: Keyman Engine for Windows 18.0 API +title: Keyman Engine for Windows API --- ## Introduction -The Keyman Engine for Windows 18.0 API is implemented in COM. It can be +The Keyman Engine for Windows API is implemented in COM. It can be instantiated with `CreateObject("keymanapi.Keyman")`. -> [!Note] +> [!Note] > This documentation applies to Keyman Engine for Windows versions 14.0 and up. ## Interface Hierarchy diff --git a/windows/docs/engine/index.md b/windows/docs/engine/index.md index acdd77d877..0687433412 100644 --- a/windows/docs/engine/index.md +++ b/windows/docs/engine/index.md @@ -1,8 +1,8 @@ --- -title: Keyman Engine for Windows 18.0 +title: Keyman Engine for Windows --- -Keyman Engine for Windows 18.0 gives you the tools to build a customised +Keyman Engine for Windows gives you the tools to build a customised desktop keyboarding product for Windows. **Note:** This documentation applies to Keyman Engine for Windows diff --git a/windows/docs/help/about/whatsnew.md b/windows/docs/help/about/whatsnew.md index c4173bf2fc..723530e09c 100644 --- a/windows/docs/help/about/whatsnew.md +++ b/windows/docs/help/about/whatsnew.md @@ -1,8 +1,8 @@ --- -title: What's New in Keyman 18.0 for Windows +title: What's New in Keyman 19.0 for Windows --- -Here are some of the new features we have added to Keyman 18.0 for Windows: +Here are some of the new features we have added to Keyman 19.0 for Windows: - Minimum supported version of Windows is 10.0 - Updates to Keyman are now applied before Keyman starts for the first time in a session, so Windows no longer needs to be restarted (#10041) diff --git a/windows/docs/help/index.md b/windows/docs/help/index.md index c7cccc7695..231ed5fc7d 100644 --- a/windows/docs/help/index.md +++ b/windows/docs/help/index.md @@ -1,5 +1,5 @@ --- -title: Keyman for Windows 18.0 Help +title: Keyman for Windows 19.0 Help --- Need help using Keyman for Windows? You'll find everything you need here, including product documentation, From d4055449368c45484b5718e1fb2c997927286a6a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 14 Feb 2025 08:44:38 +0700 Subject: [PATCH 32/61] chore: Revert "chore: Revert "Update TIER.md"" This reverts commit b9e95b927213e431a4a480f07f35a74497251023. --- TIER.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TIER.md b/TIER.md index 65b2df87f7..4a58007052 100644 --- a/TIER.md +++ b/TIER.md @@ -1 +1 @@ -beta +alpha From 992f6aa58ddebeec7b24182a0f0f879be340e7ec Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 14 Feb 2025 08:46:04 +0700 Subject: [PATCH 33/61] chore(windows): clear out whatsnew for 19.0 --- windows/docs/help/about/whatsnew.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/windows/docs/help/about/whatsnew.md b/windows/docs/help/about/whatsnew.md index 723530e09c..ee917f3870 100644 --- a/windows/docs/help/about/whatsnew.md +++ b/windows/docs/help/about/whatsnew.md @@ -4,11 +4,6 @@ title: What's New in Keyman 19.0 for Windows Here are some of the new features we have added to Keyman 19.0 for Windows: -- Minimum supported version of Windows is 10.0 -- Updates to Keyman are now applied before Keyman starts for the first time in a session, so Windows no longer needs to be restarted (#10041) -- Keyman no longer adds a desktop shortcut when it is installed (#11401) -- Added an option to make Right Alt and Right Control also work for keyboard switching hotkeys if preferred (#11471) - ## Related Topics - [Version History](history) From f9caa01bf31d7a928e96693228da6eedbf575668 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 14 Feb 2025 13:01:35 -0500 Subject: [PATCH 34/61] auto: increment master version to 19.0.5 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index eeff3d2866..8d836fa885 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 19.0.4 alpha 2025-02-14 + +* feat(developer): serialize KMXPlus into XML (#13174) + ## 19.0.3 alpha 2025-02-13 * docs: update keyboard processor build source (#13221) diff --git a/VERSION.md b/VERSION.md index 2a33de40df..6d6c32d75a 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.4 \ No newline at end of file +19.0.5 \ No newline at end of file From 98b1fac59885c770aa2d5025fbc4ca009c150d1e Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 13 Feb 2025 15:28:04 -0600 Subject: [PATCH 35/61] chore(resources): import ABNF from CLDR v47 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - update fetch-latest-cldr.sh - so next time, abnf will get updated. - note, this is abnf from 47 but we’re not doing the full 47 import yet because it's not released. Fixes: feat(developer): utilize CLDR ABNF rules to validate transforms #13175 --- .../46/abnf/transform-from-required.abnf | 139 ++++++++++++++++++ .../46/abnf/transform-to-required.abnf | 95 ++++++++++++ .../ldml-keyboards/fetch-latest-cldr.sh | 14 +- 3 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf create mode 100644 resources/standards-data/ldml-keyboards/46/abnf/transform-to-required.abnf diff --git a/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf b/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf new file mode 100644 index 0000000000..4e02db22f2 --- /dev/null +++ b/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf @@ -0,0 +1,139 @@ +; Copyright (c) 2025 Unicode, Inc. +; For terms of use, see http://www.unicode.org/copyright.html +; SPDX-License-Identifier: Unicode-3.0 +; CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/) + +; This is an ABNF grammar for the CLDR Keyboard spec transform match syntax. +; Note that there are sample matching/failing data files in tools/scripts/keyboard-abnf-tests/ + +; An entire string. +; Note that the empty string is not a match. +; Also note that a string may match this ABNF but be invalid according to the spec - which see. + +from-match = start-context atoms / atoms + +; special marker anchoring to the start of context +start-context = "^" + +; sequence of items for input match. note that empty is not allowed, must be at least one atom. +atoms = atom *(disjunction atom / atom) + +; for use with or +disjunction = "|" + +; a 'quark' is the matching part of an atom, and then a quantifier +atom = quark quantifier / quark + +; quark can be a grouping or non grouping +quark = non-group / group + +non-group = simple-matcher / escaped-codepoints / variable + +variable = string-variable / set-variable + +string-variable = "${" var-id "}" + +set-variable = "$[" var-id "]" + +; variable ID +var-id = 1*32IDCHAR + +group = capturing-group / non-capturing-group + +quantifier = bounded-quantifier / optional-quantifier + +escaped-codepoints = backslash "u" "{" codepoints-hex "}" +escaped-codepoint = backslash "u" "{" codepoint-hex "}" + +bounded-quantifier = "{" DIGIT "," DIGIT "}" +optional-quantifier = "?" + +non-capturing-group = "(" "?" ":" atoms ")" + +; a capturing group may not contain other capturing groups. +capturing-group = "(" catoms ")" + +; capturing atoms can't include any groups +catoms = catom *(catom) +; capturing atoms can't include any groups +catom = cquark / cquark quantifier + +; capturing atoms can't include groups +cquark = non-group + +; multiple hex codepoints +codepoints-hex = codepoint-hex *(SP codepoint-hex) + +; one hex codepoint (1-6 digits) +codepoint-hex = 1*6LHEXDIG + +simple-matcher = text-char / class / match-any-codepoint / match-marker + +match-any-codepoint = "." + +match-marker = match-any-marker / match-named-marker +match-any-marker = "\m{.}" +match-named-marker = "\m{" marker-id "}" +; marker id is nmtoken, but may be UAX31 in the future. +marker-id = NMTOKEN + +class = fixed-class / set-class + +fixed-class = backslash fixed-class-char + +fixed-class-char = "s" / "S" / "t" / "r" / "n" / "f" / "v" / backslash / "$" / "d" / "w" / "D" / "W" / "0" + +set-class = "[" set-negator set-members "]" +set-members = set-member *(set-member) +set-member = text-char / char-range / match-marker +char-range = range-edge "-" range-edge +range-edge = escaped-codepoint / range-char +set-negator = "^" / "" + +; Restrictions on characters in various contexts + +; normal text +text-char = content-char / ws / escaped-char / "-" / ":" +; text in a range sequence +range-char = content-char / ws / escaped-char / "."/ "|" / "{" / "}" +; group for everything BUT syntax chars. +content-char = ASCII-PUNCT / ALPHA / DIGIT / NON-ASCII + +; Character escapes +escaped-char = backslash ( backslash / "{" / "|" / "}" ) + +backslash = %x5C ; U+005C REVERSE SOLIDUS "\" +ws = SP / HTAB / CR / LF / %x3000 + +IDCHAR = ALPHA / DIGIT / "_" +; ASCII-CTRLS = %x01-08 ; omit NULL (%x00), HTAB (%x09) and LF (%x0A) +; / %x0B-0C ; omit CR (%x0D) +; / %x0E-1F ; omit SP (%x20) +ASCII-PUNCT = %x21-23 ; omit DOLLAR + / %x25-27 ; omit () * + + / %x2C ; omit . (%x2E) and - (%x2D) + / %x2F ; skip over digits and : + / %x3B-3E ; omit ? 3f + / %x5F ; omit upper A-Z and [\]^ + / %x60 ; omit a-z {|} + / %x7E-7F ; just for completeness +NON-ASCII = %x7E-D7FF ; omit surrogates + / %xE000-10FFFF ; that's the rest. (TODO: omit other non-characters) + +; from STD-68 +DIGIT = %x30-39 ; 0-9 +ALPHA = %x41-5A / %x61-7A ; A-Z / a-z +SP = %x20 +HTAB = %xF900 ; horizontal tab +LF = %x0A ; linefeed +CR = %x0D ; carriage return +HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" +; like HEXDIG but lowercase also +LHEXDIG = HEXDIG / "a" / "b" / "c" / "d" / "e" / "f" + +; from XML +NAMESTARTCHAR = ":" / ALPHA / "_" / %xC0-D6 / %xD8-F6 / %xF8-2FF / %x370-37D / %x37F-1FFF / %x200C-200D / %x2070-218F / %x2C00-2FEF / %x3001-D7FF / %xF900-FDCF / %xFDF0-FFFD +NAMESTARTCHAR =/ %x10000-10FFFF ; SKIP-NODE-ABNF: TODO: + +NAMECHAR = NAMESTARTCHAR / "-" / "." / DIGIT / %xB7 / %x0300-036F / %x203F-2040 +NMTOKEN = 1*NAMECHAR diff --git a/resources/standards-data/ldml-keyboards/46/abnf/transform-to-required.abnf b/resources/standards-data/ldml-keyboards/46/abnf/transform-to-required.abnf new file mode 100644 index 0000000000..25b16d74db --- /dev/null +++ b/resources/standards-data/ldml-keyboards/46/abnf/transform-to-required.abnf @@ -0,0 +1,95 @@ +; Copyright (c) 2025 Unicode, Inc. +; For terms of use, see http://www.unicode.org/copyright.html +; SPDX-License-Identifier: Unicode-3.0 +; CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/) + +; This is an ABNF grammar for the CLDR Keyboard spec transform to= (replacement) match syntax. +; Note that there are sample matching/failing data files in tools/scripts/keyboard-abnf-tests/ + +; An entire string. +; An empty string is valid, meaning deletion. +; Also note that a string may match this ABNF but be invalid according to the spec - which see. +to-replacement = atoms + +; a sequence of items for the output production +atoms = *(atom) + +; each atom can be one of several things +atom = replacement-char / escaped-char / group-reference / escaped-codepoints / named-marker / string-variable / mapped-set + +; normal text being output +replacement-char = content-char / ws / "-" / ":" / "(" / ")" / "." / "*" / "+" / "?" / "[" / "]" / "^" / "{" / "}" / "|" + +; Character escapes +escaped-char = backslash ( backslash / "$" ) / "$$" + +; reference to a capture group +group-reference = "$" DIGIT + +; hex codepoint such as \u{01234} +escaped-codepoints = backslash "u" "{" codepoints-hex "}" + +; multiple hex codepoints +codepoints-hex = codepoint-hex *(SP codepoint-hex) + +; one hex codepoint (1-6 digits) +codepoint-hex = 1*6LHEXDIG + +; a specific marker ID. +named-marker = "\m{" marker-id "}" + +; marker id is nmtoken, but may be UAX31 in the future. +marker-id = NMTOKEN + + +; substitution of a string variable +string-variable = "${" var-id "}" + +; variable ID +var-id = 1*32IDCHAR + +; special case for a mapped set variable +mapped-set = "$[1:" var-id "]" + +; group for everything BUT syntax chars. +content-char = ASCII-PUNCT / ALPHA / DIGIT / NON-ASCII + +; \ +backslash = %x5C ; U+005C REVERSE SOLIDUS "\" + +; whitespace +ws = SP / HTAB / CR / LF / %x3000 + +IDCHAR = ALPHA / DIGIT / "_" +; below is same as transform-from for maintenance +; ASCII-CTRLS = %x01-08 ; omit NULL (%x00), HTAB (%x09) and LF (%x0A) +; / %x0B-0C ; omit CR (%x0D) +; / %x0E-1F ; omit SP (%x20) +ASCII-PUNCT = %x21-23 ; omit DOLLAR + / %x25-27 ; omit () * + + / %x2C ; omit . (%x2E) and - (%x2D) + / %x2F ; skip over digits and : + / %x3B-3E ; omit ? 3f + / %x5F ; omit upper A-Z and [\]^ + / %x60 ; omit a-z {|} + / %x7E-7F ; just for completeness +NON-ASCII = %x7E-D7FF ; omit surrogates + / %xE000-10FFFF ; that's the rest. (TODO: omit other non-characters) + +; from STD-68 +DIGIT = %x30-39 ; 0-9 +ALPHA = %x41-5A / %x61-7A ; A-Z / a-z +SP = %x20 +HTAB = %xF900 ; horizontal tab +LF = %x0A ; linefeed +CR = %x0D ; carriage return +HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" +; like HEXDIG but lowercase also +LHEXDIG = HEXDIG / "a" / "b" / "c" / "d" / "e" / "f" + +; from XML +NAMESTARTCHAR = ":" / ALPHA / "_" / %xC0-D6 / %xD8-F6 / %xF8-2FF / %x370-37D / %x37F-1FFF / %x200C-200D / %x2070-218F / %x2C00-2FEF / %x3001-D7FF / %xF900-FDCF / %xFDF0-FFFD +NAMESTARTCHAR =/ %x10000-10FFFF ; SKIP-NODE-ABNF: TODO: + +NAMECHAR = NAMESTARTCHAR / "-" / "." / DIGIT / %xB7 / %x0300-036F / %x203F-2040 +NMTOKEN = 1*NAMECHAR diff --git a/resources/standards-data/ldml-keyboards/fetch-latest-cldr.sh b/resources/standards-data/ldml-keyboards/fetch-latest-cldr.sh index 7234c69fb9..13037eed84 100755 --- a/resources/standards-data/ldml-keyboards/fetch-latest-cldr.sh +++ b/resources/standards-data/ldml-keyboards/fetch-latest-cldr.sh @@ -49,10 +49,12 @@ DTD_DIR="${KEYBOARDS_DIR}/dtd" IMPORT_DIR="${KEYBOARDS_DIR}/import" DATA_DIR="${KEYBOARDS_DIR}/3.0" TEST_DIR="${KEYBOARDS_DIR}/test" +ABNF_DIR="${KEYBOARDS_DIR}/abnf" # a file to check -CHECK_1="${DTD_DIR}/ldmlKeyboard3.dtd" # Critical, present in prior CLDR -CHECK_2="${DTD_DIR}/ldmlKeyboardTest3.dtd" # Only in Keyboard 3.0+ +CHECK_1="${DTD_DIR}/ldmlKeyboard3.dtd" # Critical, present in prior CLDR +CHECK_2="${DTD_DIR}/ldmlKeyboardTest3.dtd" # Only in Keyboard 3.0+ +CHECK_3="${ABNF_DIR}/transform-from-required.abnf" # Present in v47+ if [[ ! -f "${CHECK_1}" ]]; then @@ -64,6 +66,12 @@ then builder_die "${CHECK_2} did not exist: is ${CLDR_DIR} a valid CLDR keyboard directory?" fi +if [[ ! -f "${CHECK_3}" ]]; +then + builder_die "${CHECK_3} did not exist: does ${CLDR_DIR} contain CLDR 47+? Or did ABNF change?" +fi + + # collect git info GIT_DESCRIBE=$(cd "${CLDR_DIR}" && git describe HEAD || echo unknown) GIT_SHA=$(cd "${CLDR_DIR}" && git rev-parse HEAD || echo unknown) @@ -82,7 +90,7 @@ pwd # delete the old files in case some were removed from CLDR rm -rf ./import ./3.0 ./dtd ./test # copy over everything -cp -Rv "${IMPORT_DIR}" "${DATA_DIR}" "${DTD_DIR}" "${TEST_DIR}" . +cp -Rv "${IMPORT_DIR}" "${DATA_DIR}" "${DTD_DIR}" "${TEST_DIR}" "${ABNF_DIR}" . # delete old files, no reason to keep them rm -vf dtd/{ldmlKeyboard,ldmlPlatform}.{xsd,dtd} From a2a0e79675131237223cca31b34dcb19312c718e Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 13 Feb 2025 16:28:35 -0600 Subject: [PATCH 36/61] feat(core): convert abnf to peggy grammar - convert each .abnf to a .pegjs file Fixes: #13175 --- developer/src/kmc-ldml/.gitignore | 1 + developer/src/kmc-ldml/build.sh | 18 +++- developer/src/kmc-ldml/package.json | 2 + developer/src/kmc-ldml/src/util/abnf/abnf.ts | 0 package-lock.json | 86 ++++++++++++++++++++ 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 developer/src/kmc-ldml/.gitignore create mode 100644 developer/src/kmc-ldml/src/util/abnf/abnf.ts diff --git a/developer/src/kmc-ldml/.gitignore b/developer/src/kmc-ldml/.gitignore new file mode 100644 index 0000000000..c27c0f4e3b --- /dev/null +++ b/developer/src/kmc-ldml/.gitignore @@ -0,0 +1 @@ +src/util/abnf/*.pegjs diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index a961fea6fd..abd213e7c4 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -9,6 +9,8 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" +# for CLDR version +. "$KEYMAN_ROOT/core/include/ldml/keyman_core_ldml.sh" builder_describe "Keyman kmc Keyboard Compiler module" \ "@/common/web/keyman-version" \ @@ -34,17 +36,31 @@ builder_describe_outputs \ builder_parse "$@" function do_clean() { - rm -rf ./build/ ./tsconfig.tsbuildinfo + rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/util/abnf/*.pegjs } function do_configure() { verify_npm_setup + do_build_abnf } function do_build() { npm run build } +function do_build_abnf() { + ABNF_SRC="$KEYMAN_ROOT/resources/standards-data/ldml-keyboards/$LDML_CLDR_VERSION_LATEST/abnf" + for file in ${ABNF_SRC}/*.abnf; do + base=$(basename "$file" .abnf) + peg="$base.pegjs" + outfile="./src/util/abnf/$peg" + if [ ! -f "$outfile" ]; then + printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${base}.abnf -> ${peg}${COLOR_RESET}" + npx -p abnf abnf_gen "$file" -o "$outfile" + fi + done +} + function do_build_fixtures() { # Build basic.kmx and emit its checksum mkdir -p ./build/test/fixtures diff --git a/developer/src/kmc-ldml/package.json b/developer/src/kmc-ldml/package.json index cecbc8e15b..08708b64cc 100644 --- a/developer/src/kmc-ldml/package.json +++ b/developer/src/kmc-ldml/package.json @@ -29,6 +29,7 @@ "@keymanapp/keyman-version": "*", "@keymanapp/kmc-kmn": "*", "@keymanapp/ldml-keyboard-constants": "*", + "peggy": "^4.2.0", "semver": "^7.5.4" }, "devDependencies": { @@ -38,6 +39,7 @@ "@types/mocha": "^5.2.7", "@types/node": "^20.4.1", "@types/semver": "^7.3.12", + "abnf": "^4.3.1", "c8": "^7.12.0", "chalk": "^2.4.2", "common-tags": "^1.8.2", diff --git a/developer/src/kmc-ldml/src/util/abnf/abnf.ts b/developer/src/kmc-ldml/src/util/abnf/abnf.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package-lock.json b/package-lock.json index 0528b2c814..012a3ea53b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1281,6 +1281,7 @@ "@keymanapp/keyman-version": "*", "@keymanapp/kmc-kmn": "*", "@keymanapp/ldml-keyboard-constants": "*", + "peggy": "^4.2.0", "semver": "^7.5.4" }, "devDependencies": { @@ -1290,6 +1291,7 @@ "@types/mocha": "^5.2.7", "@types/node": "^20.4.1", "@types/semver": "^7.3.12", + "abnf": "^4.3.1", "c8": "^7.12.0", "chalk": "^2.4.2", "common-tags": "^1.8.2", @@ -3658,6 +3660,28 @@ "@octokit/openapi-types": "^11.2.0" } }, + "node_modules/@peggyjs/from-mem": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@peggyjs/from-mem/-/from-mem-1.3.5.tgz", + "integrity": "sha512-oRyzXE7nirAn+5yYjCdWQHg3EG2XXcYRoYNOK8Quqnmm+9FyK/2YWVunwudlYl++M3xY+gIAdf0vAYS+p0nKfQ==", + "dependencies": { + "semver": "7.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@peggyjs/from-mem/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -5765,6 +5789,35 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/abnf": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/abnf/-/abnf-4.3.1.tgz", + "integrity": "sha512-j4A8wWqKqkcSjx5xFESo9GtW2EUvlUZutcWB1knhxSP9kaXJ/YwL0g6dvMhHRjCPCNsIWwNGoKMHzPwemSpCvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "commander": "^13.0.0", + "peggy": "^4.2.0" + }, + "bin": { + "abnf_ast": "bin/abnf_ast.js", + "abnf_check": "bin/abnf_check.js", + "abnf_gen": "bin/abnf_gen.js", + "abnf_test": "bin/abnf_test.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/abnf/node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/accepts": { "version": "1.3.8", "license": "MIT", @@ -12376,6 +12429,31 @@ "through": "~2.3" } }, + "node_modules/peggy": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/peggy/-/peggy-4.2.0.tgz", + "integrity": "sha512-ZjzyJYY8NqW8JOZr2PbS/J0UH/hnfGALxSDsBUVQg5Y/I+ZaPuGeBJ7EclUX2RvWjhlsi4pnuL1C/K/3u+cDeg==", + "license": "MIT", + "dependencies": { + "@peggyjs/from-mem": "1.3.5", + "commander": "^12.1.0", + "source-map-generator": "0.8.0" + }, + "bin": { + "peggy": "bin/peggy.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/peggy/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "engines": { + "node": ">=18" + } + }, "node_modules/pend": { "version": "1.2.0", "license": "MIT" @@ -13533,6 +13611,14 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-generator": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz", + "integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==", + "engines": { + "node": ">= 10" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", From 53b20e6adc962cb7bc317fa508fdd543760d2ef8 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 13 Feb 2025 16:47:12 -0600 Subject: [PATCH 37/61] feat(developer): use peggy grammar in from/to transform Fixes: #13175 --- developer/src/kmc-ldml/.gitignore | 1 + developer/src/kmc-ldml/build.sh | 3 +++ developer/src/kmc-ldml/package.json | 2 +- .../src/compiler/ldml-compiler-messages.ts | 5 +++++ developer/src/kmc-ldml/src/compiler/tran.ts | 17 +++++++++++++++++ developer/src/kmc-ldml/src/util/abnf/abnf.ts | 6 ++++++ developer/src/kmc-ldml/tsconfig.json | 3 ++- package-lock.json | 7 ++++++- 8 files changed, 41 insertions(+), 3 deletions(-) diff --git a/developer/src/kmc-ldml/.gitignore b/developer/src/kmc-ldml/.gitignore index c27c0f4e3b..0a7af4d6dd 100644 --- a/developer/src/kmc-ldml/.gitignore +++ b/developer/src/kmc-ldml/.gitignore @@ -1 +1,2 @@ src/util/abnf/*.pegjs +src/util/abnf/*.js diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index abd213e7c4..5335ca69c0 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -54,9 +54,12 @@ function do_build_abnf() { base=$(basename "$file" .abnf) peg="$base.pegjs" outfile="./src/util/abnf/$peg" + outjs="./src/util/abnf/$base.js" if [ ! -f "$outfile" ]; then printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${base}.abnf -> ${peg}${COLOR_RESET}" npx -p abnf abnf_gen "$file" -o "$outfile" + printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${peg} -> ${base}.js${COLOR_RESET}" + npx peggy "$outfile" -o "$outjs" --format es --dts fi done } diff --git a/developer/src/kmc-ldml/package.json b/developer/src/kmc-ldml/package.json index 08708b64cc..5375e2673a 100644 --- a/developer/src/kmc-ldml/package.json +++ b/developer/src/kmc-ldml/package.json @@ -29,7 +29,6 @@ "@keymanapp/keyman-version": "*", "@keymanapp/kmc-kmn": "*", "@keymanapp/ldml-keyboard-constants": "*", - "peggy": "^4.2.0", "semver": "^7.5.4" }, "devDependencies": { @@ -44,6 +43,7 @@ "chalk": "^2.4.2", "common-tags": "^1.8.2", "mocha": "^8.4.0", + "peggy": "^4.2.0", "typescript": "^5.4.5" }, "mocha": { diff --git a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts index 3577a2e110..7a78126423 100644 --- a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts +++ b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts @@ -258,4 +258,9 @@ export class LdmlCompilerMessages { \`\`. `); + static ERROR_UnparseableTransformTo = SevErrorTransform | 0x06; + static Error_UnparseableTransformTo = (o: { to: string, message: string }) => + m(this.ERROR_UnparseableTransformTo, `Invalid transform to="${def(o.to)}": "${def(o.message)}"`); + + } diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index 1a91e8d382..ea55ec2ae8 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -17,6 +17,7 @@ import LKTransforms = LDMLKeyboard.LKTransforms; import { verifyValidAndUnique } from "../util/util.js"; import { LdmlCompilerMessages } from "./ldml-compiler-messages.js"; import { Substitutions, SubstitutionUse } from "./substitution-tracker.js"; +import { transform_from_parse, transform_to_parse } from "../util/abnf/abnf.js"; type TransformCompilerType = 'simple' | 'backspace'; @@ -144,8 +145,24 @@ export abstract class TransformCompiler=18" } @@ -13615,6 +13619,7 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz", "integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==", + "dev": true, "engines": { "node": ">= 10" } From 2e842bc19ccd1c8e8dd7ca7be943354e91e0dc80 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 14 Feb 2025 13:12:11 -0600 Subject: [PATCH 38/61] feat(developer): update builder for abnf - just convert over all abnf (as we do with copying imports) - hard coded CLDR version number for now Fixes: #13175 --- developer/src/kmc-ldml/.gitignore | 5 +++-- developer/src/kmc-ldml/build.sh | 23 ++++++++++---------- developer/src/kmc-ldml/src/util/abnf/abnf.ts | 6 ++--- developer/src/kmc-ldml/tsconfig.json | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/developer/src/kmc-ldml/.gitignore b/developer/src/kmc-ldml/.gitignore index 0a7af4d6dd..3745d0bfbc 100644 --- a/developer/src/kmc-ldml/.gitignore +++ b/developer/src/kmc-ldml/.gitignore @@ -1,2 +1,3 @@ -src/util/abnf/*.pegjs -src/util/abnf/*.js +src/util/abnf/**/*.pegjs +src/util/abnf/**/*.d.ts +src/util/abnf/**/*.js diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index 5335ca69c0..fefd84d00d 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -9,8 +9,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" -# for CLDR version -. "$KEYMAN_ROOT/core/include/ldml/keyman_core_ldml.sh" builder_describe "Keyman kmc Keyboard Compiler module" \ "@/common/web/keyman-version" \ @@ -49,17 +47,20 @@ function do_build() { } function do_build_abnf() { - ABNF_SRC="$KEYMAN_ROOT/resources/standards-data/ldml-keyboards/$LDML_CLDR_VERSION_LATEST/abnf" - for file in ${ABNF_SRC}/*.abnf; do + # we convert over all abnf files found. + for file in "$KEYMAN_ROOT/resources/standards-data/ldml-keyboards"/*/abnf/*.abnf; do + cldrver=$(basename $(dirname $(dirname "$file"))) base=$(basename "$file" .abnf) peg="$base.pegjs" - outfile="./src/util/abnf/$peg" - outjs="./src/util/abnf/$base.js" - if [ ! -f "$outfile" ]; then - printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${base}.abnf -> ${peg}${COLOR_RESET}" - npx -p abnf abnf_gen "$file" -o "$outfile" - printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${peg} -> ${base}.js${COLOR_RESET}" - npx peggy "$outfile" -o "$outjs" --format es --dts + outdir="./src/util/abnf/$cldrver" + outfile="$outdir/$peg" + outjs="$outdir/$base.js" + if [ ! -f "$outjs" ]; then + mkdir -p "$outdir" + printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${cldrver}/${base}.abnf -> ${peg}${COLOR_RESET}\n" + "$KEYMAN_ROOT/node_modules/.bin/abnf_gen" "$file" -o "$outfile" + printf "${COLOR_GREY}peggy ${COLOR_PURPLE}${cldrver}/${peg} -> ${base}.js${COLOR_RESET}\n" + "$KEYMAN_ROOT/node_modules/.bin/peggy" "$outfile" -o "$outjs" --format es --dts fi done } diff --git a/developer/src/kmc-ldml/src/util/abnf/abnf.ts b/developer/src/kmc-ldml/src/util/abnf/abnf.ts index 30cbaaf4f3..17506314f7 100644 --- a/developer/src/kmc-ldml/src/util/abnf/abnf.ts +++ b/developer/src/kmc-ldml/src/util/abnf/abnf.ts @@ -1,6 +1,6 @@ /** - * Re-export the generated parsers. + * Re-export the generated parsers. At present, we hard code CLDR version. */ -export { parse as transform_to_parse } from './transform-to-required.js'; -export { parse as transform_from_parse } from './transform-from-required.js'; +export { parse as transform_to_parse } from './46/transform-to-required.js'; +export { parse as transform_from_parse } from './46/transform-from-required.js'; diff --git a/developer/src/kmc-ldml/tsconfig.json b/developer/src/kmc-ldml/tsconfig.json index 9f17f7898f..785b30125a 100644 --- a/developer/src/kmc-ldml/tsconfig.json +++ b/developer/src/kmc-ldml/tsconfig.json @@ -8,7 +8,7 @@ }, "include": [ "src/**/*.ts", - "src/util/abnf/*.js", + "src/util/abnf/**/*.js", ], "references": [ { "path": "../../../common/web/keyman-version" }, From 448bf9171a025779e17d3b2c761be74b49d2cceb Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 14 Feb 2025 22:50:51 +0100 Subject: [PATCH 39/61] fix(linux): update location of lcov.deb for Jammy This changes the download URL for the lcov package to the official Ubuntu archive, after it was no longer available at kernel.org. --- resources/docker-images/linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/docker-images/linux/Dockerfile b/resources/docker-images/linux/Dockerfile index 2083ce8c55..061e9f619b 100644 --- a/resources/docker-images/linux/Dockerfile +++ b/resources/docker-images/linux/Dockerfile @@ -23,7 +23,7 @@ RUN apt-get update && \ # version 2.0-1 from Mantic. RUN LCOV_VERSION=$(dpkg -s lcov | grep Version | cut -d' ' -f2) && \ if dpkg --compare-versions "${LCOV_VERSION}" lt 2.0; then \ - curl -sS -o /tmp/lcov.deb --location http://mirrors.kernel.org/ubuntu/pool/universe/l/lcov/lcov_2.0-1_all.deb && \ + curl -sS -o /tmp/lcov.deb --location https://old-releases.ubuntu.com/ubuntu/pool/universe/l/lcov/lcov_2.0-1ubuntu0.2_all.deb && \ apt-get -qy install /tmp/lcov.deb && \ rm /tmp/lcov.deb ; \ fi From 0d5a455aa65fe38ecb9a2ec7238d94f67215b97a Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 14 Feb 2025 15:52:07 -0600 Subject: [PATCH 40/61] chore(core): ldml: update unit test to match spec - Unless https://unicode-org.atlassian.net/browse/CLDR-18318 is put in, \+ and \* are not allowed --- core/tests/unit/ldml/keyboards/k_030_transform_plus.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml b/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml index 220ac6cbe0..7a88b20640 100644 --- a/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml +++ b/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml @@ -42,11 +42,11 @@ - + - + From 8e1aa5cdfbb35a1e2a064c530c4f416482147c3f Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 14 Feb 2025 15:52:51 -0600 Subject: [PATCH 41/61] chore(resources): ldml: update ABNF - update with an errata from ABNF - Update with patch from https://unicode-org.atlassian.net/browse/CLDR-18319 --- .../ldml-keyboards/46/abnf/transform-from-required.abnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf b/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf index 4e02db22f2..9b705ccd2d 100644 --- a/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf +++ b/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf @@ -85,7 +85,7 @@ fixed-class-char = "s" / "S" / "t" / "r" / "n" / "f" / "v" / backslash / "$" / " set-class = "[" set-negator set-members "]" set-members = set-member *(set-member) -set-member = text-char / char-range / match-marker +set-member = text-char / char-range / match-marker / escaped-codepoint char-range = range-edge "-" range-edge range-edge = escaped-codepoint / range-char set-negator = "^" / "" From acf74f02ba92491e7ee57ea7cf5038e0aebb20b6 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 14 Feb 2025 23:09:40 +0100 Subject: [PATCH 42/61] fix(linux): allow to specify ubuntu version --- resources/docker-images/run.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/resources/docker-images/run.sh b/resources/docker-images/run.sh index 63d299f7e3..bf8dd40d6d 100755 --- a/resources/docker-images/run.sh +++ b/resources/docker-images/run.sh @@ -7,6 +7,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" ## END STANDARD BUILD SCRIPT INCLUDE . "${KEYMAN_ROOT}/resources/build/minimum-versions.inc.sh" +. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" ################################ Main script ################################ @@ -35,6 +36,12 @@ run_core() { } run_linux() { + if [[ -z "${UBUNTU_VERSION:-}" ]]; then + image_version=default + else + image_version="${UBUNTU_VERSION}-java${KEYMAN_VERSION_JAVA}-node$(_print_expected_node_version)-emsdk${KEYMAN_MIN_VERSION_EMSCRIPTEN}" + fi + mkdir -p "${KEYMAN_ROOT}/linux/build/docker-linux" mkdir -p "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux" docker run -it --privileged --rm -v "${KEYMAN_ROOT}":/home/build/build \ @@ -42,7 +49,7 @@ run_linux() { -v "${KEYMAN_ROOT}/linux/build/docker-linux":/home/build/build/linux/build \ -v "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux":/home/build/build/linux/keyman-system-service/build \ -e DESTDIR=/tmp \ - keymanapp/keyman-linux-ci:default \ + "keymanapp/keyman-linux-ci:${image_version}" \ "${builder_extra_params[@]}" } From 24f629a9f104a1f6562cc968cab7e97291861f39 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 14 Feb 2025 16:29:16 -0600 Subject: [PATCH 43/61] feat(developer): ldml: update tests for ABNF - some error messages are less specific now than they were before ABNF, because we're not using custom code to test them. Fixes: #13175 --- developer/src/kmc-ldml/src/compiler/tran.ts | 7 ++ .../sections/tran/fail-bad-tran-3.xml | 13 ++ developer/src/kmc-ldml/test/helpers/index.ts | 12 +- developer/src/kmc-ldml/test/tran.tests.ts | 118 ++++++++++++------ 4 files changed, 105 insertions(+), 45 deletions(-) create mode 100644 developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-3.xml diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index ea55ec2ae8..beec06ecf9 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -148,6 +148,11 @@ export abstract class TransformCompiler + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/helpers/index.ts b/developer/src/kmc-ldml/test/helpers/index.ts index bd438c4ca1..7b67ee4e4c 100644 --- a/developer/src/kmc-ldml/test/helpers/index.ts +++ b/developer/src/kmc-ldml/test/helpers/index.ts @@ -275,12 +275,6 @@ export function testCompilationCases(compiler: SectionCompilerNew, cases : Compi return; } let section = await loadSectionFixture(compiler, testcase.subpath, callbacks, testcase.dependencies || dependencies); - if (expectFailure) { - assert.isNull(section, 'expected compilation result failure (null)'); - } else { - assert.isNotNull(section, `failed with ${compilerEventFormat(callbacks.messages)}`); - } - const testcaseErrors = matchCompilerEventsOrBoolean(callbacks.messages, testcase.errors); const testcaseWarnings = matchCompilerEvents(callbacks.messages, testcase.warnings); // if we expected errors or warnings, show them @@ -296,6 +290,12 @@ export function testCompilationCases(compiler: SectionCompilerNew, cases : Compi // no warnings, so expect zero messages assert.sameDeepMembers(callbacks.messages, [], 'expected zero messages but got ' + callbacks.messages); } + + if (expectFailure) { + assert.isNull(section, 'expected compilation result failure (null)'); + } else { + assert.isNotNull(section, `failed with ${compilerEventFormat(callbacks.messages)}`); + } // run the user-supplied callback if any if (testcase.callback) { diff --git a/developer/src/kmc-ldml/test/tran.tests.ts b/developer/src/kmc-ldml/test/tran.tests.ts index 2fc401e66b..38d4887f0c 100644 --- a/developer/src/kmc-ldml/test/tran.tests.ts +++ b/developer/src/kmc-ldml/test/tran.tests.ts @@ -287,8 +287,8 @@ describe('tran', function () { subpath: `sections/tran/fail-bad-tran-1.xml`, errors: [ { code: LdmlCompilerMessages.ERROR_UnparseableTransformFrom, - matchMessage: /Invalid regular expression.*Unterminated group/, - } + matchMessage: /.*SyntaxError.*/, + }, ], }, { @@ -298,6 +298,15 @@ describe('tran', function () { LdmlCompilerMessages.Error_InvalidQuadEscape({ cp: 295 }), ], }, + { + subpath: `sections/tran/fail-bad-tran-3.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_UnparseableTransformFrom, + matchMessage: /.*Syntax.*0-9.*/, + } + ], + }, { subpath: `sections/tran/fail-missing-var-1.xml`, errors: [ @@ -334,50 +343,81 @@ describe('tran', function () { LdmlCompilerMessages.Error_MissingStringVariable({ id: "missingstr" }), ], }, + // cases that are now caught by the abnf + ...[ + 'fail-IllegalTransformDollarsign-1', + 'fail-IllegalTransformDollarsign-2', + 'fail-IllegalTransformDollarsign-3', + 'fail-IllegalTransformAsterisk-1', + 'fail-IllegalTransformAsterisk-2', + 'fail-IllegalTransformPlus-1', + 'fail-IllegalTransformPlus-2', + 'fail-matches-nothing-3', + ].map(s => ({ + subpath: `sections/tran/${s}.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_UnparseableTransformFrom, + matchMessage: /.*/, + } + ], + })), + ...[ + 'fail-IllegalTransformUsetRHS-1', + ].map(s => ({ + subpath: `sections/tran/${s}.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_UnparseableTransformTo, + matchMessage: /.*/, + } + ], + })), // cases that share the same error code - ...[1, 2, 3].map(n => ({ - subpath: `sections/tran/fail-IllegalTransformDollarsign-${n}.xml`, - errors: [ - { - code: LdmlCompilerMessages.ERROR_IllegalTransformDollarsign, - matchMessage: /.*/, - } - ], - })), - ...[1, 2].map(n => ({ - subpath: `sections/tran/fail-IllegalTransformAsterisk-${n}.xml`, - errors: [ - { - code: LdmlCompilerMessages.ERROR_IllegalTransformAsterisk, - matchMessage: /.*/, - } - ], - })), - ...[1, 2].map(n => ({ - subpath: `sections/tran/fail-IllegalTransformPlus-${n}.xml`, - errors: [ - { - code: LdmlCompilerMessages.ERROR_IllegalTransformPlus, - matchMessage: /.*/, - } - ], - })), - ...[1].map(n => ({ - subpath: `sections/tran/fail-IllegalTransformUsetRHS-${n}.xml`, - errors: [ - { - code: LdmlCompilerMessages.ERROR_IllegalTransformToUset, - matchMessage: /.*/, - } - ], - })), + // NOTE: These used to be more helpful before ABNF. + // ...[].map(n => ({ + // subpath: `sections/tran/fail-IllegalTransformDollarsign-${n}.xml`, + // errors: [ + // { + // code: LdmlCompilerMessages.ERROR_IllegalTransformDollarsign, + // matchMessage: /.*/, + // } + // ], + // })), + // ...[].map(n => ({ + // subpath: `sections/tran/fail-IllegalTransformAsterisk-${n}.xml`, + // errors: [ + // { + // code: LdmlCompilerMessages.ERROR_IllegalTransformAsterisk, + // matchMessage: /.*/, + // } + // ], + // })), + // ...[].map(n => ({ + // subpath: `sections/tran/fail-IllegalTransformPlus-${n}.xml`, + // errors: [ + // { + // code: LdmlCompilerMessages.ERROR_IllegalTransformPlus, + // matchMessage: /.*/, + // } + // ], + // })), + // ...[].map(n => ({ + // subpath: `sections/tran/fail-IllegalTransformUsetRHS-${n}.xml`, + // errors: [ + // { + // code: LdmlCompilerMessages.ERROR_IllegalTransformToUset, + // matchMessage: /.*/, + // } + // ], + // })), // successful compile ...[1, 2].map(n => ({ subpath: `sections/tran/ok-${n}.xml`, errors: false, })), // cases that share the same error code - ...[1, 2, 3].map(n => ({ + ...[1, 2].map(n => ({ subpath: `sections/tran/fail-matches-nothing-${n}.xml`, errors: [ { From e3466b20d2170b85db6bf1abfff3a2efd9fd3574 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Sat, 15 Feb 2025 13:01:17 -0500 Subject: [PATCH 44/61] auto: increment master version to 19.0.6 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8d836fa885..318618e126 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 19.0.5 alpha 2025-02-15 + +* fix(linux): update location of lcov.deb for Jammy (#13253) + ## 19.0.4 alpha 2025-02-14 * feat(developer): serialize KMXPlus into XML (#13174) diff --git a/VERSION.md b/VERSION.md index 6d6c32d75a..b4810cb8ae 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.5 \ No newline at end of file +19.0.6 \ No newline at end of file From 92463b9a89ccafe5e840c7a8c5674baead9c5fec Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 17 Feb 2025 16:17:03 -0600 Subject: [PATCH 45/61] feat(developer): ldml: update tests for ABNF - reinstate errors Fixes: #13175 --- developer/src/kmc-ldml/src/compiler/tran.ts | 35 +++---- .../sections/tran/fail-bad-tran-4.xml | 13 +++ .../sections/tran/fail-bad-tran-5.xml | 13 +++ .../sections/tran/fail-bad-tran-6.xml | 13 +++ developer/src/kmc-ldml/test/tran.tests.ts | 99 ++++++++++--------- 5 files changed, 107 insertions(+), 66 deletions(-) create mode 100644 developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-4.xml create mode 100644 developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-5.xml create mode 100644 developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-6.xml diff --git a/developer/src/kmc-ldml/src/compiler/tran.ts b/developer/src/kmc-ldml/src/compiler/tran.ts index beec06ecf9..95d79dd468 100644 --- a/developer/src/kmc-ldml/src/compiler/tran.ts +++ b/developer/src/kmc-ldml/src/compiler/tran.ts @@ -153,23 +153,6 @@ export abstract class TransformCompiler + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-5.xml b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-5.xml new file mode 100644 index 0000000000..d3886523b5 --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-6.xml b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-6.xml new file mode 100644 index 0000000000..09dc88a6c8 --- /dev/null +++ b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/developer/src/kmc-ldml/test/tran.tests.ts b/developer/src/kmc-ldml/test/tran.tests.ts index 38d4887f0c..d64e26525d 100644 --- a/developer/src/kmc-ldml/test/tran.tests.ts +++ b/developer/src/kmc-ldml/test/tran.tests.ts @@ -287,7 +287,7 @@ describe('tran', function () { subpath: `sections/tran/fail-bad-tran-1.xml`, errors: [ { code: LdmlCompilerMessages.ERROR_UnparseableTransformFrom, - matchMessage: /.*SyntaxError.*/, + matchMessage: /.*Unterminated group.*/, }, ], }, @@ -345,14 +345,7 @@ describe('tran', function () { }, // cases that are now caught by the abnf ...[ - 'fail-IllegalTransformDollarsign-1', - 'fail-IllegalTransformDollarsign-2', - 'fail-IllegalTransformDollarsign-3', - 'fail-IllegalTransformAsterisk-1', - 'fail-IllegalTransformAsterisk-2', - 'fail-IllegalTransformPlus-1', - 'fail-IllegalTransformPlus-2', - 'fail-matches-nothing-3', + 'fail-bad-tran-5', ].map(s => ({ subpath: `sections/tran/${s}.xml`, errors: [ @@ -363,7 +356,7 @@ describe('tran', function () { ], })), ...[ - 'fail-IllegalTransformUsetRHS-1', + 'fail-bad-tran-4', ].map(s => ({ subpath: `sections/tran/${s}.xml`, errors: [ @@ -373,51 +366,59 @@ describe('tran', function () { } ], })), - // cases that share the same error code - // NOTE: These used to be more helpful before ABNF. - // ...[].map(n => ({ - // subpath: `sections/tran/fail-IllegalTransformDollarsign-${n}.xml`, - // errors: [ - // { - // code: LdmlCompilerMessages.ERROR_IllegalTransformDollarsign, - // matchMessage: /.*/, - // } - // ], - // })), - // ...[].map(n => ({ - // subpath: `sections/tran/fail-IllegalTransformAsterisk-${n}.xml`, - // errors: [ - // { - // code: LdmlCompilerMessages.ERROR_IllegalTransformAsterisk, - // matchMessage: /.*/, - // } - // ], - // })), - // ...[].map(n => ({ - // subpath: `sections/tran/fail-IllegalTransformPlus-${n}.xml`, - // errors: [ - // { - // code: LdmlCompilerMessages.ERROR_IllegalTransformPlus, - // matchMessage: /.*/, - // } - // ], - // })), - // ...[].map(n => ({ - // subpath: `sections/tran/fail-IllegalTransformUsetRHS-${n}.xml`, - // errors: [ - // { - // code: LdmlCompilerMessages.ERROR_IllegalTransformToUset, - // matchMessage: /.*/, - // } - // ], - // })), + ...[ + 'fail-IllegalTransformDollarsign-1', + 'fail-IllegalTransformDollarsign-2', + 'fail-IllegalTransformDollarsign-3', + ].map(s => ({ + subpath: `sections/tran/${s}.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_IllegalTransformDollarsign, + matchMessage: /.*/, + } + ], + })), + ...[ + 'fail-IllegalTransformAsterisk-1', + 'fail-IllegalTransformAsterisk-2', + ].map(s => ({ + subpath: `sections/tran/${s}.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_IllegalTransformAsterisk, + matchMessage: /.*/, + } + ], + })), + ...[ + 'fail-IllegalTransformPlus-1', + 'fail-IllegalTransformPlus-2', + ].map(n => ({ + subpath: `sections/tran/${n}.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_IllegalTransformPlus, + matchMessage: /.*/, + } + ], + })), + ...[1].map(n => ({ + subpath: `sections/tran/fail-IllegalTransformUsetRHS-${n}.xml`, + errors: [ + { + code: LdmlCompilerMessages.ERROR_IllegalTransformToUset, + matchMessage: /.*/, + } + ], + })), // successful compile ...[1, 2].map(n => ({ subpath: `sections/tran/ok-${n}.xml`, errors: false, })), // cases that share the same error code - ...[1, 2].map(n => ({ + ...[1, 2, 3].map(n => ({ subpath: `sections/tran/fail-matches-nothing-${n}.xml`, errors: [ { From 3c3d2586e6d5406a54368ced5c86846fb4e022eb Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Tue, 18 Feb 2025 11:05:55 -0600 Subject: [PATCH 46/61] chore(developer): ldml: build updates for ABNF - fix build output Fixes: #13175 --- developer/src/kmc-ldml/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index fefd84d00d..c7c5eec0b9 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -27,14 +27,14 @@ builder_describe "Keyman kmc Keyboard Compiler module" \ "--dry-run,-n don't actually publish, just dry run" builder_describe_outputs \ - configure /node_modules \ + configure /developer/src/kmc-ldml/src/util/abnf/46/transform-from-required.js \ build /developer/src/kmc-ldml/build/src/main.js \ api /developer/build/api/kmc-ldml.api.json builder_parse "$@" function do_clean() { - rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/util/abnf/*.pegjs + rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/util/abnf/*/*.pegjs ./src/util/abnf/*/*.ts ./src/util/abnf/*/*.js } function do_configure() { From b986dfa836e93f0d440cfc7faadc9e0107795e56 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 19 Feb 2025 09:03:48 +0100 Subject: [PATCH 47/61] =?UTF-8?q?fix(linux):=20add=20missing=20dependency?= =?UTF-8?q?=20for=20uploading=20to=20llso=20=F0=9F=8D=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-pick-of: #13279 --- .github/workflows/deb-packaging.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 7ba1a4659e..00468125c7 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -221,7 +221,7 @@ jobs: export DEBIAN_PRIORITY=critical export DEBCONF_NOWARNINGS=yes sudo apt-get update - sudo apt-get install -q -y dput + sudo apt-get install -q -y dput rsync - name: Setup .dput.cf run: | From d9992ec087974206cf4e9e6105cba27c80206aac Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 18 Feb 2025 18:12:46 +0100 Subject: [PATCH 48/61] chore(linux): allow to build and use Debian docker image --- resources/docker-images/base/Dockerfile | 11 ++++--- resources/docker-images/build.sh | 18 +++++++---- resources/docker-images/run.sh | 41 +++++++++++++------------ 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/resources/docker-images/base/Dockerfile b/resources/docker-images/base/Dockerfile index 87516b3f96..ae0d098acf 100644 --- a/resources/docker-images/base/Dockerfile +++ b/resources/docker-images/base/Dockerfile @@ -1,7 +1,8 @@ # Keyman is copyright (C) SIL Global. MIT License. -ARG UBUNTU_VERSION=latest -FROM ubuntu:${UBUNTU_VERSION} +ARG DISTRO=ubuntu +ARG DISTRO_VERSION=latest +FROM ${DISTRO}:${DISTRO_VERSION} LABEL org.opencontainers.image.authors="SIL Global." LABEL org.opencontainers.image.url="https://github.com/keymanapp/keyman.git" @@ -21,8 +22,10 @@ ENV DEBCONF_NOWARNINGS=yes # Update to the latest RUN apt-get -q -y update && \ apt-get -q -y install ca-certificates curl gnupg meson software-properties-common sudo && \ - add-apt-repository ppa:keymanapp/keyman && \ - add-apt-repository ppa:keymanapp/keyman-alpha + if [[ "$(lsb_release -is)" == "Ubuntu" ]]; then \ + add-apt-repository ppa:keymanapp/keyman && \ + add-apt-repository ppa:keymanapp/keyman-alpha ; \ + fi RUN apt-get -q -y update && \ apt-get -q -y upgrade diff --git a/resources/docker-images/build.sh b/resources/docker-images/build.sh index 8100459d47..074bc84f27 100755 --- a/resources/docker-images/build.sh +++ b/resources/docker-images/build.sh @@ -18,7 +18,9 @@ builder_describe \ ":core" \ ":linux" \ ":web" \ - "--ubuntu-version=UBUNTU_VERSION The Ubuntu version (default: ${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER})" \ + "--distro=DISTRO The distribution to use for the base image "\ + " (debian or ubuntu, default: ubuntu)" \ + "--distro-version=DISTRO_VERSION The Ubuntu/Debian version (default: ${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER})" \ "--no-cache Force rebuild of docker images" \ "build Build docker images" \ "test Test the docker images by running configure,build,test for all or the specified platforms" @@ -49,11 +51,14 @@ _add_build_args() { _convert_parameters_to_build_args() { build_args=() build_version= - local required_node_version + local required_node_version keyman_default_distro # shellcheck disable=SC2034 required_node_version="$(_print_expected_node_version)" + # shellcheck disable=SC2034 + keyman_default_distro="ubuntu" - _add_build_args UBUNTU_VERSION KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER "" + _add_build_args DISTRO keyman_default_distro "" + _add_build_args DISTRO_VERSION KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER "" _add_build_args JAVA_VERSION KEYMAN_VERSION_JAVA java _add_build_args REQUIRED_NODE_VERSION required_node_version node _add_build_args REQUIRED_EMSCRIPTEN_VERSION KEYMAN_MIN_VERSION_EMSCRIPTEN emsdk @@ -64,7 +69,7 @@ _convert_parameters_to_build_args() { } _is_default_values() { - [[ -z "${UBUNTU_VERSION:-}" ]] && [[ -z "${JAVA_VERSION:-}" ]] + [[ -z "${DISTRO_VERSION:-}" ]] && [[ -z "${JAVA_VERSION:-}" ]] } build_action() { @@ -75,7 +80,7 @@ build_action() { _convert_parameters_to_build_args if [[ "${platform}" == "base" ]]; then - docker pull --platform "amd64" "ubuntu:${UBUNTU_VERSION:-${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER}}" + docker pull --platform "amd64" "${DISTRO:-ubuntu}:${DISTRO_VERSION:-${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER}}" elif [[ "${platform}" == "linux" ]]; then cp "${KEYMAN_ROOT}/linux/debian/control" "${platform}" fi @@ -103,7 +108,8 @@ test_action() { local platform=$1 builder_echo debug "Testing image for ${platform}" - ./run.sh "${platform}" -- ./build.sh configure,build,test:"${platform}" + ./run.sh --distro "${DISTRO}" --distro-version "${DISTRO_VERSION}" \ + "${platform}" -- ./build.sh configure,build,test:"${platform}" } if builder_has_action build; then diff --git a/resources/docker-images/run.sh b/resources/docker-images/run.sh index bf8dd40d6d..f85c41b238 100755 --- a/resources/docker-images/run.sh +++ b/resources/docker-images/run.sh @@ -17,37 +17,32 @@ builder_describe \ "core" \ "linux" \ "web" \ - "--ubuntu-version=UBUNTU_VERSION The Ubuntu version (default: ${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER})" + "--distro=DISTRO The distribution (debian or ubuntu, default: ubuntu)" \ + "--distro-version=DISTRO_VERSION The Ubuntu/Debian version (default: ${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER})" builder_parse "$@" run_android() { docker run -it --rm -v "${KEYMAN_ROOT}":/home/build/build \ - -v "${KEYMAN_ROOT}/core/build/docker-core":/home/build/build/core/build \ - keymanapp/keyman-android-ci:default \ + -v "${KEYMAN_ROOT}/core/build/docker-core/${build_dir}":/home/build/build/core/build \ + "keymanapp/keyman-android-ci:${image_version}" \ "${builder_extra_params[@]}" } run_core() { docker run -it --rm -v "${KEYMAN_ROOT}":/home/build/build \ - -v "${KEYMAN_ROOT}/core/build/docker-core":/home/build/build/core/build \ - keymanapp/keyman-core-ci:default \ + -v "${KEYMAN_ROOT}/core/build/docker-core/${build_dir}":/home/build/build/core/build \ + "keymanapp/keyman-core-ci:${image_version}" \ "${builder_extra_params[@]}" } run_linux() { - if [[ -z "${UBUNTU_VERSION:-}" ]]; then - image_version=default - else - image_version="${UBUNTU_VERSION}-java${KEYMAN_VERSION_JAVA}-node$(_print_expected_node_version)-emsdk${KEYMAN_MIN_VERSION_EMSCRIPTEN}" - fi - - mkdir -p "${KEYMAN_ROOT}/linux/build/docker-linux" - mkdir -p "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux" + mkdir -p "${KEYMAN_ROOT}/linux/build/docker-linux/${build_dir}" + mkdir -p "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux/${build_dir}" docker run -it --privileged --rm -v "${KEYMAN_ROOT}":/home/build/build \ - -v "${KEYMAN_ROOT}/core/build/docker-core":/home/build/build/core/build \ - -v "${KEYMAN_ROOT}/linux/build/docker-linux":/home/build/build/linux/build \ - -v "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux":/home/build/build/linux/keyman-system-service/build \ + -v "${KEYMAN_ROOT}/core/build/docker-core/${build_dir}":/home/build/build/core/build \ + -v "${KEYMAN_ROOT}/linux/build/docker-linux/${build_dir}":/home/build/build/linux/build \ + -v "${KEYMAN_ROOT}/linux/keyman-system-service/build/docker-linux/${build_dir}":/home/build/build/linux/keyman-system-service/build \ -e DESTDIR=/tmp \ "keymanapp/keyman-linux-ci:${image_version}" \ "${builder_extra_params[@]}" @@ -55,12 +50,20 @@ run_linux() { run_web() { docker run -it --privileged --rm -v "${KEYMAN_ROOT}":/home/build/build \ - -v "${KEYMAN_ROOT}/core/build/docker-core":/home/build/build/core/build \ - keymanapp/keyman-web-ci:default \ + -v "${KEYMAN_ROOT}/core/build/docker-core/${build_dir}":/home/build/build/core/build \ + "keymanapp/keyman-web-ci:${image_version}" \ "${builder_extra_params[@]}" } -mkdir -p "${KEYMAN_ROOT}/core/build/docker-core" +if [[ -z "${DISTRO_VERSION:-}" ]]; then + image_version=default + build_dir=default +else + image_version="${DISTRO:-}-${DISTRO_VERSION}-java${KEYMAN_VERSION_JAVA}-node$(_print_expected_node_version)-emsdk${KEYMAN_MIN_VERSION_EMSCRIPTEN}" + build_dir="${DISTRO:-}-${DISTRO_VERSION}" +fi + +mkdir -p "${KEYMAN_ROOT}/core/build/docker-core/${build_dir}" builder_run_action android run_android builder_run_action core run_core From 2182f09dc34eccee6ed12f365d24ca2d04412ab3 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 19 Feb 2025 13:01:32 -0500 Subject: [PATCH 49/61] auto: increment master version to 19.0.7 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f5e31ac09f..93cbf5ab53 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 19.0.6 alpha 2025-02-19 + +* chore: merge beta to master B18S1 (#13239) +* fix(linux): add missing dependency for uploading to llso (#13280) + ## 19.0.5 alpha 2025-02-15 * fix(linux): update location of lcov.deb for Jammy (#13253) diff --git a/VERSION.md b/VERSION.md index 309a41134e..68f5c99058 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.6 +19.0.7 \ No newline at end of file From fc3abe6b6a3b3ac47573aaffd744a93505fd5feb Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Wed, 19 Feb 2025 16:55:59 -0600 Subject: [PATCH 50/61] chore(resources,core): update BNF and tests for escaping chars - late breaking update from CLDR, update with in-progress fixes to escaping chars slated for v47 Fixes: #13175 --- .../unit/ldml/keyboards/k_030_transform_plus.xml | 4 ++-- .../46/abnf/transform-from-required.abnf | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml b/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml index 7a88b20640..220ac6cbe0 100644 --- a/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml +++ b/core/tests/unit/ldml/keyboards/k_030_transform_plus.xml @@ -42,11 +42,11 @@ - + - + diff --git a/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf b/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf index 9b705ccd2d..9e58904e02 100644 --- a/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf +++ b/resources/standards-data/ldml-keyboards/46/abnf/transform-from-required.abnf @@ -81,11 +81,11 @@ class = fixed-class / set-class fixed-class = backslash fixed-class-char -fixed-class-char = "s" / "S" / "t" / "r" / "n" / "f" / "v" / backslash / "$" / "d" / "w" / "D" / "W" / "0" +fixed-class-char = "s" / "S" / "t" / "r" / "n" / "f" / "v" / "d" / "w" / "D" / "W" set-class = "[" set-negator set-members "]" set-members = set-member *(set-member) -set-member = text-char / char-range / match-marker / escaped-codepoint +set-member = char-range / range-char / match-marker / escaped-codepoint char-range = range-edge "-" range-edge range-edge = escaped-codepoint / range-char set-negator = "^" / "" @@ -95,12 +95,16 @@ set-negator = "^" / "" ; normal text text-char = content-char / ws / escaped-char / "-" / ":" ; text in a range sequence -range-char = content-char / ws / escaped-char / "."/ "|" / "{" / "}" +range-char = content-char / ws / escaped-range-char / "." / "|" / "{" / "}" ; group for everything BUT syntax chars. content-char = ASCII-PUNCT / ALPHA / DIGIT / NON-ASCII ; Character escapes -escaped-char = backslash ( backslash / "{" / "|" / "}" ) +escaped-char = backslash ( escapable-char ) +escapable-char = backslash / "$" / "{" / "|" / "}" / "(" / ")" / "*" / "+" / "." / "/" / "?" / "[" / "]" / "^" + +escaped-range-char = backslash escapable-range-char +escapable-range-char = escapable-char / "-" backslash = %x5C ; U+005C REVERSE SOLIDUS "\" ws = SP / HTAB / CR / LF / %x3000 From 7d5dce1f5fdb6c4b73efbfae088039f4f5939b19 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 20 Feb 2025 08:51:34 +0100 Subject: [PATCH 51/61] chore(linux): initialize variables with default values if not set This changes `convert_parameters_to_build_args` to set the variable to the default values unless set already. Then we don't have to deal with unset variables and setting default values when we use the variables. --- resources/docker-images/build.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/resources/docker-images/build.sh b/resources/docker-images/build.sh index 074bc84f27..d5c6a4df54 100755 --- a/resources/docker-images/build.sh +++ b/resources/docker-images/build.sh @@ -33,11 +33,7 @@ _add_build_args() { local name=$3 local value - if [[ -n "${!var:-}" ]]; then - value="${!var}" - else - value="${!default_var:-}" - fi + value="${!var:=${!default_var:-}}" build_args+=(--build-arg="${var}=${value}") @@ -77,10 +73,8 @@ build_action() { builder_echo debug "Building image for ${platform}" - _convert_parameters_to_build_args - if [[ "${platform}" == "base" ]]; then - docker pull --platform "amd64" "${DISTRO:-ubuntu}:${DISTRO_VERSION:-${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER}}" + docker pull --platform "amd64" "${DISTRO}:${DISTRO_VERSION}" elif [[ "${platform}" == "linux" ]]; then cp "${KEYMAN_ROOT}/linux/debian/control" "${platform}" fi @@ -112,6 +106,8 @@ test_action() { "${platform}" -- ./build.sh configure,build,test:"${platform}" } +_convert_parameters_to_build_args + if builder_has_action build; then build_action base BASE_VERSION="${build_version}" From 2b9ba6c96bf815d7d3e5b204389e63a8d93374d7 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 20 Feb 2025 09:58:39 +0100 Subject: [PATCH 52/61] chore(linux): deal with default values When `_convert_parameters_to_build_args` sets the defaults, our previous implementation to check for default values no longer works. --- resources/docker-images/build.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/resources/docker-images/build.sh b/resources/docker-images/build.sh index d5c6a4df54..b97e267d99 100755 --- a/resources/docker-images/build.sh +++ b/resources/docker-images/build.sh @@ -64,8 +64,16 @@ _convert_parameters_to_build_args() { fi } +_check_for_default_values() { + if [[ -z "${DISTRO_VERSION:-}" ]] && [[ -z "${JAVA_VERSION:-}" ]]; then + is_default_values=true + else + is_default_values=false + fi +} + _is_default_values() { - [[ -z "${DISTRO_VERSION:-}" ]] && [[ -z "${JAVA_VERSION:-}" ]] + ${is_default_values} } build_action() { @@ -74,6 +82,7 @@ build_action() { builder_echo debug "Building image for ${platform}" if [[ "${platform}" == "base" ]]; then + # shellcheck disable=SC2154 # set by _convert_parameters_to_build_args docker pull --platform "amd64" "${DISTRO}:${DISTRO_VERSION}" elif [[ "${platform}" == "linux" ]]; then cp "${KEYMAN_ROOT}/linux/debian/control" "${platform}" @@ -106,6 +115,7 @@ test_action() { "${platform}" -- ./build.sh configure,build,test:"${platform}" } +_check_for_default_values _convert_parameters_to_build_args if builder_has_action build; then From 7e28758892b897094c93ea95fb04e0f8fdac422b Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 20 Feb 2025 08:18:55 -0600 Subject: [PATCH 53/61] Apply suggestions from code review Co-authored-by: Marc Durdin --- developer/src/kmc-ldml/build.sh | 13 +++++++------ .../kmc-ldml/src/compiler/ldml-compiler-messages.ts | 8 +++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index c7c5eec0b9..b48e851c71 100755 --- a/developer/src/kmc-ldml/build.sh +++ b/developer/src/kmc-ldml/build.sh @@ -48,13 +48,14 @@ function do_build() { function do_build_abnf() { # we convert over all abnf files found. + local file for file in "$KEYMAN_ROOT/resources/standards-data/ldml-keyboards"/*/abnf/*.abnf; do - cldrver=$(basename $(dirname $(dirname "$file"))) - base=$(basename "$file" .abnf) - peg="$base.pegjs" - outdir="./src/util/abnf/$cldrver" - outfile="$outdir/$peg" - outjs="$outdir/$base.js" + local cldrver="$(basename $(dirname $(dirname "$file")))" + local base="$(basename "$file" .abnf)" + local peg="$base.pegjs" + local outdir="./src/util/abnf/$cldrver" + local outfile="$outdir/$peg" + local outjs="$outdir/$base.js" if [ ! -f "$outjs" ]; then mkdir -p "$outdir" printf "${COLOR_GREY}abnf_gen ${COLOR_PURPLE}${cldrver}/${base}.abnf -> ${peg}${COLOR_RESET}\n" diff --git a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts index 7a78126423..1a84b10937 100644 --- a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts +++ b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts @@ -258,9 +258,11 @@ export class LdmlCompilerMessages { \`\`. `); - static ERROR_UnparseableTransformTo = SevErrorTransform | 0x06; - static Error_UnparseableTransformTo = (o: { to: string, message: string }) => - m(this.ERROR_UnparseableTransformTo, `Invalid transform to="${def(o.to)}": "${def(o.message)}"`); + static ERROR_UnparseableTransformTo = SevErrorTransform | 0x06; + static Error_UnparseableTransformTo = (o: {to: string, message: string}) => m( + this.ERROR_UnparseableTransformTo, + `Invalid transform to="${def(o.to)}": "${def(o.message)}"`, + ); } From 61b9234daf86b51a37b5ecc194e52de76108c807 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Thu, 20 Feb 2025 08:20:50 -0600 Subject: [PATCH 54/61] feat(developer): document test cases Fixes: #13175 --- .../kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-1.xml | 1 + .../kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-3.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-1.xml b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-1.xml index a644d5875f..ffa6e981d0 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-1.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-1.xml @@ -7,6 +7,7 @@ + diff --git a/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-3.xml b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-3.xml index f529e406ed..4dcb78c98b 100644 --- a/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-3.xml +++ b/developer/src/kmc-ldml/test/fixtures/sections/tran/fail-bad-tran-3.xml @@ -7,7 +7,7 @@ - + From cc7443efc25f022d04c8be9c4c4f679a537f8548 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Thu, 20 Feb 2025 13:02:13 -0500 Subject: [PATCH 55/61] auto: increment master version to 19.0.8 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 93cbf5ab53..6b04ccb32e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 19.0.7 alpha 2025-02-20 + +* chore(linux): allow to build and use Debian docker image (#13284) + ## 19.0.6 alpha 2025-02-19 * chore: merge beta to master B18S1 (#13239) diff --git a/VERSION.md b/VERSION.md index 68f5c99058..b4104dd4eb 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.7 \ No newline at end of file +19.0.8 \ No newline at end of file From 9252b9388ba0efa63805e9a24ba29706e8aca496 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 21 Feb 2025 12:54:45 +0100 Subject: [PATCH 56/61] fix(linux): remove `--platform amd64` from docker build script Passing this parameter causes docker image builds on mac to fail (#13295). Since `amd64` is the default anyways (and we don't support other values), we can simply remove that parameter. Fixes: #13295 --- resources/docker-images/build.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/resources/docker-images/build.sh b/resources/docker-images/build.sh index b97e267d99..d47af7454c 100755 --- a/resources/docker-images/build.sh +++ b/resources/docker-images/build.sh @@ -18,8 +18,7 @@ builder_describe \ ":core" \ ":linux" \ ":web" \ - "--distro=DISTRO The distribution to use for the base image "\ - " (debian or ubuntu, default: ubuntu)" \ + "--distro=DISTRO The distribution to use for the base image (debian or ubuntu, default: ubuntu)" \ "--distro-version=DISTRO_VERSION The Ubuntu/Debian version (default: ${KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER})" \ "--no-cache Force rebuild of docker images" \ "build Build docker images" \ @@ -83,7 +82,7 @@ build_action() { if [[ "${platform}" == "base" ]]; then # shellcheck disable=SC2154 # set by _convert_parameters_to_build_args - docker pull --platform "amd64" "${DISTRO}:${DISTRO_VERSION}" + docker pull "${DISTRO}:${DISTRO_VERSION}" elif [[ "${platform}" == "linux" ]]; then cp "${KEYMAN_ROOT}/linux/debian/control" "${platform}" fi @@ -95,12 +94,12 @@ build_action() { # shellcheck disable=SC2164 cd "${platform}" # shellcheck disable=SC2248,SC2086 - docker build ${OPTION_NO_CACHE:-} --platform amd64 -t "keymanapp/keyman-${platform}-ci:${build_version}" "${build_args[@]}" . + docker build ${OPTION_NO_CACHE:-} -t "keymanapp/keyman-${platform}-ci:${build_version}" "${build_args[@]}" . # If the user didn't specify particular versions we will additionaly create an image # with the tag 'default'. if _is_default_values; then builder_echo debug "Setting default tag for ${platform}" - docker build --platform amd64 -t "keymanapp/keyman-${platform}-ci:default" "${build_args[@]}" . + docker build -t "keymanapp/keyman-${platform}-ci:default" "${build_args[@]}" . fi # shellcheck disable=SC2164,SC2103 cd - From 0960aaef6de16a278d8304f6bf01fdd441082f2c Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 21 Feb 2025 13:02:29 -0500 Subject: [PATCH 57/61] auto: increment master version to 19.0.9 --- HISTORY.md | 6 ++++++ VERSION.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6b04ccb32e..411294a0b1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ # Keyman Version History +## 19.0.8 alpha 2025-02-21 + +* feat(windows): hack in some fun features for kmdevlink (#13237) +* feat(developer): use ABNF to validate LDML transform (#13236) +* fix(linux): remove `--platform amd64` from docker build script (#13318) + ## 19.0.7 alpha 2025-02-20 * chore(linux): allow to build and use Debian docker image (#13284) diff --git a/VERSION.md b/VERSION.md index b4104dd4eb..c9ed9d4f64 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.8 \ No newline at end of file +19.0.9 \ No newline at end of file From 562ac41230671b6855d8c8dd901eda8bc74d968a Mon Sep 17 00:00:00 2001 From: "EberhardSchweizer07@gmail.com" Date: Thu, 27 Feb 2025 15:19:42 +0100 Subject: [PATCH 58/61] docs: move node.js before Emscripten node.js is required in order to run Emscripten --- docs/build/windows.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/build/windows.md b/docs/build/windows.md index 63a77d1c41..ccf74be55d 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -162,8 +162,19 @@ SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" * KeymanWeb **Requirements**: -* Emscripten * node.js +* Emscripten + +#### node.js + +Our recommended way to install node.js is to use +[nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it +easy to switch between versions of node.js. + +```bat +nvm install 20.16.0 +nvm use 20.16.0 +``` #### Emscripten @@ -216,17 +227,6 @@ installed on your computer: SETX KEYMAN_USE_EMSDK 1 ``` -#### node.js - -Our recommended way to install node.js is to use -[nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it -easy to switch between versions of node.js. - -```bat -nvm install 20.16.0 -nvm use 20.16.0 -``` - **Optional environment variables**: To let the Keyman build scripts control the version of node.js installed From 3197b768c75f7e4cd1dfedec80d260d42b91dd99 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 27 Feb 2025 17:03:52 +0100 Subject: [PATCH 59/61] chore: add a workflow to automatically close linked issues --- .../close-linked-issues-for-merged-prs.yml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/close-linked-issues-for-merged-prs.yml diff --git a/.github/workflows/close-linked-issues-for-merged-prs.yml b/.github/workflows/close-linked-issues-for-merged-prs.yml new file mode 100644 index 0000000000..9387f3d0e6 --- /dev/null +++ b/.github/workflows/close-linked-issues-for-merged-prs.yml @@ -0,0 +1,20 @@ +name: Close linked issues for merged pull requests + +on: + pull_request: + types: [closed] + branches: + - beta + - 'stable-*' + - 'epic/*' + +jobs: + closeIssueOnPrMergeTrigger: + + runs-on: ubuntu-latest + + steps: + - name: Closes issues related to a merged pull request. + uses: ldez/gha-mjolnir@v1.5.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 2e3ae99f4d297009c45e0d8afe059ce67770b054 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 27 Feb 2025 17:10:57 +0100 Subject: [PATCH 60/61] chore: use sha instead of version for security --- .github/workflows/close-linked-issues-for-merged-prs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/close-linked-issues-for-merged-prs.yml b/.github/workflows/close-linked-issues-for-merged-prs.yml index 9387f3d0e6..2a0ce0a793 100644 --- a/.github/workflows/close-linked-issues-for-merged-prs.yml +++ b/.github/workflows/close-linked-issues-for-merged-prs.yml @@ -15,6 +15,6 @@ jobs: steps: - name: Closes issues related to a merged pull request. - uses: ldez/gha-mjolnir@v1.5.0 + uses: ldez/gha-mjolnir@5574ed1f1151e4d2f11e3513cd85920a3a46bb7b # v1.5.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 64a0f2f9685279a38f37bc331e072e1fd9c2959e Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Thu, 27 Feb 2025 13:01:15 -0500 Subject: [PATCH 61/61] auto: increment master version to 19.0.10 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 411294a0b1..9de791f041 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 19.0.9 alpha 2025-02-27 + +* docs: move node.js before Emscripten (#13366) +* chore: add a workflow to automatically close linked issues (#13368) + ## 19.0.8 alpha 2025-02-21 * feat(windows): hack in some fun features for kmdevlink (#13237) diff --git a/VERSION.md b/VERSION.md index c9ed9d4f64..0394531a29 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.9 \ No newline at end of file +19.0.10 \ No newline at end of file