mirror of
https://github.com/junegunn/fzf.git
synced 2025-07-31 20:22:01 -07:00
@@ -9,6 +9,7 @@ import (
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"sort"
|
||||
@@ -377,6 +378,7 @@ type Terminal struct {
|
||||
version int64
|
||||
revision revision
|
||||
bgVersion int64
|
||||
runningCmds *util.ConcurrentSet[*exec.Cmd]
|
||||
reqBox *util.EventBox
|
||||
initialPreviewOpts previewOpts
|
||||
previewOpts previewOpts
|
||||
@@ -1030,6 +1032,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
||||
proxyScript: opts.ProxyScript,
|
||||
merger: EmptyMerger(revision{}),
|
||||
selected: make(map[int32]selectedItem),
|
||||
runningCmds: util.NewConcurrentSet[*exec.Cmd](),
|
||||
reqBox: util.NewEventBox(),
|
||||
initialPreviewOpts: opts.Preview,
|
||||
previewOpts: opts.Preview,
|
||||
@@ -4377,6 +4380,7 @@ func (t *Terminal) captureAsync(a action, firstLineOnly bool, callback func(stri
|
||||
reader := bufio.NewReader(out)
|
||||
var output string
|
||||
if err := cmd.Start(); err == nil {
|
||||
t.runningCmds.Add(cmd)
|
||||
if firstLineOnly {
|
||||
output, _ = reader.ReadString('\n')
|
||||
output = strings.TrimRight(output, "\r\n")
|
||||
@@ -4385,6 +4389,7 @@ func (t *Terminal) captureAsync(a action, firstLineOnly bool, callback func(stri
|
||||
output = string(bytes)
|
||||
}
|
||||
cmd.Wait()
|
||||
t.runningCmds.Remove(cmd)
|
||||
}
|
||||
t.callbackChan <- versionedCallback{version, func() { callback(output) }}
|
||||
}
|
||||
@@ -5053,6 +5058,9 @@ func (t *Terminal) Loop() error {
|
||||
if code <= ExitNoMatch && t.history != nil {
|
||||
t.history.append(string(t.input))
|
||||
}
|
||||
t.runningCmds.ForEach(func(cmd *exec.Cmd) {
|
||||
util.KillCommand(cmd)
|
||||
})
|
||||
running = false
|
||||
t.mutex.Unlock()
|
||||
}
|
||||
|
39
src/util/concurrent_set.go
Normal file
39
src/util/concurrent_set.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package util
|
||||
|
||||
import "sync"
|
||||
|
||||
// ConcurrentSet is a thread-safe set implementation.
|
||||
type ConcurrentSet[T comparable] struct {
|
||||
lock sync.RWMutex
|
||||
items map[T]struct{}
|
||||
}
|
||||
|
||||
// NewConcurrentSet creates a new ConcurrentSet.
|
||||
func NewConcurrentSet[T comparable]() *ConcurrentSet[T] {
|
||||
return &ConcurrentSet[T]{
|
||||
items: make(map[T]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds an item to the set.
|
||||
func (s *ConcurrentSet[T]) Add(item T) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
s.items[item] = struct{}{}
|
||||
}
|
||||
|
||||
// Remove removes an item from the set.
|
||||
func (s *ConcurrentSet[T]) Remove(item T) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
delete(s.items, item)
|
||||
}
|
||||
|
||||
// ForEach iterates over each item in the set and applies the provided function.
|
||||
func (s *ConcurrentSet[T]) ForEach(fn func(item T)) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
for item := range s.items {
|
||||
fn(item)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user