CodeEditor.hx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package hide.comp;
  2. class CodeEditor extends Component {
  3. var editor : monaco.ScriptEditor;
  4. var errorMessage : Element;
  5. var currrentDecos : Array<String> = [];
  6. public var code(get,never) : String;
  7. public var propagateKeys : Bool = false;
  8. public function new( code : String, lang : String, ?parent : Element, ?root : Element ) {
  9. super(parent,root);
  10. var root = element;
  11. root.addClass("codeeditor");
  12. root.on("keydown", function(e) {
  13. if( e.keyCode == 27 && root.find(".suggest-widget.visible").length == 0 ) onClose();
  14. if( !propagateKeys ) e.stopPropagation();
  15. });
  16. editor = monaco.ScriptEditor.create(root[0],{
  17. value : code,
  18. language : lang == null ? "javascript" : lang,
  19. automaticLayout : true,
  20. wordWrap : true,
  21. minimap : { enabled : false },
  22. theme : "vs-dark",
  23. lineNumbersMinChars: 3,
  24. fontSize: "13px",
  25. mouseWheelZoom: true,
  26. scrollBeyondLastLine: false
  27. });
  28. var model = editor.getModel();
  29. (model : Dynamic).__comp__ = this;
  30. model.updateOptions({ insertSpaces:false, trimAutoWhitespace:true });
  31. editor.onDidChangeModelContent(function() onChanged());
  32. editor.onDidBlurEditorText(function() onSave());
  33. editor.addCommand(monaco.KeyCode.KEY_S | monaco.KeyMod.CtrlCmd, function() { clearSpaces(); onSave(); });
  34. errorMessage = new Element('<div class="codeErrorMessage"></div>').appendTo(root).hide();
  35. }
  36. function clearSpaces() {
  37. var code = code;
  38. var newCode = [for( l in StringTools.trim(code).split("\n") ) StringTools.rtrim(l)].join("\n");
  39. if( newCode != code ) {
  40. var p = editor.getPosition();
  41. setCode(newCode);
  42. editor.setPosition(p);
  43. }
  44. }
  45. function get_code() {
  46. return editor.getValue({preserveBOM:true});
  47. }
  48. public function setCode( code : String ) {
  49. editor.setValue(code);
  50. }
  51. public function focus() {
  52. editor.focus();
  53. }
  54. public dynamic function onChanged() {
  55. }
  56. public dynamic function onSave() {
  57. }
  58. public dynamic function onClose() {
  59. }
  60. public function clearError() {
  61. if( currrentDecos.length != 0 )
  62. currrentDecos = editor.deltaDecorations(currrentDecos,[]);
  63. errorMessage.toggle(false);
  64. }
  65. public function setError( msg : String, line : Int, pmin : Int, pmax : Int ) {
  66. var linePos = code.substr(0,pmin).lastIndexOf("\n");
  67. if( linePos < 0 ) linePos = 0 else linePos++;
  68. var range = new monaco.Range(line,pmin + 1 - linePos,line,pmax + 2 - linePos);
  69. currrentDecos = editor.deltaDecorations(currrentDecos,[
  70. { range : range, options : { inlineClassName: "codeErrorContentLine", isWholeLine : true } },
  71. { range : range, options : { linesDecorationsClassName: "codeErrorLine", inlineClassName: "codeErrorContent" } }
  72. ]);
  73. errorMessage.html([for( l in msg.split("\n") ) StringTools.htmlEscape(l)].join("<br/>"));
  74. errorMessage.toggle(true);
  75. var rect = errorMessage[0].getBoundingClientRect();
  76. if( rect.bottom > js.Browser.window.innerHeight )
  77. errorMessage[0].scrollIntoView(false);
  78. }
  79. }