panel_ex.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. 面板扩展
  3. 功能: vim 功能,改造vim光标支持多选操作
  4. */
  5. 'use strict';
  6. const path = require('path');
  7. const fs = require('fs');
  8. let vsVim;
  9. module.exports = {
  10. /** @type import('../../panel/vs-panel/vs-panel-base') */
  11. parent : null,
  12. // 面板初始化
  13. ready(parent){
  14. // index.js 对象
  15. this.parent = parent;
  16. this.vim_cursor = []
  17. },
  18. // monaco 编辑器初始化
  19. onLoad(){
  20. vsVim = Editor.require('packages://simple-code/extensions/editor-vim-model/vim/lib/index.js');
  21. this.isWait = false;
  22. this.parent.vs_editor.onDidChangeCursorPosition((e)=>{
  23. if(this.isWait){
  24. return
  25. }
  26. // 定时器用于解决 getSelections 选中列表为空的bug
  27. setTimeout(()=>{
  28. this.isWait = true
  29. // 防止重复触发事件重复调用
  30. this.upVimCursor(this.parent.vs_editor.getSelections())
  31. this.isWait = false
  32. },0)
  33. });
  34. },
  35. // 设置选项
  36. setOptions(cfg,isInit)
  37. {
  38. // vim
  39. if(cfg.enabledVim != null){
  40. cfg.enabledVim ? this.initVimMode() : this.destoryVim();
  41. }
  42. },
  43. // 加载vim
  44. initVimMode(){
  45. if(this.vim_mode){
  46. return;
  47. }
  48. this.vimStatusBar = document.getElementById('vimStatusBar');
  49. if(this.vimStatusBar) this.vimStatusBar.remove()
  50. this.vimStatusBar = document.createElement('div')
  51. this.vimStatusBar.id = 'vimStatusBar'
  52. const parent = document.getElementsByClassName('group console flex-1 style-scope app-status-bar')[0] || document.getElementsByClassName('content')[0] || this.parent.$box; // 确定插入位置
  53. parent != this.parent.$box && parent.children[0] ? parent.insertBefore(this.vimStatusBar,parent.children[0]) : parent.appendChild(this.vimStatusBar);
  54. vsVim = vsVim || Editor.require('packages://simple-code/extensions/editor-vim-model/vim/lib/index.js');;
  55. const vim_mode = vsVim.initVimMode(this.parent.vs_editor, this.vimStatusBar);
  56. this.vim_cursor[0] = vim_mode;
  57. Editor.monaco.vim_mode = this.vim_mode = vim_mode;
  58. },
  59. upVimCursor(selections)
  60. {
  61. if(selections == null || this.vim_cursor == null){
  62. return;
  63. }
  64. let len = selections.length > this.vim_cursor.length ? selections.length : this.vim_cursor.length;
  65. if(len == 0 || this.vim_mode == null){
  66. return;
  67. }
  68. // 1.判断第一光标是否vi模式
  69. // 2.判断第一个光标是否处于选取状态
  70. // 3.同步vi/选取状态到新光标对象里
  71. let is_insert_mode = !this.vim_mode.state.vim || this.vim_mode.state.vim.insertMode;
  72. let is_visual_mode = !is_insert_mode && !selections[0].isEmpty();
  73. let has_active = false
  74. for (let i = 0; i < len; i++)
  75. {
  76. let select = selections[i];
  77. let vimObj = this.vim_cursor[i];
  78. // 新光标
  79. if(select && vimObj == null)
  80. {
  81. vimObj = this.vim_cursor[i] = vsVim.initVimMode(this.parent.vs_editor);
  82. // 设置光标ID
  83. vimObj.cursor_id = i;
  84. if(is_insert_mode){
  85. vimObj.enterInsertMode()
  86. }
  87. has_active = true;
  88. }else if(select == null && vimObj && i != 0)
  89. {
  90. // 删除光标
  91. this.vim_cursor[i] = undefined;
  92. vimObj.dispose();
  93. has_active = true;
  94. continue;
  95. }
  96. if(vimObj)
  97. {
  98. if(is_visual_mode && !vimObj.state.vim.visualMode){
  99. vimObj.setVisualSelection(select)
  100. }
  101. else{
  102. vimObj.setSelectionByRange(select)
  103. }
  104. }
  105. }
  106. // 增减光标动画会改变
  107. for (let i = 0; i < has_active ? this.vim_cursor.length : 0; i++)
  108. {
  109. let vimObj = this.vim_cursor[i];
  110. if(vimObj)
  111. {
  112. if(vimObj.state.vim.visualMode){
  113. vimObj.enterVisualMode()
  114. }else if(!vimObj.state.vim.insertMode){
  115. vimObj.enterVimMode()
  116. }else{
  117. vimObj.leaveVimMode()
  118. }
  119. }
  120. }
  121. },
  122. destoryVim(){
  123. if(!this.vim_mode) {
  124. return
  125. }
  126. for (let i = 0; i < this.vim_cursor.length; i++)
  127. {
  128. let vimObj = this.vim_cursor[i];
  129. if(vimObj) vimObj.dispose();
  130. }
  131. // this.vim_mode.dispose();
  132. this.vimStatusBar.remove()
  133. delete Editor.monaco.vim_mode;
  134. delete this.vimStatusBar;
  135. delete this.vim_mode;
  136. },
  137. // 面板销毁
  138. onDestroy(){
  139. this.destoryVim()
  140. },
  141. messages:{
  142. 'cleanFile'()
  143. {
  144. },
  145. },
  146. };