ext-code_lens.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. define("ace/ext/code_lens",["require","exports","module","ace/line_widgets","ace/lib/lang","ace/lib/dom","ace/editor","ace/config"], function(require, exports, module) {
  2. "use strict";
  3. var LineWidgets = require("../line_widgets").LineWidgets;
  4. var lang = require("../lib/lang");
  5. var dom = require("../lib/dom");
  6. function clearLensElements(renderer) {
  7. var textLayer = renderer.$textLayer;
  8. var lensElements = textLayer.$lenses;
  9. if (lensElements)
  10. lensElements.forEach(function(el) {el.remove(); });
  11. textLayer.$lenses = null;
  12. }
  13. function renderWidgets(changes, renderer) {
  14. var changed = changes & renderer.CHANGE_LINES
  15. || changes & renderer.CHANGE_FULL
  16. || changes & renderer.CHANGE_SCROLL
  17. || changes & renderer.CHANGE_TEXT;
  18. if (!changed)
  19. return;
  20. var session = renderer.session;
  21. var lineWidgets = renderer.session.lineWidgets;
  22. var textLayer = renderer.$textLayer;
  23. var lensElements = textLayer.$lenses;
  24. if (!lineWidgets) {
  25. if (lensElements)
  26. clearLensElements(renderer);
  27. return;
  28. }
  29. var textCells = renderer.$textLayer.$lines.cells;
  30. var config = renderer.layerConfig;
  31. var padding = renderer.$padding;
  32. if (!lensElements)
  33. lensElements = textLayer.$lenses = [];
  34. var index = 0;
  35. for (var i = 0; i < textCells.length; i++) {
  36. var row = textCells[i].row;
  37. var widget = lineWidgets[row];
  38. var lenses = widget && widget.lenses;
  39. if (!lenses || !lenses.length) continue;
  40. var lensContainer = lensElements[index];
  41. if (!lensContainer) {
  42. lensContainer = lensElements[index]
  43. = dom.buildDom(["div", {class: "ace_codeLens"}], renderer.container);
  44. }
  45. lensContainer.style.height = config.lineHeight + "px";
  46. index++;
  47. for (var j = 0; j < lenses.length; j++) {
  48. var el = lensContainer.childNodes[2 * j];
  49. if (!el) {
  50. if (j != 0) lensContainer.appendChild(dom.createTextNode("\xa0|\xa0"));
  51. el = dom.buildDom(["a"], lensContainer);
  52. }
  53. el.textContent = lenses[j].title;
  54. el.lensCommand = lenses[j];
  55. }
  56. while (lensContainer.childNodes.length > 2 * j - 1)
  57. lensContainer.lastChild.remove();
  58. var top = renderer.$cursorLayer.getPixelPosition({
  59. row: row,
  60. column: 0
  61. }, true).top - config.lineHeight * widget.rowsAbove - config.offset;
  62. lensContainer.style.top = top + "px";
  63. var left = renderer.gutterWidth;
  64. var indent = session.getLine(row).search(/\S|$/);
  65. if (indent == -1)
  66. indent = 0;
  67. left += indent * config.characterWidth;
  68. left -= renderer.scrollLeft;
  69. lensContainer.style.paddingLeft = padding + left + "px";
  70. }
  71. while (index < lensElements.length)
  72. lensElements.pop().remove();
  73. }
  74. function clearCodeLensWidgets(session) {
  75. if (!session.lineWidgets) return;
  76. var widgetManager = session.widgetManager;
  77. session.lineWidgets.forEach(function(widget) {
  78. if (widget && widget.lenses)
  79. widgetManager.removeLineWidget(widget);
  80. });
  81. }
  82. exports.setLenses = function(session, lenses) {
  83. var firstRow = Number.MAX_VALUE;
  84. clearCodeLensWidgets(session);
  85. lenses && lenses.forEach(function(lens) {
  86. var row = lens.start.row;
  87. var column = lens.start.column;
  88. var widget = session.lineWidgets && session.lineWidgets[row];
  89. if (!widget || !widget.lenses) {
  90. widget = session.widgetManager.$registerLineWidget({
  91. rowCount: 1,
  92. rowsAbove: 1,
  93. row: row,
  94. column: column,
  95. lenses: []
  96. });
  97. }
  98. widget.lenses.push(lens.command);
  99. if (row < firstRow)
  100. firstRow = row;
  101. });
  102. session._emit("changeFold", {data: {start: {row: firstRow}}});
  103. };
  104. function attachToEditor(editor) {
  105. editor.codeLensProviders = [];
  106. editor.renderer.on("afterRender", renderWidgets);
  107. editor.$codeLensClickHandler = function(e) {
  108. var command = e.target.lensCommand;
  109. if (command)
  110. editor.execCommand(command.id, command.arguments);
  111. };
  112. editor.container.addEventListener("click", editor.$codeLensClickHandler);
  113. editor.$updateLenses = function() {
  114. var session = editor.session;
  115. if (!session) return;
  116. if (!session.widgetManager) {
  117. session.widgetManager = new LineWidgets(session);
  118. session.widgetManager.attach(editor);
  119. }
  120. var providersToWaitNum = editor.codeLensProviders.length;
  121. var lenses = [];
  122. editor.codeLensProviders.forEach(function(provider) {
  123. provider.provideCodeLenses(session, function(currentLenses) {
  124. currentLenses.forEach(function(lens) {
  125. lenses.push(lens);
  126. });
  127. providersToWaitNum--;
  128. if (providersToWaitNum == 0) {
  129. applyLenses();
  130. }
  131. });
  132. });
  133. function applyLenses() {
  134. var cursor = session.selection.cursor;
  135. var oldRow = session.documentToScreenRow(cursor);
  136. exports.setLenses(session, lenses);
  137. var lastDelta = session.$undoManager && session.$undoManager.$lastDelta;
  138. if (lastDelta && lastDelta.action == "remove" && lastDelta.lines.length > 1)
  139. return;
  140. var row = session.documentToScreenRow(cursor);
  141. var lineHeight = editor.renderer.layerConfig.lineHeight;
  142. var top = session.getScrollTop() + (row - oldRow) * lineHeight;
  143. session.setScrollTop(top);
  144. }
  145. };
  146. var updateLenses = lang.delayedCall(editor.$updateLenses);
  147. editor.$updateLensesOnInput = function() {
  148. updateLenses.delay(250);
  149. };
  150. editor.on("input", editor.$updateLensesOnInput);
  151. }
  152. function detachFromEditor(editor) {
  153. editor.off("input", editor.$updateLensesOnInput);
  154. editor.renderer.off("afterRender", renderWidgets);
  155. if (editor.$codeLensClickHandler)
  156. editor.container.removeEventListener("click", editor.$codeLensClickHandler);
  157. }
  158. exports.registerCodeLensProvider = function(editor, codeLensProvider) {
  159. editor.setOption("enableCodeLens", true);
  160. editor.codeLensProviders.push(codeLensProvider);
  161. editor.$updateLensesOnInput();
  162. };
  163. exports.clear = function(session) {
  164. exports.setLenses(session, null);
  165. };
  166. var Editor = require("../editor").Editor;
  167. require("../config").defineOptions(Editor.prototype, "editor", {
  168. enableCodeLens: {
  169. set: function(val) {
  170. if (val) {
  171. attachToEditor(this);
  172. } else {
  173. detachFromEditor(this);
  174. }
  175. }
  176. }
  177. });
  178. dom.importCssString("\
  179. .ace_codeLens {\
  180. position: absolute;\
  181. color: #aaa;\
  182. font-size: 88%;\
  183. background: inherit;\
  184. width: 100%;\
  185. display: flex;\
  186. align-items: flex-end;\
  187. pointer-events: none;\
  188. }\
  189. .ace_codeLens > a {\
  190. cursor: pointer;\
  191. pointer-events: auto;\
  192. }\
  193. .ace_codeLens > a:hover {\
  194. color: #0000ff;\
  195. text-decoration: underline;\
  196. }\
  197. .ace_dark > .ace_codeLens > a:hover {\
  198. color: #4e94ce;\
  199. }\
  200. ", "");
  201. });
  202. (function() {
  203. window.require(["ace/ext/code_lens"], function(m) {
  204. if (typeof module == "object" && typeof exports == "object" && module) {
  205. module.exports = m;
  206. }
  207. });
  208. })();