123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680 |
- /// <reference path="./monaco-editor/monaco.d.ts"/>
- /**
- * 1.管理vscode编辑器对象
- * 2.管理文件资源
- */
- const electron = require('electron')
- const fe = require('../../tools/tools');
- const config = Editor.require('packages://simple-code/config.js');
- const packageCfg = Editor.require('packages://simple-code/package.json');
- const fs = require('fs');
- const path = require("path");
- const exec = require('child_process').exec;
- const md5 = require('md5');
- const { isArray } = require('./monaco-editor/dev/vs/editor/editor.main');
- const eventMgr = require('../../tools/eventMgr');
- const fileMgr = require('./vs-editor-file-mgr');
- const prsPath = Editor.Project && Editor.Project.path ? Editor.Project.path : Editor.remote.projectPath;
- let layer =
- {
- SEARCH_SCORES : { ".fire": 100, ".prefab": 90 },
- // 主题文件位置
- THEME_DIR : Editor.url("packages://simple-code/panel/vs-panel/monaco-editor/custom_thems"),
- // .d.ts 通用代码提示文件引入位置
- TS_API_LIB_PATHS : [prsPath,Editor.url('packages://simple-code/template/api_doc')],
- // 备忘录位置
- MEMO_FILE_PATH : prsPath + path.sep + "temp" + path.sep + (fe.getLanguage() == 'zh' ? "备忘录.md" : "Memo.md"),
- CMD_FILE_PATH : prsPath + path.sep + "temp" + path.sep + "commandLine.js",
- // 下拉框 过滤文件类型
- SEARCH_BOX_IGNORE: {},//{".png":1,".jpg":1}
- // 忽略文件
- IGNORE_FILE: ["png", "jpg", "zip", "labelatlas", "ttf", "mp3", "mp4", "wav", "ogg", "rar", 'fire', 'prefab', 'plist'],
- // 打开文件格式对应的类型
- FILE_OPEN_TYPES: { md: "markdown", js: "typescript", ts: "typescript", effect: "yaml", coffee: "coffeescript", lua: "lua", sql: "mysql", php: "php", xml: "xml", html: "html", css: "css", json: "json", manifest: "typescript", plist: "xml", gitignore: "gitignore", glsl: "glsl",text:"markdown",txt:"markdown",c:"c",cpp:"cpp",h:"cpp" },
- // 须加载配置文件
- REG_EXP_DTS : /(\.d\.ts)/,
- REG_EXP_JSON_CONFIG : /(tsconfig.*\.json|jsconfig.*\.json|package\.json)/,
- // 导入代码提示
- /** @type monaco */
- monaco:null,
- /** @type fileMgr */
- fileMgr:null,
- // 启动事件
- initVsEditor(callback)
- {
- this.is_init_finish;
- this.timer_map = {};
- this.file_list_buffer = this.file_list_buffer || [];
- this.file_list_map = this.file_list_map || {};
- this.window_event_listener = []
- this.fileMgr = new fileMgr(this);
- this.enableUpdateTs = false;
- this.isInitEditorScene = false; // 检测creator场景是否初始化完成
- this.menu = null;
- this.initVsCode(() => {
- this.initEditorData();
- this.fileMgr.initFileListBuffer(()=>{
- this.onLoadEvent()
- this.initEditorEvent();
- this.initCustomCompleter();
- this.initSceneData(callback);
- this.initContextMenu();
- });
- });
- },
- // 初始化事件
- onLoadEvent(){
- this.runExtendFunc('onLoadEvent',this);
- },
- initVsCode(callback) {
- if(Promise.prototype.finally == null){
- // Editor.require('packages://simple-code/node_modules/promise.prototype.finally').shim();
- Promise.prototype.finally = function (callback) {
- let P = this.constructor;
- return this.then(
- value => P.resolve(callback()).then(() => value),
- reason => P.resolve(callback()).then(() => { throw reason })
- );
- };
- }
- const vsLoader = Editor.require('packages://simple-code/panel/vs-panel/monaco-editor/dev/vs/loader.js');
- // vs代码路径
- vsLoader.require.config({ 'vs/nls': { availableLanguages: { '*': fe.getLanguage() == 'zh' ? 'zh-cn' : '' } }, paths: { 'vs': Editor.url('packages://simple-code/panel/vs-panel/monaco-editor/dev/vs', 'utf8') } });
- // 创建vs编辑器,api参考 monaco.d.ts文件
- vsLoader.require(['vs/editor/editor.main'], (monaco) =>
- {
- this.monaco = Editor.monaco = Editor.monaco || monaco;
- let vsEditorConfig = config.getUserEditorConfig();
- vsEditorConfig.language = 'javascript'; // 预热 typescript模块。json、javascript脚本统一交给typescript解析器一起解析,方便混合编码
- vsEditorConfig.value = ``
- var editor = monaco.editor.create(this.$editorB,vsEditorConfig);
- this.defind_model = monaco.editor.createModel('',"plaintext",monaco.Uri.parse('defind_model'));
- Editor.monaco.vs_editor = this.vs_editor = editor;
- eventMgr.merge(this.monaco); // 添加事件分发函数
- let compilerOptions = config.compilerOptions;
- for (const key in compilerOptions) {
- const v = compilerOptions[key];
- monaco.languages.typescript.typescriptDefaults._compilerOptions[key] = v;
- }
- monaco.languages.typescript.typescriptDefaults.setCompilerOptions(monaco.languages.typescript.typescriptDefaults._compilerOptions);
- monaco.editor.setTheme("vs-dark-ex")
- setTimeout(()=>
- {
- monaco.editor.setModelLanguage(this.vs_editor.getModel(), "typescript"); // 预热 typescript模块
- monaco.languages.typescript.getTypeScriptWorker().then((func)=>{func().then((tsWr)=>{
- monaco.tsWr = this.tsWr = tsWr;// ts文件静态解析器
-
- this.tsWr.getEditsForFileRename('inmemory://model/1','inmemory://model/2');// 预热模块
- this.setEnableUpdateTs(false); // 优化性能: 关闭刷新代码缓存,等所有文件加载完成后再刷新
- if(this.tsWr && this.jsWr){
- callback();
- }
- })})
- monaco.languages.typescript.getJavaScriptWorker().then((func)=>{func().then((jsWr)=>{
- this.jsWr = jsWr;// js文件静态解析器
- this.jsWr.setEnableUpdate(false);
- this.jsWr.setEnableUpdateScript(false);
- if(this.tsWr && this.jsWr){
- callback();
- }
- })})
- },100)
- })
- },
- // 右键菜单初始化
- initContextMenu(){
- this.menu = electron.remote.Menu.buildFromTemplate([
- // 关闭
- {label:fe.translate('close'),click:()=>
- {
- if(this.menu.currTabId == null) return;
- this.closeTab(this.menu.currTabId)
- }},
- // 关闭其它
- {label:fe.translate('close-others'),click:()=>
- {
- for (let i = this.edit_list.length-1; i >= 0 ; i--) {
- const file_info = this.edit_list[i];
- if(!file_info || file_info.id == this.menu.currTabId) continue;
- this.closeTab(file_info.id)
- }
- }},
- // 关闭All
- {label:fe.translate('close-all'),click:()=>
- {
- for (let i = this.edit_list.length-1; i >= 0 ; i--) {
- const file_info = this.edit_list[i];
- if(!file_info) continue;
- this.closeTab(file_info.id)
- }
- }},
- // 线条
- { type: 'separator' },
- // 复制路径
- {label:fe.translate('copy-path'),click:()=>
- {
- if(this.menu.currTabId == null || this.edit_list[this.menu.currTabId] == null) return;
- let file_info = this.edit_list[this.menu.currTabId];
- require('electron').clipboard.writeText(file_info.vs_model.fsPath);
- }},
- // 线条
- { type: 'separator' },
- // 在文件夹中显示
- {label:fe.translate('reveal-in-finder'),click:()=>
- {
- if(this.menu.currTabId == null || this.edit_list[this.menu.currTabId] == null) return;
- let file_info = this.edit_list[this.menu.currTabId];
- let url = (file_info.uuid == "outside" ? file_info.path.replace(new RegExp('/','g'),path.sep) : Editor.remote.assetdb.urlToFspath(file_info.path));
- exec(Editor.isWin32 ? 'Explorer /select,"'+url+'"' : "open -R " + url)
- }},
- // 跳到资源管理器
- {label:fe.translate('reveal-in-side-bar'),click:()=>
- {
- if(this.menu.currTabId == null || this.edit_list[this.menu.currTabId] == null) return;
- let file_info = this.edit_list[this.menu.currTabId];
- Editor.Ipc.sendToAll('assets:hint', file_info.uuid);
- }},
- ]);
- // monaco 右击菜单,在文件夹中显示
- this.vs_editor.addAction({
- id: 'reveal-in-finder', // 菜单项 id
- label: fe.translate('reveal-in-finder'), // 菜单项名称
- // keybindings: [this.monaco.KeyMod.CtrlCmd | this.monaco.KeyCode.KEY_J], // 绑定快捷键
- contextMenuGroupId: '9_cutcopypaste', // 所属菜单的分组
- contextMenuOrder: 9,
- run: () => {
- // 点击后执行的操作
- if (this.file_info.uuid == null) return;
- let url = (this.file_info.uuid == "outside" ? this.file_info.path.replace(new RegExp('/','g'),path.sep) : Editor.remote.assetdb.urlToFspath(this.file_info.path));
- exec(Editor.isWin32 ? 'Explorer /select,"'+url+'"' : "open -R " + url)
- },
- })
- },
- // 排序:设置搜索优先级
- sortFileBuffer() {
- let getScore = (extname) => {
- return this.SEARCH_SCORES[extname] || (this.FILE_OPEN_TYPES[extname] && 80) || (this.SEARCH_BOX_IGNORE[extname] && 1) || 2;
- }
- this.file_list_buffer.sort((a, b) => getScore(b.extname) - getScore(a.extname));
- },
-
- newFileInfo(extname, name, url, uuid,fsPath) {
- let item_cfg = {
- extname: extname,//格式
- value: name == "" ? url : name,
- meta: url,
- url: url,
- score: 0,//搜索优先级
- fsPath:fsPath,
- // matchMask: i,
- // exactMatch: 0,
- uuid: uuid,
- };
- return item_cfg;
- },
- setTheme(name) {
- let filePath = path.join(this.THEME_DIR , name + ".json")
- if (fe.isFileExit(filePath)) {
- let data = fs.readFileSync(filePath).toString();
- this.monaco.editor.defineTheme(name, JSON.parse(data));
- }
- this.monaco.editor.setTheme(name);
- },
- // 设置选项
- setOptions(cfg,isInit)
- {
- if(cfg.minimapSide != null){
- cfg.minimap = cfg.minimap || {};
- cfg.minimap.side = cfg.minimapSide;
- }
- if(cfg.minimapStyle != null){
- cfg.minimap = cfg.minimap || {};
- cfg.minimap.enabled = cfg.minimapStyle != 'hide';
- cfg.minimap.maxColumn = cfg.minimapStyle == 'default' ? 120 : 35;
- cfg.minimap.scale = cfg.minimapStyle == 'default' ? 1 : 3;
- }
- if (cfg["language"]) {
- this.monaco.editor.setModelLanguage(this.vs_editor.getModel(), cfg['language']);
- }
- if(cfg.theme != null){
- this.setTheme(cfg.theme);
- }
-
- if(cfg.readCodeMode == 'all' && !isInit){
- this.loadAllScript();
- }
-
- this.vs_editor.updateOptions(cfg);
- },
- // 加载数据
- initEditorData()
- {
- // tab页面id
- this.edit_id = 0;
- this.old_edit_id = null;
- // 编辑的js文件信息
- this.file_info = {};
- // 编辑tab列表
- this.edit_list = [];
- // 全局快捷键配置
- this.key_cfg = [];
- // 文件数量统计
- this.file_counts = {
- '.js':0,
- '.ts':0,
- }
- // 全局配置信息
- this.cfg = config.getLocalStorage();
- // 项目配置信息
- this.pro_cfg = config.getProjectLocalStorage()
- this.cfg.language = null;
- this.file_cfg = this.pro_cfg.file_cfg = this.pro_cfg.file_cfg || {}
- // 待刷新的文件url
- this.refresh_file_list = this.pro_cfg.refresh_file_list = this.pro_cfg.refresh_file_list || []
- this.currTabDiv = null;
- this.loadDefineMeunCfg(this.cfg)
- this.loadThemeList();
- this.loadLanguageList();
- this.loadSysFonts()
- },
- // 读取系统字体列表
- loadSysFonts()
- {
- let fontList = Editor.require('packages://simple-code/node_modules/node-font-list-master/index.js');
- fontList.getFonts()
- .then(fonts => {
- for (let i = 0; i < fonts.length; i++)
- {
- let fontName = fonts[i];
- config.optionGroups.Main["fontFamily"].items.push({ caption: fontName, value: fontName });
- }
- })
- .catch(err => {
- // console.log(err)
- })
- },
- loadLanguageList()
- {
- let list = this.monaco.languages.getLanguages()
- for (let i = 0; i < list.length; i++)
- {
- let language = list[i];
- for (let n = 0; n < language.extensions.length; n++) {
- const ext = language.extensions[n];
- if(this.FILE_OPEN_TYPES[ext.substr(1)] == null){
- this.FILE_OPEN_TYPES[ext.substr(1)] = language.id;
- }
- }
- config.optionGroups.Main["language"].items.push({ caption: language.id, value: language.id });
- }
- },
- loadThemeList()
- {
- let list = fe.getFileList(this.THEME_DIR,[])
- for (let i = 0; i < list.length; i++)
- {
- let file = list[i].replace(/\\/g,'/');
- let name = this.fileMgr.getUriInfo(file).name;
- name = name.substr(0,name.lastIndexOf('.'))
- config.optionGroups.Main["theme"].items.push({ caption: name, value: name });
- }
- },
- // 检测Creator场景编辑器窗口是否初始化了
- clickCreatorSceneInitState(){
- if(this.isInitEditorScene){
- return;
- }
-
- Editor.Ipc.sendToPanel('scene', 'scene:query-hierarchy', (error, sceneID, hierarchy) => {
- if(hierarchy && hierarchy.length > 0){
- this.isInitEditorScene = true;
- this.openActiveFile()
- Editor.log(fe.T(`${fe.translate('name')}: 所有功能初始化成功`, `${fe.translate('name')}: Init editor success`));
- }{
- this.setTimeoutById(this.clickCreatorSceneInitState.bind(this),1000,'clickCreatorSceneInitState');
- }
- });
- },
- initSceneData(callback) {
- setTimeout(()=>
- {
- this.oepnDefindFile();
- // 打开历史文件tab列表
- let showId;
- for (const key in this.file_cfg) {
- let info = this.file_cfg[key];
- if (key.indexOf("db://") != -1) {
- let uuid = Editor.remote.assetdb.urlToUuid(key);
- if (!uuid) continue;
- let temp = this.fileMgr.getFileUrlInfoByUuid(uuid);
- let file_info = this.openFile(temp, true);
- if (file_info) {
- this.setLockEdit(true,file_info.id);
- }
- if(info.is_show){
- showId = file_info.id;
- }
- }
- }
- // this.openActiveFile();
- this.clickCreatorSceneInitState();
- if(showId){
- this.setTabPage(showId)
- }
- if(callback) callback()
- },2);
- },
- // 綁定事件
- initEditorEvent() {
- let stopCamds = { "scene:undo": 1, "scene:redo": 1, };
- // 窗口进入前台
- this.addWindowEventListener("focus",()=>{
- this.setTimeoutById(this.onFocus.bind(this),100,'windowfocus'); // 阻止短时间重复调用
- },true);
- // 窗口进入后台
- // this.addWindowEventListener("blur",()=>{
- // this.setTimeoutById(this.onBlur.bind(this),100,'windowfocus');
- // },true);
- //获得焦点
- this.vs_editor.onDidFocusEditorText((e) => {
- // if (!this.isWindowMode){
- // creator上层按键事件无法吞噬掉, 只能把撤销重置命令截取了
- this._sendToPanel = this._sendToPanel || Editor.Ipc.sendToPanel;
- Editor.Ipc.sendToPanel = (n, r, ...i) => {
- if (!stopCamds[r]) {
- return this._sendToPanel(n, r, ...i);
- }
- }
- // (document.getElementById("tools") || this).transformTool = "move";
- // 关闭cocosCreator 默认的tab键盘事件,不然会冲突
- require(Editor.appPath + "/editor-framework/lib/renderer/ui/utils/focus-mgr.js").disabled = true;
- });
- // 失去焦点
- this.vs_editor.onDidBlurEditorText((e) => {
- Editor.Ipc.sendToPanel = this._sendToPanel || Editor.Ipc.sendToPanel;
- require(Editor.appPath + "/editor-framework/lib/renderer/ui/utils/focus-mgr.js").disabled = false;
- });
- // 记录光标位置
- this.vs_editor.onDidChangeCursorPosition((e)=>{
- if(this.file_info && this.file_info.vs_model){
- this.file_info.position = e.position;
- }
- });
- // 记录光标选择位置
- this.vs_editor.onDidChangeCursorSelection((e)=>{
- if(this.file_info && this.file_info.vs_model){
- this.file_info.selection = e.selection;
- }
- });
- // 编译开始
- this.vs_editor.onDidCompositionStart((e)=>{
- this.setWaitIconActive(true);
- });
- // 切换 tab、model
- // this.vs_editor.onDidChangeModel((e)=>{
- // });
-
-
- // 创建view缓存model事件
- this.monaco.editor.onDidCreateModel((model)=>
- {
- // 编辑事件
- model.onDidChangeContent(()=>{
- this.tsWr.setEnableUpdateScript(true);
- });
- this.tsWr.setEnableUpdateScript(true);
- this.upNeedImportListWorker()
- });
- // 删除代码文件 view缓存model
- this.monaco.editor.onWillDisposeModel((model)=>{
- let url = model.uri.toString();
- this.tsWr.deleteFunctionDefindsBuffer(url);
- this.tsWr.setEnableUpdateScript(true);
- this.upNeedImportListWorker()
- });
- // typescript 配置发生改变
- this.monaco.languages.typescript.typescriptDefaults.onDidChange(()=>{
- this.tsWr.setEnableUpdateScript(true);
- });
- // typescript es5 xx库文件发生改变
- this.monaco.languages.typescript.typescriptDefaults.onDidExtraLibsChange(()=>{
- this.tsWr.setEnableUpdateScript(true);
- });
-
- // vs功能:在文件夹打开文件
- // this.monaco.listenEvent('vs-reveal-in-finder',(event)=>
- // {
- // })
- // vs功能:打开网页
- this.monaco.listenEvent('vs-open-url',(url) =>
- {
- // let uri = this.monaco.Uri.parse(url)
- // if (uri.scheme == "file"){
- // url = "http://"+uri.path;
- // }
- // exec(Editor.isWin32 ? "cmd /c start "+url : "open "+url);
- })
- // vs功能:焦点
- this.monaco.listenEvent('vs-editor-focus',(url) =>
- {
- if(Editor.Panel.getFocusedPanel() == this){
- this.vs_editor.focus();
- }
- })
-
- // vs功能:
- this.monaco.listenEvent('vs-up-code-file',(_) =>
- {
- this.upCompCodeFile();
- })
-
- // vs功能:打开文件、转跳到实现、定义
- this.monaco.listenEvent('vs-open-file-tab',(info) =>
- {
- let uuid;
- let url_info ;
- let vs_model = info.uri._formatted && this.monaco.editor.getModel(info.uri._formatted);
- if(vs_model == null){
- if(info.uri.scheme == 'http' || info.uri.scheme == 'https'){
- exec(Editor.isWin32 ? "cmd /c start "+info.uri._formatted : "open "+info.uri._formatted);
- return
- }else if(info.fsPath){
- let url = Editor.remote.assetdb.fspathToUrl(info.fsPath);
- vs_model = this.loadVsModel(url || info.fsPath,path.extname(url || info.fsPath),url != null)
- }else{
- Editor.warn('未找到文件,vs_model == null:',info.uri && info.uri._formatted);
- return
- }
- }
-
- for (let i = 0; i < this.file_list_buffer.length; i++)
- {
- const _file_info = this.file_list_buffer[i];
- if(_file_info.meta == vs_model.dbUrl){
- uuid = _file_info.uuid;
- break;
- }
- }
-
- if(uuid){
- url_info = this.fileMgr.getFileUrlInfoByUuid(uuid)
- }else{
- // 项目根目录的代码提示文件
- if(fe.isFileExit(vs_model.fsPath)){
- url_info = this.fileMgr.getFileUrlInfoByFsPath(vs_model.fsPath);
- }
- }
- if(url_info){
- let file_info = this.openFile(url_info,true);
- if(file_info && info.selection && this.vs_editor.getModel() == file_info.vs_model)
- {
- if(uuid == null){
- delete file_info.new_data;
- this.setTabPage(file_info.id);
- }
- //把选中的位置放到中间显示
- if(!Editor.monaco.Range.isIRange(info.selection) && !Editor.monaco.Selection.isISelection(info.selection)){
- info.selection = new Editor.monaco.Range(info.selection.startLineNumber,info.selection.startColumn,info.selection.startLineNumber,info.selection.startColumn)
- }
- this.vs_editor.setSelection(info.selection)
- this.vs_editor.revealRangeInCenter(info.selection)
- };
- }
- })
- // 转跳定义
- this.monaco.languages.registerDefinitionProvider("typescript", {
- provideDefinition: (model, position, token)=>
- {
- // 高亮场景node
- let wordInfo = model.getWordAtPosition(position);
- // if(wordInfo)
- // {
- // this.is_not_select_active = 1;
- // this.setTimeoutById(()=>{
- // this.is_not_select_active = 0;
- // },1000,'defindToNode')
- // Editor.Scene.callSceneScript('simple-code', 'hint-node', wordInfo.word);
- // }
-
- let isJs = this.fileMgr.getUriInfo(model.uri.toString()).extname == '.js'
- let enable = isJs && this.cfg.enabledJsGlobalSugges;
- // 异步等待返回
- var p = new Promise( (resolve, reject )=>
- {
- if(!wordInfo || !enable){
- return resolve([]);
- }
- this.tsWr.getFunctionDefinds(wordInfo.word).then((hitnMap)=>
- {
- let list = []
- for (const url in hitnMap)
- {
- const synObjs = hitnMap[url];
- const modelB = this.monaco.editor.getModel(this.monaco.Uri.parse(url))
- let text = modelB && modelB.getValue();
- if(text)
- {
- let re_syns = {}
- for (let i = 0; i < synObjs.length; i++)
- {
- const synObj = synObjs[i];
- if(synObj.spans && synObj.spans[0] && re_syns[synObj.spans[0].start] == null)
- {
- re_syns[synObj.spans[0].start] = 1;
- let range = this.convertPosition(text,synObj.spans[0].start)
- list.push({
- uri: this.monaco.Uri.parse(url),
- range: range,
- })
- }
- }
- }
- }
- resolve(list);
- })
-
- } )
- return p;
- }
- })
- // 鼠标悬停提示
- this.monaco.languages.registerHoverProvider("typescript", {
- provideHover: (model, position, token)=> {
- let wordInfo = model.getWordAtPosition(position);
-
- let isJs = this.fileMgr.getUriInfo(model.uri.toString()).extname == '.js'
- let enable = isJs && this.cfg.enabledJsGlobalSugges || !isJs && this.cfg.enabledTsGlobalSugges
- var p = new Promise( (resolve, reject )=>{
- if(wordInfo && enable){
- this.tsWr.getFunctionDefindHover(wordInfo.word,model.uri._formatted).then((text)=>
- {
- text = text || '';
- let toInd = text.indexOf('\n');
- if(toInd != -1){
- text = text.substr(0,toInd);
- }
- let language = model.getLanguageIdentifier().language
- resolve({
- contents: [{
- isTrusted: false,
- supportThemeIcons:true,
- value: text == '' ? '' : `\`\`\`${language}\n* ${text}\n\`\`\``,
- }],
- // range: { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }
- });
- })
- }else{
- resolve({});
- }
- } )
- return p;
- }
- })
- // 跳转到实现
- // this.monaco.languages.registerImplementationProvider("typescript",{provideImplementation: function (model,position, token) {
- // return Promise.resolve([{
- // // contents: [ {isTrusted:true, value: 'hello world' } ],
- // range: { startLineNumber:1, startColumn:1, endLineNumber: 1, endColumn: 1 },
- // uri: monaco.Uri.parse('file://model/fn.js'),
- // }]);
- // }})
- // 编辑器内部链接操作
- // this.monaco.languages.registerLinkProvider("typescript",{provideLinks: function (model, token) {
- // return Promise.resolve([{
- // links: [{range:null,tooltip:"",url:""}],
- // }]);
- // }})
- },
- convertPosition(text,start){
- let LineNumber = 1
- let lastLine = 0
- for (let i = 0; i < start; i++) {
- const char = text[i];
- if(char == '\n') {
- LineNumber ++;
- lastLine = i;
- }
- }
- let startColumn = start - lastLine;
- return { startLineNumber: LineNumber, startColumn: startColumn, endLineNumber: LineNumber, endColumn: startColumn }
- },
- // 自定义代码輸入提示
- initCustomCompleter()
- {
- this.setEnableUpdateTs(false);
- this.loadAllScript()
-
- // 项目根目录的代码提示文件 x.d.ts
- let load_file_map = {}
- for (var n = 0; n < this.TS_API_LIB_PATHS.length; n++)
- {
- let s_path = this.TS_API_LIB_PATHS[n];
- let list = fe.getFileList(s_path, []);
- for (let i = 0; i < list.length; i++)
- {
- let file_path = list[i];
- file_path = file_path.replace(/\\/g,'/')
- let file_name = file_path.substr(file_path.lastIndexOf('/'));
- let extname = file_path.substr(file_path.lastIndexOf('.'));
- // creator.d.ts 文件
- if (extname == '.ts' && !load_file_map[file_name]) {
- load_file_map[file_name] = 1;
- this.loadVsModeAsyn(file_path, extname, false, false);
- }
- }
- }
- },
- loadAllScript()
- {
- // 加载所有脚本文件到缓存
- let script_num = 0;
- let read_num = 0;
- for (let i = 0; i < this.file_list_buffer.length; i++)
- {
- let file_info = this.file_list_buffer[i];
- if(file_info.uuid.length < 9) continue; // outside < 9
-
- let isScript = this.loadAssetAndCompleter(file_info.meta, file_info.extname, true, false, true, ()=>{
- read_num ++;
- if(read_num == script_num){
- //所有脚本加载完成,刷新下已显示的代码页面
- this.upCompCodeFile();
- }
- });
- if(isScript){
- script_num ++;
- }
- }
- },
- addWindowEventListener(eventName,callback,option){
- this.window_event_listener.push({eventName,callback,option});
- window.addEventListener(eventName,callback,option);
- },
- // 初始化时代码文件加载方式
- isReadCode(){
- return this.cfg.readCodeMode == 'all' || // 加载全部文件方式
- this.cfg.readCodeMode == 'auto' &&
- (
- this.file_counts['.js'] > this.file_counts['.ts'] && // js文件多则加载全部文件方式,否则按import需求加载
- this.file_counts['.js'] < 500 ||
- (this.file_counts['.js'] + this.file_counts['.ts']) < 100
- )
- },
- onVsDidChangeContent(e,model) {
- let file_info ;
- if(model == this.file_info.vs_model ){
- file_info = this.file_info
- }else{
- file_info = this.edit_list[this.getTabIdByModel(model)];
- }
- if (file_info && file_info.uuid) {
- file_info.new_data = model.getValue();
- file_info.is_need_save = file_info.data != file_info.new_data;//撤销到没修改的状态不需要保存了
- this.upTitle(file_info.id);
- if (this.file_info == file_info && file_info.uuid != "outside" && file_info.is_need_save) {
- //修改后 锁定编辑
- this.setLockEdit(true);
- }
- }
-
- (document.getElementById("tools") || this).transformTool = "move";//因为键盘事件吞噬不了,需要锁定场景操作为移动模式
- let model_url = model.uri._formatted;
- this.setTimeoutById(()=>{
- // this.jsWr.deleteFunctionDefindsBuffer(model_url);
- this.tsWr.deleteFunctionDefindsBuffer(model_url);
- },1000,'removeModelBuffer');
- },
-
- // 系统文件保存修改内容
- onAssetsChangedEvent(file){
- },
- onLoadAssetAndCompleter(filePath, extname, isUrlType,isScript){
- this.runExtendFunc('onLoadAssetAndCompleter',filePath, extname, isUrlType,isScript)
- },
-
- // 读取资源文件,只在文件初始化时调用该函数
- loadAssetAndCompleter(filePath, extname, isUrlType = false, isCover=true, isSasync = true, finishCallback)
- {
- let isScript = extname == ".js" || extname == ".ts" || extname == ".json";
- if(isScript)
- {
- let fsPath = fe.normPath( isUrlType ? Editor.remote.assetdb.urlToFspath(filePath) : filePath );
- if (!fe.isFileExit(fsPath)) return;
-
- let isRead = this.cfg.readCodeMode == 'all' ||
- this.cfg.readCodeMode == 'auto' && ( isUrlType || filePath.match(this.REG_EXP_JSON_CONFIG) ) || // package.json等配置必加载
- this.cfg.readCodeMode == 'atImportTo' && filePath.match(this.REG_EXP_JSON_CONFIG) // 加载本地方式
- // console.log("loadAssetAndCompleter: ",filePath,isRead)
- if(isUrlType || isRead)
- {
- let loadFunc = (err,code)=>
- {
- if(err) return Editor.info('读取文件失败:',err);
- if(this._is_destroy) return;
- code = code.toString()
-
- // 更新文件数据用于重命名时修改import路径
- if(this.file_list_map[fsPath]){
- this.file_list_map[fsPath].data = code;
- }
- if(isRead){
- // js的 d.ts提示文件
- // this.monaco.languages.typescript.javascriptDefaults.addExtraLib(code,'lib://model/' + file_name);
- let vs_model = this.loadVsModel(filePath,extname,isUrlType,false);
- if(isCover || vs_model.getValue() == ''){
- vs_model.setValue(code)
- }
- }
- if(finishCallback) finishCallback();
- }
-
- if(isSasync){
- fe.readFileAsyn(fsPath,loadFunc);
- }else{
- let code = fs.readFileSync(fsPath);
- loadFunc(0,code);
- }
- }else{
- if(finishCallback) finishCallback();
- }
- return true
- }
- this.onLoadAssetAndCompleter(filePath, extname, isUrlType,isScript)
- },
- // 异步加载 vs_model
- loadVsModeAsyn(filePath, extname, isUrlType,isCover,callback){
- let file_type = this.FILE_OPEN_TYPES[extname.substr(1).toLowerCase()];
- if(!file_type) {
- return;
- }
- let fsPath = fe.normPath( isUrlType ? Editor.remote.assetdb.urlToFspath(filePath) : filePath );
- if (!fe.isFileExit(fsPath)) {
- return;
- }
- fe.readFileAsyn(fsPath,(err,code)=>{
- if(err) {
- if(callback) callback();
- return Editor.info('读取文件失败:',err);
- }
- if(this._is_destroy ) {
- if(callback) callback();
- return
- };
- code = code.toString()
-
- // 更新文件数据用于重命名时修改import路径
- if(this.file_list_map[fsPath]){
- this.file_list_map[fsPath].data = code;
- }
- let vs_model = this.loadVsModel(filePath,extname,isUrlType,false);
- if(isCover || vs_model.getValue() == ''){
- vs_model.setValue(code)
- }
- if(callback) callback(vs_model);
- });
- },
- // *.d.ts文件里读取自定义代码輸入提示,提供精准代码提示;
- loadVsModel(filePath, extname, isUrlType,isReadText=true) {
- let file_type = this.FILE_OPEN_TYPES[extname.substr(1).toLowerCase()];
- if(file_type)
- {
- let fsPath = fe.normPath( isUrlType ? Editor.remote.assetdb.urlToFspath(filePath) : filePath );
- if (isReadText && !fe.isFileExit(fsPath)) return;
- let js_text = isReadText ? fs.readFileSync(fsPath).toString() : "";
- let str_uri = this.fileMgr.fsPathToModelUrl(fsPath)
- // 生成vs model缓存
- let model = this.monaco.editor.getModel(this.monaco.Uri.parse(str_uri)) ;
- if(!model){
- this.tsWr.setEnableUpdateScript(true);
- model = this.monaco.editor.createModel('',file_type,this.monaco.Uri.parse(str_uri))
- model.onDidChangeContent((e) => this.onVsDidChangeContent(e,model));
- model.fsPath = fsPath;
- model.dbUrl = isUrlType ? filePath : undefined;
- }
- if(isReadText) model.setValue(js_text);
- return model
- }
- },
-
- // tab页左移
- tabToLeft() {
- let ls = this.getTabList();
- let id_ind = -1;
- for (var i = ls.length - 1; i >= 0; i--) {
- let obj = ls[i];
- if (obj._id == this.edit_id) {
- id_ind = i;
- id_ind--;
- if (id_ind < 0) id_ind = ls.length - 1
- let to_id = ls[id_ind]._id;
- this.setTabPage(to_id);
- break;
- }
- }
- },
- // tab页右移
- tabToRight() {
- let ls = this.getTabList();
- let id_ind = -1;
- for (var i = 0; i < ls.length; i++) {
- let obj = ls[i];
- if (obj._id == this.edit_id) {
- id_ind = i;
- id_ind++;
- if (id_ind == ls.length) id_ind = 0;
- let to_id = ls[id_ind]._id;
- this.setTabPage(to_id);
- break;
- }
- }
- },
-
- onSaveFile(fileInfo){
- this.runExtendFunc("onSaveFile",fileInfo);
- },
-
- // 延迟保存修改
- saveFileFromDelayTime(isMandatorySaving = false, isMustCompile = false, id = -1, formatOnSaveFile = true) {
- id = id == -1 ? this.edit_id : id;
- if(this.waitSaveIntervals[id]){
- // 重复保存忽略
- return false;
- }
- // 同个文件0.6s只能保存一次
- this.waitSaveIntervals[id] = true
- this.setTimeoutById(()=>{
- this.waitSaveIntervals[id] = false
- },500,'isWaitSaveCodeInterval'+id);
- // 保存后格式化文档
- if(formatOnSaveFile && this.cfg.formatOnSaveFile){
- this.vs_editor.trigger('anything','editor.action.formatDocument')
- setTimeout(()=>{
- this.saveFile(isMandatorySaving,isMustCompile,id);
- },100)
- }else{
- this.saveFile(isMandatorySaving,isMustCompile,id);
- }
- return true;
- },
- // 保存修改
- saveFile(isMandatorySaving = false, isMustCompile = false, id = -1) {
- id = id == -1 ? this.edit_id : id;
- let file_info = this.edit_list[id];
- if (file_info && file_info.uuid && (file_info.is_need_save || isMandatorySaving)) {
- let edit_text = id == this.edit_id ? this.vs_editor.getValue() : file_info.new_data;
- if (edit_text == null) {
- Editor.error("保存文件失败:", file_info)
- return;
- }
- let is_save = true
- if (file_info.uuid == "outside") {
- fs.writeFileSync(file_info.path , edit_text); //外部文件
- } else {
- if(this.cfg.codeCompileMode == 'save' || isMustCompile){
- is_save = this.saveFileByUrl(file_info.path,edit_text);
- }else{
- fs.writeFileSync(Editor.remote.assetdb.urlToFspath(file_info.path), edit_text);
- // 用于脱离编辑状态后刷新creator
- if(this.refresh_file_list.indexOf(file_info.path) == -1){
- this.refresh_file_list.push(file_info.path);
- }
- }
- }
- if(is_save)
- {
- this.is_need_refresh = true;
- file_info.is_need_save = false;
- file_info.data = edit_text;
- file_info.new_data = edit_text;
- this.upTitle(id);
- if(id != 0) this.setLockEdit(true,id);
- this.onSaveFile(file_info);
- }
- }
- },
- saveFileByUrl(url,text)
- {
- Editor.assetdb.saveExists(url, text, (err, meta)=> {
- if (err) {
- fs.writeFileSync(Editor.remote.assetdb.urlToFspath(url), text); //外部文件
- Editor.warn("保存的脚本存在语法错误或是只读文件:",url,err,meta);
- }else{
- // 刚刚保存了,creator还没刷新
- this.is_save_wait_up = 1;
- this.setTimeoutById(()=>{
- this.is_save_wait_up = 0;
- },3000)
- }
- });
- return true;
- },
- // 刷新保存后未编译的脚本
- refreshSaveFild(isRefreshApi = false)
- {
- // 用于脱离编辑状态后刷新creator
- if(this.refresh_file_list.length){
- // Editor.assetdb.refresh(this.refresh_file_list);// 导入保存的代码状态,连续保存会引起报错
- for (let i = 0; i < this.refresh_file_list.length; i++)
- {
- let url = this.refresh_file_list[i];
- if(isRefreshApi){
- Editor.assetdb.refresh(url);// 导入保存的代码状态,连续保存会引起报错
- }else{
- let text = fs.readFileSync(Editor.remote.assetdb.urlToFspath(url)).toString();
- Editor.assetdb.saveExists(url, text, (err, meta)=> {
- if (err) {
- Editor.warn("保存的脚本存在语法错误:",url,err,meta);
- }
- });
- }
- }
- this.refresh_file_list.length = 0;
- }
- },
- // 读取文件到编辑器渲染
- readFile(info) {
- let is_lock = info.is_lock;
- let old_file_info = this.file_info;
- this.old_edit_id = this.edit_id;
- this.file_info = info;
- this.edit_id = info.id;
- let text = info.new_data || info.data || "";
- // 初始化载入代码编辑
- this.vs_editor.setModel(info.vs_model);
- if (info.vs_model.getValue() != text) {
- this.vs_editor.setValue(text);
- }
- if (info.selection) {
- this.vs_editor.setSelection(info.selection);
- }else if (info.position) {
- this.vs_editor.setPosition(info.position);
- }
- if (info.scroll_top != null) {
- this.vs_editor.setScrollTop(info.scroll_top)
- }
- // 为了应用 tsconfig.json、package.json 文件配置退出编辑器后需要将其转换成typescript语言进入ts解析器一起参与代码解析功能
- // if(old_file_info.vs_model && old_file_info.file_type == 'json'){
- // this.monaco.editor.setModelLanguage(old_file_info.vs_model,"typescript");
- // }
- // // 处于编辑状态下需要切换json文件到json解析器进行json语法解析
- // if(info.vs_model && info.file_type == 'json'){
- // this.monaco.editor.setModelLanguage(info.vs_model,"json");
- // }
- // 两次切换是为了解决个别时候import路径没刷新报错bug,触发更新编译
- this.monaco.editor.setModelLanguage(this.vs_editor.getModel(),"markdown");
- this.monaco.editor.setModelLanguage(this.vs_editor.getModel(),this.FILE_OPEN_TYPES[info.file_type || ""] || "markdown");
- // 自适应缩进格式
- if(this.cfg.detectIndentation) this.setOptions({detectIndentation:true});
- this.setLockEdit(is_lock);
- this.upTitle();
- },
- // 设置文件标题
- upTitle(id) {
- id = id != null ? id : this.edit_id;
- if (id == null) return Editor.warn("没有标题id");
- let info = this.edit_list[id] || {};
- let tabBg = this.getTabDiv(id);
- if (tabBg) {
- let title = tabBg.getElementsByClassName("tabTitle")[0];
- title.textContent = (info.is_need_save ? info.name + "* " : info.name || "无文件");
- title.setAttribute('style',info.is_lock || id == 0 ? 'font-style:normal;' : 'font-style:italic;');
- title.title = info.path;
- } else {
- Editor.warn(id)
- }
- },
- // 获得新页面可用的页码
- getNewPageInd(isIncludesInitPage = false, isIncludesInitNeedSave = true) {
- for (var i = isIncludesInitPage ? 0 : 1; i < 100; i++) {
- let tabBg = this.getTabDiv(i);
- if (!tabBg || !this.edit_list[i] || (!this.edit_list[i].is_need_save && isIncludesInitNeedSave)) {
- return i;
- }
- }
- },
- getTabDiv(id) {
- if (id == null) return;
- for (var i = 0; i < this.$tabList.children.length; i++) {
- let obj = this.$tabList.children[i]
- if (obj._id == id) {
- return obj;
- }
- }
- },
- getTabList() {
- let list = [];
- for (var i = 0; i < this.$tabList.children.length; i++) {
- let obj = this.$tabList.children[i]
- if (obj._id != null) {
- list.push(obj);
- }
- }
- return list;
- },
- // 获得页面id
- getTabIdByUuid(uuid) {
- for (var i = 0; i < this.edit_list.length; i++) {
- let v = this.edit_list[i];
- if (v && v.uuid == uuid) {
- return i;
- }
- }
- },
- // 获得页面id
- getTabIdByPath(url_path) {
- for (var i = 0; i < this.edit_list.length; i++) {
- let v = this.edit_list[i];
- if (v && v.path == url_path) {
- return i;
- }
- }
- },
- // 获得页面id
- getTabIdByModel(vs_model) {
- for (var i = 0; i < this.edit_list.length; i++) {
- let v = this.edit_list[i];
- if (v && v.vs_model == vs_model) {
- return i;
- }
- }
- },
- // 设置编辑页面信息
- newPageInfo(id, uuid, path, name, file_type, data, is_not_draw = false, is_need_save = false, is_lock = false) {
- let file_info = this.edit_list[id] = this.edit_list[id] || {};
-
- this.defind_model.setValueNotUndo(data);
- data = this.defind_model.getValue(); // model内部会转换掉特特殊换行符号,导致与原先本文不匹配
- path = path.replace(/\\/g,'/');
- file_info.uuid = uuid;
- file_info.path = path;
- file_info.data = data;
- file_info.new_data = data;;
- file_info.name = name;
- file_info.file_type = file_type;
- file_info.is_need_save = is_need_save;
- file_info.is_lock = is_lock;
- file_info.enabled_close = true;
- file_info.scroll_top = this.file_cfg[path] && this.file_cfg[path].scroll_top;
- file_info.id = id;
- file_info.can_remove_model = 0;
- file_info.position = undefined;
- file_info.selection = undefined;
- if (!file_info.vs_model)
- {
- let vs_model = this.loadVsModel(path, this.fileMgr.getUriInfo(path).extname , uuid != "outside",is_not_draw);
- if(!vs_model) {
- delete this.edit_list[id];
- Editor.warn("<代码编辑>读取文件失败:",path);
- return;
- };
- file_info.vs_model = vs_model; // vs tab标签数据
- }
- this.newTabDiv(id)
- this.upTitle(id)
- if (!is_not_draw) this.setTabPage(id, true);
- return file_info
- },
- // 新页面tab
- newTabDiv(id) {
- let tabBg = this.getTabDiv(id);
- if (tabBg) return tabBg;
- tabBg = this.$title0.cloneNode(true);
- tabBg.id = "title" + id;
- tabBg.hidden = false;
- tabBg.style.display = 'block'
- this.$tabList.appendChild(tabBg);
- // 切换标题
- tabBg._id = id;
- tabBg.addEventListener('click', (e) => {
- e.preventDefault();
- this.setTabPage(tabBg._id);
- setTimeout(()=> this.vs_editor.focus(),1)
- })
-
- // 鼠标右键事件
- tabBg.addEventListener('contextmenu', (e) => {
- if(!this.menu) return;
- e.preventDefault();
- this.menu.currTabId = tabBg._id;
- // 处于焦点时才能调用
- if(electron.remote.BrowserWindow.getFocusedWindow()){
- this.menu.popup()
- }
- })
- // 移动tab事件
- tabBg.addEventListener('mousedown', (e) => {
- this.currTabDiv = tabBg;
- });
- // 移动tab事件
- tabBg.addEventListener('mouseup', (e) => {
- // console.log("moveup:",id,e)
- if(!this.currTabDiv || this.currTabDiv == tabBg) return;
- let rectB = tabBg.getBoundingClientRect()
- if(e.clientX>rectB.left && e.clientX<rectB.right){
- let rectA = this.currTabDiv.getBoundingClientRect()
- rectA.left > rectB.left ? this.$tabList.insertBefore(this.currTabDiv,tabBg) : this.$tabList.insertBefore(this.currTabDiv,tabBg.nextSibling)
- }
- delete this.currTabDiv;
- })
-
-
- // 关闭页面
- tabBg.getElementsByClassName("closeBtn")[0].addEventListener('click', () => {
- this.closeTab(tabBg._id);
- });
- return tabBg;
- },
- setWaitIconActive(isActive){
- if(this.$waitIco){
-
- this.$waitIco.className = isActive ? 'turnAnim' : '';
- }
- },
- // 关闭页面tab
- closeTab(id) {
- let tabBg = this.getTabDiv(id);
- let file_info = this.edit_list[id];
- if (tabBg == null || !file_info.enabled_close) return;//Editor.info("不存在页面:"+id);
- if (!file_info.can_remove_model && file_info.is_need_save && !confirm(file_info.path + " 文件被修改是否丢弃修改?")) return;
- // 记录本次打开位置
- let file_name = this.edit_list[id].path
- let file_log = this.file_cfg[file_name] = this.file_cfg[file_name] || {}
- file_log.scroll_top = this.edit_list[id].vs_model == this.vs_editor.getModel() ? this.vs_editor.getScrollTop() : this.edit_list[id].scroll_top;
- // 清除页面
- if(file_info.vs_model) {
- file_info.vs_model._commandManager.clear();// 清除撤销记录
- if(file_info.is_need_save){
- file_info.vs_model.setValue(file_info.data)// 撤销到修改前
- }
- if(file_info.can_remove_model){
- file_info.vs_model.dispose();
- }
- }
- delete this.edit_list[id];
- tabBg.parentNode.removeChild(tabBg);
- if (id == this.edit_id) {
- if(this.old_edit_id != null && this.getTabDiv(this.old_edit_id)){
- // 切换到上次打开的tab
- this.setTabPage(this.old_edit_id);
- }else{
- // 切换到最后存在的页面
- for (var i = id - 1; i >= 0; i--) {
- if (this.edit_list[i]) {
- this.setTabPage(i);
- break;
- }
- }
- }
- }
- },
- // 关闭未修改的标签
- closeUnmodifiedTabs() {
- // 高亮选中
- let list = this.getTabList()
- for (let i = 0; i < list.length; i++) {
- let tabBg = list[i]
- let file_info = this.edit_list[tabBg._id];
- if (!file_info.is_need_save && file_info.enabled_close && !file_info.is_lock) this.closeTab(tabBg._id)
- }
- },
- // 切换编辑tab页面
- setTabPage(id, is_new_page = false) {
- if (!this.getTabDiv(id)) return;
- let old_id = this.edit_id;
- // 高亮选中
- let list = this.getTabList()
- for (var i = 0; i < list.length; i++) {
- let tabBg = list[i];
- tabBg.className = id == tabBg._id ? "openTab" : "closeTab";
- }
- if (this.edit_id != 0 && this.edit_list[this.edit_id]) {
- // 记录切换页面前编辑的数据
- this.edit_list[this.edit_id].new_data = this.vs_editor.getValue();
- this.edit_list[this.edit_id].scroll_top = this.vs_editor.getScrollTop()
- }
- this.upTitle(id)
- this.readFile(this.edit_list[id]);
- this.vs_editor.updateOptions({ lineNumbers: this.cfg.is_cmd_mode || this.edit_id != 0 ? "on" : 'off' });
- if(this.is_init_finish) {
- this.onSwitchTab(old_id,id);
- }
- return this.edit_list[id];
- },
- // 打开外部文件
- openOutSideFile(filePath, isShow = false) {
- return this.openFile(this.fileMgr.getFileUrlInfoByFsPath(filePath),isShow);
- // this.setLockEdit(is_lock);
- },
- // 打开文件到编辑器
- openFileByUrl(url, isShow) {
- let uuid = Editor.remote.assetdb.urlToUuid(url);
- if(uuid){
- return this.openFile(this.fileMgr.getFileUrlInfoByUuid(uuid),isShow);
- }
- },
- // 打开文件到编辑器
- openFile(info, isShow) {
- if (info == null || !this.FILE_OPEN_TYPES[info.file_type]) {
- return false
- }
- // 初始化载入代码编辑
- let id = info.uuid == "outside" ? this.getTabIdByPath(info.path) : this.getTabIdByUuid(info.uuid);
- if (id == null) {
- let file_info = this.newPageInfo(this.getNewPageInd(false, false), info.uuid, info.path, info.name, info.file_type, info.data, this.file_info.is_lock && !isShow);
- return file_info;
- } else if (!this.file_info.is_lock || isShow) {
- return this.setTabPage(id)
- }
- },
- // 打开node上的文件到编辑器
- openActiveFile(isShow,isCloseUnmodifiedTabs = true) {
- if(!this.isInitEditorScene){
- return ;
- }
-
- // 获得当前焦点uuid的信息
- Editor.Scene.callSceneScript('simple-code', 'get-active-uuid', "", (err, event) => {
- if (!event) {
- return
- };
- if(!isShow)
- {
- // 删除已经显示uuid
- for (var i = event.uuids.length - 1; i >= 0; i--) {
- let uuid = event.uuids[i]
- if (err || event && this.getTabIdByUuid(uuid)) { // 已经打开同个文件
- event.uuids.splice(i, 1);
- continue;
- }
- }
- }
- // 打开文件tab
- let ld_list = [];
- let act = Editor.Selection.curGlobalActivate()
- for (let i = 0; i < event.uuids.length; i++)
- {
- const uuid = event.uuids[i];
- const info = this.fileMgr.getFileUrlInfoByUuid(uuid);
- if(act.type != 'node' || !config.vsEditorConfig.ignoreAutoOpenFile || !path.basename(info.path).match(new RegExp(config.vsEditorConfig.ignoreAutoOpenFile)))
- {
- let file_info = this.openFile(info, isShow);
- if (file_info) {
- file_info._is_lock = file_info.is_lock;
- file_info.is_lock = true
- ld_list.push(file_info);
- }
- }
- }
-
- // 关闭未锁定的文件
- if(act && act.id && (isCloseUnmodifiedTabs || ld_list.length == 0)) this.closeUnmodifiedTabs();
- for (let i = 0; i < ld_list.length; i++){
- ld_list[i].is_lock = ld_list[i]._is_lock;
- delete ld_list[i]._is_lock;
- }
- // // 打开备忘录
- // if (ld_list.length == 0 == null && !isShow) {
- // this.oepnDefindFile();
- // }
- }, -1)
- },
- // 打开默认的备忘录、命令行文本
- oepnDefindFile() {
- // 没有备忘录就先复制一个
- let filePath = this.MEMO_FILE_PATH;
- if (!fe.isFileExit(filePath)) {
- let template = ''
- if(fe.getLanguage() == 'zh'){
- template = "packages://simple-code/template/readme-zh.md"
- }else{
- template = "packages://simple-code/template/readme-en.md"
- }
- fe.copyFile(Editor.url(template), filePath);
- }
- // 已经打开过了
- if (this.file_info.path == filePath) {
- return;
- }
- // 切换模式前先保存备忘录
- if(this.edit_list[0] && this.edit_list[0].path != filePath) {
- this.saveFile(false,false,0);
- }
- let info = this.fileMgr.getFileUrlInfoByFsPath(filePath)
- if(!this.edit_list[0] || this.edit_list[0].name != info.name)
- {
- this.newPageInfo(0,
- info.uuid,
- info.path,
- info.name,
- info.file_type,
- info.data,
- this.file_info.is_lock);
- // x不显示
- this.edit_list[0].enabled_close = false
- this.getTabDiv(0).getElementsByClassName("closeBtn")[0].hidden = true;
- }else{
- this.openOutSideFile(filePath, !this.file_info.is_lock);
- }
- // 清除撤销记录
- this.edit_list[0].vs_model._commandManager.clear();
- },
- // 检测是否存在需要import的路径,以及检查js/ts解析器进程是否处于空闲状态
- upNeedImportListWorker(callback,timeOut=500)
- {
- // let isIdleJs = false;
- let isTimeOut = false;
- let timeoutId ;
- // 超时检查
- timeoutId = setTimeout(()=>{
- isTimeOut = true;
- if(callback) callback(false);
- },timeOut);
-
- // 转圈圈动画
- let timeoutAnimId ;
- timeoutAnimId = setTimeout(()=>{
- timeoutAnimId = null;
- this.setWaitIconActive(true);
- },50);
- let loadImportPath ;
- loadImportPath = async (needImportPaths)=>
- {
- let isEmpty = fe.isEmptyObject(needImportPaths)
- if(isEmpty)
- {
- // 性能优化: 允许继续刷新代码缓存
- this.setEnableUpdateTs(true)
- // 转圈圈动画
- this.setWaitIconActive(false);
- if(timeoutAnimId) clearTimeout(timeoutAnimId);
- timeoutAnimId = null
- if(isTimeOut || timeoutId==null){
- return; // 已超时的回调
- }else{
- clearTimeout(timeoutId);
- timeoutId = null
- if(callback) callback(true);// 准时回调
- }
- }else
- {
- await this.fileMgr.loadNeedImportPathsAsync(needImportPaths);
- if(!isTimeOut){
- setTimeout(50,()=>{
- this.tsWr.getNeedImportPaths().then(loadImportPath);
- })
- }
- }
- }
- // 调用进程,检测是否空闲
- this.tsWr.getNeedImportPaths().then(loadImportPath);
- },
- // 自动刷新代码缓存开关
- setEnableUpdateTs(enable){
- if(!enable){
- this.tsWr.setEnableUpdate(enable);
- this.stopTimeoutById('enableUpdateTs')
- }else if(this.enableUpdateTs != enable)
- {
- this.setTimeoutById(async ()=>{
- let enab = await this.tsWr.isEnableUpdate()
- if(!enab){
- // 空闲时刷新代码缓存信息
- this.tsWr.setEnableUpdate(enable);
- this.upCompCodeFile();
- }
- },1000,'enableUpdateTs')
- }
- this.enableUpdateTs = enable;
- },
- // 编译编辑中的代码
- upCompCodeFile(){
- // let edits = [{
- // range:{startLineNumber:0,startColumn:0,endLineNumber:0,endColumn:0,},
- // text:' ',
- // forceMoveMarkers:false,
- // }]
- this.edit_list.forEach((editInfo, id) => {
- if(editInfo && editInfo.vs_model)
- {
- // Editor.monaco.sendEvent('upCompCodeFile',editInfo.vs_model);0
- // 只是为了触发解析格式事件,防止import后没有及时刷新
- let language = editInfo.vs_model.getLanguageIdentifier().language;
- this.monaco.editor.setModelLanguage(editInfo.vs_model,"markdown");
- this.monaco.editor.setModelLanguage(editInfo.vs_model,language);
- }
- });
- },
- isFocused(){
- return Editor.Panel.getFocusedPanel() == Editor.Panel.find('simple-code');
- },
- isHasOpenSceneWindow(){
- return this.isInitEditorScene;
- },
- // 调用原生JS的定时器,统一管理定时器,统一释放
- setTimeoutById(func,time,id='com')
- {
- // 之前有定时器先停掉
- if(this.timer_map[id]){
- this.timer_map[id]()
- }
- let headler = setTimeout(()=>{
- if(this.timer_map[id]) this.timer_map[id]()
- this.timer_map[id] = undefined;
- func()
- }, time);
- this.timer_map[id] = ()=>clearTimeout(headler);
- return this.timer_map[id];
- },
- stopTimeoutById(id='com'){
- if(this.timer_map[id]){
- this.timer_map[id]()
- this.timer_map[id] = undefined;
- }
- },
- // 调用原生JS的定时器
- setTimeoutToJS(func, time = 1, { count = -1, dt = time } = {}) {
- // 执行多少次
- if (count === 0) {
- let headler = setTimeout(func, time * 1000);
- return () => clearTimeout(headler);
- } else {
- // 小于0就永久执行
- if (count < 0) { count = -1; };//cc.macro.REPEAT_FOREVER
- let headler1, headler2;
- headler1 = setTimeout(() => {
- let i = 0;
- let funcGo = function () {
- i++;
- if (i === count) { clearInterval(headler2); }
- func();
- }
- // 小于0就永久执行
- if (count < 0) { funcGo = function () { func() } }
- headler2 = setInterval(funcGo, time * 1000);
- funcGo();
- }, dt * 1000);
- return () => {
- clearTimeout(headler1);
- clearInterval(headler2);
- }
- }
- },
-
- // 窗口获得焦点
- onFocus(){
- // 回调前台刷新需要监听的文件状态
- this.fileMgr.checkWatch();
- },
- // 窗口失去焦点
- onBlur(){
- },
- // 正在切换页面标签栏
- onSwitchTab(oldEditId = -1,newEditId){
- },
- // 页面关闭
- onDestroy() {
- },
- messages: {
- }
- };
- module.exports = layer;
|