in src/ulsp/gateway/ide-client/ide_client.go [242:298]
func (g *gateway) showWaitingForUserSelection(ctx context.Context) (doneFunc func(), err error) {
c, _, err := g.getClient(ctx)
if err != nil {
return nil, fmt.Errorf(_errSendToClient, err)
}
tokenID, err := uuid.NewV4()
if err != nil {
return nil, fmt.Errorf(_errSendToClient, err)
}
// Initial message indicating pending put.
token := protocol.NewProgressToken(tokenID.String())
if err := c.WorkDoneProgressCreate(ctx, &protocol.WorkDoneProgressCreateParams{Token: *protocol.NewProgressToken(tokenID.String())}); err != nil {
return nil, fmt.Errorf("creating user input progress: %w", err)
}
if err := c.Progress(ctx, &protocol.ProgressParams{
Token: *token,
Value: &protocol.WorkDoneProgressBegin{
Kind: protocol.WorkDoneProgressKindBegin,
Title: _titleUserInputProgress,
Message: _messageUserInputProgressInitial,
Cancellable: true,
},
}); err != nil {
return nil, fmt.Errorf("starting user input progress: %w", err)
}
// After brief delay without input, update the prompt.
updateProgressTimer := time.AfterFunc(_timeoutUserSelectionMoreInfo, func() {
c.Progress(ctx, &protocol.ProgressParams{
Token: *token,
Value: &protocol.WorkDoneProgressReport{
Kind: protocol.WorkDoneProgressKindReport,
Message: _messageUserInputProgressUpdate,
},
})
})
// Set a maximum timeout to avoid showing this indefinitely, since the user may ignore the prompt and move onto other tasks.
endProgressFunc := func() {
c.Progress(ctx, &protocol.ProgressParams{
Token: *token,
Value: &protocol.WorkDoneProgressEnd{Kind: protocol.WorkDoneProgressKindEnd},
})
}
endProgressTimer := time.AfterFunc(_timeoutUserSelectionEnd, endProgressFunc)
// Return a function that can be called to immediately end the progress.
doneFunc = func() {
updateProgressTimer.Stop()
if endProgressTimer.Stop() {
endProgressFunc()
}
}
return doneFunc, nil
}