github.com/jd-ly/tools@v0.5.7/internal/lsp/workspace.go (about) 1 // Copyright 2019 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 10 "github.com/jd-ly/tools/internal/lsp/protocol" 11 "github.com/jd-ly/tools/internal/lsp/source" 12 "github.com/jd-ly/tools/internal/span" 13 errors "golang.org/x/xerrors" 14 ) 15 16 func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error { 17 event := params.Event 18 for _, folder := range event.Removed { 19 view := s.session.View(folder.Name) 20 if view != nil { 21 view.Shutdown(ctx) 22 } else { 23 return errors.Errorf("view %s for %v not found", folder.Name, folder.URI) 24 } 25 } 26 return s.addFolders(ctx, event.Added) 27 } 28 29 func (s *Server) addView(ctx context.Context, name string, uri, tempWorkspace span.URI) (source.Snapshot, func(), error) { 30 s.stateMu.Lock() 31 state := s.state 32 s.stateMu.Unlock() 33 if state < serverInitialized { 34 return nil, func() {}, errors.Errorf("addView called before server initialized") 35 } 36 options := s.session.Options().Clone() 37 if err := s.fetchConfig(ctx, name, uri, options); err != nil { 38 return nil, func() {}, err 39 } 40 _, snapshot, release, err := s.session.NewView(ctx, name, uri, tempWorkspace, options) 41 return snapshot, release, err 42 } 43 44 func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error { 45 // Apply any changes to the session-level settings. 46 options := s.session.Options().Clone() 47 semanticTokensRegistered := options.SemanticTokens 48 if err := s.fetchConfig(ctx, "", "", options); err != nil { 49 return err 50 } 51 s.session.SetOptions(options) 52 53 // Go through each view, getting and updating its configuration. 54 for _, view := range s.session.Views() { 55 options := s.session.Options().Clone() 56 if err := s.fetchConfig(ctx, view.Name(), view.Folder(), options); err != nil { 57 return err 58 } 59 view, err := view.SetOptions(ctx, options) 60 if err != nil { 61 return err 62 } 63 go func() { 64 snapshot, release := view.Snapshot(ctx) 65 defer release() 66 s.diagnoseDetached(snapshot) 67 }() 68 } 69 70 // Update any session-specific registrations or unregistrations. 71 if !semanticTokensRegistered && options.SemanticTokens { 72 if err := s.client.RegisterCapability(ctx, &protocol.RegistrationParams{ 73 Registrations: []protocol.Registration{semanticTokenRegistration()}, 74 }); err != nil { 75 return err 76 } 77 } else if semanticTokensRegistered && !options.SemanticTokens { 78 if err := s.client.UnregisterCapability(ctx, &protocol.UnregistrationParams{ 79 Unregisterations: []protocol.Unregistration{ 80 { 81 ID: semanticTokenRegistration().ID, 82 Method: semanticTokenRegistration().Method, 83 }, 84 }, 85 }); err != nil { 86 return err 87 } 88 } 89 return nil 90 } 91 92 func semanticTokenRegistration() protocol.Registration { 93 return protocol.Registration{ 94 ID: "textDocument/semanticTokens", 95 Method: "textDocument/semanticTokens", 96 RegisterOptions: &protocol.SemanticTokensOptions{ 97 Legend: protocol.SemanticTokensLegend{ 98 // TODO(pjw): trim these to what we use (and an unused one 99 // at position 0 of TokTypes, to catch typos) 100 TokenTypes: SemanticTypes(), 101 TokenModifiers: SemanticModifiers(), 102 }, 103 Full: true, 104 Range: true, 105 }, 106 } 107 }