|
4 | 4 | from glob import glob
|
5 | 5 | from os.path import dirname, basename
|
6 | 6 | import sys
|
7 |
| -from linecache import getline |
8 | 7 | from urllib.parse import urlparse
|
9 | 8 |
|
| 9 | +CONTENTS = {} # Hash[uri, Hash[string, Union[integer, TextContent]]] |
| 10 | + |
| 11 | +class TextContent: |
| 12 | + # TODO: it should be tested |
| 13 | + def __init__(self, text): # Text -> self |
| 14 | + self.text = text.split("\n") |
| 15 | + |
| 16 | + def __getitem__(self, i): # integer -> string |
| 17 | + return self.text[i] |
| 18 | + |
| 19 | + def __str__(self): # None -> string |
| 20 | + return "\n".join(self.text) |
| 21 | + |
| 22 | + def remove_text(self, rng): # Range -> None |
| 23 | + stline = rng['start']['line'] |
| 24 | + stcol = rng['start']['character'] |
| 25 | + enline = rng['end']['line'] |
| 26 | + encol = rng['end']['character'] |
| 27 | + |
| 28 | + before = self.text[stline][:stcol] |
| 29 | + after = self.text[enline][encol:] |
| 30 | + |
| 31 | + self.text[stline] = before+after |
| 32 | + for _ in range(enline-stline): |
| 33 | + self.text.pop(stline+1) |
| 34 | + |
| 35 | + def insert_text(self, beg, text): # Position -> Text -> None |
| 36 | + stline = beg['line'] |
| 37 | + stcol = beg['character'] |
| 38 | + |
| 39 | + before = self.text[stline][:stcol] |
| 40 | + after = self.text[stline][stcol:] |
| 41 | + lines = text.split("\n") |
| 42 | + |
| 43 | + self.text[stline] = before+lines[0] |
| 44 | + idx = stline+1 |
| 45 | + for l in lines[1:]: |
| 46 | + self.text.insert(idx, l) |
| 47 | + idx += 1 |
| 48 | + self.text[idx-1] += after |
| 49 | + |
10 | 50 | def initialize(params): # InitializeParams -> InitializeResult
|
11 | 51 | return {
|
12 | 52 | 'capabilities': {
|
| 53 | + 'textDocumentSync': { |
| 54 | + 'openClose': True, |
| 55 | + 'change': 2, |
| 56 | + }, |
13 | 57 | 'completionProvider': {
|
14 | 58 | 'triggerCharacters': [': ', '- '],
|
15 | 59 | },
|
16 | 60 | },
|
17 | 61 | }
|
18 | 62 |
|
19 | 63 | def initialized(params): # InitializedParams -> None
|
20 |
| - return |
| 64 | + pass |
| 65 | + |
| 66 | +def didChangeConfiguration(params): # ConfigurationParams -> None |
| 67 | + pass |
| 68 | + |
| 69 | +def didOpen(params): # DidOpenTextDocumentParams -> None |
| 70 | + uri = params['textDocument']['uri'] |
| 71 | + text = params['textDocument']['text'] |
| 72 | + # print('Contents for {} is added.'.format(uri), file=sys.stderr) |
| 73 | + CONTENTS[uri] = { |
| 74 | + 'version': 0, |
| 75 | + 'text': TextContent(text), |
| 76 | + } |
| 77 | + |
| 78 | +def didClose(params): # DidCloseTextDocumentParams -> None |
| 79 | + # print('Contents for {} is removed.'.format(params['uri']), file=sys.stderr) |
| 80 | + del CONTENTS[params['uri']] |
| 81 | + |
| 82 | +def didChange(params): # DidChangeTextDocumentParams -> None |
| 83 | + uri = params['textDocument']['uri'] |
| 84 | + version = params['textDocument']['version'] |
| 85 | + changes = params['contentChanges'] |
| 86 | + |
| 87 | + if version is None: |
| 88 | + pass # warning |
| 89 | + elif CONTENTS[uri]['version']+len(changes) != version: |
| 90 | + pass # warning |
| 91 | + |
| 92 | + wholetxt = CONTENTS[uri]['text'] |
| 93 | + for ch in changes: |
| 94 | + txt = ch['text'] |
| 95 | + if not 'range' in ch or ch['range'] is None: |
| 96 | + CONTENTS[uri] = { |
| 97 | + 'text': TextContent(txt), |
| 98 | + 'version': 0, |
| 99 | + } |
| 100 | + wholetxt = CONTENTS[uri]['text'] |
| 101 | + continue |
| 102 | + |
| 103 | + wholetxt.remove_text(ch['range']) |
| 104 | + wholetxt.insert_text(ch['range']['start'], txt) |
21 | 105 |
|
22 | 106 | def completion(params): # CompletionParams -> CompletionList
|
23 | 107 | # print('Params: ', params, file=sys.stderr)
|
24 | 108 | ctx = params.get('context', {})
|
25 | 109 | line = params['position']['line']
|
26 | 110 | col = params['position']['character']
|
27 |
| - uri = urlparse(params['textDocument']['uri']).path |
| 111 | + uri = params['textDocument']['uri'] |
28 | 112 |
|
29 |
| - field = getline(uri, line+1)[0:col].lstrip().rstrip(': ') |
| 113 | + # print('Keys: ', CONTENTS.keys(), file=sys.stderr) |
| 114 | + field = CONTENTS[uri]['text'][line][0:col].lstrip().rstrip(': ') |
30 | 115 | if not field:
|
31 | 116 | return structs.CompletionList(False, [])
|
32 | 117 |
|
33 | 118 | if field in completion_list:
|
34 | 119 | return completion_list[field]
|
35 | 120 | if field == 'run':
|
36 |
| - cwls = glob("{}/*.cwl".format(dirname(uri))) |
37 |
| - return [structs.CompletionItem(basename(cwl)) for cwl in cwls if cwl != uri] |
| 121 | + cwls = glob("{}/*.cwl".format(dirname(urlparse(uri).path))) |
| 122 | + return [structs.CompletionItem(basename(cwl)) for cwl in cwls if cwl != urlparse(uri).path] |
38 | 123 | return structs.CompletionList(False, [])
|
39 | 124 |
|
40 | 125 | completion_list = {
|
|
0 commit comments