summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pik/web/deploy.sh (renamed from .pik/web/web.sh)0
-rw-r--r--README.md12
-rw-r--r--completion/completion.sh13
-rw-r--r--go.mod36
-rw-r--r--go.sum28
-rw-r--r--main.go7
-rw-r--r--menu/input.go47
-rw-r--r--menu/model.go33
-rw-r--r--menu/search.go11
-rw-r--r--menu/target.go9
-rw-r--r--runner/shell/shell.go4
11 files changed, 175 insertions, 25 deletions
diff --git a/.pik/web/web.sh b/.pik/web/deploy.sh
index 543142c..543142c 100644
--- a/.pik/web/web.sh
+++ b/.pik/web/deploy.sh
diff --git a/README.md b/README.md
index f120325..e7a5ab3 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ if you were already using `pik`, `pik install` would suffice!
thankfully you can `pik` yourself:
* `bash .pik/install.sh`
-wow! you just learned about `pik`s most obvious usage!
+wow! you just learned about `pik`s simplest usage!
## getting started
@@ -58,8 +58,6 @@ pik reads the first comment line from your targets and informs you in the tui!
* `--at` to run the target in an arbitrary location
* target tags in filenames which trigger flag behaviours
* aliases to sources through the `.alias` file
-* tui for viewing and running targets
- * descriptions for targets based on first comment in a target
* y/n confirmation with yes as default
* will be used if we have an uncertain target guess
* `--yes` to automatically confirm y/n prompts
@@ -70,6 +68,13 @@ pik reads the first comment line from your targets and informs you in the tui!
* env files are reread for every trigger, meaning you can have a pre-trigger fetch credentials and save it in .env
* create any kind of target: high-level support for shell and python, and arbitrary shells with the shebang.
+### tui
+* tui for viewing and running targets
+* descriptions for targets based on first comment in a target
+* external targets will also show up in the tui
+* search with `/` and `?`, scroll results with `n` and `N`
+
+
### supported external runners
* `just`
@@ -89,7 +94,6 @@ attach to these features.
* adding descriptions to external targets
* expand tui:
* support for categories and ordering of targets through the `.order` file
- * search
* more hotkeys (filter jumping, toggle all, etc.)
* git pre-commit and pre-push triggers
* linking sources together by `.include` and `.wants` files
diff --git a/completion/completion.sh b/completion/completion.sh
new file mode 100644
index 0000000..9cbd52c
--- /dev/null
+++ b/completion/completion.sh
@@ -0,0 +1,13 @@
+#/usr/bin/env bash
+_pik_completions()
+{
+ QUERY=""
+ for word in COMP_WORDS ; do
+ if [[ query != "-*" ]] ; then
+ QUERY="$QUERY $WORD"
+ fi
+ done
+ COMPREPLY=($(compgen -W "$(pik --list)" "${QUERY}"))
+}
+
+complete -F _pik_completions pik \ No newline at end of file
diff --git a/go.mod b/go.mod
index ac11be2..b8d9cb2 100644
--- a/go.mod
+++ b/go.mod
@@ -3,31 +3,39 @@ module github.com/ewy1/pik
go 1.26.1
require (
- github.com/adrg/xdg v0.5.3 // indirect
+ github.com/adrg/xdg v0.5.3
+ github.com/charmbracelet/bubbletea v1.3.10
+ github.com/charmbracelet/lipgloss v1.1.0
+ github.com/charmbracelet/x/term v0.2.2
+ github.com/joho/godotenv v1.5.1
+ github.com/pelletier/go-toml/v2 v2.3.0
+ github.com/spf13/pflag v1.0.10
+ github.com/stretchr/testify v1.11.1
+)
+
+require (
+ github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
- github.com/charmbracelet/bubbletea v1.3.10 // indirect
- github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
- github.com/charmbracelet/lipgloss v1.1.0 // indirect
- github.com/charmbracelet/x/ansi v0.10.1 // indirect
- github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
- github.com/charmbracelet/x/term v0.2.1 // indirect
+ github.com/charmbracelet/bubbles v1.0.0 // indirect
+ github.com/charmbracelet/colorprofile v0.4.1 // indirect
+ github.com/charmbracelet/x/ansi v0.11.6 // indirect
+ github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
+ github.com/clipperhouse/displaywidth v0.9.0 // indirect
+ github.com/clipperhouse/stringish v0.1.1 // indirect
+ github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
- github.com/joho/godotenv v1.5.1 // indirect
- github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+ github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
- github.com/mattn/go-runewidth v0.0.16 // indirect
+ github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
- github.com/pelletier/go-toml/v2 v2.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
- github.com/spf13/pflag v1.0.10 // indirect
- github.com/stretchr/testify v1.11.1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
- golang.org/x/sys v0.36.0 // indirect
+ golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.3.8 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index cc62c63..5d8fc5d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,19 +1,37 @@
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
+github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
+github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
+github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc=
+github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E=
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
+github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
+github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
+github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
+github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
+github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=
+github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
+github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
+github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
+github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA=
+github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA=
+github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
+github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
+github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=
+github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
@@ -22,12 +40,16 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
+github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
+github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
@@ -47,12 +69,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
+golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
+golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
+golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
+golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
index b2fb96c..6724cfd 100644
--- a/main.go
+++ b/main.go
@@ -139,8 +139,9 @@ func main() {
if *flags.List {
for _, s := range st.Sources {
+ _, _ = spool.Print("%v", s.Label()+paths.Ifs)
for _, t := range s.Targets {
- _, _ = spool.Print("%v\n", t.ShortestId()+paths.Ifs)
+ _, _ = spool.Print("%v", t.ShortestId()+paths.Ifs)
}
}
os.Exit(0)
@@ -169,7 +170,7 @@ func main() {
result := search.Search(st, args...)
// TODO: Move auto-all logic into Search?
- if !*flags.All && result.Target == nil && len(result.Args) > 0 {
+ if !*flags.All && result.Target == nil && len(result.Args) > 0 && SourcesWithoutResults == nil && !ForceConfirm {
ForceConfirm = true
if err != nil {
_, _ = spool.Warn("%v\n", err)
@@ -181,7 +182,7 @@ func main() {
}
if result.Target == nil {
- _, _ = spool.Warn("target not found.")
+ _, _ = spool.Warn("target not found.\n")
os.Exit(1)
return
}
diff --git a/menu/input.go b/menu/input.go
index cd07543..e2e35b3 100644
--- a/menu/input.go
+++ b/menu/input.go
@@ -3,8 +3,32 @@ package menu
import tea "github.com/charmbracelet/bubbletea"
func (m *Model) HandleInput(msg tea.KeyMsg) (tea.Cmd, error) {
+
+ if m.Search.Focused() {
+ var cmd tea.Cmd
+ switch msg.String() {
+ case "ctrl+c":
+ m.Search.SetValue("")
+ m.Search.Blur()
+ case "ctrl+d":
+ m.Search.Blur()
+ case "enter":
+ m.Search.Blur()
+ default:
+ result, c := m.Search.Update(msg)
+ cmd = c
+ m.Search = result
+ }
+ return cmd, nil
+ }
+
var cmd tea.Cmd
switch msg.String() {
+ case "/":
+ m.Search.SetValue("")
+ fallthrough
+ case "?":
+ return m.Search.Focus(), nil
case "i", "I":
if m.Alt {
m.Alt = false
@@ -23,6 +47,10 @@ func (m *Model) HandleInput(msg tea.KeyMsg) (tea.Cmd, error) {
m.Index--
case "down", "j":
m.Index++
+ case "n":
+ m.LeapFilter(1)
+ case "N":
+ m.LeapFilter(-1)
case "q", "esc", "ctrl+c":
m.Cancel = true
return tea.Quit, nil
@@ -31,11 +59,28 @@ func (m *Model) HandleInput(msg tea.KeyMsg) (tea.Cmd, error) {
return tea.Quit, nil
}
- m.Validate()
+ _ = m.Validate()
return cmd, nil
}
+func (m *Model) LeapFilter(direction int) {
+ startIndex := m.Index
+ for {
+ m.Index += direction
+ clamped := m.Validate()
+ if clamped {
+ m.Index = startIndex
+ return
+ }
+
+ source, target := m.Result()
+ if m.Highlights(source, target) {
+ return
+ }
+ }
+}
+
func (m *Model) Leap(direction int) {
for {
source, target := m.Result()
diff --git a/menu/model.go b/menu/model.go
index aa7b00e..4480c96 100644
--- a/menu/model.go
+++ b/menu/model.go
@@ -1,6 +1,7 @@
package menu
import (
+ "github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/x/term"
"github.com/ewy1/pik/model"
@@ -9,6 +10,7 @@ import (
"github.com/ewy1/pik/viewport"
"github.com/spf13/pflag"
"os"
+ "strings"
)
type Model struct {
@@ -21,9 +23,31 @@ type Model struct {
Height int
Alt bool
AutoAlt bool
+ Search textinput.Model
Motd string
}
+func (m *Model) Highlights(src *model.HydratedSource, t model.HydratedTarget) bool {
+ val := m.Search.Value()
+ if val == "" {
+ return false
+ }
+
+ if strings.Contains(t.Target().Label(), val) {
+ return true
+ }
+
+ if strings.Contains(t.Description(src), val) {
+ return true
+ }
+
+ if strings.Contains(strings.Join(append(t.Target().Sub(), t.Target().Label()), " "), val) {
+ return true
+ }
+
+ return false
+}
+
func (m *Model) Init() tea.Cmd {
_, h, err := term.GetSize(0)
if err != nil {
@@ -79,6 +103,9 @@ func (m *Model) View() string {
}
result := m.State()
result = viewport.Process(result, m.Height)
+ if m.Search.Focused() {
+ result = m.AddSearch(result)
+ }
return result
}
@@ -89,13 +116,16 @@ func (m *Model) Result() (*model.HydratedSource, model.HydratedTarget) {
return m.SourceIndices[m.Index], m.Indices[m.Index]
}
-func (m *Model) Validate() {
+func (m *Model) Validate() (clamped bool) {
if m.Index < 0 {
m.Index = 0
+ return true
}
if m.Index > len(m.Indices)-1 {
m.Index = len(m.Indices) - 1
+ return true
}
+ return false
}
var ForcedInlineTerminals = map[string]string{
@@ -117,6 +147,7 @@ func NewModel(st *model.State, hydrators []model.Modder) *Model {
SourceIndices: make(map[int]*model.HydratedSource),
AutoAlt: !pflag.Lookup("inline").Changed && !isBanned,
Motd: motd.One(),
+ Search: textinput.New(),
}
idx := 0
for _, src := range st.Sources {
diff --git a/menu/search.go b/menu/search.go
new file mode 100644
index 0000000..79cc03b
--- /dev/null
+++ b/menu/search.go
@@ -0,0 +1,11 @@
+package menu
+
+import "strings"
+
+func (m *Model) AddSearch(croppedInput string) string {
+ lines := strings.Split(croppedInput, "\n")
+ lastIndex := len(lines) - 1
+ view := m.Search.View()
+ lines[lastIndex] = view
+ return strings.Join(lines, "\n")
+}
diff --git a/menu/target.go b/menu/target.go
index f0b35fd..ee31889 100644
--- a/menu/target.go
+++ b/menu/target.go
@@ -14,6 +14,10 @@ var (
st := lipgloss.NewStyle().Border(lipgloss.OuterHalfBlockBorder(), false, false, false, true)
return st
})
+ TargetHighlightedColor = lipgloss.Color("1")
+ TargetHighlightedStyle = style.New(func() lipgloss.Style {
+ return TargetStyle.Get().Foreground(TargetHighlightedColor)
+ })
SelectedTargetStyle = style.New(func() lipgloss.Style {
return TargetStyle.Get().BorderBackground(SelectedTargetBackgroundColor).Background(SelectedTargetBackgroundColor)
})
@@ -59,6 +63,11 @@ func (m *Model) Target(src *model.HydratedSource, t model.HydratedTarget, header
}
selectionStyle := TargetStyle
selectionDescriptionStyle := TargetDescriptionStyle
+
+ if m.Highlights(src, t) {
+ selectionStyle = TargetHighlightedStyle
+ }
+
if selected {
selectionStyle = SelectedTargetStyle
selectionDescriptionStyle = SelectedTargetDescriptionStyle
diff --git a/runner/shell/shell.go b/runner/shell/shell.go
index 7972bf0..53b4df3 100644
--- a/runner/shell/shell.go
+++ b/runner/shell/shell.go
@@ -64,14 +64,14 @@ func (s *shell) Wants(f fs.FS, file string, entry fs.DirEntry) (bool, error) {
}
func (s *shell) Find(shell string) (string, error) {
+ s.Lock()
+ defer s.Unlock()
if s.Locations[shell] != "" {
return s.Locations[shell], nil
}
if p, err := exec.LookPath(shell); err == nil {
- s.Lock()
s.Locations[shell] = p
- s.Unlock()
return shell, nil
} else {
return "", err