v0.12.0 d035193

defaults.go RawHistoryFolder

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