Skip to content

Commit 4d9b05f

Browse files
authored
Merge pull request #3327 from processing/connie-editor-conversion-hint-file
Editor file splitting: create new hint file
2 parents 1b63a06 + 850845a commit 4d9b05f

File tree

2 files changed

+122
-111
lines changed

2 files changed

+122
-111
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import Fuse from 'fuse.js';
2+
import CodeMirror from 'codemirror';
3+
import { JSHINT } from 'jshint';
4+
import { HTMLHint } from 'htmlhint';
5+
import { CSSLint } from 'csslint';
6+
7+
import 'codemirror/addon/hint/css-hint';
8+
import * as hinterDefinition from '../../../../utils/p5-hinter';
9+
import '../show-hint'; // TODO: Remove for codemirror v6?
10+
11+
window.JSHINT = JSHINT;
12+
window.CSSLint = CSSLint;
13+
window.HTMLHint = HTMLHint;
14+
15+
const hinter = new Fuse(hinterDefinition.p5Hinter, {
16+
threshold: 0.05,
17+
keys: ['text']
18+
});
19+
20+
/** Hides the hinter. */
21+
export function hideHinter(cmInstance) {
22+
CodeMirror.showHint(cmInstance, () => {}, {});
23+
}
24+
25+
/**
26+
* Shows a hint popup in the codemirror instance.
27+
* It will only be visible if the user has autocomplete on in the settings.
28+
*/
29+
export function showHint(cmInstance, autocompleteHinter, fontSize) {
30+
if (!autocompleteHinter) {
31+
CodeMirror.showHint(cmInstance, () => {}, {});
32+
return;
33+
}
34+
35+
let focusedLinkElement = null;
36+
const setFocusedLinkElement = (set) => {
37+
if (set && !focusedLinkElement) {
38+
const activeItemLink = document.querySelector(
39+
`.CodeMirror-hint-active a`
40+
);
41+
if (activeItemLink) {
42+
focusedLinkElement = activeItemLink;
43+
focusedLinkElement.classList.add('focused-hint-link');
44+
focusedLinkElement.parentElement.parentElement.classList.add(
45+
'unfocused'
46+
);
47+
}
48+
}
49+
};
50+
const removeFocusedLinkElement = () => {
51+
if (focusedLinkElement) {
52+
focusedLinkElement.classList.remove('focused-hint-link');
53+
focusedLinkElement.parentElement.parentElement.classList.remove(
54+
'unfocused'
55+
);
56+
focusedLinkElement = null;
57+
return true;
58+
}
59+
return false;
60+
};
61+
62+
const hintOptions = {
63+
_fontSize: fontSize,
64+
completeSingle: false,
65+
extraKeys: {
66+
'Shift-Right': (cm, e) => {
67+
const activeItemLink = document.querySelector(
68+
`.CodeMirror-hint-active a`
69+
);
70+
if (activeItemLink) activeItemLink.click();
71+
},
72+
Right: (cm, e) => {
73+
setFocusedLinkElement(true);
74+
},
75+
Left: (cm, e) => {
76+
removeFocusedLinkElement();
77+
},
78+
Up: (cm, e) => {
79+
const onLink = removeFocusedLinkElement();
80+
e.moveFocus(-1);
81+
setFocusedLinkElement(onLink);
82+
},
83+
Down: (cm, e) => {
84+
const onLink = removeFocusedLinkElement();
85+
e.moveFocus(1);
86+
setFocusedLinkElement(onLink);
87+
},
88+
Enter: (cm, e) => {
89+
if (focusedLinkElement) focusedLinkElement.click();
90+
else e.pick();
91+
}
92+
},
93+
closeOnUnfocus: false
94+
};
95+
96+
if (cmInstance.options.mode === 'javascript') {
97+
CodeMirror.showHint(
98+
cmInstance,
99+
() => {
100+
const cursor = cmInstance.getCursor();
101+
const token = cmInstance.getTokenAt(cursor);
102+
103+
const hints = hinter
104+
.search(token.string)
105+
.filter((h) => h.item.text[0] === token.string[0]);
106+
107+
return {
108+
list: hints,
109+
from: CodeMirror.Pos(cursor.line, token.start),
110+
to: CodeMirror.Pos(cursor.line, cursor.ch)
111+
};
112+
},
113+
hintOptions
114+
);
115+
} else if (cmInstance.options.mode === 'css') {
116+
CodeMirror.showHint(cmInstance, CodeMirror.hint.css, hintOptions);
117+
}
118+
}

client/modules/IDE/components/Editor/index.jsx

Lines changed: 4 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import PropTypes from 'prop-types';
44
import React from 'react';
55
import CodeMirror from 'codemirror';
6-
import Fuse from 'fuse.js';
76
import emmet from '@emmetio/codemirror-plugin';
87
import prettier from 'prettier/standalone';
98
import babelParser from 'prettier/parser-babel';
@@ -33,12 +32,8 @@ import 'codemirror/addon/search/jump-to-line';
3332
import 'codemirror/addon/edit/matchbrackets';
3433
import 'codemirror/addon/edit/closebrackets';
3534
import 'codemirror/addon/selection/mark-selection';
36-
import 'codemirror/addon/hint/css-hint';
3735
import 'codemirror-colorpicker';
3836

39-
import { JSHINT } from 'jshint';
40-
import { CSSLint } from 'csslint';
41-
import { HTMLHint } from 'htmlhint';
4237
import classNames from 'classnames';
4338
import { debounce } from 'lodash';
4439
import { connect } from 'react-redux';
@@ -47,8 +42,6 @@ import MediaQuery from 'react-responsive';
4742
import '../../../../utils/htmlmixed';
4843
import '../../../../utils/p5-javascript';
4944
import { metaKey } from '../../../../utils/metaKey';
50-
import '../show-hint';
51-
import * as hinter from '../../../../utils/p5-hinter';
5245
import '../../../../utils/codemirror-search';
5346

5447
import beepUrl from '../../../../sounds/audioAlert.mp3';
@@ -73,11 +66,9 @@ import { EditorContainer, EditorHolder } from './MobileEditor';
7366
import { FolderIcon } from '../../../../common/icons';
7467
import IconButton from '../../../../common/IconButton';
7568

76-
emmet(CodeMirror);
69+
import { showHint, hideHinter } from './hinter';
7770

78-
window.JSHINT = JSHINT;
79-
window.CSSLint = CSSLint;
80-
window.HTMLHint = HTMLHint;
71+
emmet(CodeMirror);
8172

8273
const INDENTATION_AMOUNT = 2;
8374

@@ -146,11 +137,6 @@ class Editor extends React.Component {
146137
}
147138
});
148139

149-
this.hinter = new Fuse(hinter.p5Hinter, {
150-
threshold: 0.05,
151-
keys: ['text']
152-
});
153-
154140
delete this._cm.options.lint.options.errors;
155141

156142
const replaceCommand =
@@ -207,7 +193,7 @@ class Editor extends React.Component {
207193
// Show hint
208194
const mode = this._cm.getOption('mode');
209195
if (/^[a-z]$/i.test(e.key) && (mode === 'css' || mode === 'javascript')) {
210-
this.showHint(_cm);
196+
showHint(_cm, this.props.autocompleteHinter, this.props.fontSize);
211197
}
212198
if (e.key === 'Escape') {
213199
e.preventDefault();
@@ -283,7 +269,7 @@ class Editor extends React.Component {
283269
if (this.props.autocompleteHinter !== prevProps.autocompleteHinter) {
284270
if (!this.props.autocompleteHinter) {
285271
// close the hinter window once the preference is turned off
286-
CodeMirror.showHint(this._cm, () => {}, {});
272+
hideHinter(this._cm);
287273
}
288274
}
289275

@@ -378,99 +364,6 @@ class Editor extends React.Component {
378364
this._cm.execCommand('findPersistent');
379365
}
380366

381-
showHint(_cm) {
382-
if (!this.props.autocompleteHinter) {
383-
CodeMirror.showHint(_cm, () => {}, {});
384-
return;
385-
}
386-
387-
let focusedLinkElement = null;
388-
const setFocusedLinkElement = (set) => {
389-
if (set && !focusedLinkElement) {
390-
const activeItemLink = document.querySelector(
391-
`.CodeMirror-hint-active a`
392-
);
393-
if (activeItemLink) {
394-
focusedLinkElement = activeItemLink;
395-
focusedLinkElement.classList.add('focused-hint-link');
396-
focusedLinkElement.parentElement.parentElement.classList.add(
397-
'unfocused'
398-
);
399-
}
400-
}
401-
};
402-
const removeFocusedLinkElement = () => {
403-
if (focusedLinkElement) {
404-
focusedLinkElement.classList.remove('focused-hint-link');
405-
focusedLinkElement.parentElement.parentElement.classList.remove(
406-
'unfocused'
407-
);
408-
focusedLinkElement = null;
409-
return true;
410-
}
411-
return false;
412-
};
413-
414-
const hintOptions = {
415-
_fontSize: this.props.fontSize,
416-
completeSingle: false,
417-
extraKeys: {
418-
'Shift-Right': (cm, e) => {
419-
const activeItemLink = document.querySelector(
420-
`.CodeMirror-hint-active a`
421-
);
422-
if (activeItemLink) activeItemLink.click();
423-
},
424-
Right: (cm, e) => {
425-
setFocusedLinkElement(true);
426-
},
427-
Left: (cm, e) => {
428-
removeFocusedLinkElement();
429-
},
430-
Up: (cm, e) => {
431-
const onLink = removeFocusedLinkElement();
432-
e.moveFocus(-1);
433-
setFocusedLinkElement(onLink);
434-
},
435-
Down: (cm, e) => {
436-
const onLink = removeFocusedLinkElement();
437-
e.moveFocus(1);
438-
setFocusedLinkElement(onLink);
439-
},
440-
Enter: (cm, e) => {
441-
if (focusedLinkElement) focusedLinkElement.click();
442-
else e.pick();
443-
}
444-
},
445-
closeOnUnfocus: false
446-
};
447-
448-
if (_cm.options.mode === 'javascript') {
449-
// JavaScript
450-
CodeMirror.showHint(
451-
_cm,
452-
() => {
453-
const c = _cm.getCursor();
454-
const token = _cm.getTokenAt(c);
455-
456-
const hints = this.hinter
457-
.search(token.string)
458-
.filter((h) => h.item.text[0] === token.string[0]);
459-
460-
return {
461-
list: hints,
462-
from: CodeMirror.Pos(c.line, token.start),
463-
to: CodeMirror.Pos(c.line, c.ch)
464-
};
465-
},
466-
hintOptions
467-
);
468-
} else if (_cm.options.mode === 'css') {
469-
// CSS
470-
CodeMirror.showHint(_cm, CodeMirror.hint.css, hintOptions);
471-
}
472-
}
473-
474367
showReplace() {
475368
this._cm.execCommand('replace');
476369
}

0 commit comments

Comments
 (0)