React-ace: Cara menggunakan mode kustom

Dibuat pada 6 Jul 2016  ·  19Komentar  ·  Sumber: securingsincity/react-ace

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

Komentar yang paling membantu

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.

Semua 19 komentar

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:
screen shot 2016-07-19 at 18 23 14

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:

  1. Membuat kelas mode kustom saya (kode ES6 murni)
  2. Menginisialisasi komponen dengan nama mode yang ada (seperti "sql")
  3. Menggunakan fungsi 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.

custom_mode

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.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

nenadlukic picture nenadlukic  ·  6Komentar

Yuanye picture Yuanye  ·  7Komentar

Bobcui001 picture Bobcui001  ·  5Komentar

huangjiatian picture huangjiatian  ·  7Komentar

venil7 picture venil7  ·  3Komentar