func()

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
}