summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-06-14 21:33:42 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2024-06-14 21:33:42 +0900
commitb2ecb6352c2ce516a15edce3ea711623ed8a1375 (patch)
treece71d242fef3e318964d7ebf8f77908c4d4afc90
parent9dc3ed638a1c5bc7a7d4918eb736cd82c8cb3fa0 (diff)
Make GET endpoint available from 'execute' and 'transform' actions
-rw-r--r--CHANGELOG.md9
-rw-r--r--src/actiontype_string.go9
-rw-r--r--src/server.go26
-rw-r--r--src/terminal.go33
4 files changed, 50 insertions, 27 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae257ab7..4b6cf015 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,15 @@ CHANGELOG
0.53.1
------
- Bug fixes and minor improvements
+ - Better cache management and improved rendering for `--tail`
+ - Fixed crash when using `--tiebreak=end` with very long items
+ - Fixed mouse support on Windows
+ - zsh 5.0 compatibility (thanks to @LangLangBart)
+ - Fixed `--walker-skip` to also skip symlinks to directories
+ - GET endpoint is now available from `execute` and `transform` actions (it used to timeout due to lock conflict)
+ ```sh
+ fzf --listen --bind 'focus:transform-header:curl -s localhost:$FZF_PORT?limit=0 | jq .'
+ ```
0.53.0
------
diff --git a/src/actiontype_string.go b/src/actiontype_string.go
index 2a597ea5..91c2a7fe 100644
--- a/src/actiontype_string.go
+++ b/src/actiontype_string.go
@@ -117,14 +117,13 @@ func _() {
_ = x[actUnbind-106]
_ = x[actRebind-107]
_ = x[actBecome-108]
- _ = x[actResponse-109]
- _ = x[actShowHeader-110]
- _ = x[actHideHeader-111]
+ _ = x[actShowHeader-109]
+ _ = x[actHideHeader-110]
}
-const _actionType_name = "actIgnoreactStartactClickactInvalidactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeHeaderactChangeMultiactChangePreviewLabelactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactTrackCurrentactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformHeaderactTransformPreviewLabelactTransformPromptactTransformQueryactPreviewactChangePreviewactChangePreviewWindowactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactBecomeactResponseactShowHeaderactHideHeader"
+const _actionType_name = "actIgnoreactStartactClickactInvalidactCharactMouseactBeginningOfLineactAbortactAcceptactAcceptNonEmptyactAcceptOrPrintQueryactBackwardCharactBackwardDeleteCharactBackwardDeleteCharEofactBackwardWordactCancelactChangeBorderLabelactChangeHeaderactChangeMultiactChangePreviewLabelactChangePromptactChangeQueryactClearScreenactClearQueryactClearSelectionactCloseactDeleteCharactDeleteCharEofactEndOfLineactFatalactForwardCharactForwardWordactKillLineactKillWordactUnixLineDiscardactUnixWordRuboutactYankactBackwardKillWordactSelectAllactDeselectAllactToggleactToggleSearchactToggleAllactToggleDownactToggleUpactToggleInactToggleOutactToggleTrackactToggleTrackCurrentactToggleHeaderactTrackCurrentactUntrackCurrentactDownactUpactPageUpactPageDownactPositionactHalfPageUpactHalfPageDownactOffsetUpactOffsetDownactJumpactJumpAcceptactPrintQueryactRefreshPreviewactReplaceQueryactToggleSortactShowPreviewactHidePreviewactTogglePreviewactTogglePreviewWrapactTransformactTransformBorderLabelactTransformHeaderactTransformPreviewLabelactTransformPromptactTransformQueryactPreviewactChangePreviewactChangePreviewWindowactPreviewTopactPreviewBottomactPreviewUpactPreviewDownactPreviewPageUpactPreviewPageDownactPreviewHalfPageUpactPreviewHalfPageDownactPrevHistoryactPrevSelectedactPrintactPutactNextHistoryactNextSelectedactExecuteactExecuteSilentactExecuteMultiactSigStopactFirstactLastactReloadactReloadSyncactDisableSearchactEnableSearchactSelectactDeselectactUnbindactRebindactBecomeactShowHeaderactHideHeader"
-var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 42, 50, 68, 76, 85, 102, 123, 138, 159, 183, 198, 207, 227, 242, 256, 277, 292, 306, 320, 333, 350, 358, 371, 387, 399, 407, 421, 435, 446, 457, 475, 492, 499, 518, 530, 544, 553, 568, 580, 593, 604, 615, 627, 641, 662, 677, 692, 709, 716, 721, 730, 741, 752, 765, 780, 791, 804, 811, 824, 837, 854, 869, 882, 896, 910, 926, 946, 958, 981, 999, 1023, 1041, 1058, 1068, 1084, 1106, 1119, 1135, 1147, 1161, 1177, 1195, 1215, 1237, 1251, 1266, 1274, 1280, 1294, 1309, 1319, 1335, 1350, 1360, 1368, 1375, 1384, 1397, 1413, 1428, 1437, 1448, 1457, 1466, 1475, 1486, 1499, 1512}
+var _actionType_index = [...]uint16{0, 9, 17, 25, 35, 42, 50, 68, 76, 85, 102, 123, 138, 159, 183, 198, 207, 227, 242, 256, 277, 292, 306, 320, 333, 350, 358, 371, 387, 399, 407, 421, 435, 446, 457, 475, 492, 499, 518, 530, 544, 553, 568, 580, 593, 604, 615, 627, 641, 662, 677, 692, 709, 716, 721, 730, 741, 752, 765, 780, 791, 804, 811, 824, 837, 854, 869, 882, 896, 910, 926, 946, 958, 981, 999, 1023, 1041, 1058, 1068, 1084, 1106, 1119, 1135, 1147, 1161, 1177, 1195, 1215, 1237, 1251, 1266, 1274, 1280, 1294, 1309, 1319, 1335, 1350, 1360, 1368, 1375, 1384, 1397, 1413, 1428, 1437, 1448, 1457, 1466, 1475, 1488, 1501}
func (i actionType) String() string {
if i < 0 || i >= actionType(len(_actionType_index)-1) {
diff --git a/src/server.go b/src/server.go
index 0f325d8c..5757e160 100644
--- a/src/server.go
+++ b/src/server.go
@@ -38,9 +38,9 @@ const (
)
type httpServer struct {
- apiKey []byte
- actionChannel chan []*action
- responseChannel chan string
+ apiKey []byte
+ actionChannel chan []*action
+ getHandler func(getParams) string
}
type listenAddress struct {
@@ -73,7 +73,7 @@ func parseListenAddress(address string) (listenAddress, error) {
return listenAddress{parts[0], port}, nil
}
-func startHttpServer(address listenAddress, actionChannel chan []*action, responseChannel chan string) (net.Listener, int, error) {
+func startHttpServer(address listenAddress, actionChannel chan []*action, getHandler func(getParams) string) (net.Listener, int, error) {
host := address.host
port := address.port
apiKey := os.Getenv("FZF_API_KEY")
@@ -99,9 +99,9 @@ func startHttpServer(address listenAddress, actionChannel chan []*action, respon
}
server := httpServer{
- apiKey: []byte(apiKey),
- actionChannel: actionChannel,
- responseChannel: responseChannel,
+ apiKey: []byte(apiKey),
+ actionChannel: actionChannel,
+ getHandler: getHandler,
}
go func() {
@@ -165,17 +165,11 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string {
case 0:
getMatch := getRegex.FindStringSubmatch(text)
if len(getMatch) > 0 {
- server.actionChannel <- []*action{{t: actResponse, a: getMatch[1]}}
- select {
- case response := <-server.responseChannel:
+ response := server.getHandler(parseGetParams(getMatch[1]))
+ if len(response) > 0 {
return good(response)
- case <-time.After(channelTimeout):
- go func() {
- // Drain the channel
- <-server.responseChannel
- }()
- return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`)
}
+ return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`)
} else if !strings.HasPrefix(text, "POST / HTTP") {
return bad("invalid request method")
}
diff --git a/src/terminal.go b/src/terminal.go
index 7307c170..193021fa 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -318,7 +318,6 @@ type Terminal struct {
startChan chan fitpad
killChan chan bool
serverInputChan chan []*action
- serverOutputChan chan string
eventChan chan tui.Event
slab *util.Slab
theme *tui.ColorTheme
@@ -497,7 +496,6 @@ const (
actUnbind
actRebind
actBecome
- actResponse
actShowHeader
actHideHeader
)
@@ -839,7 +837,6 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
startChan: make(chan fitpad, 1),
killChan: make(chan bool),
serverInputChan: make(chan []*action, 100),
- serverOutputChan: make(chan string),
eventChan: make(chan tui.Event, 6), // (load + result + zero|one) | (focus) | (resize) | (GetChar)
tui: renderer,
ttyin: ttyin,
@@ -893,7 +890,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
_, t.hasLoadActions = t.keymap[tui.Load.AsEvent()]
if t.listenAddr != nil {
- listener, port, err := startHttpServer(*t.listenAddr, t.serverInputChan, t.serverOutputChan)
+ listener, port, err := startHttpServer(*t.listenAddr, t.serverInputChan, t.dumpStatus)
if err != nil {
return nil, err
}
@@ -2996,11 +2993,14 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
}
t.tui.Pause(true)
+ t.mutex.Unlock()
cmd.Run()
+ t.mutex.Lock()
t.tui.Resume(true, false)
t.redraw()
t.refresh()
} else {
+ t.mutex.Unlock()
if capture {
out, _ := cmd.StdoutPipe()
reader := bufio.NewReader(out)
@@ -3016,6 +3016,7 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
} else {
cmd.Run()
}
+ t.mutex.Lock()
}
t.executing.Set(false)
removeFiles(tempFiles)
@@ -3719,8 +3720,6 @@ func (t *Terminal) Loop() error {
doAction = func(a *action) bool {
switch a.t {
case actIgnore, actStart, actClick:
- case actResponse:
- t.serverOutputChan <- t.dumpStatus(parseGetParams(a.a))
case actBecome:
valid, list := t.buildPlusList(a.a, false)
if valid {
@@ -4708,7 +4707,29 @@ func (t *Terminal) dumpItem(i *Item) StatusItem {
}
}
+func (t *Terminal) tryLock(timeout time.Duration) bool {
+ sleepDuration := 10 * time.Millisecond
+
+ for {
+ if t.mutex.TryLock() {
+ return true
+ }
+
+ timeout -= sleepDuration
+ if timeout <= 0 {
+ break
+ }
+ time.Sleep(sleepDuration)
+ }
+ return false
+}
+
func (t *Terminal) dumpStatus(params getParams) string {
+ if !t.tryLock(channelTimeout) {
+ return ""
+ }
+ defer t.mutex.Unlock()
+
selectedItems := t.sortSelected()
selected := make([]StatusItem, util.Max(0, util.Min(params.limit, len(selectedItems)-params.offset)))
for i := range selected {