ajaxorg / ace

Ace (Ajax.org Cloud9 Editor)
https://ace.c9.io
Other
26.54k stars 5.27k forks source link

Embed multiple syntax highlight #3435

Open log69 opened 6 years ago

log69 commented 6 years ago

I'm using ace editor with "html" mode for web programming as a web IDE. I can highlight code for HTMl, CSS and JavaScript. It works nicely, thank you for it. This is my code:

editor.getSession().setMode('ace/mode/html');

I'd like to embed coffeescript and typescript syntax highlight support too when using the

<script type='text/coffeescript'> ...some code... </script> <script type='text/typescript'> ...some code... </script>

tags in the editor. I am aware that Ace does have modes for these languages but they are separate files (mode-coffee.js and mode-typescript.js) and I don't know how I could embed these into mode-html.js to support the above. The code is rather complicated. Could you kindly help me out? I've been studying these files for days now and I'd appreciate any help.

Thank you.

DerekTBrown commented 6 years ago

@log69 I also would use this feature. I don't think this would be too hard to implement, and I certainly would be willing to submit a PR to do this. Before I do that- do the ace editor maintainers have any guidance about doing this?

nightwing commented 6 years ago

Unfortunately this is not trivial to implement either. I think to implement this clearly one needs to make some changes to edit_session to dynamically load modes, and some changes to tokenizer to support mode attribute on rule, similar to defaultToken https://github.com/ajaxorg/ace/blob/master/lib/ace/tokenizer.js#L63.

Alternatively it is possible to modify https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/html_highlight_rules.js#L102 to include more rules, and https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/xml_highlight_rules.js#L202 to switch type based on attribute too, but that would increase the size of html mode too much.

JoshMcCullough commented 3 years ago

FWIW this would be great to support a templating "mode" plus a markup "mode" -- e.g. FTL + HTML + JS for a full-featured FTL HTML/JS editor.

github-actions[bot] commented 2 years ago

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

JoshMcCullough commented 2 years ago

It's unclear to me if the related PR (https://github.com/Felienne/hedy/pull/1509) fixes this.

Felienne commented 2 years ago

It's unclear to me if the related PR (Felienne/hedy#1509) fixes this.

No, sadly it does not. We really wanted to have multiple syntax highlighters (we support multiple natural languages), but since ACE does not support that, we now "hack" that into one highlighter, with something like this:

( print | imprimir) text

If Ace would implement multiple ones that'd make my life easier! 😄

ashishkummar commented 7 months ago

Is it possible to achieve like this ?

    var mixedMode = {
      token: function(stream, state) {
          if (stream.match('<style')) {
              state.tokenize = tokenCSS;
              return 'tag';
          }
          if (stream.match('<', false)) {
              state.tokenize = tokenHTML;
              return 'tag';
          }
          stream.next();
          return null;
      }
  };

  function tokenHTML(stream, state) {
      if (stream.match('<style')) {
          state.tokenize = tokenCSS;
          return 'tag';
      }
      var ch;
      if (stream.match('<', false)) {
          return null;
      }
      while ((ch = stream.next()) != null) {
          if (ch == '<') {
              break;
          }
      }
      return 'text';
  }

  function tokenCSS(stream, state) {
      var ch;
      while ((ch = stream.next()) != null) {
          if (ch == '>') {
              state.tokenize = tokenHTML;
              return 'tag';
          }
      }
      return 'text/css';
  }

    editor.getSession().setMode({
      path: "ace/mode/matching_brace_out",
      v: mixedMode,
      multiSelectAction: function(state) {
          if (state == 0) {
              state = this.nextMatch;
          }
          if (state != 1) {
              state = 1;
              this.nextMatch = 2;
          } else {
              state = 0;
              this.nextMatch = 1;
          }
          return state;
      },
  });