##// END OF EJS Templates
update mode on rename
Min RK -
Show More
@@ -1,178 +1,184 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'jquery',
5 'jquery',
6 'base/js/utils',
6 'base/js/utils',
7 'codemirror/lib/codemirror',
7 'codemirror/lib/codemirror',
8 'codemirror/mode/meta',
8 'codemirror/mode/meta',
9 'codemirror/addon/comment/comment',
9 'codemirror/addon/comment/comment',
10 'codemirror/addon/dialog/dialog',
10 'codemirror/addon/dialog/dialog',
11 'codemirror/addon/edit/closebrackets',
11 'codemirror/addon/edit/closebrackets',
12 'codemirror/addon/edit/matchbrackets',
12 'codemirror/addon/edit/matchbrackets',
13 'codemirror/addon/search/searchcursor',
13 'codemirror/addon/search/searchcursor',
14 'codemirror/addon/search/search',
14 'codemirror/addon/search/search',
15 'codemirror/keymap/emacs',
15 'codemirror/keymap/emacs',
16 'codemirror/keymap/sublime',
16 'codemirror/keymap/sublime',
17 'codemirror/keymap/vim',
17 'codemirror/keymap/vim',
18 ],
18 ],
19 function($,
19 function($,
20 utils,
20 utils,
21 CodeMirror
21 CodeMirror
22 ) {
22 ) {
23 "use strict";
23 "use strict";
24
24
25 var Editor = function(selector, options) {
25 var Editor = function(selector, options) {
26 var that = this;
26 var that = this;
27 this.selector = selector;
27 this.selector = selector;
28 this.contents = options.contents;
28 this.contents = options.contents;
29 this.events = options.events;
29 this.events = options.events;
30 this.base_url = options.base_url;
30 this.base_url = options.base_url;
31 this.file_path = options.file_path;
31 this.file_path = options.file_path;
32 this.config = options.config;
32 this.config = options.config;
33 this.codemirror = new CodeMirror($(this.selector)[0]);
33 this.codemirror = new CodeMirror($(this.selector)[0]);
34 this.generation = -1;
34 this.generation = -1;
35
35
36 // It appears we have to set commands on the CodeMirror class, not the
36 // It appears we have to set commands on the CodeMirror class, not the
37 // instance. I'd like to be wrong, but since there should only be one CM
37 // instance. I'd like to be wrong, but since there should only be one CM
38 // instance on the page, this is good enough for now.
38 // instance on the page, this is good enough for now.
39 CodeMirror.commands.save = $.proxy(this.save, this);
39 CodeMirror.commands.save = $.proxy(this.save, this);
40
40
41 this.save_enabled = false;
41 this.save_enabled = false;
42
42
43 this.config.loaded.then(function () {
43 this.config.loaded.then(function () {
44 // load codemirror config
44 // load codemirror config
45 var cfg = that.config.data.Editor || {};
45 var cfg = that.config.data.Editor || {};
46 var cmopts = $.extend(true, {}, // true = recursive copy
46 var cmopts = $.extend(true, {}, // true = recursive copy
47 Editor.default_codemirror_options,
47 Editor.default_codemirror_options,
48 cfg.codemirror_options || {}
48 cfg.codemirror_options || {}
49 );
49 );
50 that._set_codemirror_options(cmopts);
50 that._set_codemirror_options(cmopts);
51 that.events.trigger('config_changed.Editor', {config: that.config});
51 that.events.trigger('config_changed.Editor', {config: that.config});
52 });
52 });
53 };
53 };
54
54
55 // default CodeMirror options
55 // default CodeMirror options
56 Editor.default_codemirror_options = {
56 Editor.default_codemirror_options = {
57 extraKeys: {
57 extraKeys: {
58 "Tab" : "indentMore",
58 "Tab" : "indentMore",
59 },
59 },
60 indentUnit: 4,
60 indentUnit: 4,
61 theme: "ipython",
61 theme: "ipython",
62 lineNumbers: true,
62 lineNumbers: true,
63 };
63 };
64
64
65 Editor.prototype.load = function() {
65 Editor.prototype.load = function() {
66 /** load the file */
66 /** load the file */
67 var that = this;
67 var that = this;
68 var cm = this.codemirror;
68 var cm = this.codemirror;
69 return this.contents.get(this.file_path, {type: 'file', format: 'text'})
69 return this.contents.get(this.file_path, {type: 'file', format: 'text'})
70 .then(function(model) {
70 .then(function(model) {
71 cm.setValue(model.content);
71 cm.setValue(model.content);
72
72
73 // Setting the file's initial value creates a history entry,
73 // Setting the file's initial value creates a history entry,
74 // which we don't want.
74 // which we don't want.
75 cm.clearHistory();
75 cm.clearHistory();
76
76 that._set_mode_for_model(model);
77 // Find and load the highlighting mode,
78 // first by mime-type, then by file extension
79 var modeinfo = CodeMirror.findModeByMIME(model.mimetype);
80 if (modeinfo.mode === "null") {
81 // find by mime failed, use find by ext
82 var ext_idx = model.name.lastIndexOf('.');
83
84 if (ext_idx > 0) {
85 // CodeMirror.findModeByExtension wants extension without '.'
86 modeinfo = CodeMirror.findModeByExtension(model.name.slice(ext_idx + 1));
87 }
88 }
89 if (modeinfo) {
90 that.set_codemirror_mode(modeinfo);
91 }
92 that.save_enabled = true;
77 that.save_enabled = true;
93 that.generation = cm.changeGeneration();
78 that.generation = cm.changeGeneration();
94 that.events.trigger("file_loaded.Editor", model);
79 that.events.trigger("file_loaded.Editor", model);
95 },
80 },
96 function(error) {
81 function(error) {
97 cm.setValue("Error! " + error.message +
82 cm.setValue("Error! " + error.message +
98 "\nSaving disabled.");
83 "\nSaving disabled.");
99 that.save_enabled = false;
84 that.save_enabled = false;
100 }
85 }
101 );
86 );
102 };
87 };
88
89 Editor.prototype._set_mode_for_model = function (model) {
90 /** Set the CodeMirror mode based on the file model */
91
92 // Find and load the highlighting mode,
93 // first by mime-type, then by file extension
94 var modeinfo = CodeMirror.findModeByMIME(model.mimetype);
95 if (modeinfo.mode === "null") {
96 // find by mime failed, use find by ext
97 var ext_idx = model.name.lastIndexOf('.');
98
99 if (ext_idx > 0) {
100 // CodeMirror.findModeByExtension wants extension without '.'
101 modeinfo = CodeMirror.findModeByExtension(model.name.slice(ext_idx + 1));
102 }
103 }
104 if (modeinfo) {
105 this.set_codemirror_mode(modeinfo);
106 }
107 };
103
108
104 Editor.prototype.set_codemirror_mode = function (modeinfo) {
109 Editor.prototype.set_codemirror_mode = function (modeinfo) {
105 /** set the codemirror mode from a modeinfo struct */
110 /** set the codemirror mode from a modeinfo struct */
106 var that = this;
111 var that = this;
107 utils.requireCodeMirrorMode(modeinfo, function () {
112 utils.requireCodeMirrorMode(modeinfo, function () {
108 that.codemirror.setOption('mode', modeinfo.mode);
113 that.codemirror.setOption('mode', modeinfo.mode);
109 that.events.trigger("mode_changed.Editor", modeinfo);
114 that.events.trigger("mode_changed.Editor", modeinfo);
110 });
115 });
111 };
116 };
112
117
113 Editor.prototype.get_filename = function () {
118 Editor.prototype.get_filename = function () {
114 return utils.url_path_split(this.file_path)[1];
119 return utils.url_path_split(this.file_path)[1];
115 };
120 };
116
121
117 Editor.prototype.rename = function (new_name) {
122 Editor.prototype.rename = function (new_name) {
118 /** rename the file */
123 /** rename the file */
119 var that = this;
124 var that = this;
120 var parent = utils.url_path_split(this.file_path)[0];
125 var parent = utils.url_path_split(this.file_path)[0];
121 var new_path = utils.url_path_join(parent, new_name);
126 var new_path = utils.url_path_join(parent, new_name);
122 return this.contents.rename(this.file_path, new_path).then(
127 return this.contents.rename(this.file_path, new_path).then(
123 function (json) {
128 function (model) {
124 that.file_path = json.path;
129 that.file_path = model.path;
125 that.events.trigger('file_renamed.Editor', json);
130 that.events.trigger('file_renamed.Editor', model);
131 that._set_mode_for_model(model);
126 }
132 }
127 );
133 );
128 };
134 };
129
135
130 Editor.prototype.save = function () {
136 Editor.prototype.save = function () {
131 /** save the file */
137 /** save the file */
132 if (!this.save_enabled) {
138 if (!this.save_enabled) {
133 console.log("Not saving, save disabled");
139 console.log("Not saving, save disabled");
134 return;
140 return;
135 }
141 }
136 var model = {
142 var model = {
137 path: this.file_path,
143 path: this.file_path,
138 type: 'file',
144 type: 'file',
139 format: 'text',
145 format: 'text',
140 content: this.codemirror.getValue(),
146 content: this.codemirror.getValue(),
141 };
147 };
142 var that = this;
148 var that = this;
143 // record change generation for isClean
149 // record change generation for isClean
144 this.generation = this.codemirror.changeGeneration();
150 this.generation = this.codemirror.changeGeneration();
145 return this.contents.save(this.file_path, model).then(function(data) {
151 return this.contents.save(this.file_path, model).then(function(data) {
146 that.events.trigger("file_saved.Editor", data);
152 that.events.trigger("file_saved.Editor", data);
147 });
153 });
148 };
154 };
149
155
150 Editor.prototype._set_codemirror_options = function (options) {
156 Editor.prototype._set_codemirror_options = function (options) {
151 // update codemirror options from a dict
157 // update codemirror options from a dict
152 for (var opt in options) {
158 for (var opt in options) {
153 if (!options.hasOwnProperty(opt)) {
159 if (!options.hasOwnProperty(opt)) {
154 continue;
160 continue;
155 }
161 }
156 var value = options[opt];
162 var value = options[opt];
157 if (value === null) {
163 if (value === null) {
158 value = CodeMirror.defaults[opt];
164 value = CodeMirror.defaults[opt];
159 }
165 }
160 this.codemirror.setOption(opt, value);
166 this.codemirror.setOption(opt, value);
161 }
167 }
162 };
168 };
163
169
164 Editor.prototype.update_codemirror_options = function (options) {
170 Editor.prototype.update_codemirror_options = function (options) {
165 /** update codemirror options locally and save changes in config */
171 /** update codemirror options locally and save changes in config */
166 var that = this;
172 var that = this;
167 this._set_codemirror_options(options);
173 this._set_codemirror_options(options);
168 return this.config.update({
174 return this.config.update({
169 Editor: {
175 Editor: {
170 codemirror_options: options
176 codemirror_options: options
171 }
177 }
172 }).then(
178 }).then(
173 that.events.trigger('config_changed.Editor', {config: that.config})
179 that.events.trigger('config_changed.Editor', {config: that.config})
174 );
180 );
175 };
181 };
176
182
177 return {Editor: Editor};
183 return {Editor: Editor};
178 });
184 });
General Comments 0
You need to be logged in to leave comments. Login now