github.com/v2fly/tools@v0.100.0/internal/lsp/code_lens.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package lsp
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"sort"
    11  
    12  	"github.com/v2fly/tools/internal/event"
    13  	"github.com/v2fly/tools/internal/lsp/command"
    14  	"github.com/v2fly/tools/internal/lsp/mod"
    15  	"github.com/v2fly/tools/internal/lsp/protocol"
    16  	"github.com/v2fly/tools/internal/lsp/source"
    17  )
    18  
    19  func (s *Server) codeLens(ctx context.Context, params *protocol.CodeLensParams) ([]protocol.CodeLens, error) {
    20  	snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
    21  	defer release()
    22  	if !ok {
    23  		return nil, err
    24  	}
    25  	var lenses map[command.Command]source.LensFunc
    26  	switch fh.Kind() {
    27  	case source.Mod:
    28  		lenses = mod.LensFuncs()
    29  	case source.Go:
    30  		lenses = source.LensFuncs()
    31  	default:
    32  		// Unsupported file kind for a code lens.
    33  		return nil, nil
    34  	}
    35  	var result []protocol.CodeLens
    36  	for cmd, lf := range lenses {
    37  		if !snapshot.View().Options().Codelenses[string(cmd)] {
    38  			continue
    39  		}
    40  		added, err := lf(ctx, snapshot, fh)
    41  		// Code lens is called on every keystroke, so we should just operate in
    42  		// a best-effort mode, ignoring errors.
    43  		if err != nil {
    44  			event.Error(ctx, fmt.Sprintf("code lens %s failed", cmd), err)
    45  			continue
    46  		}
    47  		result = append(result, added...)
    48  	}
    49  	sort.Slice(result, func(i, j int) bool {
    50  		a, b := result[i], result[j]
    51  		if protocol.CompareRange(a.Range, b.Range) == 0 {
    52  			return a.Command.Command < b.Command.Command
    53  		}
    54  		return protocol.CompareRange(a.Range, b.Range) < 0
    55  	})
    56  	return result, nil
    57  }