Browse Source

added domkit completion

Nicolas Cannasse 1 year ago
parent
commit
37cda30fdb
4 changed files with 84 additions and 19 deletions
  1. 35 0
      hide/comp/CodeEditor.hx
  2. 46 4
      hide/comp/DomkitEditor.hx
  3. 2 14
      hide/comp/ScriptEditor.hx
  4. 1 1
      libs/monaco/Languages.hx

+ 35 - 0
hide/comp/CodeEditor.hx

@@ -2,6 +2,10 @@ package hide.comp;
 
 class CodeEditor extends Component {
 
+	static var INIT_DONE = false;
+	static var COMPLETIONS = [];
+
+	var lang : String;
 	var editor : monaco.ScriptEditor;
 	var errorMessage : Element;
 	var currrentDecos : Array<String> = [];
@@ -10,8 +14,17 @@ class CodeEditor extends Component {
 	public var saveOnBlur : Bool = true;
 
 	public function new( code : String, lang : String, ?parent : Element, ?root : Element ) {
+
+		if( !INIT_DONE ) {
+			INIT_DONE = true;
+			(monaco.Languages : Dynamic).typescript.javascriptDefaults.setCompilerOptions({ noLib: true, allowNonTsExtensions: true }); // disable js stdlib completion
+			(monaco.Languages : Dynamic).html.htmlDefaults.setModeConfiguration({ completionItems : false });
+			(monaco.Languages : Dynamic).css.lessDefaults.setModeConfiguration({ completionItems : false });
+		}
+
 		super(parent,root);
 		var root = element;
+		this.lang = lang;
 		root.addClass("codeeditor");
 		root.on("keydown", function(e) {
 			if( e.keyCode == 27 && root.find(".suggest-widget.visible").length == 0 ) onClose();
@@ -38,6 +51,28 @@ class CodeEditor extends Component {
 		errorMessage = new Element('<div class="codeErrorMessage"></div>').appendTo(root).hide();
 	}
 
+	function initCompletion( ?chars ) {
+		if( COMPLETIONS.indexOf(lang) < 0 ) {
+			COMPLETIONS.push(lang);
+			monaco.Languages.registerCompletionItemProvider(lang, {
+				triggerCharacters : chars,
+				provideCompletionItems : function(model,position,_,_) {
+					var comp : CodeEditor = (model : Dynamic).__comp__;
+			        var code = model.getValueInRange({startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column});
+					var res = comp.getCompletion(code.length);
+					for( r in res )
+						if( r.insertText == null )
+							r.insertText = r.label;
+					return { suggestions : res };
+				}
+			});
+		}
+	}
+
+	function getCompletion( position : Int ) : Array<monaco.Languages.CompletionItem> {
+		return [];
+	}
+
 	function clearSpaces() {
 		var code = code;
 		var newCode = [for( l in StringTools.trim(code).split("\n") ) StringTools.rtrim(l)].join("\n");

+ 46 - 4
hide/comp/DomkitEditor.hx

@@ -51,9 +51,9 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 
 	var t_string : Type;
 	var parsers : Array<domkit.CssValue.ValueParser>;
-	var components : Map<String, TypedComponent>;
-	var properties : Map<String, Array<TypedProperty>>;
-	var definedIdents : Map<String, Array<TypedComponent>>;
+	public var components : Map<String, TypedComponent>;
+	public var properties : Map<String, Array<TypedProperty>>;
+	public var definedIdents : Map<String, Array<TypedComponent>>;
 
 	public function new(config) {
 		super(config,"domkit");
@@ -533,7 +533,14 @@ class DomkitEditor extends CodeEditor {
 
 	public function new( config, kind, code : String, ?checker, ?parent : Element, ?root : Element ) {
 		this.kind = kind;
-		super(code, kind == DML ? "html" : "less", parent, root);
+		var lang = kind == DML ? "html" : "less";
+		super(code, lang, parent, root);
+		switch( kind ) {
+		case DML:
+			initCompletion(["<","/"]);
+		case Less:
+			initCompletion();
+		}
 		saveOnBlur = false;
 		if( checker == null )
 			checker = new DomkitChecker(config);
@@ -557,4 +564,39 @@ class DomkitEditor extends CodeEditor {
 		}
 	}
 
+	override function getCompletion( position : Int ) {
+		var code = code;
+		var results = super.getCompletion(position);
+		for( c in checker.components )
+			results.push({
+				kind : Class,
+				label : c.name,
+			});
+		if( kind == DML && (code.charCodeAt(position-1) == "<".code || code.charCodeAt(position-1) == "/".code) )
+			return results;
+		for( pname => pl in checker.properties ) {
+			var p = pl[0];
+			results.push({
+				kind : Field,
+				label : kind == Less ? pname : p.field,
+			});
+		}
+		switch( kind ) {
+		case Less:
+			for( c => def in checker.constants )
+				results.push({
+					kind : Property,
+					label : "@"+c,
+					detail : domkit.CssParser.valueStr(def),
+				});
+			for( id in checker.definedIdents.keys() )
+				results.push({
+					kind : Property,
+					label : id.charCodeAt(0) == "#".code ? id : "."+id,
+				});
+		case DML:
+		}
+		return results;
+	}
+
 }

+ 2 - 14
hide/comp/ScriptEditor.hx

@@ -375,23 +375,10 @@ class ScriptChecker {
 
 class ScriptEditor extends CodeEditor {
 
-	static var INIT_DONE = false;
 	var checker : ScriptChecker;
 	var checkTypes : Bool;
 
 	public function new( script : String, ?checker : ScriptChecker, ?parent : Element, ?root : Element, ?lang ) {
-		if( !INIT_DONE ) {
-			INIT_DONE = true;
-			(monaco.Languages : Dynamic).typescript.javascriptDefaults.setCompilerOptions({ noLib: true, allowNonTsExtensions: true }); // disable js stdlib completion
-			monaco.Languages.registerCompletionItemProvider("javascript", {
-				triggerCharacters : ["."],
-				provideCompletionItems : function(model,position,_,_) {
-					var comp : ScriptEditor = (model : Dynamic).__comp__;
-			        var code = model.getValueInRange({startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column});
-					return comp.getCompletion(code.length);
-				}
-			});
-		}
 		super(script, lang, parent,root);
 		if( checker == null ) {
 			checker = new ScriptChecker(new hide.Config(),"");
@@ -408,10 +395,11 @@ class ScriptEditor extends CodeEditor {
 		}
 		this.checker = checker;
 		onChanged = doCheckScript;
+		initCompletion(["."]);
 		haxe.Timer.delay(function() doCheckScript(), 0);
 	}
 
-	function getCompletion( position : Int ) : Array<monaco.Languages.CompletionItem> {
+	override function getCompletion( position : Int ) : Array<monaco.Languages.CompletionItem> {
 		var script = code.substr(0,position);
 		var vars = checker.checker.getGlobals();
 		if( script.charCodeAt(script.length-1) == ".".code ) {

+ 1 - 1
libs/monaco/Languages.hx

@@ -2,7 +2,7 @@ package monaco;
 
 typedef CompletionProvider = {
 	var ?triggerCharacters : Array<String>;
-	function provideCompletionItems( model : Model, position : Position, token : Any, context : CompletionContext ) : Array<CompletionItem>;
+	function provideCompletionItems( model : Model, position : Position, token : Any, context : CompletionContext ) : { suggestions : Array<CompletionItem> };
 }
 
 typedef CompletionContext = {