aboutsummaryrefslogtreecommitdiff
path: root/src/lsp/server.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lsp/server.zc')
-rw-r--r--src/lsp/server.zc61
1 files changed, 36 insertions, 25 deletions
diff --git a/src/lsp/server.zc b/src/lsp/server.zc
index a07e4d4..48fdf90 100644
--- a/src/lsp/server.zc
+++ b/src/lsp/server.zc
@@ -1057,8 +1057,15 @@ int doc_gap(int base, int from, int to) {
return 1;
}
// remove comment delimiters and optional line-leading stars; retain markdown.
+// the line comment emitted last: consecutive // lines are one paragraph, joined by a soft break
+int hct_doc = 0 - 1, hct_end, hct_hn;
+int hover_comment_adjacent(int base, int from, int to) {
+ int lines = 0, c;
+ while (from < to) { c = dc(base, from); if (c == 10) lines++; else if (c != 32 && c != 9 && c != 13) return 0; from++; }
+ return lines <= 1;
+}
int hover_comment_text(int i, int index) {
- int base = doff[i], o = hc_start[index] + 2, end = hc_end[index], bol = 1, c, before = hn;
+ int base = doff[i], o = hc_start[index] + 2, end = hc_end[index], bol = 1, c, before = hn, joined;
if (hc_kind[index] == 3) {
if (end >= o + 2 && dc(base, end - 2) == '*' && dc(base, end - 1) == '/') end = end - 2;
if (o < end && dc(base, o) == '*') o++;
@@ -1066,7 +1073,8 @@ int hover_comment_text(int i, int index) {
while (o < end && (dc(base, o) == 32 || dc(base, o) == 9 || dc(base, o) == 10 || dc(base, o) == 13)) o++;
while (end > o && (dc(base, end - 1) == 32 || dc(base, end - 1) == 9 || dc(base, end - 1) == 10 || dc(base, end - 1) == 13)) end--;
if (o == end) return 0;
- hov_text("\n\n");
+ joined = hc_kind[index] != 3 && hct_doc == i && hct_hn == hn && hn > 0 && hover_comment_adjacent(base, hct_end, hc_start[index]);
+ if (joined) hov_put(10); else hov_text("\n\n");
while (o < end) {
if (bol && hc_kind[index] == 3) {
while (o < end && (dc(base, o) == 32 || dc(base, o) == 9)) o++;
@@ -1078,6 +1086,7 @@ int hover_comment_text(int i, int index) {
if (c != 13) hov_put(c);
if (c == 10) bol = 1;
}
+ if (hc_kind[index] != 3) { hct_doc = i; hct_end = hc_end[index]; hct_hn = hn; } else hct_doc = 0 - 1;
return hn - before;
}
// a trailing declaration comment belongs to its last name, not the next line.
@@ -2085,18 +2094,21 @@ int do_nav(int i, int refs) {
}
//: ---- the sources of this image ----
-//: the image carries the text of rt.zc, compiler.zc, server.zc, std.zc, icon.zc and core.zc (the
-//: pieces src/tools/embed.sh made), so the definition of a built-in has somewhere to go. each source is a document
+//: the image carries the text of rt.zc, compiler.zc, server.zc, std.zc, icon.zc and core.zc, embedded
+//: when the image is built, so the definition of a built-in has somewhere to go. each source is a document
//: of its own at tinyvm:/NAME.zc, which the editor shows read only and can ask for with zc/source
const int BS_COUNT = 6;
-bstr rt_part(int i); bstr compiler_part(int i); bstr server_part(int i); bstr core_part(int i);
-bstr bs_part(int k, int i) {
- if (k == 0) return rt_part(i);
- if (k == 1) return compiler_part(i);
- if (k == 2) return server_part(i);
- if (k == 3) return run.std_part(i);
- if (k == 4) return run.icon_part(i);
- return core_part(i);
+embed "src/runtime/rt.zc" as bstr rt_embedded;
+embed "src/compiler/compiler.zc" as bstr compiler_embedded;
+embed "src/lsp/server.zc" as bstr server_embedded;
+embed "src/core/core.zc" as bstr core_embedded;
+bstr bs_text(int k) {
+ if (k == 0) return rt_embedded;
+ if (k == 1) return compiler_embedded;
+ if (k == 2) return server_embedded;
+ if (k == 3) return run.std_source();
+ if (k == 4) return run.icon_source();
+ return core_embedded;
}
char* bs_uri(int k) {
if (k == 0) return "tinyvm:/rt.zc";
@@ -2108,21 +2120,15 @@ char* bs_uri(int k) {
}
// the document of built-in source k, loaded the first time it is asked for
int bs_load(int k) {
- int i, n = 0, j = 0, b; bstr p; word text;
+ int i, n = 0, j = 0; bstr p; word text;
if (!bs_idx) bs_idx = lsp_grow(0, 0, BS_COUNT);
if (bs_idx[k]) return bs_idx[k] - 1;
- while (1) { p = bs_part(k, j); if (!p) break; n = n + rt.len_s(p); j++; }
- text = lsp_grow(0, 0, (n >> 2) + 3);
- n = 0; j = 0;
- while (1) {
- p = bs_part(k, j); if (!p) break;
- b = 0;
- while (b < rt.len_s(p)) {
- if ((n & 3) == 0) text[n >> 2] = 0;
- text[n >> 2] = text[n >> 2] | (rt.at_s(p, b) << ((n & 3) * 8));
- n++; b++;
- }
- j++;
+ p = bs_text(k); j = rt.len_s(p);
+ text = lsp_grow(0, 0, (j >> 2) + 3);
+ while (n < j) {
+ if ((n & 3) == 0) text[n >> 2] = 0;
+ text[n >> 2] = text[n >> 2] | (rt.at_s(p, n) << ((n & 3) * 8));
+ n++;
}
i = docnew(bs_uri(k), rt.len_w(bs_uri(k)));
doff[i] = text; dsize[i] = n; dver[i] = 1; dgen[i]++;
@@ -2334,8 +2340,13 @@ int fm_symbol(int base, int o, int size) {
return n;
}
// split document i into tokens, each with the spaces before it on its line (-1 for the first of a line)
+// the document the token arrays describe: hover lookups lex the same documents again and
+// again, so a lex of an unchanged document is reused
+int fm_doc = 0 - 1, fm_gen, fm_size; word fm_base;
int fm_lex(int i) {
int base = doff[i], size = dsize[i], o = 0, ln = 0, gap = 0 - 1, c, s, q, e, el, n;
+ if (fm_doc == i && fm_gen == dgen[i] && fm_base == base && fm_size == size && fm_s) return 0;
+ fm_doc = i; fm_gen = dgen[i]; fm_base = base; fm_size = size;
fm_nt = 0;
if (!fm_s) {
fm_tcap = 256;