widget.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import * as CodeMirror
  4. from 'codemirror';
  5. import 'codemirror/mode/meta';
  6. import {
  7. IKernelId
  8. } from 'jupyter-js-services';
  9. import {
  10. loadModeByFileName
  11. } from '../codemirror';
  12. import {
  13. CodeMirrorWidget
  14. } from '../codemirror/widget';
  15. import {
  16. ABCWidgetFactory, IDocumentModel, IWidgetFactory, IDocumentContext
  17. } from '../docregistry';
  18. /**
  19. * The class name added to a dirty widget.
  20. */
  21. const DIRTY_CLASS = 'jp-mod-dirty';
  22. /**
  23. * The class name added to a jupyter code mirror widget.
  24. */
  25. const EDITOR_CLASS = 'jp-EditorWidget';
  26. /**
  27. * A document widget for codemirrors.
  28. */
  29. export
  30. class EditorWidget extends CodeMirrorWidget {
  31. /**
  32. * Construct a new editor widget.
  33. */
  34. constructor(context: IDocumentContext<IDocumentModel>) {
  35. super();
  36. this.addClass(EDITOR_CLASS);
  37. let editor = this.editor;
  38. let model = context.model;
  39. editor.setOption('lineNumbers', true);
  40. let doc = editor.getDoc();
  41. doc.setValue(model.toString());
  42. this.title.text = context.path.split('/').pop();
  43. loadModeByFileName(editor, context.path);
  44. model.stateChanged.connect((m, args) => {
  45. if (args.name === 'dirty') {
  46. if (args.newValue) {
  47. this.title.className += ` ${DIRTY_CLASS}`;
  48. } else {
  49. this.title.className = this.title.className.replace(DIRTY_CLASS, '');
  50. }
  51. }
  52. });
  53. context.pathChanged.connect((c, path) => {
  54. loadModeByFileName(editor, path);
  55. this.title.text = path.split('/').pop();
  56. });
  57. model.contentChanged.connect(() => {
  58. let old = doc.getValue();
  59. let text = model.toString();
  60. if (old !== text) {
  61. doc.setValue(text);
  62. }
  63. });
  64. CodeMirror.on(doc, 'change', (instance, change) => {
  65. if (change.origin !== 'setValue') {
  66. model.fromString(instance.getValue());
  67. }
  68. });
  69. }
  70. }
  71. /**
  72. * A widget factory for editors.
  73. */
  74. export
  75. class EditorWidgetFactory extends ABCWidgetFactory implements IWidgetFactory<EditorWidget, IDocumentModel> {
  76. /**
  77. * Create a new widget given a context.
  78. */
  79. createNew(context: IDocumentContext<IDocumentModel>, kernel?: IKernelId): EditorWidget {
  80. if (kernel) {
  81. context.changeKernel(kernel);
  82. }
  83. return new EditorWidget(context);
  84. }
  85. }