v0.13.0 976176a

defaults.go RawHistoryFolder

1// Package config provides default configuration values for dumber.
2package config
3
4// Default configuration constants
5const (
6	// History defaults
7	defaultMaxHistoryEntries = 10000 // entries
8	defaultRetentionDays     = 365   // 1 year
9
10	// Dmenu defaults
11	defaultMaxHistoryItems = 20 // items
12
13	// Logging defaults
14	defaultMaxLogSizeMB  = 100 // MB
15	defaultMaxBackups    = 3   // backup files
16	defaultMaxLogAgeDays = 7   // days
17
18	// Appearance defaults
19	defaultFontSize = 16 // points
20
21	// Workspace defaults
22	defaultPaneActivationShortcut  = "ctrl+p"
23	defaultPaneTimeoutMilliseconds = 3000
24	defaultPopupPlacement          = "right"
25
26	// Workspace styling defaults
27	defaultBorderWidth         = 2
28	defaultBorderColor         = "@theme_selected_bg_color"
29	defaultPaneModeBorderColor = "#FFA500" // Orange for pane mode indicator
30	defaultTransitionDuration  = 120
31	defaultBorderRadius        = 0
32)
33
34// getDefaultLogDir returns the default log directory, falls back to empty string on error
35func getDefaultLogDir() string {
36	logDir, err := GetLogDir()
37	if err != nil {
38		return ""
39	}
40	return logDir
41}
42
43// DefaultConfig returns the default configuration values for dumber.
44func DefaultConfig() *Config {
45	return &Config{
46		Database: DatabaseConfig{
47			// Path is set dynamically in config.Load()
48		},
49		History: HistoryConfig{
50			MaxEntries:          defaultMaxHistoryEntries,
51			RetentionPeriodDays: defaultRetentionDays, // 1 year
52			CleanupIntervalDays: 1,                    // daily cleanup
53		},
54		SearchShortcuts: GetDefaultSearchShortcuts(),
55		Dmenu: DmenuConfig{
56			MaxHistoryItems:  defaultMaxHistoryItems,
57			ShowVisitCount:   true,
58			ShowLastVisited:  true,
59			HistoryPrefix:    "🕒",
60			ShortcutPrefix:   "🔍",
61			URLPrefix:        "🌐",
62			DateFormat:       "2006-01-02 15:04",
63			SortByVisitCount: true,
64		},
65		Logging: LoggingConfig{
66			Level:          "info",
67			Format:         "text",              // text or json
68			Filename:       "",                  // empty means stdout
69			MaxSize:        defaultMaxLogSizeMB, // MB
70			MaxBackups:     defaultMaxBackups,
71			MaxAge:         defaultMaxLogAgeDays, // days
72			Compress:       true,
73			LogDir:         getDefaultLogDir(),
74			EnableFileLog:  true,
75			CaptureStdout:  false,
76			CaptureStderr:  false,
77			CaptureCOutput: false, // Disabled by default to avoid performance impact
78			CaptureConsole: false, // Disabled by default
79			DebugFile:      "debug.log",
80			VerboseWebKit:  false,
81		},
82		Appearance: AppearanceConfig{
83			SansFont:        "Fira Sans",
84			SerifFont:       "Fira Sans",
85			MonospaceFont:   "Fira Code",
86			DefaultFontSize: defaultFontSize,
87			LightPalette: ColorPalette{
88				Background:     "#f8f8f8",
89				Surface:        "#f2f2f2",
90				SurfaceVariant: "#ececec",
91				Text:           "#1a1a1a",
92				Muted:          "#6e6e6e",
93				Accent:         "#404040",
94				Border:         "#d2d2d2",
95			},
96			DarkPalette: ColorPalette{
97				Background:     "#0e0e0e",
98				Surface:        "#1a1a1a",
99				SurfaceVariant: "#141414",
100				Text:           "#e4e4e4",
101				Muted:          "#848484",
102				Accent:         "#a8a8a8",
103				Border:         "#363636",
104			},
105			ColorScheme: "default", // default follows system theme
106		},
107		VideoAcceleration: VideoAccelerationConfig{
108			EnableVAAPI:      true,
109			AutoDetectGPU:    true,
110			VAAPIDriverName:  "", // Will be auto-detected
111			EnableAllDrivers: true,
112			LegacyVAAPI:      false,
113		},
114		CodecPreferences: CodecConfig{
115			PreferredCodecs:           "av1,h264",                                                                                              // AV1 first, but allow VP9 fallback for higher resolutions
116			ForceAV1:                  false,                                                                                                   // Use smart AV1 negotiation instead of forcing
117			BlockVP9:                  false,                                                                                                   // Allow VP9 for higher resolutions
118			BlockVP8:                  true,                                                                                                    // Still block VP8 as it's outdated
119			AV1HardwareOnly:           false,                                                                                                   // Allow software AV1 fallback
120			DisableVP9Hardware:        false,                                                                                                   // Allow VP9 hardware for high res content
121			VideoBufferSizeMB:         16,                                                                                                      // Larger buffer for AV1 streams
122			QueueBufferTimeSec:        10,                                                                                                      // More buffering time for smooth playback
123			CustomUserAgent:           "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", // Chrome UA with AV1 support
124			AV1MaxResolution:          "1080p", // Optimal AV1 up to 1080p, fallback to VP9 for higher res
125			DisableTwitchCodecControl: true,    // Disable codec control on Twitch by default (prevents theater/fullscreen freezing)
126		},
127		Debug: DebugConfig{
128			EnableWebKitDebug:     false,
129			WebKitDebugCategories: "Network:preconnectTo,ContentFilters",
130			EnableFilteringDebug:  false,
131			EnableWebViewDebug:    false,
132			LogWebKitCrashes:      true, // Always log crashes
133			EnableScriptDebug:     false,
134			EnableGeneralDebug:    false,
135			EnableWorkspaceDebug:  false,
136			EnableFocusDebug:      false,
137			EnableCSSDebug:        false,
138			EnableFocusMetrics:    false,
139			EnablePaneCloseDebug:  false,
140		},
141		RenderingMode: RenderingModeGPU,
142		UseDomZoom:    false,
143		DefaultZoom:   1.2, // 120% default zoom for better readability
144		Workspace: WorkspaceConfig{
145			EnableZellijControls: true,
146			PaneMode: PaneModeConfig{
147				ActivationShortcut:  defaultPaneActivationShortcut,
148				TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
149				ActionBindings: map[string]string{
150					"arrowright": "split-right",
151					"arrowleft":  "split-left",
152					"arrowup":    "split-up",
153					"arrowdown":  "split-down",
154					"r":          "split-right",
155					"l":          "split-left",
156					"u":          "split-up",
157					"d":          "split-down",
158					"x":          "close-pane",
159					"enter":      "confirm",
160					"escape":     "cancel",
161				},
162			},
163			Tabs: TabKeyConfig{
164				NewTab:      "ctrl+t",
165				CloseTab:    "ctrl+w",
166				NextTab:     "ctrl+tab",
167				PreviousTab: "ctrl+shift+tab",
168			},
169			Popups: PopupBehaviorConfig{
170				Behavior:             PopupBehaviorSplit, // Default: open popups in split panes
171				Placement:            defaultPopupPlacement,
172				OpenInNewPane:        true,
173				FollowPaneContext:    true,
174				BlankTargetBehavior:  "pane", // Default to pane, future: "tab"
175				EnableSmartDetection: true,   // Use WindowProperties to detect popup vs tab
176				OAuthAutoClose:       true,   // Auto-close OAuth popups on success
177			},
178			Styling: WorkspaceStylingConfig{
179				BorderWidth:         defaultBorderWidth,
180				BorderColor:         defaultBorderColor,
181				PaneModeBorderColor: defaultPaneModeBorderColor,
182				TransitionDuration:  defaultTransitionDuration,
183				BorderRadius:        defaultBorderRadius,
184			},
185		},
186		ContentFilteringWhitelist: []string{
187			"twitch.tv",          // Arkose Labs bot detection breaks with filtering
188			"passport.twitch.tv", // Auth subdomain
189			"gql.twitch.tv",      // GraphQL API
190		},
191	}
192}
193
194// GetDefaultSearchShortcuts returns the default search shortcuts.
195func GetDefaultSearchShortcuts() map[string]SearchShortcut {
196	return map[string]SearchShortcut{
197		"ddg": {
198			URL:         "https://duckduckgo.com/?q=%s",
199			Description: "DuckDuckGo search",
200		},
201		"g": {
202			URL:         "https://www.google.com/search?q=%s",
203			Description: "Google search",
204		},
205		"gh": {
206			URL:         "https://github.com/search?q=%s",
207			Description: "GitHub search",
208		},
209		"go": {
210			URL:         "https://pkg.go.dev/search?q=%s",
211			Description: "Go package search",
212		},
213		"mdn": {
214			URL:         "https://developer.mozilla.org/en-US/search?q=%s",
215			Description: "MDN Web Docs search",
216		},
217		"npm": {
218			URL:         "https://www.npmjs.com/search?q=%s",
219			Description: "npm package search",
220		},
221		"r": {
222			URL:         "https://www.reddit.com/search?q=%s",
223			Description: "Reddit search",
224		},
225		"so": {
226			URL:         "https://stackoverflow.com/search?q=%s",
227			Description: "Stack Overflow search",
228		},
229		"w": {
230			URL:         "https://en.wikipedia.org/wiki/%s",
231			Description: "Wikipedia search",
232		},
233		"yt": {
234			URL:         "https://www.youtube.com/results?search_query=%s",
235			Description: "YouTube search",
236		},
237	}
238}
239
240// Note: We build our own browser, so no external browser commands needed

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close