From d3d8fc944c1bb7e95f6df0e6aa2eae578297f9ab Mon Sep 17 00:00:00 2001 From: moson-mo Date: Thu, 28 Jul 2022 12:40:18 +0200 Subject: [PATCH] refactor: a bit of renaming and restructuring Signed-off-by: moson-mo --- internal/pacseek/commands.go | 36 ++--- internal/pacseek/{show.go => display.go} | 136 +++++++++--------- internal/pacseek/draw.go | 136 +++++++++--------- internal/pacseek/pacman.go | 2 +- internal/pacseek/pacseek_test.go | 4 +- internal/pacseek/setup.go | 176 +++++++++++------------ internal/pacseek/spinner.go | 4 +- internal/pacseek/ui.go | 68 ++++----- internal/util/util.go | 11 ++ 9 files changed, 290 insertions(+), 283 deletions(-) rename internal/pacseek/{show.go => display.go} (63%) diff --git a/internal/pacseek/commands.go b/internal/pacseek/commands.go index 28f6c64..e840c1d 100644 --- a/internal/pacseek/commands.go +++ b/internal/pacseek/commands.go @@ -10,10 +10,10 @@ import ( // installs or removes a package func (ps *UI) installPackage() { - row, _ := ps.packages.GetSelection() - pkg := ps.packages.GetCell(row, 0).Text - source := ps.packages.GetCell(row, 1).Text - installed := ps.packages.GetCell(row, 2).Text + row, _ := ps.tablePackages.GetSelection() + pkg := ps.tablePackages.GetCell(row, 0).Text + source := ps.tablePackages.GetCell(row, 1).Text + installed := ps.tablePackages.GetCell(row, 2).Text // set command based on source and install status command := ps.conf.InstallCommand @@ -78,10 +78,23 @@ func (ps *UI) runCommand(command string, args []string) { // we need to reinitialize the alpm handler to get the proper install state err := ps.reinitPacmanDbs() if err != nil { - ps.showMessage(err.Error(), true) + ps.displayMessage(err.Error(), true) } } +// re-initializes the alpm handler +func (ps *UI) reinitPacmanDbs() error { + err := ps.alpmHandle.Release() + if err != nil { + return err + } + ps.alpmHandle, err = initPacmanDbs(ps.conf.PacmanDbPath, ps.conf.PacmanConfigPath, ps.filterRepos) + if err != nil { + return err + } + return nil +} + // handles SIGINT call and passes it to a cmd process func handleSigint(cmd *exec.Cmd) chan bool { quit := make(chan bool, 1) @@ -98,16 +111,3 @@ func handleSigint(cmd *exec.Cmd) chan bool { }() return quit } - -// re-initializes the alpm handler -func (ps *UI) reinitPacmanDbs() error { - err := ps.alpmHandle.Release() - if err != nil { - return err - } - ps.alpmHandle, err = initPacmanDbs(ps.conf.PacmanDbPath, ps.conf.PacmanConfigPath, ps.repos) - if err != nil { - return err - } - return nil -} diff --git a/internal/pacseek/show.go b/internal/pacseek/display.go similarity index 63% rename from internal/pacseek/show.go rename to internal/pacseek/display.go index 33e7b33..118246c 100644 --- a/internal/pacseek/show.go +++ b/internal/pacseek/display.go @@ -10,42 +10,42 @@ import ( ) // gets packages from repos/AUR and displays them -func (ps *UI) showPackages(text string) { +func (ps *UI) displayPackages(text string) { go func() { ps.locker.Lock() defer ps.locker.Unlock() - defer ps.app.QueueUpdate(func() { ps.showPackageInfo(1, 0) }) + defer ps.app.QueueUpdate(func() { ps.displayPackageInfo(1, 0) }) var packages []Package - packagesCache, foundCache := ps.searchCache.Get(text) + packagesCache, foundCache := ps.cacheSearch.Get(text) if !foundCache { - ps.startSpin() - defer ps.stopSpin() + ps.startSpinner() + defer ps.stopSpinner() var err error packages, err = searchRepos(ps.alpmHandle, text, ps.conf.SearchMode, ps.conf.SearchBy, ps.conf.MaxResults, false) if err != nil { ps.app.QueueUpdateDraw(func() { - ps.showMessage(err.Error(), true) + ps.displayMessage(err.Error(), true) }) } localPackages, err := searchRepos(ps.alpmHandle, text, ps.conf.SearchMode, ps.conf.SearchBy, ps.conf.MaxResults, true) if err != nil { ps.app.QueueUpdateDraw(func() { - ps.showMessage(err.Error(), true) + ps.displayMessage(err.Error(), true) }) } if !ps.conf.DisableAur { aurPackages, err := searchAur(ps.conf.AurRpcUrl, text, ps.conf.AurTimeout, ps.conf.SearchMode, ps.conf.SearchBy, ps.conf.MaxResults) if err != nil { ps.app.QueueUpdateDraw(func() { - ps.showMessage(err.Error(), true) + ps.displayMessage(err.Error(), true) }) } for i := 0; i < len(aurPackages); i++ { - aurPackages[i].IsInstalled = isInstalled(ps.alpmHandle, aurPackages[i].Name) + aurPackages[i].IsInstalled = isPackageInstalled(ps.alpmHandle, aurPackages[i].Name) } packages = append(packages, aurPackages...) @@ -69,7 +69,7 @@ func (ps *UI) showPackages(text string) { if len(packages) == 0 { ps.app.QueueUpdateDraw(func() { - ps.showMessage("No packages found for search-term: "+text, false) + ps.displayMessage("No packages found for search-term: "+text, false) }) } if len(packages) > ps.conf.MaxResults { @@ -92,76 +92,64 @@ func (ps *UI) showPackages(text string) { if !ps.conf.DisableCache { aurInfos := infoAur(ps.conf.AurRpcUrl, aurPkgs, ps.conf.AurTimeout) for _, pkg := range aurInfos.Results { - ps.infoCache.Set(pkg.Name, RpcResult{Results: []InfoRecord{pkg}}, time.Duration(ps.conf.CacheExpiry)*time.Minute) + ps.cacheInfo.Set(pkg.Name, RpcResult{Results: []InfoRecord{pkg}}, time.Duration(ps.conf.CacheExpiry)*time.Minute) } repoInfos := infoPacman(ps.alpmHandle, repoPkgs) for _, pkg := range repoInfos.Results { - ps.infoCache.Set(pkg.Name, RpcResult{Results: []InfoRecord{pkg}}, time.Duration(ps.conf.CacheExpiry)*time.Minute) + ps.cacheInfo.Set(pkg.Name, RpcResult{Results: []InfoRecord{pkg}}, time.Duration(ps.conf.CacheExpiry)*time.Minute) } - ps.searchCache.Set(text, packages, time.Duration(ps.conf.CacheExpiry)*time.Minute) + ps.cacheSearch.Set(text, packages, time.Duration(ps.conf.CacheExpiry)*time.Minute) } } else { packages = packagesCache.([]Package) } ps.shownPackages = packages - // rank packages and save index of closest one to search term - bestMatch := 0 - prevRank := 9999 - for i := 0; i < len(packages); i++ { - rank := fuzzy.RankMatch(text, packages[i].Name) - if rank < prevRank { - bestMatch = i - prevRank = rank - } - if rank == 0 { - break - } - } + best := bestMatch(text, packages) + 1 // draw packages ps.app.QueueUpdateDraw(func() { - if text != ps.search.GetText() { + if text != ps.inputSearch.GetText() { return } - ps.drawPackages(packages) - if ps.right.GetItem(0) == ps.settings { - ps.right.Clear() - ps.right.AddItem(ps.details, 0, 1, false) + ps.drawPackageListContent(packages) + if ps.flexRight.GetItem(0) == ps.formSettings { + ps.flexRight.Clear() + ps.flexRight.AddItem(ps.tableDetails, 0, 1, false) } - ps.packages.Select(bestMatch+1, 0) // select the best match + ps.tablePackages.Select(best, 0) // select the best match }) }() } // retrieves package information from repo/AUR and displays them -func (ps *UI) showPackageInfo(row, column int) { - if row == -1 || row+1 > ps.packages.GetRowCount() { +func (ps *UI) displayPackageInfo(row, column int) { + if row == -1 || row+1 > ps.tablePackages.GetRowCount() { return } - ps.details.SetTitle("") - ps.details.Clear() - pkg := ps.packages.GetCell(row, 0).Text - source := ps.packages.GetCell(row, 1).Text + ps.tableDetails.SetTitle("") + ps.tableDetails.Clear() + pkg := ps.tablePackages.GetCell(row, 0).Text + source := ps.tablePackages.GetCell(row, 1).Text go func() { - infoCached, foundCached := ps.infoCache.Get(pkg) + infoCached, foundCached := ps.cacheInfo.Get(pkg) if source == "AUR" && !foundCached { time.Sleep(time.Duration(ps.conf.AurSearchDelay) * time.Millisecond) } - if !ps.isSelected(pkg, true) { + if !ps.isPackageSelected(pkg, true) { return } ps.app.QueueUpdateDraw(func() { - ps.details.SetTitle(" [::b]" + pkg + " - Retrieving data... ") + ps.tableDetails.SetTitle(" [::b]" + pkg + " - Retrieving data... ") }) ps.locker.Lock() if !foundCached { - ps.startSpin() - defer ps.stopSpin() + ps.startSpinner() + defer ps.stopSpinner() } defer ps.locker.Unlock() @@ -173,7 +161,7 @@ func (ps *UI) showPackageInfo(row, column int) { info = infoPacman(ps.alpmHandle, []string{pkg}) } if !ps.conf.DisableCache { - ps.infoCache.Set(pkg, info, time.Duration(ps.conf.CacheExpiry)*time.Minute) + ps.cacheInfo.Set(pkg, info, time.Duration(ps.conf.CacheExpiry)*time.Minute) } } else { info = infoCached.(RpcResult) @@ -181,7 +169,7 @@ func (ps *UI) showPackageInfo(row, column int) { // draw results ps.app.QueueUpdateDraw(func() { - if !ps.isSelected(pkg, false) { + if !ps.isPackageSelected(pkg, false) { return } if len(info.Results) != 1 { @@ -189,42 +177,42 @@ func (ps *UI) showPackageInfo(row, column int) { if info.Error != "" { errorMsg = info.Error } - ps.details.SetTitle(" [red]Error ") - ps.details.SetCellSimple(0, 0, "[red]"+errorMsg) + ps.tableDetails.SetTitle(" [red]Error ") + ps.tableDetails.SetCellSimple(0, 0, "[red]"+errorMsg) return } ps.selectedPackage = &info.Results[0] - _, _, w, _ := ps.root.GetRect() + _, _, w, _ := ps.flexRoot.GetRect() ps.drawPackageInfo(info.Results[0], w) }) }() } -// shows status bar with error message -func (ps *UI) showMessage(message string, isError bool) { +// displays status bar with error message +func (ps *UI) displayMessage(message string, isError bool) { txt := message if isError { txt = "[red]Error: " + message } - ps.status.SetText(txt) - ps.root.ResizeItem(ps.status, 3, 1) + ps.textMessage.SetText(txt) + ps.flexRoot.ResizeItem(ps.textMessage, 3, 1) go func() { ps.messageLocker.Lock() defer ps.messageLocker.Unlock() time.Sleep(10 * time.Second) ps.app.QueueUpdateDraw(func() { - ps.root.ResizeItem(ps.status, 0, 0) + ps.flexRoot.ResizeItem(ps.textMessage, 0, 0) }) }() } -// show help text -func (ps *UI) showHelp() { - ps.details.Clear(). +// displays help text +func (ps *UI) displayHelp() { + ps.tableDetails.Clear(). SetTitle(" [::b]Usage ") - ps.details.SetCellSimple(0, 0, "ENTER: Search; Install or remove a selected package"). + ps.tableDetails.SetCellSimple(0, 0, "ENTER: Search; Install or remove a selected package"). SetCellSimple(1, 0, "TAB / CTRL+Up/Down/Right/Left: Navigate between boxes"). SetCellSimple(2, 0, "Up/Down: Navigate within package list"). SetCellSimple(3, 0, "Shift+Left/Right: Change size of package list"). @@ -236,10 +224,10 @@ func (ps *UI) showHelp() { SetCellSimple(10, 0, "CTRL+Q / ESC: Quit") } -// show about text -func (ps *UI) showAbout() { - ps.details.SetTitle(" [::b]About ") - ps.details.Clear(). +// displays about text +func (ps *UI) displayAbout() { + ps.tableDetails.SetTitle(" [::b]About ") + ps.tableDetails.Clear(). SetCell(0, 0, &tview.TableCell{ Text: "[::b]Version", Color: ps.conf.Colors().Accent, @@ -267,16 +255,16 @@ func (ps *UI) showAbout() { ` s := 3 for i, l := range tview.WordWrap(pic, 100) { - ps.details.SetCellSimple(s+i, 0, l) + ps.tableDetails.SetCellSimple(s+i, 0, l) } } // checks if a given package is currently selected in the package list -func (ps *UI) isSelected(pkg string, queue bool) bool { +func (ps *UI) isPackageSelected(pkg string, queue bool) bool { var sel string f := func() { - crow, _ := ps.packages.GetSelection() - sel = ps.packages.GetCell(crow, 0).Text + crow, _ := ps.tablePackages.GetSelection() + sel = ps.tablePackages.GetCell(crow, 0).Text } if queue { @@ -287,3 +275,21 @@ func (ps *UI) isSelected(pkg string, queue bool) bool { return sel == pkg } + +// returns index of best matching package name +func bestMatch(text string, packages []Package) int { + // rank packages and save index of closest one to search term + bestMatch := 0 + prevRank := 9999 + for i := 0; i < len(packages); i++ { + rank := fuzzy.RankMatch(text, packages[i].Name) + if rank < prevRank { + bestMatch = i + prevRank = rank + } + if rank == 0 { + break + } + } + return bestMatch +} diff --git a/internal/pacseek/draw.go b/internal/pacseek/draw.go index 0b7a188..bf85f35 100644 --- a/internal/pacseek/draw.go +++ b/internal/pacseek/draw.go @@ -16,7 +16,7 @@ import ( // draws input fields on settings form func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands bool) { - ps.settings.Clear(false) + ps.formSettings.Clear(false) mode := 0 if ps.conf.SearchMode != "StartsWith" { mode = 1 @@ -34,18 +34,18 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b } // input fields - ps.settings.AddDropDown("Color scheme: ", config.ColorSchemes(), cIndex, nil) - if dd, ok := ps.settings.GetFormItemByLabel("Color scheme: ").(*tview.DropDown); ok { + ps.formSettings.AddDropDown("Color scheme: ", config.ColorSchemes(), cIndex, nil) + if dd, ok := ps.formSettings.GetFormItemByLabel("Color scheme: ").(*tview.DropDown); ok { dd.SetSelectedFunc(func(text string, index int) { ps.conf.SetColorScheme(text) - ps.setupColors() + ps.applyColors() if text != ps.conf.ColorScheme { ps.settingsChanged = true } }) } - ps.settings.AddDropDown("Border style: ", config.BorderStyles(), bIndex, nil) - if dd, ok := ps.settings.GetFormItemByLabel("Border style: ").(*tview.DropDown); ok { + ps.formSettings.AddDropDown("Border style: ", config.BorderStyles(), bIndex, nil) + if dd, ok := ps.formSettings.GetFormItemByLabel("Border style: ").(*tview.DropDown); ok { dd.SetSelectedFunc(func(text string, index int) { ps.conf.SetBorderStyle(text) if text != ps.conf.BorderStyle { @@ -53,27 +53,27 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b } }) } - ps.settings.AddCheckbox("Disable AUR: ", disableAur, func(checked bool) { + ps.formSettings.AddCheckbox("Disable AUR: ", disableAur, func(checked bool) { ps.settingsChanged = true ps.drawSettingsFields(checked, disableCache, separateAurCommands) - ps.app.SetFocus(ps.settings) + ps.app.SetFocus(ps.formSettings) }) if !disableAur { - ps.settings.AddInputField("AUR RPC URL: ", ps.conf.AurRpcUrl, 40, nil, sc). + ps.formSettings.AddInputField("AUR RPC URL: ", ps.conf.AurRpcUrl, 40, nil, sc). AddInputField("AUR timeout (ms): ", strconv.Itoa(ps.conf.AurTimeout), 6, nil, sc). AddInputField("AUR search delay (ms): ", strconv.Itoa(ps.conf.AurSearchDelay), 6, nil, sc) } - ps.settings.AddCheckbox("Disable Cache: ", disableCache, func(checked bool) { + ps.formSettings.AddCheckbox("Disable Cache: ", disableCache, func(checked bool) { ps.settingsChanged = true - i, _ := ps.settings.GetFocusedItemIndex() + i, _ := ps.formSettings.GetFocusedItemIndex() ps.drawSettingsFields(disableAur, checked, separateAurCommands) - ps.settings.SetFocus(i) - ps.app.SetFocus(ps.settings) + ps.formSettings.SetFocus(i) + ps.app.SetFocus(ps.formSettings) }) if !disableCache { - ps.settings.AddInputField("Cache expiry (m): ", strconv.Itoa(ps.conf.CacheExpiry), 6, nil, sc) + ps.formSettings.AddInputField("Cache expiry (m): ", strconv.Itoa(ps.conf.CacheExpiry), 6, nil, sc) } - ps.settings.AddInputField("Max search results: ", strconv.Itoa(ps.conf.MaxResults), 6, nil, sc). + ps.formSettings.AddInputField("Max search results: ", strconv.Itoa(ps.conf.MaxResults), 6, nil, sc). AddDropDown("Search mode: ", []string{"StartsWith", "Contains"}, mode, func(text string, index int) { if text != ps.conf.SearchMode { ps.settingsChanged = true @@ -88,10 +88,10 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b AddInputField("Pacman config path: ", ps.conf.PacmanConfigPath, 40, nil, sc). AddCheckbox("Separate AUR commands: ", separateAurCommands, func(checked bool) { ps.settingsChanged = true - i, _ := ps.settings.GetFocusedItemIndex() + i, _ := ps.formSettings.GetFocusedItemIndex() ps.drawSettingsFields(disableAur, disableCache, checked) - ps.settings.SetFocus(i) - ps.app.SetFocus(ps.settings) + ps.formSettings.SetFocus(i) + ps.app.SetFocus(ps.formSettings) }) if separateAurCommands { icom := ps.conf.AurInstallCommand @@ -102,23 +102,23 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b if ucom == "" { ucom = ps.conf.SysUpgradeCommand } - ps.settings.AddInputField("AUR Install command: ", icom, 40, nil, sc). + ps.formSettings.AddInputField("AUR Install command: ", icom, 40, nil, sc). AddInputField("AUR Upgrade command: ", ucom, 40, nil, sc) } - ps.settings.AddInputField("Install command: ", ps.conf.InstallCommand, 40, nil, sc). + ps.formSettings.AddInputField("Install command: ", ps.conf.InstallCommand, 40, nil, sc). AddInputField("Upgrade command: ", ps.conf.SysUpgradeCommand, 40, nil, sc). AddInputField("Uninstall command: ", ps.conf.UninstallCommand, 40, nil, sc) - ps.setupDropDownColors() + ps.applyDropDownColors() // key bindings - ps.settings.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + ps.formSettings.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { // CTRL + Left navigates to the previous control if event.Key() == tcell.KeyLeft && event.Modifiers() == tcell.ModCtrl { - if ps.prevControl != nil { - ps.app.SetFocus(ps.prevControl) + if ps.prevComponent != nil { + ps.app.SetFocus(ps.prevComponent) } else { - ps.app.SetFocus(ps.packages) + ps.app.SetFocus(ps.tablePackages) } return nil } @@ -126,9 +126,9 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b if event.Key() == tcell.KeyDown || event.Key() == tcell.KeyUp || event.Key() == tcell.KeyTab { - i, b := ps.settings.GetFocusedItemIndex() + i, b := ps.formSettings.GetFocusedItemIndex() if b > -1 { - i = ps.settings.GetFormItemCount() + b + i = ps.formSettings.GetFormItemCount() + b } n := i if event.Key() == tcell.KeyUp { @@ -136,25 +136,25 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b } else { n++ // move down } - if i >= 0 && i < ps.settings.GetFormItemCount() { + if i >= 0 && i < ps.formSettings.GetFormItemCount() { // drop downs are excluded from Up / Down handling - if _, ok := ps.settings.GetFormItem(i).(*tview.DropDown); ok { + if _, ok := ps.formSettings.GetFormItem(i).(*tview.DropDown); ok { if event.Key() != tcell.KeyTAB && event.Modifiers() != tcell.ModCtrl { return event } } } // Leave settings from - if b == ps.settings.GetButtonCount()-1 && event.Key() != tcell.KeyUp { - ps.app.SetFocus(ps.search) + if b == ps.formSettings.GetButtonCount()-1 && event.Key() != tcell.KeyUp { + ps.app.SetFocus(ps.inputSearch) return nil } if i == 0 && event.Key() == tcell.KeyUp { - ps.app.SetFocus(ps.packages) + ps.app.SetFocus(ps.tablePackages) return nil } - ps.settings.SetFocus(n) - ps.app.SetFocus(ps.settings) + ps.formSettings.SetFocus(n) + ps.app.SetFocus(ps.formSettings) return nil } return event @@ -163,8 +163,8 @@ func (ps *UI) drawSettingsFields(disableAur, disableCache, separateAurCommands b // draw package information on screen func (ps *UI) drawPackageInfo(i InfoRecord, width int) { - ps.details.Clear() - ps.details.SetTitle(" [::b]"+i.Name+" ").SetBorderPadding(1, 1, 1, 1) + ps.tableDetails.Clear() + ps.tableDetails.SetTitle(" [::b]"+i.Name+" ").SetBorderPadding(1, 1, 1, 1) r := 0 ln := 0 @@ -178,14 +178,14 @@ func (ps *UI) drawPackageInfo(i InfoRecord, width int) { w := width - (int(float64(width)*(float64(ps.leftProportion)/10)) + 21) // left box = 40% size, then we use 13 characters for column 0, 2 for padding and 6 for borders lines := tview.WordWrap(v, w) mr := r - ps.details.SetCell(r, 0, &tview.TableCell{ + ps.tableDetails.SetCell(r, 0, &tview.TableCell{ Text: "[::b]" + k, Color: ps.conf.Colors().Accent, BackgroundColor: tcell.ColorBlack, }) for _, l := range lines { if mr != r { - ps.details.SetCellSimple(r, 0, "") // we need to add some blank content otherwise it looks weird with some terminal configs + ps.tableDetails.SetCellSimple(r, 0, "") // we need to add some blank content otherwise it looks weird with some terminal configs } cell := &tview.TableCell{ Text: l, @@ -198,21 +198,21 @@ func (ps *UI) drawPackageInfo(i InfoRecord, width int) { return true }) } - ps.details.SetCell(r, 1, cell) + ps.tableDetails.SetCell(r, 1, cell) r++ } ln++ } } - ps.details.ScrollToBeginning() + ps.tableDetails.ScrollToBeginning() } // draw packages on screen -func (ps *UI) drawPackages(packages []Package) { - ps.packages.Clear() +func (ps *UI) drawPackageListContent(packages []Package) { + ps.tablePackages.Clear() // header - ps.drawPackagesHeader() + ps.drawPackageListHeader() // rows for i, pkg := range packages { @@ -225,28 +225,28 @@ func (ps *UI) drawPackages(packages []Package) { color = ps.conf.Colors().PackagelistSourceAUR } - ps.packages.SetCellSimple(i+1, 0, pkg.Name) - ps.packages.SetCell(i+1, 1, &tview.TableCell{ + ps.tablePackages.SetCellSimple(i+1, 0, pkg.Name) + ps.tablePackages.SetCell(i+1, 1, &tview.TableCell{ Text: pkg.Source, Color: color, BackgroundColor: tcell.ColorBlack, }) - ps.packages.SetCell(i+1, 2, &tview.TableCell{ + ps.tablePackages.SetCell(i+1, 2, &tview.TableCell{ Text: installed, Expansion: 1000, Color: tcell.ColorWhite, BackgroundColor: tcell.ColorBlack, }) } - ps.packages.ScrollToBeginning() + ps.tablePackages.ScrollToBeginning() } // adds header row to package table -func (ps *UI) drawPackagesHeader() { +func (ps *UI) drawPackageListHeader() { columns := []string{"Package", "Source", "Installed"} for i, col := range columns { col := col - ps.packages.SetCell(0, i, &tview.TableCell{ + ps.tablePackages.SetCell(0, i, &tview.TableCell{ Text: col, NotSelectable: true, Color: ps.conf.Colors().PackagelistHeader, @@ -254,11 +254,11 @@ func (ps *UI) drawPackagesHeader() { Clicked: func() bool { switch col { case "Package": - ps.sortAndRedrawPkgList('N') + ps.sortAndRedrawPackageList('N') case "Source": - ps.sortAndRedrawPkgList('S') + ps.sortAndRedrawPackageList('S') case "Installed": - ps.sortAndRedrawPkgList('I') + ps.sortAndRedrawPackageList('I') } return true }, @@ -267,11 +267,11 @@ func (ps *UI) drawPackagesHeader() { } // sorts and redraws the list of packages -func (ps *UI) sortAndRedrawPkgList(runeKey rune) { +func (ps *UI) sortAndRedrawPackageList(runeKey rune) { // n - sort by name switch runeKey { case 'N': // sort by name - if ps.sortAsc { + if ps.sortAscending { sort.Slice(ps.shownPackages, func(i, j int) bool { return ps.shownPackages[i].Name > ps.shownPackages[j].Name }) @@ -281,7 +281,7 @@ func (ps *UI) sortAndRedrawPkgList(runeKey rune) { }) } case 'S': // sort by source - if ps.sortAsc { + if ps.sortAscending { sort.Slice(ps.shownPackages, func(i, j int) bool { if ps.shownPackages[i].Source == ps.shownPackages[j].Source { return ps.shownPackages[j].Name > ps.shownPackages[i].Name @@ -297,7 +297,7 @@ func (ps *UI) sortAndRedrawPkgList(runeKey rune) { }) } case 'I': // sort by installed state - if ps.sortAsc { + if ps.sortAscending { sort.Slice(ps.shownPackages, func(i, j int) bool { if ps.shownPackages[i].IsInstalled == ps.shownPackages[j].IsInstalled { return ps.shownPackages[j].Name > ps.shownPackages[i].Name @@ -313,7 +313,7 @@ func (ps *UI) sortAndRedrawPkgList(runeKey rune) { }) } case 'M': // sort by last modified date - if ps.sortAsc { + if ps.sortAscending { sort.Slice(ps.shownPackages, func(i, j int) bool { return ps.shownPackages[i].LastModified > ps.shownPackages[j].LastModified }) @@ -323,7 +323,7 @@ func (ps *UI) sortAndRedrawPkgList(runeKey rune) { }) } case 'P': // sort by popularity - if ps.sortAsc { + if ps.sortAscending { sort.Slice(ps.shownPackages, func(i, j int) bool { if ps.shownPackages[i].Popularity == ps.shownPackages[j].Popularity { return ps.shownPackages[j].Name > ps.shownPackages[i].Name @@ -339,9 +339,9 @@ func (ps *UI) sortAndRedrawPkgList(runeKey rune) { }) } } - ps.sortAsc = !ps.sortAsc - ps.drawPackages(ps.shownPackages) - ps.packages.Select(1, 0) + ps.sortAscending = !ps.sortAscending + ps.drawPackageListContent(ps.shownPackages) + ps.tablePackages.Select(1, 0) } // composes a map with fields and values (package information) for our details box @@ -416,27 +416,27 @@ func getDependenciesJoined(i InfoRecord) string { // updates the "install state" of all packages in cache and package list func (ps *UI) updateInstalledState() { // update cached packages - sterm := ps.search.GetText() - cpkg, exp, found := ps.searchCache.GetWithExpiration(sterm) + sterm := ps.inputSearch.GetText() + cpkg, exp, found := ps.cacheSearch.GetWithExpiration(sterm) if found { scpkg := cpkg.([]Package) for i := 0; i < len(scpkg); i++ { - scpkg[i].IsInstalled = isInstalled(ps.alpmHandle, scpkg[i].Name) + scpkg[i].IsInstalled = isPackageInstalled(ps.alpmHandle, scpkg[i].Name) } - ps.searchCache.Set(sterm, scpkg, exp.Sub(time.Now())) + ps.cacheSearch.Set(sterm, scpkg, exp.Sub(time.Now())) } // update currently shown packages - for i := 1; i < ps.packages.GetRowCount(); i++ { + for i := 1; i < ps.tablePackages.GetRowCount(); i++ { newCell := &tview.TableCell{ Text: "-", Expansion: 1000, Color: tcell.ColorWhite, BackgroundColor: tcell.ColorBlack, } - if isInstalled(ps.alpmHandle, ps.packages.GetCell(i, 0).Text) { + if isPackageInstalled(ps.alpmHandle, ps.tablePackages.GetCell(i, 0).Text) { newCell.Text = "Y" } - ps.packages.SetCell(i, 2, newCell) + ps.tablePackages.SetCell(i, 2, newCell) } } diff --git a/internal/pacseek/pacman.go b/internal/pacseek/pacman.go index 7cf9b7f..8b0cb12 100644 --- a/internal/pacseek/pacman.go +++ b/internal/pacseek/pacman.go @@ -85,7 +85,7 @@ func searchRepos(h *alpm.Handle, term string, mode string, by string, maxResults } // checks the local db if a package is installed -func isInstalled(h *alpm.Handle, pkg string) bool { +func isPackageInstalled(h *alpm.Handle, pkg string) bool { local, err := h.LocalDB() if err != nil { return false diff --git a/internal/pacseek/pacseek_test.go b/internal/pacseek/pacseek_test.go index c29b95f..060ae6a 100644 --- a/internal/pacseek/pacseek_test.go +++ b/internal/pacseek/pacseek_test.go @@ -88,11 +88,11 @@ func (suite *pacseekTestSuite) TestIsInstalled() { suite.Nil(err, err) // ok - r := isInstalled(h, "glibc") + r := isPackageInstalled(h, "glibc") suite.True(r, "glibc not installed?") // nok - r = isInstalled(h, "nonsense_nonsense") + r = isPackageInstalled(h, "nonsense_nonsense") suite.False(r, "nonsense_nonsense is installed?") } diff --git a/internal/pacseek/setup.go b/internal/pacseek/setup.go index 12cae51..b455fa8 100644 --- a/internal/pacseek/setup.go +++ b/internal/pacseek/setup.go @@ -10,79 +10,79 @@ import ( ) // sets up all our ui components -func (ps *UI) setupComponents() { +func (ps *UI) createComponents() { // flex grids - ps.root = tview.NewFlex().SetDirection(tview.FlexRow) - ps.container = tview.NewFlex() - ps.left = tview.NewFlex().SetDirection(tview.FlexRow) - ps.topleft = tview.NewFlex() - ps.right = tview.NewFlex().SetDirection(tview.FlexRow) + ps.flexRoot = tview.NewFlex().SetDirection(tview.FlexRow) + ps.flexContainer = tview.NewFlex() + ps.flexLeft = tview.NewFlex().SetDirection(tview.FlexRow) + ps.flexTopLeft = tview.NewFlex() + ps.flexRight = tview.NewFlex().SetDirection(tview.FlexRow) // components - ps.search = tview.NewInputField() - ps.packages = tview.NewTable() - ps.details = tview.NewTable() + ps.inputSearch = tview.NewInputField() + ps.tablePackages = tview.NewTable() + ps.tableDetails = tview.NewTable() ps.spinner = tview.NewTextView() - ps.settings = tview.NewForm() - ps.status = tview.NewTextView() + ps.formSettings = tview.NewForm() + ps.textMessage = tview.NewTextView() // component config - ps.root.SetBorder(true). + ps.flexRoot.SetBorder(true). SetTitle(" [::b]pacseek - v" + version + " "). SetTitleAlign(tview.AlignLeft) - ps.search.SetLabelStyle(tcell.StyleDefault.Bold(true)). + ps.inputSearch.SetLabelStyle(tcell.StyleDefault.Bold(true)). SetBorder(true) - ps.details.SetBorder(true). + ps.tableDetails.SetBorder(true). SetTitleAlign(tview.AlignLeft). SetBorderPadding(1, 1, 1, 1) - ps.showHelp() - ps.packages.SetSelectable(true, false). + ps.displayHelp() + ps.tablePackages.SetSelectable(true, false). SetFixed(1, 1). SetBorder(true). SetTitleAlign(tview.AlignLeft) ps.spinner.SetText(""). SetBorder(true) - ps.settings. + ps.formSettings. SetItemPadding(0). SetBorder(true). SetTitle(" [::b]Settings "). SetTitleAlign(tview.AlignLeft) - ps.status.SetDynamicColors(true). + ps.textMessage.SetDynamicColors(true). SetBorder(true) // layouting ps.leftProportion = 4 - ps.root.AddItem(ps.container, 0, 1, true). - AddItem(ps.status, 0, 0, false) - ps.container.AddItem(ps.left, 0, ps.leftProportion, true). - AddItem(ps.right, 0, 10-ps.leftProportion, false) - ps.left.AddItem(ps.topleft, 3, 1, true). - AddItem(ps.packages, 0, 1, false) - ps.topleft.AddItem(ps.search, 0, 1, true). + ps.flexRoot.AddItem(ps.flexContainer, 0, 1, true). + AddItem(ps.textMessage, 0, 0, false) + ps.flexContainer.AddItem(ps.flexLeft, 0, ps.leftProportion, true). + AddItem(ps.flexRight, 0, 10-ps.leftProportion, false) + ps.flexLeft.AddItem(ps.flexTopLeft, 3, 1, true). + AddItem(ps.tablePackages, 0, 1, false) + ps.flexTopLeft.AddItem(ps.inputSearch, 0, 1, true). AddItem(ps.spinner, 3, 1, false) - ps.right.AddItem(ps.details, 0, 1, false) + ps.flexRight.AddItem(ps.tableDetails, 0, 1, false) } // apply colors from color scheme -func (ps *UI) setupColors() { +func (ps *UI) applyColors() { // containers - ps.root.SetTitleColor(ps.conf.Colors().Title) - ps.settings.SetTitleColor(ps.conf.Colors().Title) - ps.details.SetTitleColor(ps.conf.Colors().Title) - ps.search.SetFieldBackgroundColor(ps.conf.Colors().SearchBar) + ps.flexRoot.SetTitleColor(ps.conf.Colors().Title) + ps.formSettings.SetTitleColor(ps.conf.Colors().Title) + ps.tableDetails.SetTitleColor(ps.conf.Colors().Title) + ps.inputSearch.SetFieldBackgroundColor(ps.conf.Colors().SearchBar) // settings form - ps.settings.SetFieldBackgroundColor(ps.conf.Colors().SettingsFieldBackground). + ps.formSettings.SetFieldBackgroundColor(ps.conf.Colors().SettingsFieldBackground). SetFieldTextColor(ps.conf.Colors().SettingsFieldText). SetButtonBackgroundColor(ps.conf.Colors().SettingsFieldBackground). SetButtonTextColor(ps.conf.Colors().SettingsFieldText). SetLabelColor(ps.conf.Colors().SettingsFieldLabel) - ps.setupDropDownColors() + ps.applyDropDownColors() // package list - ps.drawPackagesHeader() - for i := 1; i < ps.packages.GetRowCount(); i++ { - c := ps.packages.GetCell(i, 1) + ps.drawPackageListHeader() + for i := 1; i < ps.tablePackages.GetRowCount(); i++ { + c := ps.tablePackages.GetCell(i, 1) col := ps.conf.Colors().PackagelistSourceRepository if c.Text == "AUR" { col = ps.conf.Colors().PackagelistSourceAUR @@ -91,17 +91,15 @@ func (ps *UI) setupColors() { } // details - if ps.details.GetCell(0, 0) != nil && ps.details.GetCell(0, 0).Text == "[::b]Description" { - for i := 0; i < ps.details.GetRowCount(); i++ { - ps.details.GetCell(i, 0).SetTextColor(ps.conf.Colors().Accent) - } + if ps.selectedPackage != nil { + ps.drawPackageInfo(*ps.selectedPackage, ps.width) } } // apply drop-down colors -func (ps *UI) setupDropDownColors() { +func (ps *UI) applyDropDownColors() { for _, title := range []string{"Search mode: ", "Search by: ", "Color scheme: ", "Border style: "} { - if dd, ok := ps.settings.GetFormItemByLabel(title).(*tview.DropDown); ok { + if dd, ok := ps.formSettings.GetFormItemByLabel(title).(*tview.DropDown); ok { dd.SetListStyles(tcell.StyleDefault.Background(ps.conf.Colors().SettingsDropdownNotSelected).Foreground(ps.conf.Colors().SettingsFieldText), tcell.StyleDefault.Background(ps.conf.Colors().SettingsFieldText).Foreground(ps.conf.Colors().SettingsDropdownNotSelected)) } @@ -109,7 +107,7 @@ func (ps *UI) setupDropDownColors() { } // replace border characters for ASCII mode -func (ps *UI) setASCIIMode() { +func (ps *UI) applyASCIIMode() { tview.Borders.Horizontal = '-' tview.Borders.HorizontalFocus = '-' tview.Borders.Vertical = '|' @@ -131,8 +129,8 @@ func (ps *UI) setASCIIMode() { func (ps *UI) setupKeyBindings() { // resize function is called when resize keys are used resize := func() { - ps.container.ResizeItem(ps.left, 0, ps.leftProportion) - ps.container.ResizeItem(ps.right, 0, 10-ps.leftProportion) + ps.flexContainer.ResizeItem(ps.flexLeft, 0, ps.leftProportion) + ps.flexContainer.ResizeItem(ps.flexRight, 0, 10-ps.leftProportion) if ps.selectedPackage != nil { ps.drawPackageInfo(*ps.selectedPackage, ps.width) } @@ -140,7 +138,7 @@ func (ps *UI) setupKeyBindings() { // app / global ps.app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { - settingsVisible := ps.right.GetItem(0) == ps.settings + settingsVisible := ps.flexRight.GetItem(0) == ps.formSettings // CTRL+Q - Quit if event.Key() == tcell.KeyCtrlQ || (event.Key() == tcell.KeyEscape && !settingsVisible) { @@ -164,12 +162,12 @@ func (ps *UI) setupKeyBindings() { if event.Key() == tcell.KeyCtrlS || (event.Key() == tcell.KeyEscape && settingsVisible) { if !settingsVisible { - ps.right.Clear() - ps.right.AddItem(ps.settings, 0, 1, false) + ps.flexRight.Clear() + ps.flexRight.AddItem(ps.formSettings, 0, 1, false) } else { - ps.right.Clear() - ps.right.AddItem(ps.details, 0, 1, false) - ps.app.SetFocus(ps.search) + ps.flexRight.Clear() + ps.flexRight.AddItem(ps.tableDetails, 0, 1, false) + ps.app.SetFocus(ps.inputSearch) if event.Key() == tcell.KeyEscape { ps.drawSettingsFields(ps.conf.DisableAur, ps.conf.DisableCache, ps.conf.AurUseDifferentCommands) ps.settingsChanged = false @@ -179,10 +177,10 @@ func (ps *UI) setupKeyBindings() { } // CTRL+N - Show help/instructions if event.Key() == tcell.KeyCtrlN { - ps.showHelp() - if ps.right.GetItem(0) == ps.settings { - ps.right.Clear() - ps.right.AddItem(ps.details, 0, 1, false) + ps.displayHelp() + if ps.flexRight.GetItem(0) == ps.formSettings { + ps.flexRight.Clear() + ps.flexRight.AddItem(ps.tableDetails, 0, 1, false) } return nil } @@ -198,14 +196,14 @@ func (ps *UI) setupKeyBindings() { } // CTRL+B - Show about if event.Key() == tcell.KeyCtrlB { - ps.showAbout() + ps.displayAbout() return nil } // CTRL+W - Wipe cache if event.Key() == tcell.KeyCtrlW { - ps.searchCache.Flush() - ps.infoCache.Flush() + ps.cacheSearch.Flush() + ps.cacheInfo.Flush() return nil } // Shift+Left - decrease size of left container @@ -238,51 +236,51 @@ func (ps *UI) setupKeyBindings() { }) // search - ps.search.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + ps.inputSearch.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { // TAB / Down if event.Key() == tcell.KeyTAB || event.Key() == tcell.KeyDown { - ps.app.SetFocus(ps.packages) + ps.app.SetFocus(ps.tablePackages) return nil } // ENTER if event.Key() == tcell.KeyEnter { - ps.lastTerm = ps.search.GetText() - if len(ps.lastTerm) < 2 { - ps.showMessage("Minimum number of characters is 2", true) + ps.lastSearchTerm = ps.inputSearch.GetText() + if len(ps.lastSearchTerm) < 2 { + ps.displayMessage("Minimum number of characters is 2", true) return nil } - ps.showPackages(ps.lastTerm) + ps.displayPackages(ps.lastSearchTerm) return nil } // CTRL+Right if event.Key() == tcell.KeyRight && event.Modifiers() == tcell.ModCtrl && - ps.right.GetItem(0) == ps.settings { - ps.app.SetFocus(ps.settings.GetFormItem(0)) - ps.prevControl = ps.search + ps.flexRight.GetItem(0) == ps.formSettings { + ps.app.SetFocus(ps.formSettings.GetFormItem(0)) + ps.prevComponent = ps.inputSearch return nil } return event }) // packages - ps.packages.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + ps.tablePackages.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { // TAB / Up - row, _ := ps.packages.GetSelection() + row, _ := ps.tablePackages.GetSelection() if event.Key() == tcell.KeyTAB || (event.Key() == tcell.KeyUp && row <= 1) || (event.Key() == tcell.KeyUp && event.Modifiers() == tcell.ModCtrl) { - if ps.right.GetItem(0) == ps.settings && event.Key() == tcell.KeyTAB { - ps.app.SetFocus(ps.settings.GetFormItem(0)) + if ps.flexRight.GetItem(0) == ps.formSettings && event.Key() == tcell.KeyTAB { + ps.app.SetFocus(ps.formSettings.GetFormItem(0)) } else { - ps.app.SetFocus(ps.search) + ps.app.SetFocus(ps.inputSearch) } return nil } // Right - if event.Key() == tcell.KeyRight && ps.right.GetItem(0) == ps.settings { - ps.app.SetFocus(ps.settings.GetFormItem(0)) - ps.prevControl = ps.packages + if event.Key() == tcell.KeyRight && ps.flexRight.GetItem(0) == ps.formSettings { + ps.app.SetFocus(ps.formSettings.GetFormItem(0)) + ps.prevComponent = ps.tablePackages return nil } // ENTER @@ -293,25 +291,25 @@ func (ps *UI) setupKeyBindings() { // sorting keys if util.SliceContains([]rune{'N', 'S', 'I', 'M', 'P'}, event.Rune()) { - ps.sortAndRedrawPkgList(event.Rune()) + ps.sortAndRedrawPackageList(event.Rune()) return nil } return event }) - ps.packages.SetSelectionChangedFunc(ps.showPackageInfo) + ps.tablePackages.SetSelectionChangedFunc(ps.displayPackageInfo) } // sets up settings form func (ps *UI) setupSettingsForm() { // Save button clicked - ps.settings.AddButton("Apply & Save", func() { + ps.formSettings.AddButton("Apply & Save", func() { ps.saveSettings(false) ps.drawSettingsFields(ps.conf.DisableAur, ps.conf.DisableCache, ps.conf.AurUseDifferentCommands) }) // Defaults button clicked - ps.settings.AddButton("Defaults", func() { + ps.formSettings.AddButton("Defaults", func() { ps.conf = config.Defaults() ps.drawSettingsFields(ps.conf.DisableAur, ps.conf.DisableCache, ps.conf.AurUseDifferentCommands) ps.saveSettings(true) @@ -324,8 +322,8 @@ func (ps *UI) setupSettingsForm() { // read settings from from and saves to config file func (ps *UI) saveSettings(defaults bool) { var err error - for i := 0; i < ps.settings.GetFormItemCount(); i++ { - item := ps.settings.GetFormItem(i) + for i := 0; i < ps.formSettings.GetFormItemCount(); i++ { + item := ps.formSettings.GetFormItem(i) if input, ok := item.(*tview.InputField); ok { txt := input.GetText() switch input.GetLabel() { @@ -334,13 +332,13 @@ func (ps *UI) saveSettings(defaults bool) { case "AUR timeout (ms): ": ps.conf.AurTimeout, err = strconv.Atoi(txt) if err != nil { - ps.showMessage("Can't convert timeout value to int", true) + ps.displayMessage("Can't convert timeout value to int", true) return } case "AUR search delay (ms): ": ps.conf.AurSearchDelay, err = strconv.Atoi(txt) if err != nil { - ps.showMessage("Can't convert delay value to int", true) + ps.displayMessage("Can't convert delay value to int", true) return } case "Pacman DB path: ": @@ -360,13 +358,13 @@ func (ps *UI) saveSettings(defaults bool) { case "Max search results: ": ps.conf.MaxResults, err = strconv.Atoi(txt) if err != nil { - ps.showMessage("Can't convert max results value to int", true) + ps.displayMessage("Can't convert max results value to int", true) return } case "Cache expiry (m): ": ps.conf.CacheExpiry, err = strconv.Atoi(txt) if err != nil { - ps.showMessage("Can't convert cache expiry value to int", true) + ps.displayMessage("Can't convert cache expiry value to int", true) return } } @@ -395,17 +393,17 @@ func (ps *UI) saveSettings(defaults bool) { } err = ps.conf.Save() if err != nil { - ps.showMessage(err.Error(), true) + ps.displayMessage(err.Error(), true) return } msg := "Settings have been applied / saved" if defaults { msg = "Default settings have been restored" } - ps.showMessage(msg, false) + ps.displayMessage(msg, false) ps.settingsChanged = false - ps.searchCache.Flush() + ps.cacheSearch.Flush() if ps.conf.DisableCache { - ps.infoCache.Flush() + ps.cacheInfo.Flush() } } diff --git a/internal/pacseek/spinner.go b/internal/pacseek/spinner.go index df1094b..0a81791 100644 --- a/internal/pacseek/spinner.go +++ b/internal/pacseek/spinner.go @@ -3,7 +3,7 @@ package pacseek import "time" // starts the spinner -func (ps *UI) startSpin() { +func (ps *UI) startSpinner() { chars := "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" if ps.asciiMode { chars = "|/-\\" @@ -27,6 +27,6 @@ func (ps *UI) startSpin() { } // stops the spinner -func (ps *UI) stopSpin() { +func (ps *UI) stopSpinner() { ps.quitSpin <- true } diff --git a/internal/pacseek/ui.go b/internal/pacseek/ui.go index fb58988..0011c6b 100644 --- a/internal/pacseek/ui.go +++ b/internal/pacseek/ui.go @@ -1,12 +1,12 @@ package pacseek import ( - "os" "sync" "time" "github.com/Jguer/go-alpm/v2" "github.com/moson-mo/pacseek/internal/config" + "github.com/moson-mo/pacseek/internal/util" "github.com/patrickmn/go-cache" "github.com/rivo/tview" ) @@ -25,19 +25,19 @@ type UI struct { alpmHandle *alpm.Handle - root *tview.Flex - left *tview.Flex - topleft *tview.Flex - right *tview.Flex - container *tview.Flex + flexRoot *tview.Flex + flexLeft *tview.Flex + flexTopLeft *tview.Flex + flexRight *tview.Flex + flexContainer *tview.Flex - search *tview.InputField - packages *tview.Table - details *tview.Table - spinner *tview.TextView - settings *tview.Form - status *tview.TextView - prevControl tview.Primitive + inputSearch *tview.InputField + tablePackages *tview.Table + tableDetails *tview.Table + spinner *tview.TextView + formSettings *tview.Form + textMessage *tview.TextView + prevComponent tview.Primitive locker *sync.RWMutex messageLocker *sync.RWMutex @@ -47,14 +47,14 @@ type UI struct { leftProportion int selectedPackage *InfoRecord settingsChanged bool - infoCache *cache.Cache - searchCache *cache.Cache - repos []string + cacheInfo *cache.Cache + cacheSearch *cache.Cache + filterRepos []string asciiMode bool shell string - lastTerm string + lastSearchTerm string shownPackages []Package - sortAsc bool + sortAscending bool } // New creates a UI object and makes sure everything is initialized @@ -66,15 +66,15 @@ func New(conf *config.Settings, repos []string, asciiMode, monoMode bool) (*UI, messageLocker: &sync.RWMutex{}, quitSpin: make(chan bool), settingsChanged: false, - infoCache: cache.New(time.Duration(conf.CacheExpiry)*time.Minute, 1*time.Minute), - searchCache: cache.New(time.Duration(conf.CacheExpiry)*time.Minute, 1*time.Minute), - repos: repos, + cacheInfo: cache.New(time.Duration(conf.CacheExpiry)*time.Minute, 1*time.Minute), + cacheSearch: cache.New(time.Duration(conf.CacheExpiry)*time.Minute, 1*time.Minute), + filterRepos: repos, asciiMode: asciiMode, - sortAsc: true, + sortAscending: true, } // get users default shell - ui.shell = getShell() + ui.shell = util.Shell() // get a handle to the pacman DB's var err error @@ -84,14 +84,14 @@ func New(conf *config.Settings, repos []string, asciiMode, monoMode bool) (*UI, } // setup UI - ui.setupComponents() + ui.createComponents() if monoMode { ui.conf.SetColorScheme("Monochrome") } if asciiMode { - ui.setASCIIMode() + ui.applyASCIIMode() } - ui.setupColors() + ui.applyColors() ui.setupKeyBindings() ui.setupSettingsForm() @@ -101,21 +101,13 @@ func New(conf *config.Settings, repos []string, asciiMode, monoMode bool) (*UI, // Start runs application / event-loop func (ps *UI) Start(term string) error { if term != "" { - ps.search.SetText(term) - ps.showPackages(term) + ps.inputSearch.SetText(term) + ps.displayPackages(term) } - return ps.app.SetRoot(ps.root, true).EnableMouse(true).Run() -} - -// get users shell -func getShell() string { - shell := os.Getenv("SHELL") - if shell == "" { - shell = "/bin/sh" // fallback - } - return shell + return ps.app.SetRoot(ps.flexRoot, true).EnableMouse(true).Run() } +// ArchRepos returns a list of Arch Linux repositories func ArchRepos() []string { return []string{"core", "community", "community-testing", "extra", "kde-unstable", "multilib", "multilib-testing", "testing"} } diff --git a/internal/util/util.go b/internal/util/util.go index 57b556a..0ac98a8 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -1,5 +1,7 @@ package util +import "os" + // SliceContains checks if a slice contains a certain element func SliceContains[T comparable](values []T, value T) bool { for _, v := range values { @@ -19,3 +21,12 @@ func IndexOf[T comparable](values []T, value T) int { } return -1 } + +// Shell returns the users default shell +func Shell() string { + shell := os.Getenv("SHELL") + if shell == "" { + shell = "/bin/sh" // fallback + } + return shell +}