Hai,
Pertanyaan saya mungkin agak bodoh (maaf untuk itu), tetapi saya tidak tahu cara menggunakan mode kustom/penyorot sintaks/pelengkapan otomatis. Ada yang bisa bantu saya? Saya sangat baru dalam hal brace, ace, dan react, tetapi saya melihat beberapa materi tentang cara membuat dan mengatur mode kustom Anda menggunakan Ace. Apa yang saya tidak tahu adalah bagaimana melakukan hal yang sama dengan react-ace.
Kristen
Hai,
dan apa implementasi Anda? Saya dapat menunjukkan apa yang berhasil untuk saya. Saya tidak ingat persisnya, tetapi saya pikir saya juga harus menginstal perpustakaan brace
terlebih dahulu. Jadi
npm install -D brace react-ace
Dan ini adalah komponen saya dengan editor Ace:
import React from 'react'
import brace from 'brace'
import AceEditor from 'react-ace'
import 'brace/mode/javascript'
import 'brace/theme/tomorrow'
const MyEditor = () => {
return (
<AceEditor
name="my-editor"
mode="javascript"
theme="tomorrow"
value=""
width="100%"
height="500px" />
)
}
export default MyEditor
Dan ini screenshotnya:
Saya memang bisa menggunakan mode default dari brace. Yang saya heran adalah bagaimana cara menggunakan mode saya sendiri? Saya menulis mode khusus sendiri dan ingin memasukkannya, tetapi sejauh ini tidak dapat melakukannya dengan react-ace.
@sichvoge Apakah Anda membuat kemajuan dalam hal ini sama sekali?
Tidak juga. Pada akhirnya saya mengembangkan komponen reaksi saya sendiri menggunakan Ace dan bukan brace.
Cukup adil - mungkin Anda bisa membagikannya saat Anda senang? Terima kasih @sichvoge
Pasti aku akan.
@sichvoge , dapatkah Anda membagikan komponen Anda?
Saya mengalami masalah yang sama dan itu akan sangat membantu :)
Saya mencoba melakukan hal serupa. Mengimpor mode di ujung depan sepertinya tidak berhasil untuk saya.
Tampaknya AceEditor mencarinya sebagai file sisi server. Jadi saya akhirnya hanya menyajikan file mode secara terpisah ke skrip paket webpack saya. (Ini mungkin sama sekali bukan cara yang tepat untuk melakukannya tetapi tampaknya berhasil ....)
Jadi katakan mode kustom saya disebut 'eikelang'
Kode React saya terlihat seperti ini
import React from 'react';
import AceEditor from 'react-ace';
import 'brace/theme/github';
export default ({value}) => {
<AceEditor
mode="eikelang"
theme="github"
width="auto"
height="200px"
value={value}
/>
};
Saya memiliki file js bernama 'mode-eikelang.js' yang disajikan dari direktori root server saya, yang hanya merupakan rip off dari file mode brace mysql dengan beberapa nama diubah:
ace.define('ace/mode/doc_comment_highlight_rules',
['require', 'exports', 'module', 'ace/lib/oop', 'ace/mode/text_highlight_rules'],
function(acequire, exports, module) {
'use strict';
let oop = acequire('../lib/oop');
let TextHighlightRules = acequire('./text_highlight_rules').TextHighlightRules;
var DocCommentHighlightRules = function() {
this.$rules = {
'start': [{
token: 'comment.doc.tag',
regex: '@[\\w\\d_]+' // TODO: fix email addresses
},
DocCommentHighlightRules.getTagRule(),
{
defaultToken: 'comment.doc',
caseInsensitive: true
}]
};
};
oop.inherits(DocCommentHighlightRules, TextHighlightRules);
DocCommentHighlightRules.getTagRule = function(start) {
return {
token: 'comment.doc.tag.storage.type',
regex: '\\b(?:TODO|FIXME|XXX|HACK)\\b'
};
};
DocCommentHighlightRules.getStartRule = function(start) {
return {
token: 'comment.doc', // doc comment
regex: '\\/\\*(?=\\*)',
next: start
};
};
DocCommentHighlightRules.getEndRule = function(start) {
return {
token: 'comment.doc', // closing comment
regex: '\\*\\/',
next: start
};
};
exports.DocCommentHighlightRules = DocCommentHighlightRules;
});
ace.define('ace/mode/eikelang_highlight_rules', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/lang', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(acequire, exports, module) {
let oop = acequire('../lib/oop');
let lang = acequire('../lib/lang');
let DocCommentHighlightRules = acequire('./doc_comment_highlight_rules').DocCommentHighlightRules;
let TextHighlightRules = acequire('./text_highlight_rules').TextHighlightRules;
let EikelangHighlightRules = function() {
let builtins = 'drop|hash|keep|linear_transformation|map|rename|string_manipulation|string_submatcher';
let keywordMapper = this.createKeywordMapper({
'support.function': builtins
}, 'identifier', true);
function string(rule) {
let start = rule.start;
let escapeSeq = rule.escape;
return {
token: 'string.start',
regex: start,
next: [
{token: 'constant.language.escape', regex: escapeSeq},
{token: 'string.end', next: 'start', regex: start},
{defaultToken: 'string'}
]
};
}
this.$rules = {
'start': [{
token: 'comment', regex: '(?:-- |#).*$'
},
string({start: '"', escape: /\\[0'"bnrtZ\\%_]?/}),
string({start: '\'', escape: /\\[0'"bnrtZ\\%_]?/}),
DocCommentHighlightRules.getStartRule('doc-start'),
{
token: 'comment', // multi line comment
regex: /\/\*/,
next: 'comment'
}, {
token: 'constant.numeric', // hex
regex: /0[xX][0-9a-fA-F]+|[xX]'[0-9a-fA-F]+'|0[bB][01]+|[bB]'[01]+'/
}, {
token: 'constant.numeric', // float
regex: '[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b'
}, {
token: keywordMapper,
regex: '[a-zA-Z_$][a-zA-Z0-9_$]*\\b'
}, {
token: 'constant.class',
regex: '@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\b'
}, {
token: 'constant.buildin',
regex: '`[^`]*`'
}, {
token: 'keyword.operator',
regex: '\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|='
}, {
token: 'paren.lparen',
regex: '[\\(]'
}, {
token: 'paren.rparen',
regex: '[\\)]'
}, {
token: 'text',
regex: '\\s+'
}],
'comment': [
{token: 'comment', regex: '\\*\\/', next: 'start'},
{defaultToken: 'comment'}
]
};
this.embedRules(DocCommentHighlightRules, 'doc-', [DocCommentHighlightRules.getEndRule('start')]);
this.normalizeRules();
};
oop.inherits(EikelangHighlightRules, TextHighlightRules);
exports.EikelangHighlightRules = EikelangHighlightRules;
});
ace.define('ace/mode/eikelang', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/mode/text', 'ace/mode/eikelang_highlight_rules'],
function(acequire, exports, module) {
let oop = acequire('../lib/oop');
let TextMode = acequire('../mode/text').Mode;
let EikelangHighlightRules = acequire('./eikelang_highlight_rules').EikelangHighlightRules;
let Mode = function() {
this.HighlightRules = EikelangHighlightRules;
this.$behaviour = this.$defaultBehaviour;
};
oop.inherits(Mode, TextMode);
(function() {
this.lineCommentStart = ['--', '#']; // todo space
this.blockComment = {start: '/*', end: '*/'};
this.$id = 'ace/mode/eikelang';
}).call(Mode.prototype);
exports.Mode = Mode;
});
Hai @pollen8 ,
Jika Anda melihat kode react-ace, Anda akan melihat bahwa komponen mencoba mengatur mode menggunakan namanya
Artinya Anda harus memastikan mode Anda sudah ada di cache "Ace" menggunakan ace.define
dan oop.inherits(Mode, TextMode)
dan kode Ace asli lainnya, yang menurut saya cukup lama ketika Anda memiliki ES6 di pihak Anda.
Jadi mengapa tidak menulis mode kustom Anda seperti kami menulis kelas lain?
Itu akan membuat kelas mode kustom Anda terlihat lebih baik
(lebih sedikit baris kode + sintaks yang lebih baik => lebih sedikit perawatan)
Jadi saya:
componentDidMount
dan memanggil session.setMode
dengan instance mode kustom saya.Mode kustom saya adalah:
export default class CustomSqlMode extends ace.acequire('ace/mode/text').Mode {
constructor(){
super();
// Your code goes here
}
}
Dan kode react-ace saya terlihat seperti:
render() {
return <div>
<AceEditor
ref="aceEditor"
mode="sql" // Default value since this props must be set.
theme="chrome" // Default value since this props must be set.
/>
</div>;
}
componentDidMount() {
const customMode = new CustomSqlMode();
this.refs.aceEditor.editor.getSession().setMode(customMode);
}
Satu-satunya downside yang dilihatnya adalah tergantung pada ace.acequire('ace/mode/text').Mode
untuk menjadi baris yang valid ketika saya mendefinisikan kelas mode.
Tapi itu tetap valid karena react-ace menempatkan modul "ace" di bawah window.ace (https://github.com/ajaxorg/ace/blob/4c7e5eb3f5d5ca9434847be51834a4e41661b852/lib/ace/worker/worker.js#L19)
@AlonBe @pollen8
Adakah yang punya jsfiddle atau contoh yang berfungsi untuk ini?
Mencoba mengikuti petunjuk yang @AlonBe terdaftar dengan mode kustom yang disediakan oleh @ pollen8 dan sayangnya saya tidak bisa mendapatkan penyorot sintaks untuk mendaftar dengan benar... :(
Bantuan apa pun akan dihargai.
Di mana editor saya sedang dirender:
componentDidMount () {
const customMode = new CustomSqlMode();
this.refs.ace.editor.getSession().setMode(test);
console.log(customMode);
}
@solemnify , Apakah Anda mencoba melakukan this.refs.ace.editor.getSession().setMode(customMode);
?
Coba ikuti kelas CustomSqlMode yang saya buat.
Untuk melihat apakah itu berfungsi, Anda dapat memasukkan baris berikut ke dalam konstruktor:
this.lineCommentStart = '--';
Jika Anda ingin menggunakan penyorot sintaks, Anda perlu mengganti this.HighlightRules
dari kelas mode kustom.
Lihatlah salah satu mode saat ini seperti sql_mode
@AlonBe
Bisakah Anda memberikan contoh kode untuk dimasukkan ke dalam komponen CustomSqlMode Anda?
Saya tidak tahu cara mengubah aturan sorotan di es6 ...
Terima kasih sebelumnya atas bantuan Anda.
Kode berikut berfungsi untuk saya:
aplikasi.js
import React, { Component } from 'react';
import brace from 'brace';
import AceEditor from 'react-ace';
import CustomSqlMode from './CustomSqlMode.js'
import 'brace/theme/github';
class App extends Component {
componentDidMount() {
const customMode = new CustomSqlMode();
this.refs.aceEditor.editor.getSession().setMode(customMode);
}
render() {
return (
<div className="App">
<AceEditor
ref="aceEditor"
mode="text"
theme="github"
name="UNIQUE_ID_OF_DIV"
editorProps={{ $blockScrolling: true }}
/>
</div>
);
}
}
export default App;
CustomSqlMode.js
import 'brace/mode/java';
export class CustomHighlightRules extends window.ace.acequire("ace/mode/text_highlight_rules").TextHighlightRules {
constructor() {
super();
this.$rules = {
"start": [{
token: "comment",
regex: "#.*$"
}, {
token: "string",
regex: '".*?"'
}]
};
}
}
export default class CustomSqlMode extends window.ace.acequire('ace/mode/java').Mode {
constructor() {
super();
this.HighlightRules = CustomHighlightRules;
}
}
Kode sebelumnya hanya menyoroti komentar dan string. Saya tidak yakin apakah yang saya lakukan adalah praktik yang baik atau tidak, tetapi setidaknya itu berhasil.
@newint33h terima kasih! Ini bekerja untuk saya.
@newint33h Saya mencoba menggunakan struktur ini tetapi mengeluh bahwa TypeError: Cannot read property 'editor' of undefined.
@shuotongli Saya memiliki masalah yang sama dan sepertinya masalah itu karena this.refs
React sekarang tidak digunakan lagi. Ada beberapa cara untuk membuat referensi, tergantung pada versi React yang Anda gunakan. Untuk cara yang saat ini didukung, lihat ini:
https://reactjs.org/docs/refs-and-the-dom.html#creating -refs
Kode berikut berfungsi untuk saya:
aplikasi.js
import React, { Component } from 'react'; import brace from 'brace'; import AceEditor from 'react-ace'; import CustomSqlMode from './CustomSqlMode.js' import 'brace/theme/github'; class App extends Component { componentDidMount() { const customMode = new CustomSqlMode(); this.refs.aceEditor.editor.getSession().setMode(customMode); } render() { return ( <div className="App"> <AceEditor ref="aceEditor" mode="text" theme="github" name="UNIQUE_ID_OF_DIV" editorProps={{ $blockScrolling: true }} /> </div> ); } } export default App;
CustomSqlMode.js
import 'brace/mode/java'; export class CustomHighlightRules extends window.ace.acequire("ace/mode/text_highlight_rules").TextHighlightRules { constructor() { super(); this.$rules = { "start": [{ token: "comment", regex: "#.*$" }, { token: "string", regex: '".*?"' }] }; } } export default class CustomSqlMode extends window.ace.acequire('ace/mode/java').Mode { constructor() { super(); this.HighlightRules = CustomHighlightRules; } }
Kode sebelumnya hanya menyoroti komentar dan string. Saya tidak yakin apakah yang saya lakukan adalah praktik yang baik atau tidak, tetapi setidaknya itu berhasil.
mengapa mode='teks', apa artinya teks?
@TaurusWood , karena render
terjadi sebelum componentDidMount
- Anda harus melewati "mode" yang valid untuk react-ace Component.
nanti, pada componentDidMount
Anda dapat melihat bahwa kode menimpa mode itu ( setMode
)
dan BTW, jika saya tidak salah, mode='text' adalah mode dasar Ace yang ditimpa oleh yang lainnya
Adakah yang bisa menjelaskan mengapa itu tidak berfungsi lagi, semua kode saya ditafsirkan sebagai teks alih-alih file Java setelah mengatur mode khusus? Terima kasih
Kode berikut berfungsi untuk saya:
aplikasi.js
import React, { Component } from 'react'; import brace from 'brace'; import AceEditor from 'react-ace'; import CustomSqlMode from './CustomSqlMode.js' import 'brace/theme/github'; class App extends Component { componentDidMount() { const customMode = new CustomSqlMode(); this.refs.aceEditor.editor.getSession().setMode(customMode); } render() { return ( <div className="App"> <AceEditor ref="aceEditor" mode="text" theme="github" name="UNIQUE_ID_OF_DIV" editorProps={{ $blockScrolling: true }} /> </div> ); } } export default App;
CustomSqlMode.js
import 'brace/mode/java'; export class CustomHighlightRules extends window.ace.acequire("ace/mode/text_highlight_rules").TextHighlightRules { constructor() { super(); this.$rules = { "start": [{ token: "comment", regex: "#.*$" }, { token: "string", regex: '".*?"' }] }; } } export default class CustomSqlMode extends window.ace.acequire('ace/mode/java').Mode { constructor() { super(); this.HighlightRules = CustomHighlightRules; } }
Kode sebelumnya hanya menyoroti komentar dan string. Saya tidak yakin apakah yang saya lakukan adalah praktik yang baik atau tidak, tetapi setidaknya itu berhasil.
Komentar yang paling membantu
Kode berikut berfungsi untuk saya:
aplikasi.js
CustomSqlMode.js
Kode sebelumnya hanya menyoroti komentar dan string. Saya tidak yakin apakah yang saya lakukan adalah praktik yang baik atau tidak, tetapi setidaknya itu berhasil.