From 7d82105d1da8bf7f18f841fe17b95c8f14e15565 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Wed, 28 Oct 2026 22:59:13 -0400 Subject: [PATCH] Fenrir can now create aliases for application overrides and put them in your clipboard. --- README.md | 8 + docs/user.md | 28 +++- internal/app/application_alias.go | 35 ++++ internal/app/application_alias_test.go | 153 ++++++++++++++++++ internal/app/application_overrides.go | 43 ++++- internal/app/application_overrides_test.go | 1 + internal/app/remote_application.go | 30 ++++ internal/app/remote_application_test.go | 117 ++++++++++++++ internal/app/remote_settings.go | 3 + internal/i18n/locale/de/LC_MESSAGES/fenrir.po | 50 +++--- internal/i18n/locale/es/LC_MESSAGES/fenrir.po | 50 +++--- internal/i18n/locale/fenrir.pot | 40 +++-- internal/i18n/locale/pl/LC_MESSAGES/fenrir.po | 50 +++--- internal/i18n/locale/pt/LC_MESSAGES/fenrir.po | 50 +++--- internal/i18n/locale/ru/LC_MESSAGES/fenrir.po | 50 +++--- 15 files changed, 594 insertions(+), 114 deletions(-) create mode 100644 internal/app/application_alias.go create mode 100644 internal/app/application_alias_test.go create mode 100644 internal/app/remote_application.go create mode 100644 internal/app/remote_application_test.go diff --git a/README.md b/README.md index deb84239..d28d8c9a 100644 --- a/README.md +++ b/README.md @@ -235,12 +235,20 @@ using the standard socket: ```bash echo "command say Hello" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock +echo "command application ninjam" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock +echo "command application default" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock echo "setting set reading#mode=highlight" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-daemon.sock ``` Set `remote.enabled = false` to disable remote control. Command and settings requests can also be enabled separately in the `[remote]` section. +`command application ID` selects an override for the reader's active terminal, +like Fenrir+A. IDs are `default`, `networkmanager`, `ninjam`, `rogue`, and `codex`. +In Fenrir+A, select an application and Tab to **Copy alias to clipboard** to +copy a Bash alias that selects its override before launching the program. +The program still launches if Fenrir or `socat` is unavailable. + ## Command-line help Run `./fenrir --help` for all options. Useful options include `--config`, diff --git a/docs/user.md b/docs/user.md index 253eb774..8a88cf30 100644 --- a/docs/user.md +++ b/docs/user.md @@ -12,8 +12,9 @@ For build requirements and setup, see the [README](../README.md). Press **Fenrir+A** to open **Applications**. Up and Down select an item; Enter activates it and closes the menu. Escape or the Cancel button closes the menu -without changing the selection. Tab and Shift+Tab move between the list, Cancel, -and the tab selector. The active override is initially selected. +without changing the selection. Tab and Shift+Tab move between the list, +Copy alias to clipboard, Cancel, and the tab selector. The active override is +initially selected. Type the start of a name to jump to it: **n** selects NetworkManager, then **i** selects Ninjam. Searching ignores letter case and does not activate the item. @@ -26,6 +27,22 @@ launch programs. Choose **Default** to restore the settings and reading regions that were in effect before the override. Overrides are built into Fenrir and are never selected automatically or remembered across restarts. +To launch a program with its override, select its name in this list, then Tab +to **Copy alias to clipboard** and press Enter. This copies a Bash alias into +Fenrir's clipboard without selecting the override or closing the menu. Paste it +into your Bash configuration, such as `~/.bashrc`, and load that configuration +in a new shell. The aliases use the executable names `cninjam`, `nmtui`, `rogue`, +and `codex`; Default has no alias. Existing aliases with those names are replaced +when you load the definition. + +The alias requests the override through `socat`, then launches the real program +with the arguments you supplied. Errors remain visible, and the program still +launches if the request fails, remote control is disabled, or Fenrir or `socat` +is missing. Socket inactivity is limited to two seconds. It uses the standard +socket, or your configured `remote.socket_file`, rather than a process-specific +socket that changes at restart. Paste with Fenrir's clipboard command; desktop +clipboard synchronization follows your normal clipboard settings. + While an override is active, **Fenrir+F** opens its application settings, with the application name in the title. **OK**, **Fenrir+Control+S**, and remote `SETTING SAVE` save that application's preferences. Quick and remote changes @@ -559,6 +576,13 @@ Other supported operations include: - `command tempdisablespeech`: temporarily silence speech. - `command clipboard TEXT`: add text to the clipboard. - `command exportclipboard`: export the selected clipboard. +- `command application ID`: select `default`, `networkmanager`, `ninjam`, + `rogue`, or `codex` for this reader's active terminal, like Fenrir+A. + This requires command remote control. An empty reply means selection + succeeded; invalid IDs, busy settings, and restoration failures return an + error. Application recognition and profile loading happen later, when the + application appears; this command does not launch it. `default` restores + ordinary settings. Use a private socket when targeting a particular reader. - `command window X1 Y1 X2 Y2`: set a reading window, using zero-based, inclusive coordinates. - `command resetwindow`: clear the window. diff --git a/internal/app/application_alias.go b/internal/app/application_alias.go new file mode 100644 index 00000000..c7f17eb1 --- /dev/null +++ b/internal/app/application_alias.go @@ -0,0 +1,35 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/fenrir/internal/control" +) + +func shell_quote(text string) string { + return "'" + strings.ReplaceAll(text, "'", "'\"'\"'") + "'" +} + +// The last simple command receives the arguments following the alias. Keep the +// optional reader request in an OR list so errexit cannot prevent the launch. +func application_alias(id, socketPath string) string { + program := "" + switch id { + case "networkmanager": + program = "nmtui" + case "ninjam": + program = "cninjam" + case "rogue", "codex": + program = id + default: + return "" + } + if socketPath == "" { + socketPath = control.MainSocket + } + body := "(echo " + shell_quote("command application "+id) + " | socat -T 2 - " + shell_quote("UNIX-CLIENT:"+socketPath) + ") || :; command " + program + return "alias " + program + "=" + shell_quote(body) +} diff --git a/internal/app/application_alias_test.go b/internal/app/application_alias_test.go new file mode 100644 index 00000000..2b654eaf --- /dev/null +++ b/internal/app/application_alias_test.go @@ -0,0 +1,153 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + "git.stormux.org/storm/fenrir/internal/control" + "git.stormux.org/storm/fenrir/internal/interaction" +) + +func TestApplicationAliasesShellCheck(t *testing.T) { + path, err := exec.LookPath("shellcheck") + if err != nil { + t.Skip("shellcheck unavailable") + } + for _, id := range []string{"networkmanager", "ninjam", "rogue", "codex"} { + process := exec.Command(path, "-s", "bash", "-") + process.Stdin = strings.NewReader(application_alias(id, "") + "\n") + if output, err := process.CombinedOutput(); err != nil { + t.Fatalf("%s: %v: %s", id, err, output) + } + } +} + +func TestApplicationAliasThroughPrivateSocket(t *testing.T) { + socatPath, err := exec.LookPath("socat") + if err != nil { + t.Skip("socat unavailable") + } + directory := t.TempDir() + socketPath := filepath.Join(directory, "reader.sock") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + server, err := control.Open(ctx, control.Options{SocketFile: socketPath, RegistryDirectory: directory}) + if err != nil { + t.Fatal(err) + } + defer server.Close() + if err := os.Symlink(socatPath, filepath.Join(directory, "socat")); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(directory, "cninjam"), []byte("#!/bin/sh\necho application-launched\n"), 0700); err != nil { + t.Fatal(err) + } + a, _ := persistence_application(t, true) + override_read(t, a, override_screen(1, "[Username@host directory] $")) + process := exec.CommandContext(ctx, "/bin/bash", "--noprofile", "--norc", "-c", "shopt -s expand_aliases\n"+application_alias("ninjam", socketPath)+"\ncninjam\n") + process.Env = append(os.Environ(), "PATH="+directory) + completed := make(chan struct{}) + var output []byte + var processError error + go func() { + output, processError = process.CombinedOutput() + close(completed) + }() + select { + case request := <-server.Requests(): + if request.Text != "command application ninjam" { + t.Fatal(request.Text) + } + a.remote_request(request) + case <-ctx.Done(): + t.Fatal("alias did not send selection request") + } + <-completed + if processError != nil || string(output) != "application-launched\n" || a.overrides[1] == nil { + t.Fatalf("launch failed: %v, %s", processError, output) + } + override_read(t, a, override_screen(1, "ninjam")) + if a.overrideCurrent == nil || a.overrideCurrent.id != "ninjam" { + t.Fatal("pre-launch selection did not activate when application appeared") + } +} + +func TestApplicationAliasLaunchesWithArgumentsDespiteReaderFailure(t *testing.T) { + for _, scenario := range []string{"success", "rejected", "failed", "missing"} { + t.Run(scenario, func(t *testing.T) { + directory := t.TempDir() + requestPath := filepath.Join(directory, "request") + argsPath := filepath.Join(directory, "args") + program := "#!/bin/sh\nprintf '%s\\n' \"$@\" > \"$ALIAS_ARGS\"\nexit 7\n" + if err := os.WriteFile(filepath.Join(directory, "cninjam"), []byte(program), 0700); err != nil { + t.Fatal(err) + } + if scenario != "missing" { + client := "#!/bin/sh\nprintf '%s\\n' \"$@\" > \"$ALIAS_REQUEST\"\n/bin/cat >> \"$ALIAS_REQUEST\"\n" + if scenario == "rejected" { + client += "echo 'Command remote control is disabled'\n" + } + if scenario == "failed" { + client += "exit 1\n" + } + if err := os.WriteFile(filepath.Join(directory, "socat"), []byte(client), 0700); err != nil { + t.Fatal(err) + } + } + socketPath := "/tmp/example socket'$(false).sock" + script := "set -euo pipefail\nshopt -s expand_aliases\n" + application_alias("ninjam", socketPath) + "\ncninjam 'argument with spaces' '*.wav'\n" + process := exec.Command("/bin/bash", "--noprofile", "--norc", "-c", script) + process.Env = append(os.Environ(), "PATH="+directory, "ALIAS_ARGS="+argsPath, "ALIAS_REQUEST="+requestPath) + output, err := process.CombinedOutput() + if failure, ok := err.(*exec.ExitError); !ok || failure.ExitCode() != 7 { + t.Fatalf("application status lost: %v, %s", err, output) + } + args, err := os.ReadFile(argsPath) + if err != nil || string(args) != "argument with spaces\n*.wav\n" { + t.Fatal("arguments lost", string(args), err) + } + if scenario != "missing" { + request, err := os.ReadFile(requestPath) + if err != nil || string(request) != "-T\n2\n-\nUNIX-CLIENT:"+socketPath+"\ncommand application ninjam\n" { + t.Fatal("socket or request changed by shell", string(request), err) + } + } + if scenario == "rejected" && !strings.Contains(string(output), "Command remote control is disabled") { + t.Fatal("reader error hidden", string(output)) + } + }) + } +} + +func TestApplicationsMenuCopiesAliasWithoutSelecting(t *testing.T) { + a, voice := persistence_application(t, true) + override_read(t, a, override_screen(1, "ninjam")) + a.open_applications() + a.ui.handle(interaction.Key{Name: "tab"}) + a.ui.handle(interaction.Key{Name: "enter"}) + if got := voice.messages[len(voice.messages)-1]; got != "Default has no application alias" { + t.Fatal(got) + } + a.ui.handle(interaction.Key{Name: "tab", Shift: true}) + // Use the list's prefix search, then Tab to the copy button. + a.ui.handle(interaction.Key{Text: "n"}) + a.ui.handle(interaction.Key{Text: "i"}) + a.ui.handle(interaction.Key{Name: "tab"}) + a.ui.handle(interaction.Key{Name: "enter"}) + if !a.ui.active || len(a.overrides) != 0 { + t.Fatal("copy closed menu or selected an override") + } + text, ok := a.clipboards.history.Current() + if !ok || text != application_alias("ninjam", "") { + t.Fatal("wrong clipboard contents", text) + } + a.ui.handle(interaction.Key{Name: "escape"}) +} diff --git a/internal/app/application_overrides.go b/internal/app/application_overrides.go index 526dc279..d4bfc86a 100644 --- a/internal/app/application_overrides.go +++ b/internal/app/application_overrides.go @@ -16,6 +16,7 @@ import ( "git.stormux.org/storm/fenrir/internal/config" "git.stormux.org/storm/fenrir/internal/i18n" "git.stormux.org/storm/fenrir/internal/interaction" + "git.stormux.org/storm/fenrir/internal/presentation" "git.stormux.org/storm/fenrir/internal/prompt" "git.stormux.org/storm/fenrir/internal/reader" "git.stormux.org/storm/fenrir/internal/screen" @@ -119,12 +120,20 @@ func (a *application) install_override(saved overrideSnapshot, terminal int) { // A synthesizer selection can require asynchronous restoration. Until it // completes, no new context is installed and all settings mutations are gated. func (a *application) restore_override(done func()) bool { + return a.restore_override_result(func(err error) { + if err == nil { + done() + } + }) +} + +func (a *application) restore_override_result(done func(error)) bool { current := a.overrideCurrent if current == nil { current = a.overrideFailed } if current == nil { - done() + done(nil) return true } if a.speechPending || a.saver.busy || a.overrideTransition || a.overrideRestoreFailed { @@ -141,7 +150,7 @@ func (a *application) restore_override(done func()) bool { a.overrideCurrent = nil a.overrideFailed = nil current.adapter.Reset() - done() + done(nil) } if same_speech_selection(a.settings.live.Presentation.Speech, current.underlying.settings.live.Presentation.Speech) { restore() @@ -161,6 +170,7 @@ func (a *application) restore_override(done func()) bool { a.overrideCurrent, a.overrideFailed = nil, current current.adapter.Reset() a.voice.Say(i18n.Format("Could not restore application settings: {0}", err.Error())) + done(err) return } restore() @@ -177,8 +187,21 @@ func (a *application) select_override(id string) { if terminal == 0 || !a.lastActive { return } + a.select_override_result(id, func(string) {}) +} + +// Completion means selected, not recognized or profile-loaded: launchers must +// be able to select an override before starting the application. Callers check +// the ID and busy/terminal gates before entering this path. +func (a *application) select_override_result(id string, done func(string)) { + terminal := a.lastTerminal a.overrideRestoreFailed = false // An explicit selection retries restoration. - a.restore_override(func() { + a.restore_override_result(func(err error) { + if err != nil { + done("Could not restore application settings: " + err.Error()) + return + } + a.ui.close() a.overrideDirty = true if old := a.overrides[terminal]; old != nil { old.adapter.Close() @@ -186,6 +209,7 @@ func (a *application) select_override(id string) { } if id == "default" { a.voice.Say(i18n.T("Default settings restored")) + done("") return } var adapter applicationoverrides.Adapter @@ -211,6 +235,7 @@ func (a *application) select_override(id string) { selected.shell.Observe(a.lastSnapshot) a.overrides[terminal] = selected a.voice.Say(i18n.Format("{0} application override selected", i18n.T(adapter.Name()))) + done("") }) } @@ -329,6 +354,7 @@ func (a *application) open_applications() { } session, err := interaction.New_session(interaction.Form{Type: interaction.TabForm, Title: "Applications", Tabs: []interaction.Tab{{ID: "applications", Label: "Applications", Controls: []interaction.Control{ {ID: "application", Label: "Application", Kind: interaction.List, Items: items, Selected: position, Action: "activate"}, + {ID: "copy_alias", Label: "Copy alias to clipboard", Kind: interaction.Button, Action: "copy_alias"}, {ID: "cancel", Label: "Cancel", Kind: interaction.Button, Action: "cancel"}, }}}}) if err != nil { @@ -351,6 +377,17 @@ func (a *application) open_applications() { a.ui.close() a.select_override(ids[selected]) } + if action == "copy_alias" { + selected := session.Values()["applications.application"].Selected + text := application_alias(ids[selected], a.settings.live.Remote.SocketFile) + if text == "" { + a.voice.Say(i18n.T("Default has no application alias")) + return + } + if a.clipboards.add(text, true) { + a.present(i18n.T("Application alias copied to clipboard"), presentation.CopyToClipboard) + } + } } a.voice.Say(session.Open()) } diff --git a/internal/app/application_overrides_test.go b/internal/app/application_overrides_test.go index b47ec356..ad04c5a1 100644 --- a/internal/app/application_overrides_test.go +++ b/internal/app/application_overrides_test.go @@ -213,6 +213,7 @@ func TestApplicationsMenuActivatesOnlyOnEnterAndReleasesCapture(t *testing.T) { t.Fatal("active item not selected") } a.ui.handle(interaction.Key{Name: "tab"}) + a.ui.handle(interaction.Key{Name: "tab"}) // Skip Copy alias to reach Cancel. a.ui.handle(interaction.Key{Name: "enter"}) if a.ui.active || a.overrides[1] == nil { t.Fatal("Cancel button changed selection") diff --git a/internal/app/remote_application.go b/internal/app/remote_application.go new file mode 100644 index 00000000..d6486ac6 --- /dev/null +++ b/internal/app/remote_application.go @@ -0,0 +1,30 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/fenrir/internal/control" +) + +// Runs after the command authorization and enablement gates. +func (a *application) remote_application(parameter string, request control.Request) { + id := strings.ToLower(strings.TrimSpace(parameter)) + switch id { + case "default", "networkmanager", "ninjam", "rogue", "codex": + default: + remote_reply(request.Reply, "APPLICATION requires one ID: default, networkmanager, ninjam, rogue, codex") + return + } + if a.saver.busy || a.speechPending || a.overrideTransition { + remote_reply(request.Reply, "Settings are busy; try again after the current operation") + return + } + if a.lastTerminal == 0 || !a.lastActive { + remote_reply(request.Reply, "No active terminal for application selection") + return + } + a.select_override_result(id, func(response string) { remote_reply(request.Reply, response) }) +} diff --git a/internal/app/remote_application_test.go b/internal/app/remote_application_test.go new file mode 100644 index 00000000..258a434e --- /dev/null +++ b/internal/app/remote_application_test.go @@ -0,0 +1,117 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "errors" + "os" + "testing" + + "git.stormux.org/storm/fenrir/internal/config" + "git.stormux.org/storm/fenrir/internal/control" + "git.stormux.org/storm/fenrir/internal/speech" +) + +func TestRemoteApplicationSelectionAndDefault(t *testing.T) { + for _, terminalMode := range []bool{true, false} { + a, _ := persistence_application(t, terminalMode) + override_read(t, a, override_screen(1, "ninjam")) + for _, id := range []string{"ninjam", "networkmanager", "rogue", "codex", "default"} { + if got := runtime_request(a, "COMMAND APPLICATION "+id); got != "" { + t.Fatal(id, got) + } + selected := a.overrides[1] + if id == "default" { + if selected != nil { + t.Fatal("Default retained selection") + } + } else if selected == nil || selected.id != id { + t.Fatal("wrong application selected", id) + } + } + if got := runtime_request(a, "command application NINJAM"); got != "" { + t.Fatal(got) + } + override_read(t, a, override_screen(1, "ninjam")) + if a.overrideCurrent == nil || a.engine.Tracking_mode() != "highlight" { + t.Fatal("remote selection did not activate Ninjam") + } + if got := runtime_request(a, "command application default"); got != "" || a.overrideCurrent != nil { + t.Fatal("Default did not restore settings", got) + } + } +} + +func TestRemoteApplicationRejectsInvalidAndUnavailableRequests(t *testing.T) { + a, _ := persistence_application(t, true) + override_read(t, a, override_screen(1, "ninjam")) + a.select_override("ninjam") + selected := a.overrides[1] + for _, parameter := range []string{"", "unknown", "ninjam extra", "default extra"} { + if got := runtime_request(a, "COMMAND APPLICATION "+parameter); got == "" || a.overrides[1] != selected { + t.Fatal("invalid request changed selection", parameter, got) + } + } + for _, gate := range []string{"disabled", "save", "speech", "transition", "inactive", "no-terminal", "unauthorized"} { + t.Run(gate, func(t *testing.T) { + uid := os.Geteuid() + switch gate { + case "disabled": + a.settings.live.Remote.EnableCommandRemote = false + case "save": + a.saver.busy = true + case "speech": + a.speechPending = true + case "transition": + a.overrideTransition = true + case "inactive": + a.lastActive = false + case "no-terminal": + a.lastTerminal = 0 + case "unauthorized": + uid++ + } + reply := make(chan string, 1) + a.remote_request(control.Request{UID: uid, Text: "COMMAND APPLICATION default", Reply: reply}) + if got := <-reply; got == "" || a.overrides[1] != selected { + t.Fatal("gated request changed selection", got) + } + a.settings.live.Remote.EnableCommandRemote = true + a.saver.busy, a.speechPending, a.overrideTransition = false, false, false + a.lastActive, a.lastTerminal = true, 1 + }) + } +} + +func TestRemoteApplicationWaitsForVoiceRestoration(t *testing.T) { + for _, fail := range []bool{false, true} { + a, _, _ := selection_application(t, true) + a.prepareSpeech = func(config.Speech) (speech.Transport, error) { return &preparedVoice{}, nil } + override_read(t, a, override_screen(1, "ninjam")) + a.select_override("ninjam") + override_read(t, a, override_screen(1, "ninjam")) + if got := request_selection(t, a, "SET speech#module=fixture;speech#voice=Temporary"); got != "" { + t.Fatal(got) + } + if fail { + a.prepareSpeech = func(config.Speech) (speech.Transport, error) { return nil, errors.New("fixture unavailable") } + } + reply := make(chan string, 1) + a.remote_request(control.Request{UID: os.Geteuid(), Text: "COMMAND APPLICATION rogue", Reply: reply}) + select { + case got := <-reply: + t.Fatal("selection replied before restoration", got) + default: + } + finish_selection(t, a) + got := <-reply + if fail { + if got == "" || a.overrides[1].id != "ninjam" { + t.Fatal("restoration failure lost", got) + } + } else if got != "" || a.overrides[1].id != "rogue" { + t.Fatal("selection failed after restoration", got) + } + } +} diff --git a/internal/app/remote_settings.go b/internal/app/remote_settings.go index 27cdde1b..1f428917 100644 --- a/internal/app/remote_settings.go +++ b/internal/app/remote_settings.go @@ -226,6 +226,9 @@ func (a *application) remote_request(request control.Request) { a.clipboards.add(parameter, true) case "EXPORTCLIPBOARD": a.clipboards.command(command.ExportClipboard) + case "APPLICATION": + a.remote_application(parameter, request) + deferred = true default: response = "Unsupported remote command: " + verb } diff --git a/internal/i18n/locale/de/LC_MESSAGES/fenrir.po b/internal/i18n/locale/de/LC_MESSAGES/fenrir.po index 7a71361d..02b50d26 100644 --- a/internal/i18n/locale/de/LC_MESSAGES/fenrir.po +++ b/internal/i18n/locale/de/LC_MESSAGES/fenrir.po @@ -71,11 +71,15 @@ msgstr "Wütend" msgid "Apple" msgstr "Apfel" -#: internal/app/application_overrides.go:331 +#: internal/app/application_overrides.go:356 msgid "Application" msgstr "Anwendung" -#: internal/app/application_overrides.go:330 +#: internal/app/application_overrides.go:388 +msgid "Application alias copied to clipboard" +msgstr "Anwendungsalias in die Zwischenablage kopiert" + +#: internal/app/application_overrides.go:355 msgid "Applications" msgstr "Anwendungen" @@ -172,7 +176,7 @@ msgstr "Schmetterling" msgid "Canada" msgstr "Kanada" -#: internal/app/application_overrides.go:332 +#: internal/app/application_overrides.go:358 #: internal/preferences/settings.go:93 msgid "Cancel" msgstr "Abbrechen" @@ -274,7 +278,7 @@ msgstr "Import aus der Zwischenablage fehlgeschlagen" msgid "Clipboard sync" msgstr "Zwischenablage synchronisieren" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Codex" msgstr "Codex" @@ -330,17 +334,21 @@ msgstr "Verbindung, Tempo und Intervall" msgid "Cool" msgstr "Cool" +#: internal/app/application_overrides.go:357 +msgid "Copy alias to clipboard" +msgstr "Alias in die Zwischenablage kopieren" + #: internal/app/spellcheck_menu.go:175 msgid "Could not check spelling: {0}" msgstr "Rechtschreibung konnte nicht geprüft werden: {0}" -#: internal/app/application_overrides.go:284 -#: internal/app/application_overrides.go:85 +#: internal/app/application_overrides.go:309 +#: internal/app/application_overrides.go:86 msgid "Could not load application settings: {0}" msgstr "Anwendungseinstellungen konnten nicht geladen werden: {0}" -#: internal/app/application_overrides.go:335 -#: internal/app/application_overrides.go:339 +#: internal/app/application_overrides.go:361 +#: internal/app/application_overrides.go:365 msgid "Could not open Applications: {0}" msgstr "Anwendungen konnten nicht geöffnet werden: {0}" @@ -357,8 +365,8 @@ msgstr "Fenrir-Menü konnte nicht geöffnet werden: {0}" msgid "Could not open Spellcheck Menu: {0}" msgstr "Rechtschreibmenü konnte nicht geöffnet werden: {0}" -#: internal/app/application_overrides.go:163 -#: internal/app/application_overrides.go:302 +#: internal/app/application_overrides.go:172 +#: internal/app/application_overrides.go:327 msgid "Could not restore application settings: {0}" msgstr "Anwendungseinstellungen konnten nicht wiederhergestellt werden: {0}" @@ -387,12 +395,16 @@ msgstr "Dolch" msgid "Date format" msgstr "Datumsformat" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Default" msgstr "Standard" -#: internal/app/application_overrides.go:188 -#: internal/app/application_overrides.go:248 +#: internal/app/application_overrides.go:384 +msgid "Default has no application alias" +msgstr "Standard hat keinen Anwendungsalias" + +#: internal/app/application_overrides.go:211 +#: internal/app/application_overrides.go:273 msgid "Default settings restored" msgstr "Standardeinstellungen wiederhergestellt" @@ -817,7 +829,7 @@ msgstr "Übelkeit" msgid "Netherlands" msgstr "Niederlande" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "NetworkManager" msgstr "NetworkManager" @@ -825,7 +837,7 @@ msgstr "NetworkManager" msgid "New channel" msgstr "Neuer Kanal" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Ninjam" msgstr "Ninjam" @@ -1101,7 +1113,7 @@ msgstr "Ring" msgid "Rock on" msgstr "Rock-Geste" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Rogue" msgstr "Rogue" @@ -1201,8 +1213,8 @@ msgstr "Live-Bereich aus einer oder zwei Markierungen festlegen" msgid "Set window begin and end marks" msgstr "Setze Fensteranfangs- und -endmarken" -#: internal/app/application_overrides.go:173 -#: internal/app/application_overrides.go:321 internal/app/commands.go:84 +#: internal/app/application_overrides.go:183 +#: internal/app/application_overrides.go:346 internal/app/commands.go:84 msgid "Settings are busy" msgstr "Einstellungen sind beschäftigt" @@ -2469,7 +2481,7 @@ msgstr "Zwinkern" msgid "{0} added to dictionary" msgstr "{0} zum Wörterbuch hinzugefügt" -#: internal/app/application_overrides.go:213 +#: internal/app/application_overrides.go:237 msgid "{0} application override selected" msgstr "Anwendungseinstellungen für {0} ausgewählt" diff --git a/internal/i18n/locale/es/LC_MESSAGES/fenrir.po b/internal/i18n/locale/es/LC_MESSAGES/fenrir.po index 976f8b83..3b8851d7 100644 --- a/internal/i18n/locale/es/LC_MESSAGES/fenrir.po +++ b/internal/i18n/locale/es/LC_MESSAGES/fenrir.po @@ -71,11 +71,15 @@ msgstr "Enfadado" msgid "Apple" msgstr "Manzana" -#: internal/app/application_overrides.go:331 +#: internal/app/application_overrides.go:356 msgid "Application" msgstr "Aplicación" -#: internal/app/application_overrides.go:330 +#: internal/app/application_overrides.go:388 +msgid "Application alias copied to clipboard" +msgstr "Alias de la aplicación copiado al portapapeles" + +#: internal/app/application_overrides.go:355 msgid "Applications" msgstr "Aplicaciones" @@ -172,7 +176,7 @@ msgstr "Mariposa" msgid "Canada" msgstr "Canadá" -#: internal/app/application_overrides.go:332 +#: internal/app/application_overrides.go:358 #: internal/preferences/settings.go:93 msgid "Cancel" msgstr "Cancelar" @@ -274,7 +278,7 @@ msgstr "Error al importar el portapapeles" msgid "Clipboard sync" msgstr "Sincronización del portapapeles" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Codex" msgstr "Codex" @@ -332,17 +336,21 @@ msgstr "Conexión, tempo e intervalo" msgid "Cool" msgstr "Genial" +#: internal/app/application_overrides.go:357 +msgid "Copy alias to clipboard" +msgstr "Copiar alias al portapapeles" + #: internal/app/spellcheck_menu.go:175 msgid "Could not check spelling: {0}" msgstr "No se pudo revisar la ortografía: {0}" -#: internal/app/application_overrides.go:284 -#: internal/app/application_overrides.go:85 +#: internal/app/application_overrides.go:309 +#: internal/app/application_overrides.go:86 msgid "Could not load application settings: {0}" msgstr "No se pudo cargar la configuración de la aplicación: {0}" -#: internal/app/application_overrides.go:335 -#: internal/app/application_overrides.go:339 +#: internal/app/application_overrides.go:361 +#: internal/app/application_overrides.go:365 msgid "Could not open Applications: {0}" msgstr "No se pudo abrir Aplicaciones: {0}" @@ -359,8 +367,8 @@ msgstr "No se pudo abrir el menú de Fenrir: {0}" msgid "Could not open Spellcheck Menu: {0}" msgstr "No se pudo abrir el menú de ortografía: {0}" -#: internal/app/application_overrides.go:163 -#: internal/app/application_overrides.go:302 +#: internal/app/application_overrides.go:172 +#: internal/app/application_overrides.go:327 msgid "Could not restore application settings: {0}" msgstr "No se pudo restaurar la configuración de la aplicación: {0}" @@ -389,12 +397,16 @@ msgstr "Daga" msgid "Date format" msgstr "Formato de fecha" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Default" msgstr "Predeterminado" -#: internal/app/application_overrides.go:188 -#: internal/app/application_overrides.go:248 +#: internal/app/application_overrides.go:384 +msgid "Default has no application alias" +msgstr "Predeterminado no tiene un alias de aplicación" + +#: internal/app/application_overrides.go:211 +#: internal/app/application_overrides.go:273 msgid "Default settings restored" msgstr "Configuración predeterminada restaurada" @@ -827,7 +839,7 @@ msgstr "Náuseas" msgid "Netherlands" msgstr "Países Bajos" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "NetworkManager" msgstr "NetworkManager" @@ -835,7 +847,7 @@ msgstr "NetworkManager" msgid "New channel" msgstr "Nuevo canal" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Ninjam" msgstr "Ninjam" @@ -1110,7 +1122,7 @@ msgstr "Anillo" msgid "Rock on" msgstr "Gesto de rock" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Rogue" msgstr "Rogue" @@ -1210,8 +1222,8 @@ msgstr "Definir una región dinámica a partir de una o dos marcas" msgid "Set window begin and end marks" msgstr "Establece una marca de principio y otra para el final de la ventana" -#: internal/app/application_overrides.go:173 -#: internal/app/application_overrides.go:321 internal/app/commands.go:84 +#: internal/app/application_overrides.go:183 +#: internal/app/application_overrides.go:346 internal/app/commands.go:84 msgid "Settings are busy" msgstr "La configuración está ocupada" @@ -2477,7 +2489,7 @@ msgstr "guiño" msgid "{0} added to dictionary" msgstr "{0} añadido al diccionario" -#: internal/app/application_overrides.go:213 +#: internal/app/application_overrides.go:237 msgid "{0} application override selected" msgstr "Ajustes de aplicación seleccionados para {0}" diff --git a/internal/i18n/locale/fenrir.pot b/internal/i18n/locale/fenrir.pot index 2da03187..591ac113 100644 --- a/internal/i18n/locale/fenrir.pot +++ b/internal/i18n/locale/fenrir.pot @@ -61,11 +61,15 @@ msgstr "" msgid "Apple" msgstr "" -#: internal/app/application_overrides.go:331 +#: internal/app/application_overrides.go:356 msgid "Application" msgstr "" -#: internal/app/application_overrides.go:330 +#: internal/app/application_overrides.go:388 +msgid "Application alias copied to clipboard" +msgstr "" + +#: internal/app/application_overrides.go:355 msgid "Applications" msgstr "" @@ -161,7 +165,7 @@ msgstr "" msgid "Canada" msgstr "" -#: internal/app/application_overrides.go:332 internal/preferences/settings.go:93 +#: internal/app/application_overrides.go:358 internal/preferences/settings.go:93 msgid "Cancel" msgstr "" @@ -261,7 +265,7 @@ msgstr "" msgid "Clipboard sync" msgstr "" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Codex" msgstr "" @@ -317,15 +321,19 @@ msgstr "" msgid "Cool" msgstr "" +#: internal/app/application_overrides.go:357 +msgid "Copy alias to clipboard" +msgstr "" + #: internal/app/spellcheck_menu.go:175 msgid "Could not check spelling: {0}" msgstr "" -#: internal/app/application_overrides.go:284 internal/app/application_overrides.go:85 +#: internal/app/application_overrides.go:309 internal/app/application_overrides.go:86 msgid "Could not load application settings: {0}" msgstr "" -#: internal/app/application_overrides.go:335 internal/app/application_overrides.go:339 +#: internal/app/application_overrides.go:361 internal/app/application_overrides.go:365 msgid "Could not open Applications: {0}" msgstr "" @@ -341,7 +349,7 @@ msgstr "" msgid "Could not open Spellcheck Menu: {0}" msgstr "" -#: internal/app/application_overrides.go:163 internal/app/application_overrides.go:302 +#: internal/app/application_overrides.go:172 internal/app/application_overrides.go:327 msgid "Could not restore application settings: {0}" msgstr "" @@ -369,11 +377,15 @@ msgstr "" msgid "Date format" msgstr "" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Default" msgstr "" -#: internal/app/application_overrides.go:188 internal/app/application_overrides.go:248 +#: internal/app/application_overrides.go:384 +msgid "Default has no application alias" +msgstr "" + +#: internal/app/application_overrides.go:211 internal/app/application_overrides.go:273 msgid "Default settings restored" msgstr "" @@ -785,7 +797,7 @@ msgstr "" msgid "Netherlands" msgstr "" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "NetworkManager" msgstr "" @@ -793,7 +805,7 @@ msgstr "" msgid "New channel" msgstr "" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Ninjam" msgstr "" @@ -1061,7 +1073,7 @@ msgstr "" msgid "Rock on" msgstr "" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Rogue" msgstr "" @@ -1161,7 +1173,7 @@ msgstr "" msgid "Set window begin and end marks" msgstr "" -#: internal/app/application_overrides.go:173 internal/app/application_overrides.go:321 internal/app/commands.go:84 +#: internal/app/application_overrides.go:183 internal/app/application_overrides.go:346 internal/app/commands.go:84 msgid "Settings are busy" msgstr "" @@ -2361,7 +2373,7 @@ msgstr "" msgid "{0} added to dictionary" msgstr "" -#: internal/app/application_overrides.go:213 +#: internal/app/application_overrides.go:237 msgid "{0} application override selected" msgstr "" diff --git a/internal/i18n/locale/pl/LC_MESSAGES/fenrir.po b/internal/i18n/locale/pl/LC_MESSAGES/fenrir.po index 8ed59581..81cf85c7 100644 --- a/internal/i18n/locale/pl/LC_MESSAGES/fenrir.po +++ b/internal/i18n/locale/pl/LC_MESSAGES/fenrir.po @@ -72,11 +72,15 @@ msgstr "Złość" msgid "Apple" msgstr "Jabłko" -#: internal/app/application_overrides.go:331 +#: internal/app/application_overrides.go:356 msgid "Application" msgstr "Aplikacja" -#: internal/app/application_overrides.go:330 +#: internal/app/application_overrides.go:388 +msgid "Application alias copied to clipboard" +msgstr "Alias aplikacji skopiowany do schowka" + +#: internal/app/application_overrides.go:355 msgid "Applications" msgstr "Aplikacje" @@ -173,7 +177,7 @@ msgstr "Motyl" msgid "Canada" msgstr "Kanada" -#: internal/app/application_overrides.go:332 +#: internal/app/application_overrides.go:358 #: internal/preferences/settings.go:93 msgid "Cancel" msgstr "Anuluj" @@ -275,7 +279,7 @@ msgstr "Importowanie schowka nie powiodło się" msgid "Clipboard sync" msgstr "Synchronizacja schowka" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Codex" msgstr "Codex" @@ -332,17 +336,21 @@ msgstr "Połączenie, tempo i interwał" msgid "Cool" msgstr "Wyluzowanie" +#: internal/app/application_overrides.go:357 +msgid "Copy alias to clipboard" +msgstr "Kopiuj alias do schowka" + #: internal/app/spellcheck_menu.go:175 msgid "Could not check spelling: {0}" msgstr "Nie można sprawdzić pisowni: {0}" -#: internal/app/application_overrides.go:284 -#: internal/app/application_overrides.go:85 +#: internal/app/application_overrides.go:309 +#: internal/app/application_overrides.go:86 msgid "Could not load application settings: {0}" msgstr "Nie można wczytać ustawień aplikacji: {0}" -#: internal/app/application_overrides.go:335 -#: internal/app/application_overrides.go:339 +#: internal/app/application_overrides.go:361 +#: internal/app/application_overrides.go:365 msgid "Could not open Applications: {0}" msgstr "Nie można otworzyć menu aplikacji: {0}" @@ -359,8 +367,8 @@ msgstr "Nie można otworzyć menu Fenrira: {0}" msgid "Could not open Spellcheck Menu: {0}" msgstr "Nie można otworzyć menu sprawdzania pisowni: {0}" -#: internal/app/application_overrides.go:163 -#: internal/app/application_overrides.go:302 +#: internal/app/application_overrides.go:172 +#: internal/app/application_overrides.go:327 msgid "Could not restore application settings: {0}" msgstr "Nie można przywrócić ustawień aplikacji: {0}" @@ -389,12 +397,16 @@ msgstr "Sztylet" msgid "Date format" msgstr "Format daty" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Default" msgstr "Domyślne" -#: internal/app/application_overrides.go:188 -#: internal/app/application_overrides.go:248 +#: internal/app/application_overrides.go:384 +msgid "Default has no application alias" +msgstr "Ustawienia domyślne nie mają aliasu aplikacji" + +#: internal/app/application_overrides.go:211 +#: internal/app/application_overrides.go:273 msgid "Default settings restored" msgstr "Przywrócono ustawienia domyślne" @@ -822,7 +834,7 @@ msgstr "Nudności" msgid "Netherlands" msgstr "Holandia" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "NetworkManager" msgstr "NetworkManager" @@ -830,7 +842,7 @@ msgstr "NetworkManager" msgid "New channel" msgstr "Nowy kanał" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Ninjam" msgstr "Ninjam" @@ -1104,7 +1116,7 @@ msgstr "Pierścień" msgid "Rock on" msgstr "Gest rockowy" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Rogue" msgstr "Rogue" @@ -1204,8 +1216,8 @@ msgstr "Ustaw obszar dynamiczny za pomocą jednego lub dwóch znaczników" msgid "Set window begin and end marks" msgstr "Ustaw początek i koniec okna." -#: internal/app/application_overrides.go:173 -#: internal/app/application_overrides.go:321 internal/app/commands.go:84 +#: internal/app/application_overrides.go:183 +#: internal/app/application_overrides.go:346 internal/app/commands.go:84 msgid "Settings are busy" msgstr "Ustawienia są zajęte" @@ -2468,7 +2480,7 @@ msgstr "mrugnięcie" msgid "{0} added to dictionary" msgstr "Dodano {0} do słownika" -#: internal/app/application_overrides.go:213 +#: internal/app/application_overrides.go:237 msgid "{0} application override selected" msgstr "Wybrano ustawienia aplikacji {0}" diff --git a/internal/i18n/locale/pt/LC_MESSAGES/fenrir.po b/internal/i18n/locale/pt/LC_MESSAGES/fenrir.po index 9bd4fb28..cc79940b 100644 --- a/internal/i18n/locale/pt/LC_MESSAGES/fenrir.po +++ b/internal/i18n/locale/pt/LC_MESSAGES/fenrir.po @@ -70,11 +70,15 @@ msgstr "Zangado" msgid "Apple" msgstr "Maçã" -#: internal/app/application_overrides.go:331 +#: internal/app/application_overrides.go:356 msgid "Application" msgstr "Aplicativo" -#: internal/app/application_overrides.go:330 +#: internal/app/application_overrides.go:388 +msgid "Application alias copied to clipboard" +msgstr "Alias da aplicação copiado para a área de transferência" + +#: internal/app/application_overrides.go:355 msgid "Applications" msgstr "Aplicativos" @@ -171,7 +175,7 @@ msgstr "Borboleta" msgid "Canada" msgstr "Canadá" -#: internal/app/application_overrides.go:332 +#: internal/app/application_overrides.go:358 #: internal/preferences/settings.go:93 msgid "Cancel" msgstr "Cancelar" @@ -273,7 +277,7 @@ msgstr "Falha ao importar a área de transferência" msgid "Clipboard sync" msgstr "Sincronização da área de transferência" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Codex" msgstr "Codex" @@ -330,17 +334,21 @@ msgstr "Conexão, andamento e intervalo" msgid "Cool" msgstr "Legal" +#: internal/app/application_overrides.go:357 +msgid "Copy alias to clipboard" +msgstr "Copiar alias para a área de transferência" + #: internal/app/spellcheck_menu.go:175 msgid "Could not check spelling: {0}" msgstr "Não foi possível verificar a ortografia: {0}" -#: internal/app/application_overrides.go:284 -#: internal/app/application_overrides.go:85 +#: internal/app/application_overrides.go:309 +#: internal/app/application_overrides.go:86 msgid "Could not load application settings: {0}" msgstr "Não foi possível carregar as configurações do aplicativo: {0}" -#: internal/app/application_overrides.go:335 -#: internal/app/application_overrides.go:339 +#: internal/app/application_overrides.go:361 +#: internal/app/application_overrides.go:365 msgid "Could not open Applications: {0}" msgstr "Não foi possível abrir Aplicativos: {0}" @@ -357,8 +365,8 @@ msgstr "Não foi possível abrir o menu do Fenrir: {0}" msgid "Could not open Spellcheck Menu: {0}" msgstr "Não foi possível abrir o menu de ortografia: {0}" -#: internal/app/application_overrides.go:163 -#: internal/app/application_overrides.go:302 +#: internal/app/application_overrides.go:172 +#: internal/app/application_overrides.go:327 msgid "Could not restore application settings: {0}" msgstr "Não foi possível restaurar as configurações do aplicativo: {0}" @@ -387,12 +395,16 @@ msgstr "Adaga" msgid "Date format" msgstr "Formato da data" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Default" msgstr "Padrão" -#: internal/app/application_overrides.go:188 -#: internal/app/application_overrides.go:248 +#: internal/app/application_overrides.go:384 +msgid "Default has no application alias" +msgstr "Padrão não tem um alias de aplicação" + +#: internal/app/application_overrides.go:211 +#: internal/app/application_overrides.go:273 msgid "Default settings restored" msgstr "Configurações padrão restauradas" @@ -824,7 +836,7 @@ msgstr "Enjoado" msgid "Netherlands" msgstr "Países Baixos" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "NetworkManager" msgstr "NetworkManager" @@ -832,7 +844,7 @@ msgstr "NetworkManager" msgid "New channel" msgstr "Novo canal" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Ninjam" msgstr "Ninjam" @@ -1108,7 +1120,7 @@ msgstr "Anel" msgid "Rock on" msgstr "Gesto de rock" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Rogue" msgstr "Rogue" @@ -1208,8 +1220,8 @@ msgstr "Definir uma região dinâmica a partir de uma ou duas marcas" msgid "Set window begin and end marks" msgstr "Definir marcas de início e fim da janela" -#: internal/app/application_overrides.go:173 -#: internal/app/application_overrides.go:321 internal/app/commands.go:84 +#: internal/app/application_overrides.go:183 +#: internal/app/application_overrides.go:346 internal/app/commands.go:84 msgid "Settings are busy" msgstr "As configurações estão ocupadas" @@ -2481,7 +2493,7 @@ msgstr "piscadela" msgid "{0} added to dictionary" msgstr "{0} adicionado ao dicionário" -#: internal/app/application_overrides.go:213 +#: internal/app/application_overrides.go:237 msgid "{0} application override selected" msgstr "Configurações do aplicativo {0} selecionadas" diff --git a/internal/i18n/locale/ru/LC_MESSAGES/fenrir.po b/internal/i18n/locale/ru/LC_MESSAGES/fenrir.po index 74dcf1da..d9a2bd6e 100644 --- a/internal/i18n/locale/ru/LC_MESSAGES/fenrir.po +++ b/internal/i18n/locale/ru/LC_MESSAGES/fenrir.po @@ -69,11 +69,15 @@ msgstr "Злость" msgid "Apple" msgstr "Яблоко" -#: internal/app/application_overrides.go:331 +#: internal/app/application_overrides.go:356 msgid "Application" msgstr "Приложение" -#: internal/app/application_overrides.go:330 +#: internal/app/application_overrides.go:388 +msgid "Application alias copied to clipboard" +msgstr "Псевдоним приложения скопирован в буфер обмена" + +#: internal/app/application_overrides.go:355 msgid "Applications" msgstr "Приложения" @@ -170,7 +174,7 @@ msgstr "Бабочка" msgid "Canada" msgstr "Канада" -#: internal/app/application_overrides.go:332 +#: internal/app/application_overrides.go:358 #: internal/preferences/settings.go:93 msgid "Cancel" msgstr "Отмена" @@ -272,7 +276,7 @@ msgstr "Не удалось импортировать буфер обмена" msgid "Clipboard sync" msgstr "Синхронизация буфера обмена" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Codex" msgstr "Codex" @@ -329,17 +333,21 @@ msgstr "Соединение, темп и интервал" msgid "Cool" msgstr "Круто" +#: internal/app/application_overrides.go:357 +msgid "Copy alias to clipboard" +msgstr "Копировать псевдоним в буфер обмена" + #: internal/app/spellcheck_menu.go:175 msgid "Could not check spelling: {0}" msgstr "Не удалось проверить правописание: {0}" -#: internal/app/application_overrides.go:284 -#: internal/app/application_overrides.go:85 +#: internal/app/application_overrides.go:309 +#: internal/app/application_overrides.go:86 msgid "Could not load application settings: {0}" msgstr "Не удалось загрузить настройки приложения: {0}" -#: internal/app/application_overrides.go:335 -#: internal/app/application_overrides.go:339 +#: internal/app/application_overrides.go:361 +#: internal/app/application_overrides.go:365 msgid "Could not open Applications: {0}" msgstr "Не удалось открыть меню приложений: {0}" @@ -356,8 +364,8 @@ msgstr "Не удалось открыть меню Fenrir: {0}" msgid "Could not open Spellcheck Menu: {0}" msgstr "Не удалось открыть меню проверки правописания: {0}" -#: internal/app/application_overrides.go:163 -#: internal/app/application_overrides.go:302 +#: internal/app/application_overrides.go:172 +#: internal/app/application_overrides.go:327 msgid "Could not restore application settings: {0}" msgstr "Не удалось восстановить настройки приложения: {0}" @@ -386,12 +394,16 @@ msgstr "Кинжал" msgid "Date format" msgstr "Формат даты" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Default" msgstr "По умолчанию" -#: internal/app/application_overrides.go:188 -#: internal/app/application_overrides.go:248 +#: internal/app/application_overrides.go:384 +msgid "Default has no application alias" +msgstr "Для настроек по умолчанию нет псевдонима приложения" + +#: internal/app/application_overrides.go:211 +#: internal/app/application_overrides.go:273 msgid "Default settings restored" msgstr "Настройки по умолчанию восстановлены" @@ -817,7 +829,7 @@ msgstr "Тошнота" msgid "Netherlands" msgstr "Нидерланды" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "NetworkManager" msgstr "NetworkManager" @@ -825,7 +837,7 @@ msgstr "NetworkManager" msgid "New channel" msgstr "Новый канал" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Ninjam" msgstr "Ninjam" @@ -1100,7 +1112,7 @@ msgstr "Кольцо" msgid "Rock on" msgstr "Рокерский жест" -#: internal/app/application_overrides.go:324 +#: internal/app/application_overrides.go:349 msgid "Rogue" msgstr "Rogue" @@ -1200,8 +1212,8 @@ msgstr "Задать динамическую область по одной и msgid "Set window begin and end marks" msgstr "Установка начала и конца окна" -#: internal/app/application_overrides.go:173 -#: internal/app/application_overrides.go:321 internal/app/commands.go:84 +#: internal/app/application_overrides.go:183 +#: internal/app/application_overrides.go:346 internal/app/commands.go:84 msgid "Settings are busy" msgstr "Настройки заняты" @@ -2465,7 +2477,7 @@ msgstr "подмигивание" msgid "{0} added to dictionary" msgstr "{0} добавлено в словарь" -#: internal/app/application_overrides.go:213 +#: internal/app/application_overrides.go:237 msgid "{0} application override selected" msgstr "Выбраны настройки приложения {0}"