Skip to content

Commit 11d16e5

Browse files
authored
Merge branch 'develop' into refactor/lang-menu
2 parents fd331de + 9539b33 commit 11d16e5

File tree

6 files changed

+251
-23
lines changed

6 files changed

+251
-23
lines changed

client/modules/IDE/components/Editor.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ class Editor extends React.Component {
269269
if (this.props.autocompleteHinter !== prevProps.autocompleteHinter) {
270270
if (!this.props.autocompleteHinter) {
271271
// close the hinter window once the preference is turned off
272-
CodeMirror.showHint(this._cm, () => {});
272+
CodeMirror.showHint(this._cm, () => {}, {});
273273
}
274274
}
275275

@@ -352,7 +352,7 @@ class Editor extends React.Component {
352352

353353
showHint(_cm) {
354354
if (!this.props.autocompleteHinter) {
355-
CodeMirror.showHint(_cm, () => {});
355+
CodeMirror.showHint(_cm, () => {}, {});
356356
return;
357357
}
358358

@@ -425,7 +425,9 @@ class Editor extends React.Component {
425425
const c = _cm.getCursor();
426426
const token = _cm.getTokenAt(c);
427427

428-
const hints = this.hinter.search(token.string);
428+
const hints = this.hinter
429+
.search(token.string)
430+
.filter((h) => h.item.text[0] === token.string[0]);
429431

430432
return {
431433
list: hints,

client/modules/IDE/components/show-hint.js

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,70 @@
275275
}
276276
}
277277

278-
function displayHint(name, type) {
278+
function displayHint(name, type, p5) {
279279
return `<p class="${type}-item">\
280280
<span class="${type}-name hint-name">${name}</span>\
281281
<span class="hint-hidden">, </span>\
282282
<span class="hint-type">${type}</span>\
283283
<span class="hint-hidden">, </span>\
284-
<a href="https://p5js.org/reference/#/p5/${name}" role="link" onclick="event.stopPropagation()" target="_blank">\
284+
${
285+
p5
286+
? `<a href="https://p5js.org/reference/#/p5/${
287+
typeof p5 === 'string' ? p5 : name
288+
}" role="link" onclick="event.stopPropagation()" target="_blank">\
285289
<span class="hint-hidden">open ${name} reference</span>\
286-
<span aria-hidden="true">&#10132;</span></a></p>`;
290+
<span aria-hidden="true">&#10132;</span></a>`
291+
: `<span class="no-link-placeholder"><span class="hint-hidden">no reference for ${name}</span></span>`
292+
}</p>`;
293+
}
294+
295+
function getInlineHintSuggestion(focus, tokenLength) {
296+
const suggestionItem = focus.item;
297+
const baseCompletion = `<span class="inline-hinter-suggestion">${suggestionItem.text.slice(
298+
tokenLength
299+
)}</span>`;
300+
if (suggestionItem.type !== 'fun') return baseCompletion;
301+
302+
// for functions
303+
return (
304+
baseCompletion +
305+
'<span class="inline-hinter-suggestion-light">(' +
306+
(suggestionItem.params && suggestionItem.params.length
307+
? suggestionItem.params.map(({ p, o }) => (o ? `[${p}]` : p)).join(', ')
308+
: '') +
309+
')</span>'
310+
);
311+
}
312+
313+
function removeInlineHint(cm) {
314+
if (cm.state.inlineHint) {
315+
cm.state.inlineHint.clear();
316+
cm.state.inlineHint = null;
317+
}
318+
}
319+
320+
function changeInlineHint(cm, focus) {
321+
// Copilot-style inline suggestion for autocomplete feature
322+
removeInlineHint(cm);
323+
324+
const cursor = cm.getCursor();
325+
const token = cm.getTokenAt(cursor);
326+
327+
if (token && focus.item) {
328+
const suggestionHTML = getInlineHintSuggestion(
329+
focus,
330+
token.string.length
331+
);
332+
333+
const widgetElement = document.createElement('span');
334+
widgetElement.className = 'autocomplete-inline-hinter';
335+
widgetElement.innerHTML = suggestionHTML;
336+
337+
const widget = cm.setBookmark(cursor, { widget: widgetElement });
338+
cm.state.inlineHint = widget;
339+
340+
cm.setCursor(cursor);
341+
}
287342
}
288343

289344
function Widget(completion, data) {
@@ -306,6 +361,9 @@
306361
hints.className = 'CodeMirror-hints ' + theme;
307362
this.selectedHint = data.selectedHint || 0;
308363

364+
// Show inline hint
365+
changeInlineHint(cm, data.list[this.selectedHint]);
366+
309367
var completions = data.list;
310368

311369
for (var i = 0; i < completions.length; ++i) {
@@ -325,7 +383,7 @@
325383
const name = getText(cur);
326384

327385
if (cur.item && cur.item.type) {
328-
cur.displayText = displayHint(name, cur.item.type);
386+
cur.displayText = displayHint(name, cur.item.type, cur.item.p5);
329387
}
330388

331389
elt.appendChild(e);
@@ -431,10 +489,10 @@
431489
cm.addKeyMap(
432490
(this.keyMap = buildKeyMap(completion, {
433491
moveFocus: function (n, avoidWrap) {
434-
widget.changeActive(widget.selectedHint + n, avoidWrap);
492+
return widget.changeActive(widget.selectedHint + n, avoidWrap);
435493
},
436494
setFocus: function (n) {
437-
widget.changeActive(n);
495+
return widget.changeActive(n);
438496
},
439497
menuSize: function () {
440498
return widget.screenAmount();
@@ -540,6 +598,8 @@
540598
cm.off('focus', this.onFocus);
541599
}
542600
cm.off('scroll', this.onScroll);
601+
602+
removeInlineHint(cm);
543603
},
544604

545605
disable: function () {
@@ -561,7 +621,12 @@
561621
if (i >= this.data.list.length)
562622
i = avoidWrap ? this.data.list.length - 1 : 0;
563623
else if (i < 0) i = avoidWrap ? 0 : this.data.list.length - 1;
564-
if (this.selectedHint == i) return;
624+
625+
if (this.selectedHint == i) {
626+
changeInlineHint(this.completion.cm, this.data.list[this.selectedHint]);
627+
return this.data.list[this.selectedHint];
628+
}
629+
565630
var node = this.hints.childNodes[this.selectedHint];
566631
if (node) {
567632
node.className = node.className.replace(
@@ -583,6 +648,9 @@
583648
this.data.list[this.selectedHint],
584649
node
585650
);
651+
652+
changeInlineHint(this.completion.cm, this.data.list[this.selectedHint]);
653+
return this.data.list[this.selectedHint];
586654
},
587655

588656
scrollToActive: function () {

client/styles/abstracts/_variables.scss

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,23 @@ $themes: (
123123
hint-item-border-bottom-color: $white,
124124
hint-fun-text-color: #0B7CA9,
125125
hint-var-text-color: #D52889,
126+
hint-keyword-text-color: #7A5A3A,
126127
hint-type-text-color: $medium-dark,
127128
hint-arrow-color: $lightest,
128129
hint-arrow-background-color: #ed225ddd,
129130
hint-arrow-background-active-color: $p5js-active-pink,
130131
hint-arrow-focus-outline-color: $middle-dark,
132+
hint-no-link-background-color: $medium-light,
131133
hint-item-hover-background-color: #f4f4f4,
132134
hint-item-active-text-color: $white,
133135
hint-item-active-background-color: $middle-gray,
134136
hint-fun-active-border-bottom-color: #0B7CA9,
135137
hint-var-active-border-bottom-color: #D52889,
136138
hint-item-active-type-text-color: $white,
137139
hint-item-active-outline: none,
138-
hint-item-active-outline-offset: 0
140+
hint-item-active-outline-offset: 0,
141+
hint-inline-text-color-light: $middle-light,
142+
hint-inline-text-color: $middle-gray,
139143
),
140144
dark: (
141145
logo-color: $p5js-pink,
@@ -222,19 +226,23 @@ $themes: (
222226
hint-item-border-bottom-color: $darker,
223227
hint-fun-text-color: #0F9DD7,
224228
hint-var-text-color: #DE4A9B,
229+
hint-keyword-text-color: #B58318,
225230
hint-type-text-color: $light,
226231
hint-arrow-color: $lightest,
227232
hint-arrow-background-color: #ed225ddd,
228233
hint-arrow-background-active-color: $p5js-active-pink,
229234
hint-arrow-focus-outline-color: #cfcfcf,
235+
hint-no-link-background-color: $medium-dark,
230236
hint-item-hover-background-color: $medium-dark,
231237
hint-item-active-text-color: $darker,
232238
hint-item-active-background-color: #cfcfcf,
233239
hint-fun-active-border-bottom-color: #0F9DD7,
234240
hint-var-active-border-bottom-color: #DE4A9B,
235241
hint-item-active-type-text-color: $darker,
236242
hint-item-active-outline: none,
237-
hint-item-active-outline-offset: 0
243+
hint-item-active-outline-offset: 0,
244+
hint-inline-text-color-light: $middle-gray,
245+
hint-inline-text-color: #cfcfcf,
238246
),
239247
contrast: (
240248
logo-color: $yellow,
@@ -321,19 +329,23 @@ $themes: (
321329
hint-item-border-bottom-color: $medium-dark,
322330
hint-fun-text-color: #00FFFF,
323331
hint-var-text-color: #FFA9D9,
332+
hint-keyword-text-color: #F5DC23,
324333
hint-type-text-color: $middle-light,
325334
hint-arrow-color: $darker,
326335
hint-arrow-background-color: #F5DC23DD,
327336
hint-arrow-background-active-color: #F5DC23,
328337
hint-arrow-focus-outline-color: $lighter,
338+
hint-no-link-background-color: $medium-dark,
329339
hint-item-hover-background-color: $dark,
330340
hint-item-active-text-color: $lighter,
331341
hint-item-active-background-color: unset,
332342
hint-fun-active-border-bottom-color: none,
333343
hint-var-active-border-bottom-color: none,
334344
hint-item-active-type-text-color: $lighter,
335345
hint-item-active-outline: 2px solid $lighter,
336-
hint-item-active-outline-offset: -2px
346+
hint-item-active-outline-offset: -2px,
347+
hint-inline-text-color-light: $middle-gray,
348+
hint-inline-text-color: #cfcfcf,
337349
)
338350
);
339351

client/styles/components/_hints.scss

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,17 @@
3131
height: 100%;
3232
}
3333

34-
.fun-name {
34+
.fun-name, .obj-name {
3535
color: getThemifyVariable('hint-fun-text-color');
3636
}
3737

38-
.var-name {
38+
.var-name, .boolean-name {
3939
color: getThemifyVariable('hint-var-text-color');
4040
}
41+
42+
.keyword-name {
43+
color: getThemifyVariable('hint-keyword-text-color');
44+
}
4145

4246
.hint-type {
4347
color: getThemifyVariable('hint-type-text-color');
@@ -57,6 +61,11 @@
5761
outline-offset: #{-3 / $base-font-size}rem;
5862
}
5963
}
64+
65+
.no-link-placeholder {
66+
background: getThemifyVariable('hint-no-link-background-color');
67+
pointer-events: none;
68+
}
6069

6170
li.CodeMirror-hint-active:not(.unfocused) {
6271
background: getThemifyVariable('hint-item-active-background-color');
@@ -75,13 +84,17 @@
7584
color: getThemifyVariable('hint-item-active-text-color');
7685
}
7786

78-
.fun-name {
87+
.fun-name, .obj-name {
7988
background-color: getThemifyVariable('hint-fun-text-color');
8089
}
8190

82-
.var-name {
91+
.var-name, .boolean-name {
8392
background-color: getThemifyVariable('hint-var-text-color');
8493
}
94+
95+
.keyword-name {
96+
background-color: getThemifyVariable('hint-keyword-text-color');
97+
}
8598

8699
.hint-type, .plain-hint-item {
87100
color: getThemifyVariable('hint-item-active-type-text-color');
@@ -140,7 +153,7 @@
140153
@extend %hidden-element;
141154
}
142155

143-
a {
156+
a, .no-link-placeholder {
144157
position: absolute;
145158
top: 0;
146159
right: 0;
@@ -160,3 +173,31 @@
160173
}
161174
}
162175
}
176+
177+
// Inline hinter
178+
.CodeMirror-widget {
179+
line-height: inherit;
180+
181+
@include themify() {
182+
.autocomplete-inline-hinter {
183+
// make the border left look like a cursor and animate like a cursor
184+
// border-left: #{1.2 / $base-font-size}rem solid getThemifyVariable(hint-inline-text-color);
185+
// animation: inline-hint-caret-blink 1s step-end infinite;
186+
pointer-events: none;
187+
188+
.inline-hinter-suggestion {
189+
color: getThemifyVariable(hint-inline-text-color);
190+
font-style: italic;
191+
}
192+
193+
.inline-hinter-suggestion-light {
194+
color: getThemifyVariable(hint-inline-text-color-light);
195+
font-style: italic;
196+
}
197+
}
198+
}
199+
}
200+
201+
@keyframes inline-hint-caret-blink {
202+
50% { border-color: transparent; }
203+
}

0 commit comments

Comments
 (0)