v0.6.0 5c50dd3

parser_service.go RawHistoryFolder

1package services
2
3import (
4	"context"
5	"database/sql"
6	"fmt"
7
8	"github.com/bnema/dumber/internal/config"
9	"github.com/bnema/dumber/internal/db"
10	"github.com/bnema/dumber/internal/parser"
11)
12
13// ParserService wraps the parser functionality for the application.
14type ParserService struct {
15	parser    *parser.Parser
16	dbQueries *db.Queries
17}
18
19// NewParserService creates a new ParserService instance.
20func NewParserService(cfg *config.Config, queries *db.Queries) *ParserService {
21	// Create history provider from database
22	historyProvider := &DatabaseHistoryProvider{queries: queries}
23
24	// Create parser with configuration
25	p := parser.NewParser(cfg, historyProvider)
26
27	return &ParserService{
28		parser:    p,
29		dbQueries: queries,
30	}
31}
32
33// ParseInput parses user input and returns navigation result.
34func (s *ParserService) ParseInput(ctx context.Context, input string) (*parser.ParseResult, error) {
35	_ = ctx
36	if input == "" {
37		return nil, fmt.Errorf("input cannot be empty")
38	}
39
40	return s.parser.ParseInput(input)
41}
42
43// GetCompletions provides URL/search completions based on input.
44func (s *ParserService) GetCompletions(ctx context.Context, input string, limit int) ([]string, error) {
45	_ = ctx
46	if limit <= 0 {
47		limit = 10 // Default limit
48	}
49
50	return s.parser.SuggestCompletions(input, limit)
51}
52
53// FuzzySearchHistory performs fuzzy search on history entries.
54func (s *ParserService) FuzzySearchHistory(
55	ctx context.Context, query string, threshold float64,
56) ([]parser.FuzzyMatch, error) {
57	_ = ctx
58	if threshold <= 0 {
59		threshold = 0.3 // Default threshold
60	}
61
62	return s.parser.FuzzySearchHistory(query, threshold)
63}
64
65// GetSupportedShortcuts returns configured search shortcuts.
66func (s *ParserService) GetSupportedShortcuts(ctx context.Context) (map[string]config.SearchShortcut, error) {
67	_ = ctx
68	return s.parser.GetSupportedShortcuts(), nil
69}
70
71// ProcessShortcut processes a shortcut and returns the resulting URL.
72func (s *ParserService) ProcessShortcut(ctx context.Context, shortcut, query string) (string, error) {
73	_ = ctx
74	shortcuts := s.parser.GetSupportedShortcuts()
75	return s.parser.ProcessShortcut(shortcut, query, shortcuts)
76}
77
78// CalculateSimilarity calculates similarity between two strings.
79func (s *ParserService) CalculateSimilarity(ctx context.Context, s1, s2 string) (float64, error) {
80	_ = ctx
81	return s.parser.CalculateSimilarity(s1, s2), nil
82}
83
84// ValidateURL checks if the input represents a valid URL.
85func (s *ParserService) ValidateURL(ctx context.Context, input string) (bool, error) {
86	_ = ctx
87	return s.parser.IsValidURL(input), nil
88}
89
90// PreviewParse provides a preview of what ParseInput would return.
91func (s *ParserService) PreviewParse(ctx context.Context, input string) (*parser.ParseResult, error) {
92	_ = ctx
93	if input == "" {
94		return nil, fmt.Errorf("input cannot be empty")
95	}
96
97	return s.parser.PreviewParse(input)
98}
99
100// GetFuzzyConfig returns current fuzzy matching configuration.
101func (s *ParserService) GetFuzzyConfig(ctx context.Context) (*parser.FuzzyConfig, error) {
102	_ = ctx
103	return s.parser.GetFuzzyConfig(), nil
104}
105
106// UpdateFuzzyConfig updates the fuzzy matching configuration.
107func (s *ParserService) UpdateFuzzyConfig(ctx context.Context, config *parser.FuzzyConfig) error {
108	_ = ctx
109	return s.parser.UpdateFuzzyConfig(config)
110}
111
112// DatabaseHistoryProvider implements HistoryProvider using the database.
113type DatabaseHistoryProvider struct {
114	queries *db.Queries
115}
116
117// GetRecentHistory returns recent history entries limited by count.
118func (h *DatabaseHistoryProvider) GetRecentHistory(limit int) ([]*db.History, error) {
119	ctx := context.Background()
120
121	entries, err := h.queries.GetHistory(ctx, int64(limit))
122	if err != nil {
123		return nil, err
124	}
125
126	// Convert to pointer slice
127	result := make([]*db.History, len(entries))
128	for i, entry := range entries {
129		entryCopy := entry
130		result[i] = &entryCopy
131	}
132
133	return result, nil
134}
135
136// GetAllHistory returns all history entries for fuzzy search.
137func (h *DatabaseHistoryProvider) GetAllHistory() ([]*db.History, error) {
138	ctx := context.Background()
139
140	// Use a large limit to get all history
141	const allHistoryLimit = 10000
142	entries, err := h.queries.GetHistory(ctx, allHistoryLimit)
143	if err != nil {
144		return nil, err
145	}
146
147	// Convert to pointer slice
148	result := make([]*db.History, len(entries))
149	for i, entry := range entries {
150		entryCopy := entry
151		result[i] = &entryCopy
152	}
153
154	return result, nil
155}
156
157// SearchHistory performs a basic text search in history.
158func (h *DatabaseHistoryProvider) SearchHistory(query string, limit int) ([]*db.History, error) {
159	ctx := context.Background()
160
161	// Use SQL LIKE pattern for basic search
162	urlPattern := sql.NullString{String: "%" + query + "%", Valid: true}
163	titlePattern := sql.NullString{String: "%" + query + "%", Valid: true}
164
165	entries, err := h.queries.SearchHistory(ctx, urlPattern, titlePattern, int64(limit))
166	if err != nil {
167		return nil, err
168	}
169
170	// Convert to pointer slice
171	result := make([]*db.History, len(entries))
172	for i, entry := range entries {
173		entryCopy := entry
174		result[i] = &entryCopy
175	}
176
177	return result, nil
178}
179
180// GetHistoryByURL retrieves history entry by exact URL match.
181func (h *DatabaseHistoryProvider) GetHistoryByURL(url string) (*db.History, error) {
182	ctx := context.Background()
183
184	// Search for exact URL match using SearchHistory
185	urlPattern := sql.NullString{String: url, Valid: true}
186	emptyPattern := sql.NullString{Valid: false}
187
188	entries, err := h.queries.SearchHistory(ctx, urlPattern, emptyPattern, 1)
189	if err != nil {
190		return nil, err
191	}
192
193	if len(entries) == 0 {
194		return nil, fmt.Errorf("history entry not found for URL: %s", url)
195	}
196
197	return &entries[0], nil
198}

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