all repos

clerk @ 33b67bd

missing tooling for ledger/hledger

clerk/internal/lsp/textdocument_sync.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
add support of subdirectives and it's highlights, 1 month ago
1
package lsp
2
3
import (
4
	"context"
5
6
	"go.lsp.dev/protocol"
7
	"go.lsp.dev/uri"
8
9
	"olexsmir.xyz/clerk/journal/ast"
10
	"olexsmir.xyz/clerk/journal/lexer"
11
	"olexsmir.xyz/clerk/journal/parser"
12
)
13
14
func (s *server) DidOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error {
15
	s.openDoc(params.TextDocument.URI, params.TextDocument.Text, params.TextDocument.Version, params.TextDocument.LanguageID)
16
	s.scheduleDiagnostics(ctx)
17
	return nil
18
}
19
20
func (s *server) DidChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error {
21
	s.updateDoc(params.TextDocument.URI, params.TextDocument.Version, params.ContentChanges)
22
	s.scheduleDiagnostics(ctx)
23
	return nil
24
}
25
26
func (s *server) DidClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error {
27
	s.closeDoc(params.TextDocument.URI)
28
	s.scheduleDiagnostics(ctx)
29
	return nil
30
}
31
32
func (s *server) DidSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error {
33
	return nil
34
}
35
36
// Document management
37
38
type docState struct {
39
	text       string
40
	version    int32
41
	languageID protocol.LanguageKind
42
	semTokens  []semanticToken // cached semantic tokens
43
}
44
45
func (s *server) openDoc(u uri.URI, text string, version int32, langID protocol.LanguageKind) {
46
	s.mu.Lock()
47
	s.openDocs[u] = docState{
48
		text:       text,
49
		version:    version,
50
		languageID: langID,
51
	}
52
	s.mu.Unlock()
53
}
54
55
func (s *server) updateDoc(u uri.URI, version int32, changes []protocol.TextDocumentContentChangeEvent) {
56
	s.mu.Lock()
57
	defer s.mu.Unlock()
58
	state, ok := s.openDocs[u]
59
	if !ok {
60
		return
61
	}
62
	state.version = version
63
	for _, ch := range changes {
64
		switch ev := ch.(type) {
65
		case *protocol.TextDocumentContentChangeWholeDocument:
66
			state.text = ev.Text
67
			state.semTokens = nil
68
		case *protocol.TextDocumentContentChangePartial:
69
			_ = ev // TODO: incremental edit support
70
		}
71
	}
72
	s.openDocs[u] = state
73
}
74
75
func (s *server) getDocState(u uri.URI) (docState, bool) {
76
	s.mu.Lock()
77
	state, ok := s.openDocs[u]
78
	s.mu.Unlock()
79
	return state, ok
80
}
81
82
func (s *server) closeDoc(u uri.URI) {
83
	s.mu.Lock()
84
	delete(s.openDocs, u)
85
	s.mu.Unlock()
86
}
87
88
func parseJournalStr(content string) *ast.Journal {
89
	l := lexer.New("", []byte(content))
90
	p := parser.New(l)
91
	return p.ParseJournal()
92
}