From 0a78663551be8d10f36ec43fcb796e579ddf68a2 Mon Sep 17 00:00:00 2001 From: lxsang Date: Mon, 6 Dec 2021 12:30:26 +0100 Subject: [PATCH] improve antdedit output log display --- Antedit/README.md | 1 + Antedit/build/debug/README.md | 1 + Antedit/build/debug/main.js | 2 +- Antedit/build/debug/package.json | 2 +- Antedit/build/release/Antedit.zip | Bin 12554 -> 12597 bytes Antedit/package.json | 2 +- Antedit/ts/main.ts | 13 ++++++++++++- packages.json | 2 +- 8 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Antedit/README.md b/Antedit/README.md index 7ed266d..c9be55d 100644 --- a/Antedit/README.md +++ b/Antedit/README.md @@ -6,6 +6,7 @@ The editor functionality can be extended by its extension mechanism. Extension can be developed/released/isntalled by the editor itself. ### Change logs +- 0.1.14-b: improve output log display - 0.1.13-b: Allow file upload in file view, add menu context in tabbar - 0.1.12-b: fix recent files not adding correctly - 0.1.11-b: fix file type parsing from path diff --git a/Antedit/build/debug/README.md b/Antedit/build/debug/README.md index 7ed266d..c9be55d 100644 --- a/Antedit/build/debug/README.md +++ b/Antedit/build/debug/README.md @@ -6,6 +6,7 @@ The editor functionality can be extended by its extension mechanism. Extension can be developed/released/isntalled by the editor itself. ### Change logs +- 0.1.14-b: improve output log display - 0.1.13-b: Allow file upload in file view, add menu context in tabbar - 0.1.12-b: fix recent files not adding correctly - 0.1.11-b: fix file type parsing from path diff --git a/Antedit/build/debug/main.js b/Antedit/build/debug/main.js index cf7338b..b68f70f 100644 --- a/Antedit/build/debug/main.js +++ b/Antedit/build/debug/main.js @@ -1 +1 @@ -var OS;!function(t){let e;!function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.editormux=!1,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>this.editormux?(this.editormux=!1,!1):this.currfile.dirty?void 0:(this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0))),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let a=0;a(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(t){this.currfile.cache=this.getValue(),t.write("text/plain").then(e=>{t.dirty=!1,t.text=t.basename,this.tabbar.update(void 0)}).catch(e=>this.app.error(__("Unable to save file: {0}",t.path),e))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write(this.currfile):this.saveAs()}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write(this.currfile)})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.resetEditor()}isDirty(){return this.dirties().length>0}setTabbarCtxMenu(t,e){this.tabbar.contextmenuHandle=(i,a)=>(a.items=t,a.onmenuselect=t=>{if(e){const a=$(i.target).closest("afx-list-item");e(a[0],t.data.item.data)}},a.show(i))}}}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(e){class i extends t.application.BaseEditorModel{constructor(t,e,i){super(t,e,i)}resetEditor(){this.setValue("")}getTexModel(){return{model:this.editor.getModel(),position:this.editor.getPosition()}}setTextModel(t){this.editor.setModel(t.model),t.position&&(this.editor.setPosition(t.position),this.editor.revealLineInCenter(t.position.lineNumber))}newTextModelFrom(t){if("Untitled"===t.path.toString())return{model:monaco.editor.createModel(t.cache,"textplain")};const e=monaco.Uri.parse(t.protocol+"://antedit/file/"+t.genealogy.join("/")),i=monaco.editor.getModel(e);return i?(i.setValue(t.cache),{model:i}):{model:monaco.editor.createModel(t.cache,void 0,e)}}getModes(){return monaco.languages.getLanguages().map(t=>(t.text=t.aliases[0],t))}setTheme(t){}setMode(t){monaco.editor.setModelLanguage(this.editor.getModel(),t.id),this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}editorSetup(t){this.editor=monaco.editor.create(t,{value:"",language:"textplain"}),i.modes||(i.modes={},monaco.languages.getLanguages().forEach(t=>{i.modes[t.id]=t}))}on(t,e){switch(t){case"input":this.editor.onDidChangeModelContent(e);break;case"focus":this.editor.onDidFocusEditorText(e);break;case"changeCursor":this.editor.onDidChangeCursorPosition(e)}}resize(){this.editor&&this.editor.layout()}focus(){this.editor&&this.editor.focus()}getModeForPath(t){return{}}getEditorStatus(){const t=this.editor.getPosition(),e=i.modes[this.editor.getModel().getModeId()];return{row:t.lineNumber,column:t.column,line:this.editor.getModel().getLineCount(),langmode:{text:e.aliases[0],mode:e},file:this.currfile.path}}getValue(){return this.editor.getValue()}setValue(t){this.editor.setValue(t)}getEditor(){return this.editor}}e.MonacoEditorModel=i}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e,i;!function(t){let e;!function(t){class e extends t.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"afx-label",ref:"label"},{el:"p",ref:"desc",id:"ext-list-item-d-p"},{el:"p",id:"ext-list-item-b-p",children:[{el:"i",ref:"intall_status"},{el:"afx-button",ref:"btn_remove"},{el:"afx-button",ref:"btn_install"}]}]}}ondatachange(){const t=this.data;if(!t)return;const e=this.refs.label;e.iconclass="bi bi-puzzle",e.text=`${t.text} - v${t.version}`;const i=this.refs.desc;$(i).text(t.description);const a=this.refs.btn_install,s=this.refs.btn_remove;t.installed?($(s).show(),s.iconclass="bi bi-trash-fill",a.iconclass="bi bi-arrow-repeat",$(this.refs.intall_status).text(__("Installed: v{0} ",t.installed).__())):($(s).hide(),a.iconclass="fa bi-cloud-download-fill",$(this.refs.intall_status).text(" "))}init(){this.closable=!1,this.data={};const t=this.refs.btn_install,e=this.refs.btn_remove;t.onbtclick=t=>{this.data.download&&this.data.install_action&&this.data.install_action(this.data.download,t=>{this.data.installed=t,this.update(void 0)})},e.onbtclick=t=>{this.data.installed&&this.data.uninstall_action&&this.data.uninstall_action(this.data.name,()=>{delete this.data.installed,this.update(void 0)})}}reload(t){this.data=this.data}}t.define("afx-antedit-ext-list-item",e)}(e=t.tag||(t.tag={}))}(e=t.GUI||(t.GUI={})),function(e){class i extends e.BaseApplication{constructor(t){super("Antedit",t),this.currdir=void 0}main(){this.extensions={},this.eum=new a,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.sidebar_container=this.find("sidebar-tab-container"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.extension_list_view=this.find("extension-list"),this.logger=new s(this.find("output-tab")),this.split_mode=!0,this.fileview.fetch=t=>new Promise((async function(e,i){let a;a="string"==typeof t?t.asFileHandle():t;try{const t=await a.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let e="Untitled".asFileHandle();this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(e=this.args[0].path.asFileHandle(),this.currdir=e.parent())),this.setting.recent||(this.setting.recent=[]),this.setting.extension_repos||(this.setting.extension_repos=["https://raw.githubusercontent.com/lxsang/antos-antedit-extensions/master/extensions.json"]);const i=this.find("wrapper");$(i).css("visibility","hidden"),monaco.editor.setTheme("vs-dark");const n=new t.application.MonacoEditorModel(this,this.find("left-tabbar"),this.find("left-editorarea")),o=new t.application.MonacoEditorModel(this,this.find("right-tabbar"),this.find("right-editorarea"));n.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,n)),o.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,o)),this.eum.add(n).add(o),this.eum.onstatuschange=t=>this.updateStatus(t),$(i).css("visibility","visible"),this.setup(),this.eum.active.openFile(e)}get tb_ctxmenu(){return[{text:"__(Close)",id:"close"},{text:"__(Close All)",id:"close-all"},{text:"__(Move to other side)",id:"mv-side"}]}tabbar_ctx_menu_handle(t,e,i){switch(e.id){case"close":if(!t)return;i.closeTab(t);break;case"close-all":i.closeAll(),i.openFile("Untitled".asFileHandle());break;case"mv-side":if(!t)return;let e=this.eum.editors[0];i==e&&(e=this.eum.editors[1]),e.openFile(t.data),i.closeTab(t),0==this.split_mode&&this.toggleSplitMode()}}setup(){this.sidebar_container.selectedIndex=0,this.extension_list_view.itemtag="afx-antedit-ext-list-item",this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&(this.addRecent(t.data.path),"dir"!==t.data.type))return this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.fileview.contextmenuHandle=(t,e)=>(e.items=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"},{text:"__(Upload)",id:"upload"}],e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)),this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.fileview.ondragndrop=t=>{const e=t.data.from.data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(a){const s=i,n=e.parent().path;s.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1);const t={name:"Editor",text:__("Editor")},e={name:"langmode",text:__("Change language mode"),shortcut:"CTRL-K"};this.eum.addAction(t,e,async t=>{try{const t=await this.openDialog("SelectionDialog",{title:__("Select language"),data:this.eum.active.getModes()});this.eum.active.setMode(t)}catch(t){}}),$(this.find("txt_ext_search")).keyup(t=>this.extension_search(t)),this.loadExtensionMetaData(),this.toggleSideBar(),this.toggleSplitMode(),this.applyAllSetting()}extension_search(t){let e;const i=this.find("txt_ext_search");switch(t.which){case 37:return t.preventDefault();case 38:return this.extension_list_view.selectPrev(),t.preventDefault();case 39:return t.preventDefault();case 40:return this.extension_list_view.selectNext(),t.preventDefault();case 13:return t.preventDefault();default:var a=i.value,s=[];if(2===a.length)return void(this.extension_list_view.data=this.extension_meta_data);if(a.length<3)return;var n=new RegExp(a,"i");for(e in this.extension_meta_data)this.extension_meta_data[e].text.match(n)&&s.push(this.extension_meta_data[e]);this.extension_list_view.data=s}}refreshExtensionRepositories(){const t=[],e=this.meta().path+"/extensions/extensions.json";for(let i of[e].concat(this.setting.extension_repos))t.push(i.asFileHandle().read("json"));Promise.all(t).then(t=>{const e={};for(let i of t.shift())e[i.name]=i;this.extension_meta_data=[];for(let a of t)for(let t of a)e[t.name]&&(t.installed=e[t.name].version),t.install_action=(e,a)=>{new i.extensions.EditorExtensionMaker(this).installZip(e).then(()=>{this.loadExtensionMetaData(),a&&a(t.version),this.notify(__("Extension '{0}' installed",t.text))}).catch(e=>{this.error(__("Unable to install '{0}': {1}",t.text,e.toString()),e)})},t.uninstall_action=(t,e)=>{new i.extensions.EditorExtensionMaker(this).uninstall(t).then(()=>{this.loadExtensionMetaData(),e&&e(),this.notify(__("Extension '{0}' uninstalled",t))}).catch(e=>{this.error(__("Unable to uninstall '{0}': {1}",t,e.toString()),e)})},this.extension_meta_data.push(t);this.extension_list_view.data=this.extension_meta_data}).catch(t=>{this.error(__("Unable to read extension from repositories: {0}",t.toString()),t)})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row,t.column,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path,this.refreshExtensionRepositories()):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&this.showBottomBar(!0),this.bottombar.selectedIndex=0}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){this.setting.showBottomBar=t,t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.showBottomBar(!this.setting.showBottomBar)}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let a=this.fileview.selectedFile,s=this.currdir;switch(a&&"dir"===a.type&&(s=a.path.asFileHandle()),a&&"file"===a.type&&(s=a.path.asFileHandle().parent()),i.id){case"new":if(!s)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${s.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),__e(t))}});break;case"newdir":if(!s)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await s.mk(t),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",s.path),__e(t))}});break;case"rename":if(!a)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:a.filename}).then(async t=>{if(t!==a.filename){a=a.path.asFileHandle(),s=a.parent();try{return await a.move(`${s.path}/${t}`),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to rename: {0}",a.path),__e(t))}}});break;case"delete":if(!a)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",a.filename)}).then(async t=>{if(t){a=a.path.asFileHandle(),s=a.parent();try{return await a.remove(),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to delete: {0}",a.path),__e(t))}}});break;case"upload":if(!s)return;s.upload().then(t=>(this.notify(__("File uploaded to: {0}",s.path)),this.fileview.update(s.path))).catch(t=>this.error(__("Unable to upload file: {e}",t.toString()),__e(t)))}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.unshift(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t]&&this.extensions[t].cleanup&&this.extensions[t].cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}loadExtensionMetaData(){this.loadExtensionMetaFromFile(this.meta().path+"/extensions/extensions.json").catch(t=>this.error(__("Cannot load extension meta data"),t))}loadExtensionMetaFromFile(t){return new Promise((e,i)=>{t.asFileHandle().read("json").then(t=>{for(let e of t)for(let t of e.actions)this.eum.addAction(e,t,(t,i)=>{this.loadAndRunExtensionAction(t,i,e.root)});e()}).catch(t=>{i(__e(t))})})}loadAndRunExtensionAction(t,e,a){if(i.extensions[t])this.runExtensionAction(t,e);else{let i=`${this.meta().path}/extensions/${t}/main.js`;a&&(i=a+"/main.js"),this._api.requires(i,!0).then(()=>this.runExtensionAction(t,e)).catch(e=>this.error(__("unable to load extension: {0}",t),e))}}runExtensionAction(t,e){if(!this.extensions[t]){if(!i.extensions[t])return this.error(__("Unable to find extension: {0}",t));this.extensions[t]=new i.extensions[t](this)}if(!this.extensions[t][e])return this.error(__("Unable to find action: {0}",e));this.extensions[t].preload().then(()=>this.extensions[t][e]()).catch(t=>this.error(__("Unable to preload extension"),t))}}e.Antedit=i;class a{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}addAction(t,e,i){const a={id:`${t.name}:${e.name}`,label:`${t.text.__()}: ${e.text.__()}`,keybindings:[],precondition:null,keybindingContext:null,contextMenuGroupId:t.name,run:()=>i(t.name,e.name)};if(e.shortcut){const t=e.shortcut.split("-");let i=0;for(const e of t)switch(e){case"CTRL":i|=monaco.KeyMod.CtrlCmd;break;case"ALT":i|=monaco.KeyMod.Alt;break;case"SHIFT":i|=monaco.KeyMod.Shift;break;case"SUPPER":i|=monaco.KeyMod.WinCtrl;break;default:const t="KEY_"+e;monaco.KeyCode[t]?i|=monaco.KeyCode[t]:i=0}0!=i&&a.keybindings.push(i)}for(let t of this.models){const e=t.getEditor();e.getAction(a.id)||e.addAction(a)}}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class s{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let a=$("
").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();a.text(`[${i}]: ${e.__()}`)}else a.text(e.__());$(this.target).append(a),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=s,i.dependencies=["pkg://MonacoCore/path.js","pkg://MonacoCore/bundle/app.bundle.js"]}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){class e{constructor(t,e){this.app=e,this.name=t}preload(){return t.API.require(t.application.Antedit.extensions[this.name].dependencies)}basedir(){return`${this.app.meta().path}/extensions/${this.name}`}notify(t){return this.app.notify(t)}error(t,e){return this.app.error(t,e)}logger(){return this.app.setting.showBottomBar?this.app.showOutput(!1):this.app.showOutput(!0),this.app.logger}metadata(e){return new Promise((i,a)=>{if(!this.app.currdir)return a(t.API.throwe(__("Current folder is not found")));`${this.app.currdir.path}/${e}`.asFileHandle().read("json").then(t=>{!t.root&&this.app.currdir&&(t.root=this.app.currdir.path),i(t)}).catch(s=>{this.app.openDialog("FileDialog",{title:__("Select build directory"),root:this.app.currdir.path,mimes:["dir"]}).then(t=>{`${t.file.path}/${e}`.asFileHandle().read("json").then(e=>{e.root||(e.root=t.file.path),i(e)}).catch(t=>a(t))}).catch(e=>a(t.API.throwe(__("Unable to read meta-data"))))})})}}e.dependencies=[],t.application.Antedit.extensions={},t.application.Antedit.EditorBaseExtension=e,t.application.Antedit.extensions.EditorExtensionMaker=class extends e{constructor(t){super("EditorExtensionMaker",t)}create(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(New extension at)",file:{basename:__("ExtensionName")},mimes:["dir"]}).then(t=>this.mktpl(t.file.path,t.name))}build(e){this.logger().clear(),this.metadata("extension.json").then(async i=>{try{const a=await t.API.VFS.cat(i.javascripts.map(t=>`${i.root}/${t}`),"");await(i.root+"/build/debug/main.js").asFileHandle().setCache(a).write("text/plain"),await(i.root+"/build/debug/extension.json").asFileHandle().setCache(i.meta).write("object"),await t.API.VFS.copy(i.copies.map(t=>`${i.root}/${t}`),i.root+"/build/debug"),this.logger().info(__("Files generated in {0}",i.root+"/build/debug")),e&&e()}catch(t){return this.logger().error(__("Unable to build extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}run(){this.logger().clear(),this.metadata("extension.json").then(async e=>{if(!e||!e.meta||!e.meta.name)return this.logger().error(__("Invalid extension meta-data"));try{const i=e.root+"/build/debug/main.js";t.API.shared[i]&&delete t.API.shared[i],await t.API.requires(i),this.app.extensions[e.meta.name]&&this.app.extensions[e.meta.name].cleanup&&this.app.extensions[e.meta.name].cleanup(),this.app.extensions[e.meta.name]=new t.application.Antedit.extensions[e.meta.name](this.app);for(let t of e.meta.actions)this.app.eum.addAction(e.meta,t,(t,i)=>{this.app.loadAndRunExtensionAction(t,i,e.root+"/build")});this.app.eum.active.getEditor().trigger(e.meta.name,"editor.action.quickCommand")}catch(t){return this.logger().error(__("Unable to run extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}release(){this.logger().clear(),this.metadata("extension.json").then(async e=>{this.build(async()=>{try{await t.API.VFS.mkar(e.root+"/build/debug",`${e.root}/build/release/${e.meta.name}.zip`),this.logger().info(__("Archive created at {0}",`${e.root}/build/release/${e.meta.name}.zip`))}catch(t){return this.logger().error(__("Unable to create archive: {0}",t.stack))}})}).catch(t=>this.logger().error(__("Unable to read meta-data: {0}",t.stack)))}install(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(Select extension archive)",mimes:[".*/zip"]}).then(async t=>{try{return await this.installZip(t.file.path),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(t){return this.logger().error(__("Unable to install extension: {0}",t.stack))}})}installFromURL(){this.logger().clear(),this.app.openDialog("PromptDialog",{title:__("Enter URI"),label:__("Please enter extension URI:")}).then(async t=>{if(t)try{return await this.installZip(t),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(e){return this.app.error(__("Unable to install extension: {0}",t))}})}mktpl(e,i){const a=`${e}/${i}`,s=[a,a+"/build",a+"/build/release",a+"/build/debug"],n=[["main.tpl",`${a}/${i}.js`],["meta.tpl",a+"/extension.json"]];t.API.VFS.mkdirAll(s,!0).then(async()=>{try{return await t.API.VFS.mktpl(n,this.basedir(),t=>t.format(i,`${e}/${i}`)),this.app.currdir=a.asFileHandle(),this.app.toggleSideBar(),this.app.eum.active.openFile(`${a}/${i}.js`.asFileHandle())}catch(t){return this.logger().error(__("Unable to create extension template: {0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to create extension directories: {0}",t.stack)))}uninstall(t){return new Promise(async(e,i)=>{try{const i=this.app.meta().path+"/extensions",a=(i+"/extensions.json").asFileHandle(),s=await a.read("json");let n=void 0,o=void 0;for(let e in s)if(s[e].name===t){n=s[e],o=e;break}if(void 0===n)return e();await`${i}/${t}`.asFileHandle().remove(),s.splice(o,1),a.cache=s,await a.write("object"),e()}catch(t){i(t)}})}installZip(e){return new Promise(async(i,a)=>{try{await t.API.requires("os://scripts/jszip.min.js");const a=await e.asFileHandle().read("binary"),s=await JSZip.loadAsync(a),n=await s.file("extension.json").async("uint8array"),o=JSON.parse(new TextDecoder("utf-8").decode(n));await this.uninstall(o.name);const r=this.ext_dir(o.name),l=[r],h=[];for(let t in s.files)s.files[t].dir?l.push(r+"/"+t):"extension.json"!=t&&h.push(t);l.length>0?(await t.API.VFS.mkdirAll(l,!0),await this.installFiles(h,s,o)):await this.installFiles(h,s,o),i()}catch(t){a(__e(t))}})}ext_dir(t){return`${this.app.meta().path}/extensions/${t}`}installFiles(t,e,i){return 0===t.length?this.installMeta(i):new Promise(async(a,s)=>{try{const n=t.splice(0,1)[0],o=`${this.ext_dir(i.name)}/${n}`,r=await e.file(n).async("uint8array"),l=await o.asFileHandle().setCache(new Blob([r],{type:"octet/stream"})).write("text/plain");if(l.error)return s(l.error);await this.installFiles(t,e,i),a()}catch(t){s(__e(t))}})}installMeta(t){return new Promise(async(e,i)=>{const a=(this.ext_dir("")+"/extensions.json").asFileHandle();try{const s=await a.read("json"),n=[];for(let t of s)n.push(t.name);const o=n.indexOf(t.name);o>=0&&s.splice(o,1),s.push(t);try{return await a.setCache(s).write("object"),e()}catch(t){return i(__e(t))}}catch(s){try{return await a.setCache([t]).write("object"),e()}catch(t){return i(__e(t))}}})}}}(OS||(OS={}));
\ No newline at end of file
+var OS;!function(t){let e;!function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.editormux=!1,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>this.editormux?(this.editormux=!1,!1):this.currfile.dirty?void 0:(this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0))),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let a=0;a(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(t){this.currfile.cache=this.getValue(),t.write("text/plain").then(e=>{t.dirty=!1,t.text=t.basename,this.tabbar.update(void 0)}).catch(e=>this.app.error(__("Unable to save file: {0}",t.path),e))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write(this.currfile):this.saveAs()}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write(this.currfile)})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.resetEditor()}isDirty(){return this.dirties().length>0}setTabbarCtxMenu(t,e){this.tabbar.contextmenuHandle=(i,a)=>(a.items=t,a.onmenuselect=t=>{if(e){const a=$(i.target).closest("afx-list-item");e(a[0],t.data.item.data)}},a.show(i))}}}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(e){class i extends t.application.BaseEditorModel{constructor(t,e,i){super(t,e,i)}resetEditor(){this.setValue("")}getTexModel(){return{model:this.editor.getModel(),position:this.editor.getPosition()}}setTextModel(t){this.editor.setModel(t.model),t.position&&(this.editor.setPosition(t.position),this.editor.revealLineInCenter(t.position.lineNumber))}newTextModelFrom(t){if("Untitled"===t.path.toString())return{model:monaco.editor.createModel(t.cache,"textplain")};const e=monaco.Uri.parse(t.protocol+"://antedit/file/"+t.genealogy.join("/")),i=monaco.editor.getModel(e);return i?(i.setValue(t.cache),{model:i}):{model:monaco.editor.createModel(t.cache,void 0,e)}}getModes(){return monaco.languages.getLanguages().map(t=>(t.text=t.aliases[0],t))}setTheme(t){}setMode(t){monaco.editor.setModelLanguage(this.editor.getModel(),t.id),this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}editorSetup(t){this.editor=monaco.editor.create(t,{value:"",language:"textplain"}),i.modes||(i.modes={},monaco.languages.getLanguages().forEach(t=>{i.modes[t.id]=t}))}on(t,e){switch(t){case"input":this.editor.onDidChangeModelContent(e);break;case"focus":this.editor.onDidFocusEditorText(e);break;case"changeCursor":this.editor.onDidChangeCursorPosition(e)}}resize(){this.editor&&this.editor.layout()}focus(){this.editor&&this.editor.focus()}getModeForPath(t){return{}}getEditorStatus(){const t=this.editor.getPosition(),e=i.modes[this.editor.getModel().getModeId()];return{row:t.lineNumber,column:t.column,line:this.editor.getModel().getLineCount(),langmode:{text:e.aliases[0],mode:e},file:this.currfile.path}}getValue(){return this.editor.getValue()}setValue(t){this.editor.setValue(t)}getEditor(){return this.editor}}e.MonacoEditorModel=i}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e,i;!function(t){let e;!function(t){class e extends t.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"afx-label",ref:"label"},{el:"p",ref:"desc",id:"ext-list-item-d-p"},{el:"p",id:"ext-list-item-b-p",children:[{el:"i",ref:"intall_status"},{el:"afx-button",ref:"btn_remove"},{el:"afx-button",ref:"btn_install"}]}]}}ondatachange(){const t=this.data;if(!t)return;const e=this.refs.label;e.iconclass="bi bi-puzzle",e.text=`${t.text} - v${t.version}`;const i=this.refs.desc;$(i).text(t.description);const a=this.refs.btn_install,s=this.refs.btn_remove;t.installed?($(s).show(),s.iconclass="bi bi-trash-fill",a.iconclass="bi bi-arrow-repeat",$(this.refs.intall_status).text(__("Installed: v{0} ",t.installed).__())):($(s).hide(),a.iconclass="fa bi-cloud-download-fill",$(this.refs.intall_status).text(" "))}init(){this.closable=!1,this.data={};const t=this.refs.btn_install,e=this.refs.btn_remove;t.onbtclick=t=>{this.data.download&&this.data.install_action&&this.data.install_action(this.data.download,t=>{this.data.installed=t,this.update(void 0)})},e.onbtclick=t=>{this.data.installed&&this.data.uninstall_action&&this.data.uninstall_action(this.data.name,()=>{delete this.data.installed,this.update(void 0)})}}reload(t){this.data=this.data}}t.define("afx-antedit-ext-list-item",e)}(e=t.tag||(t.tag={}))}(e=t.GUI||(t.GUI={})),function(e){class i extends e.BaseApplication{constructor(t){super("Antedit",t),this.currdir=void 0}main(){this.extensions={},this.eum=new a,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.sidebar_container=this.find("sidebar-tab-container"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.extension_list_view=this.find("extension-list"),this.logger=new s(this.find("output-tab")),this.split_mode=!0,this.fileview.fetch=t=>new Promise((async function(e,i){let a;a="string"==typeof t?t.asFileHandle():t;try{const t=await a.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let e="Untitled".asFileHandle();this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(e=this.args[0].path.asFileHandle(),this.currdir=e.parent())),this.setting.recent||(this.setting.recent=[]),this.setting.extension_repos||(this.setting.extension_repos=["https://raw.githubusercontent.com/lxsang/antos-antedit-extensions/master/extensions.json"]);const i=this.find("wrapper");$(i).css("visibility","hidden"),monaco.editor.setTheme("vs-dark");const n=new t.application.MonacoEditorModel(this,this.find("left-tabbar"),this.find("left-editorarea")),o=new t.application.MonacoEditorModel(this,this.find("right-tabbar"),this.find("right-editorarea"));n.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,n)),o.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,o)),this.eum.add(n).add(o),this.eum.onstatuschange=t=>this.updateStatus(t),$(i).css("visibility","visible"),this.setup(),this.eum.active.openFile(e)}get tb_ctxmenu(){return[{text:"__(Close)",id:"close"},{text:"__(Close All)",id:"close-all"},{text:"__(Move to other side)",id:"mv-side"}]}tabbar_ctx_menu_handle(t,e,i){switch(e.id){case"close":if(!t)return;i.closeTab(t);break;case"close-all":i.closeAll(),i.openFile("Untitled".asFileHandle());break;case"mv-side":if(!t)return;let e=this.eum.editors[0];i==e&&(e=this.eum.editors[1]),e.openFile(t.data),i.closeTab(t),0==this.split_mode&&this.toggleSplitMode()}}setup(){this.sidebar_container.selectedIndex=0,this.extension_list_view.itemtag="afx-antedit-ext-list-item",this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&(this.addRecent(t.data.path),"dir"!==t.data.type))return this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.fileview.contextmenuHandle=(t,e)=>(e.items=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"},{text:"__(Upload)",id:"upload"}],e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)),this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.fileview.ondragndrop=t=>{const e=t.data.from.data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(a){const s=i,n=e.parent().path;s.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1);const t={name:"Editor",text:__("Editor")},e={name:"langmode",text:__("Change language mode"),shortcut:"CTRL-K"};this.eum.addAction(t,e,async t=>{try{const t=await this.openDialog("SelectionDialog",{title:__("Select language"),data:this.eum.active.getModes()});this.eum.active.setMode(t)}catch(t){}}),$(this.find("txt_ext_search")).keyup(t=>this.extension_search(t)),this.loadExtensionMetaData(),this.toggleSideBar(),this.toggleSplitMode(),this.applyAllSetting()}extension_search(t){let e;const i=this.find("txt_ext_search");switch(t.which){case 37:return t.preventDefault();case 38:return this.extension_list_view.selectPrev(),t.preventDefault();case 39:return t.preventDefault();case 40:return this.extension_list_view.selectNext(),t.preventDefault();case 13:return t.preventDefault();default:var a=i.value,s=[];if(2===a.length)return void(this.extension_list_view.data=this.extension_meta_data);if(a.length<3)return;var n=new RegExp(a,"i");for(e in this.extension_meta_data)this.extension_meta_data[e].text.match(n)&&s.push(this.extension_meta_data[e]);this.extension_list_view.data=s}}refreshExtensionRepositories(){const t=[],e=this.meta().path+"/extensions/extensions.json";for(let i of[e].concat(this.setting.extension_repos))t.push(i.asFileHandle().read("json"));Promise.all(t).then(t=>{const e={};for(let i of t.shift())e[i.name]=i;this.extension_meta_data=[];for(let a of t)for(let t of a)e[t.name]&&(t.installed=e[t.name].version),t.install_action=(e,a)=>{new i.extensions.EditorExtensionMaker(this).installZip(e).then(()=>{this.loadExtensionMetaData(),a&&a(t.version),this.notify(__("Extension '{0}' installed",t.text))}).catch(e=>{this.error(__("Unable to install '{0}': {1}",t.text,e.toString()),e)})},t.uninstall_action=(t,e)=>{new i.extensions.EditorExtensionMaker(this).uninstall(t).then(()=>{this.loadExtensionMetaData(),e&&e(),this.notify(__("Extension '{0}' uninstalled",t))}).catch(e=>{this.error(__("Unable to uninstall '{0}': {1}",t,e.toString()),e)})},this.extension_meta_data.push(t);this.extension_list_view.data=this.extension_meta_data}).catch(t=>{this.error(__("Unable to read extension from repositories: {0}",t.toString()),t)})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row,t.column,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path,this.refreshExtensionRepositories()):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&this.showBottomBar(!0),this.bottombar.selectedIndex=0}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){this.setting.showBottomBar=t,t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.showBottomBar(!this.setting.showBottomBar)}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let a=this.fileview.selectedFile,s=this.currdir;switch(a&&"dir"===a.type&&(s=a.path.asFileHandle()),a&&"file"===a.type&&(s=a.path.asFileHandle().parent()),i.id){case"new":if(!s)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${s.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),__e(t))}});break;case"newdir":if(!s)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await s.mk(t),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",s.path),__e(t))}});break;case"rename":if(!a)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:a.filename}).then(async t=>{if(t!==a.filename){a=a.path.asFileHandle(),s=a.parent();try{return await a.move(`${s.path}/${t}`),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to rename: {0}",a.path),__e(t))}}});break;case"delete":if(!a)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",a.filename)}).then(async t=>{if(t){a=a.path.asFileHandle(),s=a.parent();try{return await a.remove(),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to delete: {0}",a.path),__e(t))}}});break;case"upload":if(!s)return;s.upload().then(t=>(this.notify(__("File uploaded to: {0}",s.path)),this.fileview.update(s.path))).catch(t=>this.error(__("Unable to upload file: {e}",t.toString()),__e(t)))}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.unshift(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t]&&this.extensions[t].cleanup&&this.extensions[t].cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}loadExtensionMetaData(){this.loadExtensionMetaFromFile(this.meta().path+"/extensions/extensions.json").catch(t=>this.error(__("Cannot load extension meta data"),t))}loadExtensionMetaFromFile(t){return new Promise((e,i)=>{t.asFileHandle().read("json").then(t=>{for(let e of t)for(let t of e.actions)this.eum.addAction(e,t,(t,i)=>{this.loadAndRunExtensionAction(t,i,e.root)});e()}).catch(t=>{i(__e(t))})})}loadAndRunExtensionAction(t,e,a){if(i.extensions[t])this.runExtensionAction(t,e);else{let i=`${this.meta().path}/extensions/${t}/main.js`;a&&(i=a+"/main.js"),this._api.requires(i,!0).then(()=>this.runExtensionAction(t,e)).catch(e=>this.error(__("unable to load extension: {0}",t),e))}}runExtensionAction(t,e){if(!this.extensions[t]){if(!i.extensions[t])return this.error(__("Unable to find extension: {0}",t));this.extensions[t]=new i.extensions[t](this)}if(!this.extensions[t][e])return this.error(__("Unable to find action: {0}",e));this.extensions[t].preload().then(()=>this.extensions[t][e]()).catch(t=>this.error(__("Unable to preload extension"),t))}}e.Antedit=i;class a{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}addAction(t,e,i){const a={id:`${t.name}:${e.name}`,label:`${t.text.__()}: ${e.text.__()}`,keybindings:[],precondition:null,keybindingContext:null,contextMenuGroupId:t.name,run:()=>i(t.name,e.name)};if(e.shortcut){const t=e.shortcut.split("-");let i=0;for(const e of t)switch(e){case"CTRL":i|=monaco.KeyMod.CtrlCmd;break;case"ALT":i|=monaco.KeyMod.Alt;break;case"SHIFT":i|=monaco.KeyMod.Shift;break;case"SUPPER":i|=monaco.KeyMod.WinCtrl;break;default:const t="KEY_"+e;monaco.KeyCode[t]?i|=monaco.KeyCode[t]:i=0}0!=i&&a.keybindings.push(i)}for(let t of this.models){const e=t.getEditor();e.getAction(a.id)||e.addAction(a)}}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class s{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let a=$("
").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();a.text(`[${i}]: ${e.__()}`)}else a.text(e.__());$(this.target).append(a),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){t.match(/warn/i)?this.log("warn",t,!1):t.match(/error/i)?this.log("error",t,!1):this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=s,i.dependencies=["pkg://MonacoCore/path.js","pkg://MonacoCore/bundle/app.bundle.js"]}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){class e{constructor(t,e){this.app=e,this.name=t}preload(){return t.API.require(t.application.Antedit.extensions[this.name].dependencies)}basedir(){return`${this.app.meta().path}/extensions/${this.name}`}notify(t){return this.app.notify(t)}error(t,e){return this.app.error(t,e)}logger(){return this.app.setting.showBottomBar?this.app.showOutput(!1):this.app.showOutput(!0),this.app.logger}metadata(e){return new Promise((i,a)=>{if(!this.app.currdir)return a(t.API.throwe(__("Current folder is not found")));`${this.app.currdir.path}/${e}`.asFileHandle().read("json").then(t=>{!t.root&&this.app.currdir&&(t.root=this.app.currdir.path),i(t)}).catch(s=>{this.app.openDialog("FileDialog",{title:__("Select build directory"),root:this.app.currdir.path,mimes:["dir"]}).then(t=>{`${t.file.path}/${e}`.asFileHandle().read("json").then(e=>{e.root||(e.root=t.file.path),i(e)}).catch(t=>a(t))}).catch(e=>a(t.API.throwe(__("Unable to read meta-data"))))})})}}e.dependencies=[],t.application.Antedit.extensions={},t.application.Antedit.EditorBaseExtension=e,t.application.Antedit.extensions.EditorExtensionMaker=class extends e{constructor(t){super("EditorExtensionMaker",t)}create(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(New extension at)",file:{basename:__("ExtensionName")},mimes:["dir"]}).then(t=>this.mktpl(t.file.path,t.name))}build(e){this.logger().clear(),this.metadata("extension.json").then(async i=>{try{const a=await t.API.VFS.cat(i.javascripts.map(t=>`${i.root}/${t}`),"");await(i.root+"/build/debug/main.js").asFileHandle().setCache(a).write("text/plain"),await(i.root+"/build/debug/extension.json").asFileHandle().setCache(i.meta).write("object"),await t.API.VFS.copy(i.copies.map(t=>`${i.root}/${t}`),i.root+"/build/debug"),this.logger().info(__("Files generated in {0}",i.root+"/build/debug")),e&&e()}catch(t){return this.logger().error(__("Unable to build extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}run(){this.logger().clear(),this.metadata("extension.json").then(async e=>{if(!e||!e.meta||!e.meta.name)return this.logger().error(__("Invalid extension meta-data"));try{const i=e.root+"/build/debug/main.js";t.API.shared[i]&&delete t.API.shared[i],await t.API.requires(i),this.app.extensions[e.meta.name]&&this.app.extensions[e.meta.name].cleanup&&this.app.extensions[e.meta.name].cleanup(),this.app.extensions[e.meta.name]=new t.application.Antedit.extensions[e.meta.name](this.app);for(let t of e.meta.actions)this.app.eum.addAction(e.meta,t,(t,i)=>{this.app.loadAndRunExtensionAction(t,i,e.root+"/build")});this.app.eum.active.getEditor().trigger(e.meta.name,"editor.action.quickCommand")}catch(t){return this.logger().error(__("Unable to run extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}release(){this.logger().clear(),this.metadata("extension.json").then(async e=>{this.build(async()=>{try{await t.API.VFS.mkar(e.root+"/build/debug",`${e.root}/build/release/${e.meta.name}.zip`),this.logger().info(__("Archive created at {0}",`${e.root}/build/release/${e.meta.name}.zip`))}catch(t){return this.logger().error(__("Unable to create archive: {0}",t.stack))}})}).catch(t=>this.logger().error(__("Unable to read meta-data: {0}",t.stack)))}install(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(Select extension archive)",mimes:[".*/zip"]}).then(async t=>{try{return await this.installZip(t.file.path),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(t){return this.logger().error(__("Unable to install extension: {0}",t.stack))}})}installFromURL(){this.logger().clear(),this.app.openDialog("PromptDialog",{title:__("Enter URI"),label:__("Please enter extension URI:")}).then(async t=>{if(t)try{return await this.installZip(t),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(e){return this.app.error(__("Unable to install extension: {0}",t))}})}mktpl(e,i){const a=`${e}/${i}`,s=[a,a+"/build",a+"/build/release",a+"/build/debug"],n=[["main.tpl",`${a}/${i}.js`],["meta.tpl",a+"/extension.json"]];t.API.VFS.mkdirAll(s,!0).then(async()=>{try{return await t.API.VFS.mktpl(n,this.basedir(),t=>t.format(i,`${e}/${i}`)),this.app.currdir=a.asFileHandle(),this.app.toggleSideBar(),this.app.eum.active.openFile(`${a}/${i}.js`.asFileHandle())}catch(t){return this.logger().error(__("Unable to create extension template: {0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to create extension directories: {0}",t.stack)))}uninstall(t){return new Promise(async(e,i)=>{try{const i=this.app.meta().path+"/extensions",a=(i+"/extensions.json").asFileHandle(),s=await a.read("json");let n=void 0,o=void 0;for(let e in s)if(s[e].name===t){n=s[e],o=e;break}if(void 0===n)return e();await`${i}/${t}`.asFileHandle().remove(),s.splice(o,1),a.cache=s,await a.write("object"),e()}catch(t){i(t)}})}installZip(e){return new Promise(async(i,a)=>{try{await t.API.requires("os://scripts/jszip.min.js");const a=await e.asFileHandle().read("binary"),s=await JSZip.loadAsync(a),n=await s.file("extension.json").async("uint8array"),o=JSON.parse(new TextDecoder("utf-8").decode(n));await this.uninstall(o.name);const r=this.ext_dir(o.name),l=[r],h=[];for(let t in s.files)s.files[t].dir?l.push(r+"/"+t):"extension.json"!=t&&h.push(t);l.length>0?(await t.API.VFS.mkdirAll(l,!0),await this.installFiles(h,s,o)):await this.installFiles(h,s,o),i()}catch(t){a(__e(t))}})}ext_dir(t){return`${this.app.meta().path}/extensions/${t}`}installFiles(t,e,i){return 0===t.length?this.installMeta(i):new Promise(async(a,s)=>{try{const n=t.splice(0,1)[0],o=`${this.ext_dir(i.name)}/${n}`,r=await e.file(n).async("uint8array"),l=await o.asFileHandle().setCache(new Blob([r],{type:"octet/stream"})).write("text/plain");if(l.error)return s(l.error);await this.installFiles(t,e,i),a()}catch(t){s(__e(t))}})}installMeta(t){return new Promise(async(e,i)=>{const a=(this.ext_dir("")+"/extensions.json").asFileHandle();try{const s=await a.read("json"),n=[];for(let t of s)n.push(t.name);const o=n.indexOf(t.name);o>=0&&s.splice(o,1),s.push(t);try{return await a.setCache(s).write("object"),e()}catch(t){return i(__e(t))}}catch(s){try{return await a.setCache([t]).write("object"),e()}catch(t){return i(__e(t))}}})}}}(OS||(OS={}));
\ No newline at end of file
diff --git a/Antedit/build/debug/package.json b/Antedit/build/debug/package.json
index 664306f..e61138f 100644
--- a/Antedit/build/debug/package.json
+++ b/Antedit/build/debug/package.json
@@ -7,7 +7,7 @@
         "author": "Xuan Sang LE",
         "email": "mrsang@iohub.dev"
     },
-    "version": "0.1.13-b",
+    "version": "0.1.14-b",
     "category": "Development",
     "iconclass": "bi bi-journal-code",
     "mimes": [
diff --git a/Antedit/build/release/Antedit.zip b/Antedit/build/release/Antedit.zip
index c552d3df1900e8ad42236d757b44374ea107d5a6..666ade29980b7ce918a223e7cb9bfa363b9cfcc5 100644
GIT binary patch
delta 3599
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
HTuuB7{wIJT

delta 3501
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
Jbrij_{ts63EY|=4

diff --git a/Antedit/package.json b/Antedit/package.json
index 664306f..e61138f 100644
--- a/Antedit/package.json
+++ b/Antedit/package.json
@@ -7,7 +7,7 @@
         "author": "Xuan Sang LE",
         "email": "mrsang@iohub.dev"
     },
-    "version": "0.1.13-b",
+    "version": "0.1.14-b",
     "category": "Development",
     "iconclass": "bi bi-journal-code",
     "mimes": [
diff --git a/Antedit/ts/main.ts b/Antedit/ts/main.ts
index 199a5ea..eb9cb54 100644
--- a/Antedit/ts/main.ts
+++ b/Antedit/ts/main.ts
@@ -1465,7 +1465,18 @@ namespace OS {
              * @memberof Logger
              */
             print(s: string | FormattedString): void {
-                this.log("info", s, false);
+                if(s.match(/warn/i))
+                {
+                    this.log("warn", s, false);
+                }
+                else if(s.match(/error/i))
+                {
+                    this.log("error", s, false);
+                }
+                else
+                {
+                    this.log("info", s, false);
+                }
             }
 
             /**
diff --git a/packages.json b/packages.json
index 703516f..e97615f 100644
--- a/packages.json
+++ b/packages.json
@@ -45,7 +45,7 @@
 		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Antedit/README.md",
 		"category": "Development",
 		"author": "Xuan Sang LE",
-		"version": "0.1.13-b",
+		"version": "0.1.14-b",
 		"dependencies": ["MonacoCore@0.23.0-r"],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Antedit/build/release/Antedit.zip"
 	},