v0.26.0 ae3a77a

defaults.go RawHistoryFolder

1package config
2
3// Default configuration constants
4const (
5	// History defaults
6	defaultMaxHistoryEntries = 10000 // entries
7	defaultRetentionDays     = 365   // 1 year
8
9	// Dmenu defaults
10	defaultMaxHistoryDays = 30 // days
11
12	// Logging defaults
13	defaultMaxLogAgeDays = 7 // days
14
15	// Appearance defaults
16	defaultFontSize = 16 // points
17
18	// Workspace defaults
19	defaultNewPaneURL = "about:blank"
20
21	// Omnibox defaults
22	defaultOmniboxInitialBehavior   = "recent"
23	defaultOmniboxAutoOpenOnNewPane = false
24
25	// Workspace defaults
26	defaultPaneActivationShortcut    = "ctrl+p"
27	defaultPaneTimeoutMilliseconds   = 3000
28	defaultTabActivationShortcut     = "ctrl+t"
29	defaultTabTimeoutMilliseconds    = 3000
30	defaultResizeActivationShortcut  = "ctrl+n"
31	defaultResizeTimeoutMilliseconds = 3000
32	defaultResizeStepPercent         = 5.0
33	defaultResizeMinPanePercent      = 10.0
34	defaultTabBarPosition            = "bottom"
35	defaultPopupPlacement            = "right"
36
37	// Session defaults
38	defaultSessionActivationShortcut  = "ctrl+o"
39	defaultSessionTimeoutMilliseconds = 3000
40	defaultSnapshotIntervalMs         = 5000
41	defaultMaxExitedSessions          = 50
42	defaultMaxExitedSessionAgeDays    = 7
43
44	// Workspace styling defaults
45	// Active pane border (overlay)
46	defaultBorderWidth = 1
47	defaultBorderColor = "@theme_selected_bg_color"
48
49	// Mode border width (consolidated for all modes)
50	defaultModeBorderWidth = 4
51
52	// Mode colors (used for both borders and toaster)
53	defaultPaneModeColor    = "#4A90E2" // Blue for pane mode
54	defaultTabModeColor     = "#FFA500" // Orange for tab mode
55	defaultSessionModeColor = "#9B59B6" // Purple for session mode
56	defaultResizeModeColor  = "#00D4AA" // Cyan/teal for resize mode
57
58	// Mode indicator toaster
59	defaultModeIndicatorToasterEnabled = true
60
61	// Other styling
62	defaultTransitionDuration = 120
63	defaultUIScale            = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%)
64
65	// Performance defaults
66	defaultZoomCacheSize           = 256 // domains to cache (~20KB memory)
67	defaultWebViewPoolPrewarmCount = 4   // WebViews to pre-create at startup
68
69	// Skia threading defaults (0 = unset, -1 = unset for GPU threads)
70	defaultSkiaCPUPaintingThreads = 0
71	defaultSkiaGPUPaintingThreads = -1 // -1 means unset; 0 would disable GPU tile painting
72)
73
74// getDefaultLogDir returns the default log directory, falls back to empty string on error
75func getDefaultLogDir() string {
76	logDir, err := GetLogDir()
77	if err != nil {
78		return ""
79	}
80	return logDir
81}
82
83// DefaultConfig returns the default configuration values for dumber.
84func DefaultConfig() *Config {
85	return &Config{
86		Database: DatabaseConfig{
87			// Path is set dynamically in config.Load()
88		},
89		History: HistoryConfig{
90			MaxEntries:          defaultMaxHistoryEntries,
91			RetentionPeriodDays: defaultRetentionDays, // 1 year
92			CleanupIntervalDays: 1,                    // daily cleanup
93		},
94		SearchShortcuts:     GetDefaultSearchShortcuts(),
95		DefaultSearchEngine: "https://duckduckgo.com/?q=%s",
96		Dmenu: DmenuConfig{
97			MaxHistoryDays:   defaultMaxHistoryDays,
98			ShowVisitCount:   true,
99			ShowLastVisited:  true,
100			HistoryPrefix:    "🕒",
101			ShortcutPrefix:   "🔍",
102			URLPrefix:        "🌐",
103			DateFormat:       "2006-01-02 15:04",
104			SortByVisitCount: true,
105		},
106		Logging: LoggingConfig{
107			Level:          "info",
108			Format:         "text", // text or json
109			MaxAge:         defaultMaxLogAgeDays,
110			LogDir:         getDefaultLogDir(),
111			EnableFileLog:  true,
112			CaptureConsole: false, // Disabled by default
113			CaptureGTKLogs: false, // Disabled by default
114		},
115		Appearance: AppearanceConfig{
116			SansFont:        "Fira Sans",
117			SerifFont:       "Fira Sans",
118			MonospaceFont:   "Fira Code",
119			DefaultFontSize: defaultFontSize,
120			LightPalette: ColorPalette{
121				Background:     "#fafafa",
122				Surface:        "#f4f4f5",
123				SurfaceVariant: "#e4e4e7",
124				Text:           "#18181b",
125				Muted:          "#71717a",
126				Accent:         "#22c55e", // Green-500 - vibrant primary
127				Border:         "#d4d4d8",
128			},
129			DarkPalette: ColorPalette{
130				Background:     "#0a0a0b",
131				Surface:        "#18181b",
132				SurfaceVariant: "#27272a",
133				Text:           "#fafafa",
134				Muted:          "#a1a1aa",
135				Accent:         "#4ade80", // Green-400 - vibrant primary
136				Border:         "#3f3f46",
137			},
138			ColorScheme: "default", // default follows system theme
139		},
140		Debug: DebugConfig{
141			EnableDevTools: true,
142		},
143		Rendering: RenderingConfig{
144			Mode:                      RenderingModeGPU,
145			DisableDMABufRenderer:     false,
146			ForceCompositingMode:      false,
147			DisableCompositingMode:    false,
148			GSKRenderer:               GSKRendererAuto, // Let GTK choose - Vulkan can conflict with WebKit's DMA-BUF
149			DisableMipmaps:            false,
150			PreferGL:                  false,
151			DrawCompositingIndicators: false,
152			ShowFPS:                   false,
153			SampleMemory:              false,
154			DebugFrames:               false,
155		},
156		DefaultWebpageZoom: 1.2,            // 120% default zoom for better readability
157		DefaultUIScale:     defaultUIScale, // 1.0 = 100%, 2.0 = 200%
158		Workspace: WorkspaceConfig{
159			NewPaneURL:        defaultNewPaneURL,
160			SwitchToTabOnMove: true,
161			PaneMode: PaneModeConfig{
162				ActivationShortcut:  defaultPaneActivationShortcut,
163				TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
164				Actions: map[string]ActionBinding{
165					"split-right":           {Keys: []string{"arrowright", "r"}, Desc: "Split pane to the right"},
166					"split-left":            {Keys: []string{"arrowleft", "l"}, Desc: "Split pane to the left"},
167					"split-up":              {Keys: []string{"arrowup", "u"}, Desc: "Split pane upward"},
168					"split-down":            {Keys: []string{"arrowdown", "d"}, Desc: "Split pane downward"},
169					"stack-pane":            {Keys: []string{"s"}, Desc: "Stack pane with sibling"},
170					"close-pane":            {Keys: []string{"x"}, Desc: "Close current pane"},
171					"move-pane-to-tab":      {Keys: []string{"m"}, Desc: "Move pane to different tab"},
172					"move-pane-to-next-tab": {Keys: []string{"M", "shift+m"}, Desc: "Move pane to next tab"},
173
174					"consume-or-expel-left":  {Keys: []string{"["}, Desc: "Consume/expel pane left"},
175					"consume-or-expel-right": {Keys: []string{"]"}, Desc: "Consume/expel pane right"},
176					"consume-or-expel-up":    {Keys: []string{"{"}, Desc: "Consume/expel pane up"},
177					"consume-or-expel-down":  {Keys: []string{"}"}, Desc: "Consume/expel pane down"},
178
179					"focus-right": {Keys: []string{"shift+arrowright", "shift+l"}, Desc: "Focus pane to the right"},
180					"focus-left":  {Keys: []string{"shift+arrowleft", "shift+h"}, Desc: "Focus pane to the left"},
181					"focus-up":    {Keys: []string{"shift+arrowup", "shift+k"}, Desc: "Focus pane above"},
182					"focus-down":  {Keys: []string{"shift+arrowdown", "shift+j"}, Desc: "Focus pane below"},
183					"confirm":     {Keys: []string{"enter"}, Desc: "Confirm action"},
184					"cancel":      {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
185				},
186			},
187			TabMode: TabModeConfig{
188				ActivationShortcut:  defaultTabActivationShortcut,
189				TimeoutMilliseconds: defaultTabTimeoutMilliseconds,
190				Actions: map[string]ActionBinding{
191					"new-tab":      {Keys: []string{"n", "c"}, Desc: "Create new tab"},
192					"close-tab":    {Keys: []string{"x"}, Desc: "Close current tab"},
193					"next-tab":     {Keys: []string{"l", "tab"}, Desc: "Switch to next tab"},
194					"previous-tab": {Keys: []string{"h", "shift+tab"}, Desc: "Switch to previous tab"},
195					"rename-tab":   {Keys: []string{"r"}, Desc: "Rename current tab"},
196					"confirm":      {Keys: []string{"enter"}, Desc: "Confirm action"},
197					"cancel":       {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
198				},
199			},
200			ResizeMode: ResizeModeConfig{
201				ActivationShortcut:  defaultResizeActivationShortcut,
202				TimeoutMilliseconds: defaultResizeTimeoutMilliseconds,
203				StepPercent:         defaultResizeStepPercent,
204				MinPanePercent:      defaultResizeMinPanePercent,
205				Actions: map[string]ActionBinding{
206					"resize-increase-left":  {Keys: []string{"h", "arrowleft"}, Desc: "Increase size leftward"},
207					"resize-increase-down":  {Keys: []string{"j", "arrowdown"}, Desc: "Increase size downward"},
208					"resize-increase-up":    {Keys: []string{"k", "arrowup"}, Desc: "Increase size upward"},
209					"resize-increase-right": {Keys: []string{"l", "arrowright"}, Desc: "Increase size rightward"},
210					"resize-decrease-left":  {Keys: []string{"H"}, Desc: "Decrease size leftward"},
211					"resize-decrease-down":  {Keys: []string{"J"}, Desc: "Decrease size downward"},
212					"resize-decrease-up":    {Keys: []string{"K"}, Desc: "Decrease size upward"},
213					"resize-decrease-right": {Keys: []string{"L"}, Desc: "Decrease size rightward"},
214					"resize-increase":       {Keys: []string{"+", "="}, Desc: "Increase pane size"},
215					"resize-decrease":       {Keys: []string{"-"}, Desc: "Decrease pane size"},
216					"confirm":               {Keys: []string{"enter"}, Desc: "Confirm action"},
217					"cancel":                {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
218				},
219			},
220			Shortcuts: GlobalShortcutsConfig{
221				Actions: map[string]ActionBinding{
222					"close_pane":             {Keys: []string{"ctrl+w"}, Desc: "Close active pane"},
223					"next_tab":               {Keys: []string{"ctrl+tab"}, Desc: "Switch to next tab"},
224					"previous_tab":           {Keys: []string{"ctrl+shift+tab"}, Desc: "Switch to previous tab"},
225					"consume_or_expel_left":  {Keys: []string{"alt+["}, Desc: "Consume/expel pane left"},
226					"consume_or_expel_right": {Keys: []string{"alt+]"}, Desc: "Consume/expel pane right"},
227					"consume_or_expel_up":    {Keys: []string{"alt+{"}, Desc: "Consume/expel pane up"},
228					"consume_or_expel_down":  {Keys: []string{"alt+}"}, Desc: "Consume/expel pane down"},
229				},
230			},
231			TabBarPosition:          defaultTabBarPosition,
232			HideTabBarWhenSingleTab: true,
233			Popups: PopupBehaviorConfig{
234				Behavior:             PopupBehaviorSplit, // Default: open JavaScript popups in split panes
235				Placement:            defaultPopupPlacement,
236				OpenInNewPane:        true,
237				FollowPaneContext:    true,
238				BlankTargetBehavior:  "stacked", // Default: open _blank links in stacked mode
239				EnableSmartDetection: true,      // Use WindowProperties to detect popup vs tab
240				OAuthAutoClose:       true,      // Auto-close OAuth popups on success
241			},
242			Styling: WorkspaceStylingConfig{
243				BorderWidth:                 defaultBorderWidth,
244				BorderColor:                 defaultBorderColor,
245				ModeBorderWidth:             defaultModeBorderWidth,
246				PaneModeColor:               defaultPaneModeColor,
247				TabModeColor:                defaultTabModeColor,
248				SessionModeColor:            defaultSessionModeColor,
249				ResizeModeColor:             defaultResizeModeColor,
250				ModeIndicatorToasterEnabled: defaultModeIndicatorToasterEnabled,
251				TransitionDuration:          defaultTransitionDuration,
252			},
253		},
254		ContentFiltering: ContentFilteringConfig{
255			Enabled:    true, // Ad blocking enabled by default
256			AutoUpdate: true, // Auto-update filters from GitHub releases
257		},
258		Clipboard: ClipboardConfig{
259			AutoCopyOnSelection: true, // Enabled by default (zellij-style)
260		},
261		Omnibox: OmniboxConfig{
262			InitialBehavior:   defaultOmniboxInitialBehavior,
263			AutoOpenOnNewPane: defaultOmniboxAutoOpenOnNewPane,
264		},
265		Session: SessionConfig{
266			AutoRestore:             false,
267			SnapshotIntervalMs:      defaultSnapshotIntervalMs,
268			MaxExitedSessions:       defaultMaxExitedSessions,
269			MaxExitedSessionAgeDays: defaultMaxExitedSessionAgeDays,
270			SessionMode: SessionModeConfig{
271				ActivationShortcut:  defaultSessionActivationShortcut,
272				TimeoutMilliseconds: defaultSessionTimeoutMilliseconds,
273				Actions: map[string]ActionBinding{
274					"session-manager": {Keys: []string{"s", "w"}, Desc: "Open session manager"},
275					"confirm":         {Keys: []string{"enter"}, Desc: "Confirm action"},
276					"cancel":          {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
277				},
278			},
279		},
280		Media: MediaConfig{
281			HardwareDecodingMode:     HardwareDecodingAuto, // auto allows sw fallback
282			PreferAV1:                false,                // Don't force codec preference, let site choose
283			ShowDiagnosticsOnStartup: false,                // Disabled - diagnostics can be noisy
284			ForceVSync:               false,                // Let compositor handle VSync
285			GLRenderingMode:          GLRenderingModeAuto,  // GStreamer picks best GL API
286			GStreamerDebugLevel:      0,                    // Disabled by default
287		},
288		Runtime: RuntimeConfig{
289			Prefix: "",
290		},
291		Performance: PerformanceConfig{
292			Profile:                 ProfileDefault, // Use WebKit defaults, no tuning
293			ZoomCacheSize:           defaultZoomCacheSize,
294			WebViewPoolPrewarmCount: defaultWebViewPoolPrewarmCount,
295			// Skia threading - balanced defaults (unset = use WebKit defaults)
296			// These only apply when Profile is "custom"
297			SkiaCPUPaintingThreads: defaultSkiaCPUPaintingThreads,
298			SkiaGPUPaintingThreads: defaultSkiaGPUPaintingThreads,
299			SkiaEnableCPURendering: false,
300			// Web process memory pressure - all unset by default
301			WebProcessMemoryLimitMB:               0,
302			WebProcessMemoryPollIntervalSec:       0,
303			WebProcessMemoryConservativeThreshold: 0,
304			WebProcessMemoryStrictThreshold:       0,
305			// Network process memory pressure - all unset by default
306			NetworkProcessMemoryLimitMB:               0,
307			NetworkProcessMemoryPollIntervalSec:       0,
308			NetworkProcessMemoryConservativeThreshold: 0,
309			NetworkProcessMemoryStrictThreshold:       0,
310		},
311		Update: UpdateConfig{
312			EnableOnStartup:     true,  // Check for updates on startup by default
313			AutoDownload:        false, // Conservative: don't auto-download by default
314			NotifyOnNewSettings: true,  // Show toast when new config settings available
315		},
316		Downloads: DownloadsConfig{
317			Path: "", // Empty = use XDG_DOWNLOAD_DIR or ~/Downloads
318		},
319	}
320}
321
322// GetDefaultSearchShortcuts returns the default search shortcuts.
323func GetDefaultSearchShortcuts() map[string]SearchShortcut {
324	return map[string]SearchShortcut{
325		"ddg": {
326			URL:         "https://duckduckgo.com/?q=%s",
327			Description: "DuckDuckGo search",
328		},
329		"g": {
330			URL:         "https://www.google.com/search?q=%s",
331			Description: "Google search",
332		},
333		"gi": {
334			URL:         "https://www.google.com/search?tbm=isch&q=%s",
335			Description: "Google Images search",
336		},
337		"gh": {
338			URL:         "https://github.com/search?q=%s",
339			Description: "GitHub search",
340		},
341		"go": {
342			URL:         "https://pkg.go.dev/search?q=%s",
343			Description: "Go package search",
344		},
345		"mdn": {
346			URL:         "https://developer.mozilla.org/en-US/search?q=%s",
347			Description: "MDN Web Docs search",
348		},
349		"npm": {
350			URL:         "https://www.npmjs.com/search?q=%s",
351			Description: "npm package search",
352		},
353		"r": {
354			URL:         "https://www.reddit.com/search?q=%s",
355			Description: "Reddit search",
356		},
357		"so": {
358			URL:         "https://stackoverflow.com/search?q=%s",
359			Description: "Stack Overflow search",
360		},
361		"w": {
362			URL:         "https://en.wikipedia.org/wiki/%s",
363			Description: "Wikipedia search",
364		},
365		"yt": {
366			URL:         "https://www.youtube.com/results?search_query=%s",
367			Description: "YouTube search",
368		},
369	}
370}

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