panel_ex.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. 面板扩展
  3. 功能: 书签🔖
  4. */
  5. 'use strict';
  6. const path = require('path');
  7. const fs = require('fs');
  8. const config = Editor.require('packages://simple-code/config.js');
  9. let id = 'editor-book-mark'
  10. module.exports = {
  11. /** @type import('../../panel/vs-panel/vs-panel-base') */
  12. parent : null,
  13. styleText : `.editor-book-mark {
  14. background: lightblue;
  15. width: 5px !important;
  16. margin-left: 3px;
  17. }`,
  18. // 面板初始化
  19. ready(parent){
  20. // index.js 对象
  21. this.parent = parent;
  22. // 本地保存数据
  23. this.pro_cfg = config.getProjectLocalStorage();
  24. this.book_marks = this.pro_cfg.book_marks = this.pro_cfg.book_marks || {};
  25. },
  26. getMarks(){
  27. let url = this.parent.vs_editor.getModel().uri.toString()
  28. return this.book_marks[url] = this.book_marks[url] || [];
  29. },
  30. getNextMark()
  31. {
  32. let list = this.getMarks()
  33. list.sort((a,b)=>a.range.startLineNumber-b.range.startLineNumber);
  34. let pos = this.parent.vs_editor.getPosition()
  35. let ind = list.findIndex(v=>v.range.startLineNumber > pos.lineNumber)
  36. return list[ind] || list[0];
  37. },
  38. // monaco 编辑器初始化
  39. onLoad(){
  40. // 1.判断点击已有的书签是否在点击区域
  41. // 2.在:删除该书签重新渲染
  42. // 3.不在:新建书签重新渲染
  43. // 4.渲染装饰物
  44. this.parent.vs_editor.onMouseDown(e => {
  45. const target = e.target;
  46. // 判断点击的区域位置是否行符地方
  47. if (target.type === this.parent.monaco.editor.MouseTargetType.GUTTER_LINE_DECORATIONS) {
  48. // 找出书签装饰物
  49. this.clickMark(target.position.lineNumber)
  50. }
  51. });
  52. // 书签样式
  53. this.parent.runExtendFunc('setDecoratorStyle',id,this.styleText);
  54. this.bindKeybody()
  55. },
  56. clickMark(lineNumber){
  57. let list = this.getMarks();
  58. let existIndex = list.findIndex(v=>v.range.startLineNumber === lineNumber);
  59. if (existIndex === -1) {
  60. let select = this.parent.vs_editor.getSelection();
  61. select = lineNumber == select.selectionStartLineNumber ? select : undefined
  62. this.addMark(lineNumber,select);
  63. } else {
  64. list.splice(existIndex, 1);
  65. }
  66. this.onLoadDecoratorStyle();
  67. },
  68. addMark(lineNumber,selection){
  69. let list = this.getMarks();
  70. list.push({
  71. // id: "",
  72. // ownerId: 0,
  73. selection : selection || undefined,
  74. scroll_top : this.parent.vs_editor.getScrollTop(),
  75. range: new this.parent.monaco.Range(
  76. lineNumber,
  77. 1,
  78. lineNumber,
  79. 1,
  80. ),
  81. options: {
  82. isWholeLine: true,
  83. linesDecorationsClassName: id,
  84. minimap: {position:2},
  85. stickiness: this.parent.monaco.editor.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
  86. },
  87. });
  88. },
  89. // 广播通知需要刷新装饰物
  90. onLoadDecoratorStyle(){
  91. let list = this.getMarks();
  92. if(list){
  93. // 检测超出范围的标签删除掉
  94. let line_max = this.parent.vs_editor.getModel().getLineCount()
  95. for (let i = list.length-1; i >=0; i--) {
  96. const mark = list[i];
  97. if(mark.range.startLineNumber > line_max){
  98. list.splice(i,1);
  99. }
  100. }
  101. }
  102. this.parent.runExtendFunc('setDecorator',id,list);
  103. },
  104. bindKeybody(){
  105. // 跳到编辑器标签
  106. for (let i = 0; i < 10; i++) {
  107. // 绑定页面全局快捷键事件,注意: 区分大小写 Ctrl = ctrl
  108. this.parent.addKeybodyEvent([[Editor.isWin32 ? "Alt" : "Meta",String(i)]],(e)=>
  109. {
  110. if(this.parent.file_info == null) return;
  111. let tab_tag_cfg = this.pro_cfg.tab_tag_cfg = this.pro_cfg.tab_tag_cfg || {};
  112. let tab_info = tab_tag_cfg[String(i)];
  113. if(tab_info){
  114. let file_info = this.parent.openOutSideFile(tab_info.fsPath,true)
  115. if(file_info){
  116. file_info.position = tab_info.position;
  117. file_info.selection = tab_info.selection;
  118. file_info.scroll_top = tab_info.scroll_top;
  119. this.parent.readFile(file_info);
  120. e.preventDefault();// 吞噬捕获事件
  121. return false;
  122. }
  123. }
  124. },1)
  125. }
  126. // 绑定编辑器标签
  127. for (let i = 0; i < 10; i++) {
  128. // 绑定页面全局快捷键事件,注意: 区分大小写 Ctrl = ctrl
  129. this.parent.addKeybodyEvent([[Editor.isWin32 ? "Ctrl" : "Alt",String(i)]],(e)=>
  130. {
  131. if(this.parent.file_info == null || this.parent.file_info.vs_model == null) return;
  132. let tab_tag_cfg = this.pro_cfg.tab_tag_cfg = this.pro_cfg.tab_tag_cfg || {}
  133. tab_tag_cfg[String(i)] = {
  134. fsPath : this.parent.file_info.vs_model.fsPath,
  135. position:this.parent.file_info.position,
  136. selection:this.parent.file_info.selection,
  137. scroll_top:this.parent.vs_editor.getScrollTop()
  138. }
  139. e.preventDefault();// 吞噬捕获事件
  140. return false;
  141. },1)
  142. }
  143. this.parent.addKeybodyEventByName('nextBookmark',(e)=>
  144. {
  145. if(this.parent.file_info == null || this.parent.file_info.vs_model == null) return;
  146. let mark = this.getNextMark();
  147. if(mark == null) return;
  148. let file_info = this.parent.file_info;
  149. file_info.selection = mark.selection || {
  150. selectionStartLineNumber: mark.range.startLineNumber,
  151. selectionStartColumn: mark.range.startColumn,
  152. positionLineNumber: mark.range.endLineNumber,
  153. positionColumn: mark.range.endColumn,
  154. };
  155. file_info.scroll_top = mark.scroll_top;
  156. this.parent.readFile(file_info);
  157. e.preventDefault();// 吞噬捕获事件
  158. return false;
  159. },1)
  160. },
  161. // 面板销毁
  162. onDestroy(){
  163. for (const key in this.book_marks) {
  164. if (this.book_marks[key] == null || this.book_marks[key].length == 0) {
  165. delete this.book_marks[key]
  166. }
  167. }
  168. },
  169. messages:{
  170. // 'cleanFile'()
  171. // {
  172. // },
  173. },
  174. };