index.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import 'es6-promise/auto'; // polyfill Promise on IE
  4. import {
  5. CommandRegistry
  6. } from '@phosphor/commands';
  7. import {
  8. CommandPalette, SplitPanel, Widget
  9. } from '@phosphor/widgets';
  10. import {
  11. ServiceManager
  12. } from '@jupyterlab/services';
  13. import {
  14. NotebookPanel, NotebookWidgetFactory,
  15. NotebookModelFactory, NotebookActions
  16. } from '@jupyterlab/notebook';
  17. import {
  18. CompleterModel, Completer, CompletionHandler
  19. } from '@jupyterlab/completer';
  20. import {
  21. editorServices
  22. } from '@jupyterlab/codemirror';
  23. import {
  24. DocumentManager
  25. } from '@jupyterlab/docmanager';
  26. import {
  27. DocumentRegistry
  28. } from '@jupyterlab/docregistry';
  29. import {
  30. RenderMime
  31. } from '@jupyterlab/rendermime';
  32. import '@jupyterlab/theming/style/index.css';
  33. import '@jupyterlab/theming/style/variables-light.css';
  34. import '../index.css';
  35. let NOTEBOOK = 'test.ipynb';
  36. /**
  37. * The map of command ids used by the notebook.
  38. */
  39. const cmdIds = {
  40. invoke: 'completer:invoke',
  41. select: 'completer:select',
  42. invokeNotebook: 'completer:invoke-notebook',
  43. selectNotebook: 'completer:select-notebook',
  44. save: 'notebook:save',
  45. interrupt: 'notebook:interrupt-kernel',
  46. restart: 'notebook:restart-kernel',
  47. switchKernel: 'notebook:switch-kernel',
  48. runAndAdvance: 'notebook-cells:run-and-advance',
  49. deleteCell: 'notebook-cells:delete',
  50. selectAbove: 'notebook-cells:select-above',
  51. selectBelow: 'notebook-cells:select-below',
  52. extendAbove: 'notebook-cells:extend-above',
  53. extendBelow: 'notebook-cells:extend-below',
  54. editMode: 'notebook:edit-mode',
  55. merge: 'notebook-cells:merge',
  56. split: 'notebook-cells:split',
  57. commandMode: 'notebook:command-mode',
  58. undo: 'notebook-cells:undo',
  59. redo: 'notebook-cells:redo'
  60. };
  61. function main(): void {
  62. let manager = new ServiceManager();
  63. manager.ready.then(() => {
  64. createApp(manager);
  65. });
  66. }
  67. function createApp(manager: ServiceManager.IManager): void {
  68. // Initialize the command registry with the bindings.
  69. let commands = new CommandRegistry();
  70. let useCapture = true;
  71. // Setup the keydown listener for the document.
  72. document.addEventListener('keydown', event => {
  73. commands.processKeydownEvent(event);
  74. }, useCapture);
  75. let initialFactories = RenderMime.getDefaultFactories();
  76. let rendermime = new RenderMime({ initialFactories });
  77. let opener = {
  78. open: (widget: Widget) => {
  79. // Do nothing for sibling widgets for now.
  80. }
  81. };
  82. let docRegistry = new DocumentRegistry();
  83. let docManager = new DocumentManager({
  84. registry: docRegistry,
  85. manager,
  86. opener
  87. });
  88. let mFactory = new NotebookModelFactory({});
  89. let editorFactory = editorServices.factoryService.newInlineEditor.bind(
  90. editorServices.factoryService);
  91. let contentFactory = new NotebookPanel.ContentFactory({ editorFactory });
  92. let wFactory = new NotebookWidgetFactory({
  93. name: 'Notebook',
  94. modelName: 'notebook',
  95. fileExtensions: ['.ipynb'],
  96. defaultFor: ['.ipynb'],
  97. preferKernel: true,
  98. canStartKernel: true,
  99. rendermime, contentFactory,
  100. mimeTypeService: editorServices.mimeTypeService
  101. });
  102. docRegistry.addModelFactory(mFactory);
  103. docRegistry.addWidgetFactory(wFactory);
  104. let nbWidget = docManager.open(NOTEBOOK) as NotebookPanel;
  105. let palette = new CommandPalette({ commands });
  106. const editor = nbWidget.notebook.activeCell && nbWidget.notebook.activeCell.editor;
  107. const model = new CompleterModel();
  108. const completer = new Completer({ editor, model });
  109. const handler = new CompletionHandler({ completer, session: nbWidget.session });
  110. // Set the handler's editor.
  111. handler.editor = editor;
  112. // Listen for active cell changes.
  113. nbWidget.notebook.activeCellChanged.connect((sender, cell) => {
  114. handler.editor = cell && cell.editor;
  115. });
  116. // Hide the widget when it first loads.
  117. completer.hide();
  118. let panel = new SplitPanel();
  119. panel.id = 'main';
  120. panel.orientation = 'horizontal';
  121. panel.spacing = 0;
  122. SplitPanel.setStretch(palette, 0);
  123. panel.addWidget(completer);
  124. panel.addWidget(palette);
  125. panel.addWidget(nbWidget);
  126. Widget.attach(panel, document.body);
  127. SplitPanel.setStretch(nbWidget, 1);
  128. window.onresize = () => panel.update();
  129. commands.addCommand(cmdIds.invoke, {
  130. label: 'Completer: Invoke',
  131. execute: () => handler.invoke()
  132. });
  133. commands.addCommand(cmdIds.select, {
  134. label: 'Completer: Select',
  135. execute: () => handler.completer.selectActive()
  136. });
  137. commands.addCommand(cmdIds.invokeNotebook, {
  138. label: 'Invoke Notebook',
  139. execute: () => {
  140. if (nbWidget.notebook.activeCell.model.type === 'code') {
  141. return commands.execute(cmdIds.invoke);
  142. }
  143. }
  144. });
  145. commands.addCommand(cmdIds.selectNotebook, {
  146. label: 'Select Notebook',
  147. execute: () => {
  148. if (nbWidget.notebook.activeCell.model.type === 'code') {
  149. return commands.execute(cmdIds.select);
  150. }
  151. }
  152. });
  153. commands.addCommand(cmdIds.save, {
  154. label: 'Save',
  155. execute: () => nbWidget.context.save()
  156. });
  157. commands.addCommand(cmdIds.interrupt, {
  158. label: 'Interrupt',
  159. execute: () => {
  160. if (nbWidget.context.session.kernel) {
  161. nbWidget.context.session.kernel.interrupt();
  162. }
  163. }
  164. });
  165. commands.addCommand(cmdIds.restart, {
  166. label: 'Restart Kernel',
  167. execute: () => nbWidget.context.session.restart()
  168. });
  169. commands.addCommand(cmdIds.switchKernel, {
  170. label: 'Switch Kernel',
  171. execute: () => nbWidget.context.session.selectKernel()
  172. });
  173. commands.addCommand(cmdIds.runAndAdvance, {
  174. label: 'Run and Advance',
  175. execute: () => {
  176. NotebookActions.runAndAdvance(nbWidget.notebook, nbWidget.context.session);
  177. }
  178. });
  179. commands.addCommand(cmdIds.editMode, {
  180. label: 'Edit Mode',
  181. execute: () => { nbWidget.notebook.mode = 'edit'; }
  182. });
  183. commands.addCommand(cmdIds.commandMode, {
  184. label: 'Command Mode',
  185. execute: () => { nbWidget.notebook.mode = 'command'; }
  186. });
  187. commands.addCommand(cmdIds.selectBelow, {
  188. label: 'Select Below',
  189. execute: () => NotebookActions.selectBelow(nbWidget.notebook)
  190. });
  191. commands.addCommand(cmdIds.selectAbove, {
  192. label: 'Select Above',
  193. execute: () => NotebookActions.selectAbove(nbWidget.notebook)
  194. });
  195. commands.addCommand(cmdIds.extendAbove, {
  196. label: 'Extend Above',
  197. execute: () => NotebookActions.extendSelectionAbove(nbWidget.notebook)
  198. });
  199. commands.addCommand(cmdIds.extendBelow, {
  200. label: 'Extend Below',
  201. execute: () => NotebookActions.extendSelectionBelow(nbWidget.notebook)
  202. });
  203. commands.addCommand(cmdIds.merge, {
  204. label: 'Merge Cells',
  205. execute: () => NotebookActions.mergeCells(nbWidget.notebook)
  206. });
  207. commands.addCommand(cmdIds.split, {
  208. label: 'Split Cell',
  209. execute: () => NotebookActions.splitCell(nbWidget.notebook)
  210. });
  211. commands.addCommand(cmdIds.undo, {
  212. label: 'Undo',
  213. execute: () => NotebookActions.undo(nbWidget.notebook)
  214. });
  215. commands.addCommand(cmdIds.redo, {
  216. label: 'Redo',
  217. execute: () => NotebookActions.redo(nbWidget.notebook)
  218. });
  219. let category = 'Notebook Operations';
  220. [
  221. cmdIds.interrupt,
  222. cmdIds.restart,
  223. cmdIds.editMode,
  224. cmdIds.commandMode,
  225. cmdIds.switchKernel
  226. ].forEach(command => palette.addItem({ command, category }));
  227. category = 'Notebook Cell Operations';
  228. [
  229. cmdIds.runAndAdvance,
  230. cmdIds.split,
  231. cmdIds.merge,
  232. cmdIds.selectAbove,
  233. cmdIds.selectBelow,
  234. cmdIds.extendAbove,
  235. cmdIds.extendBelow,
  236. cmdIds.undo,
  237. cmdIds.redo
  238. ].forEach(command => palette.addItem({ command, category }));
  239. let bindings = [
  240. {
  241. selector: '.jp-Notebook.jp-mod-editMode .jp-mod-completer-enabled',
  242. keys: ['Tab'],
  243. command: cmdIds.invokeNotebook
  244. },
  245. {
  246. selector: `.jp-mod-completer-enabled`,
  247. keys: ['Enter'],
  248. command: cmdIds.selectNotebook
  249. },
  250. {
  251. selector: '.jp-Notebook',
  252. keys: ['Shift Enter'],
  253. command: cmdIds.runAndAdvance
  254. },
  255. {
  256. selector: '.jp-Notebook',
  257. keys: ['Accel S'],
  258. command: cmdIds.save
  259. },
  260. {
  261. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  262. keys: ['I', 'I'],
  263. command: cmdIds.interrupt
  264. },
  265. {
  266. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  267. keys: ['0', '0'],
  268. command: cmdIds.restart
  269. },
  270. {
  271. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  272. keys: ['Enter'],
  273. command: cmdIds.editMode
  274. },
  275. {
  276. selector: '.jp-Notebook.jp-mod-editMode',
  277. keys: ['Escape'],
  278. command: cmdIds.commandMode
  279. },
  280. {
  281. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  282. keys: ['Shift M'],
  283. command: cmdIds.merge
  284. },
  285. {
  286. selector: '.jp-Notebook.jp-mod-editMode',
  287. keys: ['Ctrl Shift -'],
  288. command: cmdIds.split
  289. },
  290. {
  291. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  292. keys: ['J'],
  293. command: cmdIds.selectBelow
  294. },
  295. {
  296. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  297. keys: ['ArrowDown'],
  298. command: cmdIds.selectBelow
  299. },
  300. {
  301. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  302. keys: ['K'],
  303. command: cmdIds.selectAbove
  304. },
  305. {
  306. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  307. keys: ['ArrowUp'],
  308. command: cmdIds.selectAbove
  309. },
  310. {
  311. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  312. keys: ['Shift K'],
  313. command: cmdIds.extendAbove
  314. },
  315. {
  316. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  317. keys: ['Shift J'],
  318. command: cmdIds.extendBelow
  319. },
  320. {
  321. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  322. keys: ['Z'],
  323. command: cmdIds.undo
  324. },
  325. {
  326. selector: '.jp-Notebook.jp-mod-commandMode:focus',
  327. keys: ['Y'],
  328. command: cmdIds.redo
  329. }
  330. ];
  331. bindings.map(binding => commands.addKeyBinding(binding));
  332. }
  333. window.onload = main;