-
Notifications
You must be signed in to change notification settings - Fork 104
Ace Mode
-
The previous editor mode was adapted from the built-in javascript mode from ace-builds. Previously, js-slang made use of the default javascript mode from the ace-builds library. However, as Source Academy is growing in size, there is an urgent need to customize the editor mode to better suit the need of the Source Academy.
-
Currently, we have developed our customized ace editor designed specially for source. We shall take a closer look at the benefits brought by the customized ace editor in the following page.
-
-
The customized source mode is stored inside js-slang as an api for cadet-front to use:
- To include source mode, simply import it from js-slang as follows.
import { HighlightRulesSelector, ModeSelector } from 'js-slang/dist/editors/ace/modes/source'; import 'js-slang/dist/editors/ace/theme/source';
-
Separation of Source Chapters:
-
Previously, by importing javascript mode from ace-builds as a bulk, we lack flexibility to adjust for the difference between different source chapters. Now, with source mode, we can specify the special features we want to include for different chapters.
export function HighlightRulesSelector(id: number) { // @ts-ignore function _SourceHighlightRules(acequire, exports, module) {
As shown in the above code from source.ts inside js-slang, the function
HighlightRulesSelector
requiresid
as an argument. As such we can manipulate the function by including the chapter id and the features to be developed. This makes further extension of the source mode much more convenient.
-
-
Composition:
- The current source mode is composed of two parts: The _SourceHighlightRules and the _Mode. The _SourceHighlighRules involves codes relating to the categorisation of tokens and the parsing method, while the _Mode takes the _SourceHighlightRules and integrate it with Javascript Mode to ensure that source functions properly as a subset of Javascript language.
-
-
-
Syntax highlighting Respect to Source Chapters.
-
With the benefit provided by Source Mode, we can specified as set of functions, keywords and forbidden words inside source.ts and asks the _SourceHighlightRules to handle them for us.
const chapter1 = { keywords: 'const|else|if|return|function', functions: 'display|error|is_boolean|is_function|is_number|is_string|is_undefined|' + 'math_abs|math_acos|math_acosh|math_asin|math_asinh|math_atan|' + 'math_atan2|math_atanh|math_cbrt|math_ceil|math_clz32|' + 'math_cos|math_cosh|math_exp|math_expm1|math_floor|math_fround|math_hypot|math_imul|' + 'math_log|math_log1p|math_log2|math_log10|math_max|math_min|math_pow|math_random|' + 'math_round|math_sign|math_sin|math_sinh|math_sqrt|math_tan|math_tanh|' + 'math_tanh|math_trunc|parse_int|prompt|runtime|stringify' } const chapter2 = { keywords: '', functions: 'accumulate|append|build_list|' + 'draw_data|enum_list|equal|error|filter|for_each|head|' + 'is_pair|length|list|list_ref|list_to_string|' + 'map|member|pair|parse_int|prompt|remove|remove_all|reverse|runtime|tail' } const chapter3 = { keywords: 'while|for|break|continue|let', functions: 'array_length|build_stream|enum_stream|' + 'eval_stream|integers_from|is_array|is_stream|' + 'list_to_stream|set_head|set_tail|stream|stream_append|' + 'stream_filter|stream_for_each|stream_length|' + 'stream_map|stream_member|stream_ref|stream_remove|' + 'stream_remove_all|stream_reverse|stream_tail|stream_to_list' } const chapter34 = { keywords: '', functions: 'test_and_set|clear|concurrent_execute' } const chapter4 = { keywords: '', functions: 'apply_in_underlying_javascript' }
As shown in the above code, we have specified the functions and keywords to be used in different chapters as of Apr 2nd, 2020. We can easily edit this set in the future as source language progresses.
-
The source mode internally categorizes tokens into 5 different types:
support.function
,constant.language
,variable.language
,storage.type
, andkeyword
. Inside the editor, the tokens will be highlighted accordingly in different colours. Most importantly, this will respect the source chapter id. As such, we can define functions or keywords that are forbidden in certain chapters. -
Moreover, we can also highlight regex expressions. In the current version of source mode, we have already made an effort to highlight all expressions such as
+=
,++
,--
in pink, the forbidden colour. The related code is shown below:{ token: ['variable.language'], regex: /\.{3}|--+|\+\++|\^|(==|!=)[^=]|[$%&*+\-~\/^]=+|[^&]*&[^&]|[^\|]*\|[^\|]/ }, { token: 'keyword.operator', regex: /===|=|!==|<+=?|>+=?|!|&&|\|\||[%*+-\/]/, next: 'start' },
-
-
Supporting Editor
-
The source mode features discussed above allows more features to be built on. For example, the customized categorisation of tokens makes loop-up features in the cadet-front editor an easy job. Since we have defined the set of source functions, we can just ask
AceEditor
to check if a token is of the typesupport.function
and perform loop-ups. The code is shown below:{ name: 'navigate', bindKey: { win: 'Ctrl-B', mac: 'Command-B' }, exec: this.handleNavigate }, private handleNavigate = () => { const chapter = this.props.sourceChapter; const pos = (this.AceEditor.current as any).editor.selection.getCursor(); const token = (this.AceEditor.current as any).editor.session.getTokenAt(pos.row, pos.column); const url = LINKS.TEXTBOOK; if (token !== null && /\bsupport.function\b/.test(token.type)) { window.open(`${url}/source/source_${chapter}/global.html#${token.value}`); // opens the link } else if (token !== null && /\bstorage.type\b/.test(token.type)) { window.open(`${url}/source/source_${chapter}.pdf`); } };
As demonstrated in the code, we used
/\bsupport.function\b/.test(token.type)
to test if a token is of the typesupport.function
. Then we can perform the look-up.
-
-
- Currently, the Ace editor only provides source mode. In the future, we may include modes for other languages.
- Improve the mode to provide support for a smarter editor. The mode can be further improved to include features that make the editor more user friendly.
Zhou Zijian...
Hopefully more join in