Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Sources/Trimmy/AccessibilityPermissionCallout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ struct AccessibilityPermissionCallout: View {
VStack(alignment: .leading, spacing: 8) {
Label {
VStack(alignment: .leading, spacing: 2) {
Text("Accessibility needed to paste")
Text("Bedienungshilfen für Einfügen benötigt")
.font(.callout.weight(.semibold))
Text(
"Enable Trimmy in System Settings → Privacy & SecurityAccessibility "
+ "so ⌘V can be sent to the front app.")
"Trimmy in Systemeinstellungen → Datenschutz & SicherheitBedienungshilfen "
+ "aktivieren, damit ⌘V an die aktive App gesendet werden kann.")
.font(.caption)
.foregroundStyle(.secondary)
.fixedSize(horizontal: false, vertical: true)
Expand All @@ -25,13 +25,13 @@ struct AccessibilityPermissionCallout: View {
}

HStack(spacing: 10) {
Button("Grant Accessibility") {
Button("Bedienungshilfen erlauben") {
self.permissions.requestPermissionPrompt()
}
.buttonStyle(.borderedProminent)
.controlSize(self.compactButtons ? .small : .regular)

Button("Open Settings") {
Button("Einstellungen öffnen") {
self.permissions.openSystemSettings()
}
.buttonStyle(.bordered)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Trimmy/GeneralAggressiveness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public enum GeneralAggressiveness: String, CaseIterable, Identifiable, Codable,
public var title: String {
switch self {
case .none:
"None (no auto-trim)"
"Keine (kein Auto-Trim)"
case .low:
Aggressiveness.low.title
case .normal:
Expand All @@ -24,7 +24,7 @@ public enum GeneralAggressiveness: String, CaseIterable, Identifiable, Codable,

public var titleShort: String {
switch self {
case .none: "None"
case .none: "Keine"
case .low: Aggressiveness.low.titleShort
case .normal: Aggressiveness.normal.titleShort
case .high: Aggressiveness.high.titleShort
Expand All @@ -34,7 +34,7 @@ public enum GeneralAggressiveness: String, CaseIterable, Identifiable, Codable,
public var blurb: String {
switch self {
case .none:
"Skip auto-flattening for non-terminal apps. Manual “Paste Trimmed” still uses High."
"Auto-Flattening für Nicht-Terminal-Apps überspringen. Manuelles “Getrimmt einfügen” nutzt weiterhin Hoch.”
case .low:
Aggressiveness.low.blurb
case .normal:
Expand Down
14 changes: 7 additions & 7 deletions Sources/Trimmy/MenuContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ struct MenuContentView: View {
Text("Auto-Trim")
}
.toggleStyle(.checkbox)
Button("Settings…") {
Button("Einstellungen …") {
self.open(tab: .general)
}
.keyboardShortcut(",", modifiers: [.command])
Button("About Trimmy") {
Button("Über Trimmy") {
self.open(tab: .about)
}
if self.updater.isAvailable, self.updateStatus.isUpdateReady {
Button("Update ready, restart now?") { self.updater.checkForUpdates(nil) }
Button("Update bereit, jetzt neu starten?") { self.updater.checkForUpdates(nil) }
}
}
.padding(.vertical, 6)
Expand Down Expand Up @@ -139,7 +139,7 @@ struct MenuContentView: View {
extension MenuContentView {
private var pasteButtons: some View {
VStack(alignment: .leading, spacing: 4) {
Button("Paste Trimmed to \(self.targetAppLabel)\(self.trimmedStatsSuffix)") {
Button("Getrimmt einfügen in \(self.targetAppLabel)\(self.trimmedStatsSuffix)") {
self.handlePasteTrimmed()
}
.applyKeyboardShortcut(self.pasteTrimmedKeyboardShortcut)
Expand All @@ -155,7 +155,7 @@ extension MenuContentView {
let markdownPreviewSource = self.markdownPreviewSource
{
let markdownStatsSuffix = self.statsSuffix(for: markdownPreviewSource, showTruncations: true)
Button("Paste Reformatted Markdown to \(self.targetAppLabel)\(markdownStatsSuffix)") {
Button("Markdown neu formatiert einfügen in \(self.targetAppLabel)\(markdownStatsSuffix)") {
self.handlePasteReformattedMarkdown()
}
Text(self.markdownPreviewLine(for: markdownPreviewSource))
Expand All @@ -167,7 +167,7 @@ extension MenuContentView {
.frame(maxWidth: 260, alignment: .leading)
}

Button("Paste Original to \(self.targetAppLabel)\(self.originalStatsSuffix)") {
Button("Original einfügen in \(self.targetAppLabel)\(self.originalStatsSuffix)") {
self.handlePasteOriginal()
}
.applyKeyboardShortcut(self.pasteOriginalKeyboardShortcut)
Expand Down Expand Up @@ -207,7 +207,7 @@ extension MenuContentView {
original.count > trimmed.count
{
let removed = original.count - trimmed.count
return "\(base) · \(removed) trimmed"
return "\(base) · \(removed) getrimmt"
}
return base
}
Expand Down
10 changes: 5 additions & 5 deletions Sources/Trimmy/SettingsAboutPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ struct AboutPane: View {
if let buildTimestamp {
let git = Bundle.main.object(forInfoDictionaryKey: "TrimmyGitCommit") as? String
let suffix = Self.buildSuffix(for: git)
Text("Built \(buildTimestamp)\(suffix)")
Text("Erstellt \(buildTimestamp)\(suffix)")
.font(.footnote)
.foregroundStyle(.secondary)
}
Text("Paste-once, run-once clipboard cleaner for terminal snippets.")
Text("Einmal einfügen, einmal ausführen — Zwischenablage-Bereiniger für Terminal-Snippets.")
.font(.footnote)
.foregroundStyle(.secondary)
}
Expand All @@ -86,14 +86,14 @@ struct AboutPane: View {
.padding(.vertical, 8)
if updater.isAvailable {
VStack(spacing: 10) {
Toggle("Check for updates automatically", isOn: self.$autoCheckEnabled)
Toggle("Automatisch nach Updates suchen", isOn: self.$autoCheckEnabled)
.toggleStyle(.checkbox)
.frame(maxWidth: .infinity, alignment: .center)

Button("Check for Updates…") { updater.checkForUpdates(nil) }
Button("Nach Updates suchen …") { updater.checkForUpdates(nil) }
}
} else {
Text(updater.unavailableReason ?? "Updates unavailable in this build.")
Text(updater.unavailableReason ?? "Updates in diesem Build nicht verfügbar.")
.foregroundStyle(.secondary)
.padding(.top, 4)
}
Expand Down
20 changes: 10 additions & 10 deletions Sources/Trimmy/SettingsAdvancedPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ struct AdvancedSettingsPane: View {
var body: some View {
VStack(alignment: .leading, spacing: 18) {
PreferenceToggleRow(
title: "Use extra clipboard fallbacks",
subtitle: "Try RTF and public text types when plain text is missing.",
title: "Zusätzliche Zwischenablage-Fallbacks",
subtitle: "RTF und öffentliche Texttypen versuchen, wenn Klartext fehlt.",
binding: self.$settings.usePasteboardFallbacks)

self.cliInstallerSection

#if DEBUG
PreferenceToggleRow(
title: "Enable debug tools",
subtitle: "Show the Debug tab for sample previews and dev-only controls.",
title: "Debug-Werkzeuge aktivieren",
subtitle: "Debug-Tab für Vorschau und Entwickler-Optionen anzeigen.",
binding: self.$settings.debugPaneEnabled)
#endif
}
Expand All @@ -35,7 +35,7 @@ struct AdvancedSettingsPane: View {
if self.isInstallingCLI {
ProgressView().controlSize(.small)
} else {
Text("Install CLI")
Text("CLI installieren")
}
}
.disabled(self.isInstallingCLI)
Expand All @@ -48,7 +48,7 @@ struct AdvancedSettingsPane: View {
}
}

Text("Install `trimmy` into /usr/local/bin and /opt/homebrew/bin.")
Text("`trimmy` nach /usr/local/bin und /opt/homebrew/bin installieren.")
.font(.callout)
.foregroundStyle(.secondary)
.lineLimit(2)
Expand All @@ -69,7 +69,7 @@ struct AdvancedSettingsPane: View {
.appendingPathComponent("TrimmyCLI")

guard FileManager.default.isExecutableFile(atPath: helperURL.path) else {
await MainActor.run { self.cliStatus = "Helper missing; reinstall Trimmy." }
await MainActor.run { self.cliStatus = "Helper fehlt; Trimmy neu installieren." }
return
}

Expand Down Expand Up @@ -106,15 +106,15 @@ struct AdvancedSettingsPane: View {
process.waitUntilExit()
let status: String
if process.terminationStatus == 0 {
status = "Installed. Try: trimmy --help"
status = "Installiert. Teste: trimmy --help"
} else {
let data = stderrPipe.fileHandleForReading.readDataToEndOfFile()
let msg = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
status = "Failed: \(msg ?? "error")"
status = "Fehlgeschlagen: \(msg ?? "Fehler")"
}
await MainActor.run { self.cliStatus = status }
} catch {
await MainActor.run { self.cliStatus = "Failed: \(error.localizedDescription)" }
await MainActor.run { self.cliStatus = "Fehlgeschlagen: \(error.localizedDescription)" }
}
}
}
50 changes: 25 additions & 25 deletions Sources/Trimmy/SettingsAggressivenessPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct AggressivenessSettingsPane: View {
VStack(alignment: .leading, spacing: 14) {
Grid(alignment: .leading, horizontalSpacing: 16, verticalSpacing: 10) {
GridRow {
Text("General apps")
Text("Allgemeine Apps")
.frame(minWidth: 110, alignment: .leading)
Picker("", selection: self.$settings.generalAggressiveness) {
ForEach(GeneralAggressiveness.allCases) { level in
Expand All @@ -36,14 +36,14 @@ struct AggressivenessSettingsPane: View {
}

Text(
"""
Automatic trimming uses separate aggressiveness levels for regular apps and terminals. \
The terminal setting only applies when Context-aware trimming is enabled. “None” disables \
command flattening for regular apps, but manual “Paste Trimmed” always runs at High. \
Low/Normal skip code-like snippets (braces + language keywords) unless there are strong \
command cues. Leading shell prompts (#/$) are stripped when they look like commands, but \
Markdown-style headings stay.
""")
“””
Automatisches Trimmen verwendet separate Aggressivitätsstufen für normale Apps und Terminals. \
Die Terminal-Einstellung gilt nur bei aktiviertem kontextabhängigem Trimmen. „Keine” deaktiviert \
das Befehlsflattening für normale Apps, aber manuelles „Getrimmt einfügen” nutzt immer Hoch. \
Niedrig/Normal überspringen code-ähnliche Snippets (Klammern + Schlüsselwörter), außer bei \
starken Befehlshinweisen. Führende Shell-Prompts (#/$) werden entfernt, wenn sie wie Befehle \
aussehen, aber Markdown-Überschriften bleiben erhalten.
“””)
.font(.footnote)
.foregroundStyle(.tertiary)
.fixedSize(horizontal: false, vertical: true)
Expand Down Expand Up @@ -80,9 +80,9 @@ struct AggressivenessPreview: View {
.fixedSize(horizontal: false, vertical: true)

VStack(alignment: .leading, spacing: 8) {
PreviewCard(title: "Before", text: self.example.sample)
PreviewCard(title: "Vorher", text: self.example.sample)
PreviewCard(
title: "After",
title: "Nachher",
text: AggressivenessPreviewEngine.previewAfter(
for: self.example.sample,
level: self.level.coreAggressiveness,
Expand Down Expand Up @@ -165,13 +165,13 @@ struct AggressivenessExample {
switch level {
case .none:
AggressivenessExample(
title: "None keeps regular app copies intact",
caption: "Auto-trim stays off for non-terminal apps.",
sample: """
title: “Keine: Kopien aus normalen Apps bleiben unverändert”,
caption: Auto-Trim bleibt für Nicht-Terminal-Apps deaktiviert.”,
sample: “””
brew update \\
&& brew upgrade
""",
note: "Manual “Paste Trimmed” still uses High, and terminals use their own level.")
“””,
note: “Manuelles „Getrimmt einfügen” nutzt weiterhin Hoch, und Terminals verwenden ihre eigene Stufe.”)
case .low:
self.example(for: Aggressiveness.low)
case .normal:
Expand All @@ -185,33 +185,33 @@ struct AggressivenessExample {
switch level {
case .low:
AggressivenessExample(
title: "Low only flattens obvious shell commands",
caption: "Continuations plus pipes are obvious enough to collapse.",
title: "Niedrig: Nur offensichtliche Shell-Befehle zusammenfalten",
caption: "Fortsetzungen und Pipes sind offensichtlich genug zum Zusammenfalten.",
sample: """
ls -la \\
| grep '^d' \\
> dirs.txt
""",
note: "Because of the continuation, pipe, and redirect, even Low collapses this into one line.")
note: "Wegen Fortsetzung, Pipe und Redirect faltet selbst Niedrig dies in eine Zeile zusammen.")
case .normal:
AggressivenessExample(
title: "Normal flattens typical blog commands",
caption: "Perfect for README snippets with pipes or continuations.",
title: "Normal: Typische Blog-Befehle zusammenfalten",
caption: "Perfekt für README-Snippets mit Pipes oder Fortsetzungen.",
sample: """
kubectl get pods \\
-n kube-system \\
| jq '.items[].metadata.name'
""",
note: "Normal trims this to a single runnable line.")
note: "Normal trimmt dies zu einer einzigen ausführbaren Zeile.")
case .high:
AggressivenessExample(
title: "High collapses almost anything command-shaped",
caption: "Use when you want Trimmy to be bold. Even short two-liners get flattened.",
title: "Hoch: Fast alles Befehlsähnliche zusammenfalten",
caption: "Wenn Trimmy mutig sein soll. Selbst kurze Zweizeiler werden zusammengefaltet.",
sample: """
echo "hello"
print status
""",
note: "High trims this even though it barely looks like a command.")
note: "Hoch trimmt dies, obwohl es kaum wie ein Befehl aussieht.")
}
}
}
Expand Down
28 changes: 14 additions & 14 deletions Sources/Trimmy/SettingsGeneralPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,42 +12,42 @@ struct GeneralSettingsPane: View {
AccessibilityPermissionCallout(permissions: self.permissions)
}
PreferenceToggleRow(
title: "Auto-trim enabled",
subtitle: "Automatically trim clipboard content when it looks like a command.",
title: "Auto-Trim aktiviert",
subtitle: "Zwischenablage automatisch kürzen, wenn der Inhalt wie ein Befehl aussieht.",
binding: self.$settings.autoTrimEnabled)

PreferenceToggleRow(
title: "Context-aware trimming",
subtitle: "Use the terminal-specific aggressiveness when a terminal is detected "
+ "(Cmd-C + app snapshot).",
title: "Kontextabhängiges Trimmen",
subtitle: "Terminal-spezifische Aggressivität verwenden, wenn ein Terminal erkannt wird "
+ "(Cmd-C + App-Snapshot).",
binding: self.$settings.contextAwareTrimmingEnabled)

PreferenceToggleRow(
title: "Keep blank lines",
subtitle: "Preserve intentional blank lines instead of collapsing them.",
title: "Leerzeilen beibehalten",
subtitle: "Beabsichtigte Leerzeilen beibehalten statt sie zusammenzufassen.",
binding: self.$settings.preserveBlankLines)

PreferenceToggleRow(
title: "Remove box drawing chars (│┃)",
subtitle: "Strip prompt-style box gutters (any count, leading/trailing) before trimming.",
title: "Box-Drawing-Zeichen entfernen (│┃)",
subtitle: "Prompt-Box-Rahmen (beliebige Anzahl, führend/nachfolgend) vor dem Trimmen entfernen.",
binding: self.$settings.removeBoxDrawing)

PreferenceToggleRow(
title: "Show Markdown reformat option",
subtitle: "Expose a menu-only paste action that reflows markdown bullets and headings.",
title: "Markdown-Neuformatierung anzeigen",
subtitle: "Einfüge-Aktion im Menü, die Markdown-Aufzählungen und Überschriften neu formatiert.",
binding: self.$settings.showMarkdownReformatOption)

Divider()
.padding(.vertical, 4)

PreferenceToggleRow(
title: "Start at Login",
subtitle: "Automatically opens the app when you start your Mac.",
title: "Bei Anmeldung starten",
subtitle: "Öffnet die App automatisch beim Mac-Start.",
binding: self.$settings.launchAtLogin)

HStack {
Spacer()
Button("Quit Trimmy") {
Button("Trimmy beenden") {
NSApp.terminate(nil)
}
.buttonStyle(.borderedProminent)
Expand Down
Loading