mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-24 21:57:36 +00:00
Make GET endpoint available from 'execute' and 'transform' actions
This commit is contained in:
parent
9dc3ed638a
commit
b2ecb6352c
@ -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
|
||||
------
|
||||
|
@ -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) {
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user