mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-01 20:52:06 -07:00
@@ -9,6 +9,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -377,6 +378,7 @@ type Terminal struct {
|
|||||||
version int64
|
version int64
|
||||||
revision revision
|
revision revision
|
||||||
bgVersion int64
|
bgVersion int64
|
||||||
|
runningCmds *util.ConcurrentSet[*exec.Cmd]
|
||||||
reqBox *util.EventBox
|
reqBox *util.EventBox
|
||||||
initialPreviewOpts previewOpts
|
initialPreviewOpts previewOpts
|
||||||
previewOpts previewOpts
|
previewOpts previewOpts
|
||||||
@@ -1030,6 +1032,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
proxyScript: opts.ProxyScript,
|
proxyScript: opts.ProxyScript,
|
||||||
merger: EmptyMerger(revision{}),
|
merger: EmptyMerger(revision{}),
|
||||||
selected: make(map[int32]selectedItem),
|
selected: make(map[int32]selectedItem),
|
||||||
|
runningCmds: util.NewConcurrentSet[*exec.Cmd](),
|
||||||
reqBox: util.NewEventBox(),
|
reqBox: util.NewEventBox(),
|
||||||
initialPreviewOpts: opts.Preview,
|
initialPreviewOpts: opts.Preview,
|
||||||
previewOpts: opts.Preview,
|
previewOpts: opts.Preview,
|
||||||
@@ -4377,6 +4380,7 @@ func (t *Terminal) captureAsync(a action, firstLineOnly bool, callback func(stri
|
|||||||
reader := bufio.NewReader(out)
|
reader := bufio.NewReader(out)
|
||||||
var output string
|
var output string
|
||||||
if err := cmd.Start(); err == nil {
|
if err := cmd.Start(); err == nil {
|
||||||
|
t.runningCmds.Add(cmd)
|
||||||
if firstLineOnly {
|
if firstLineOnly {
|
||||||
output, _ = reader.ReadString('\n')
|
output, _ = reader.ReadString('\n')
|
||||||
output = strings.TrimRight(output, "\r\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)
|
output = string(bytes)
|
||||||
}
|
}
|
||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
|
t.runningCmds.Remove(cmd)
|
||||||
}
|
}
|
||||||
t.callbackChan <- versionedCallback{version, func() { callback(output) }}
|
t.callbackChan <- versionedCallback{version, func() { callback(output) }}
|
||||||
}
|
}
|
||||||
@@ -5053,6 +5058,9 @@ func (t *Terminal) Loop() error {
|
|||||||
if code <= ExitNoMatch && t.history != nil {
|
if code <= ExitNoMatch && t.history != nil {
|
||||||
t.history.append(string(t.input))
|
t.history.append(string(t.input))
|
||||||
}
|
}
|
||||||
|
t.runningCmds.ForEach(func(cmd *exec.Cmd) {
|
||||||
|
util.KillCommand(cmd)
|
||||||
|
})
|
||||||
running = false
|
running = false
|
||||||
t.mutex.Unlock()
|
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