##// END OF EJS Templates
removed tab backward
Andrew Dawes -
Show More
@@ -1,301 +1,300
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 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 'base/js/dialog',
8 'base/js/dialog',
9 ], function(IPython, $, utils, dialog) {
9 ], function(IPython, $, utils, dialog) {
10 "use strict";
10 "use strict";
11 var platform = utils.platform;
11 var platform = utils.platform;
12
12
13 var QuickHelp = function (options) {
13 var QuickHelp = function (options) {
14 /**
14 /**
15 * Constructor
15 * Constructor
16 *
16 *
17 * Parameters:
17 * Parameters:
18 * options: dictionary
18 * options: dictionary
19 * Dictionary of keyword arguments.
19 * Dictionary of keyword arguments.
20 * events: $(Events) instance
20 * events: $(Events) instance
21 * keyboard_manager: KeyboardManager instance
21 * keyboard_manager: KeyboardManager instance
22 * notebook: Notebook instance
22 * notebook: Notebook instance
23 */
23 */
24 this.keyboard_manager = options.keyboard_manager;
24 this.keyboard_manager = options.keyboard_manager;
25 this.notebook = options.notebook;
25 this.notebook = options.notebook;
26 this.keyboard_manager.quick_help = this;
26 this.keyboard_manager.quick_help = this;
27 this.events = options.events;
27 this.events = options.events;
28 };
28 };
29
29
30 var cmd_ctrl = 'Ctrl-';
30 var cmd_ctrl = 'Ctrl-';
31 var platform_specific;
31 var platform_specific;
32
32
33 if (platform === 'MacOS') {
33 if (platform === 'MacOS') {
34 // Mac OS X specific
34 // Mac OS X specific
35 cmd_ctrl = 'Cmd-';
35 cmd_ctrl = 'Cmd-';
36 platform_specific = [
36 platform_specific = [
37 { shortcut: "Cmd-Up", help:"go to cell start" },
37 { shortcut: "Cmd-Up", help:"go to cell start" },
38 { shortcut: "Cmd-Down", help:"go to cell end" },
38 { shortcut: "Cmd-Down", help:"go to cell end" },
39 { shortcut: "Alt-Left", help:"go one word left" },
39 { shortcut: "Alt-Left", help:"go one word left" },
40 { shortcut: "Alt-Right", help:"go one word right" },
40 { shortcut: "Alt-Right", help:"go one word right" },
41 { shortcut: "Alt-Backspace", help:"del word before" },
41 { shortcut: "Alt-Backspace", help:"del word before" },
42 { shortcut: "Alt-Delete", help:"del word after" },
42 { shortcut: "Alt-Delete", help:"del word after" },
43 ];
43 ];
44 } else {
44 } else {
45 // PC specific
45 // PC specific
46 platform_specific = [
46 platform_specific = [
47 { shortcut: "Ctrl-Home", help:"go to cell start" },
47 { shortcut: "Ctrl-Home", help:"go to cell start" },
48 { shortcut: "Ctrl-Up", help:"go to cell start" },
48 { shortcut: "Ctrl-Up", help:"go to cell start" },
49 { shortcut: "Ctrl-End", help:"go to cell end" },
49 { shortcut: "Ctrl-End", help:"go to cell end" },
50 { shortcut: "Ctrl-Down", help:"go to cell end" },
50 { shortcut: "Ctrl-Down", help:"go to cell end" },
51 { shortcut: "Ctrl-Left", help:"go one word left" },
51 { shortcut: "Ctrl-Left", help:"go one word left" },
52 { shortcut: "Ctrl-Right", help:"go one word right" },
52 { shortcut: "Ctrl-Right", help:"go one word right" },
53 { shortcut: "Ctrl-Backspace", help:"del word before" },
53 { shortcut: "Ctrl-Backspace", help:"del word before" },
54 { shortcut: "Ctrl-Delete", help:"del word after" },
54 { shortcut: "Ctrl-Delete", help:"del word after" },
55 ];
55 ];
56 }
56 }
57
57
58 var cm_shortcuts = [
58 var cm_shortcuts = [
59 { shortcut:"Tab", help:"code completion or indent" },
59 { shortcut:"Tab", help:"code completion or indent" },
60 { shortcut:"Shift-Tab", help:"tooltip" },
60 { shortcut:"Shift-Tab", help:"tooltip" },
61 { shortcut: cmd_ctrl + "]", help:"indent" },
61 { shortcut: cmd_ctrl + "]", help:"indent" },
62 { shortcut: cmd_ctrl + "[", help:"dedent" },
62 { shortcut: cmd_ctrl + "[", help:"dedent" },
63 { shortcut: cmd_ctrl + "a", help:"select all" },
63 { shortcut: cmd_ctrl + "a", help:"select all" },
64 { shortcut: cmd_ctrl + "z", help:"undo" },
64 { shortcut: cmd_ctrl + "z", help:"undo" },
65 { shortcut: cmd_ctrl + "Shift-z", help:"redo" },
65 { shortcut: cmd_ctrl + "Shift-z", help:"redo" },
66 { shortcut: cmd_ctrl + "y", help:"redo" },
66 { shortcut: cmd_ctrl + "y", help:"redo" },
67 ].concat( platform_specific );
67 ].concat( platform_specific );
68
68
69 var mac_humanize_map = {
69 var mac_humanize_map = {
70 // all these are unicode, will probably display badly on anything except macs.
70 // all these are unicode, will probably display badly on anything except macs.
71 // these are the standard symbol that are used in MacOS native menus
71 // these are the standard symbol that are used in MacOS native menus
72 // cf http://apple.stackexchange.com/questions/55727/
72 // cf http://apple.stackexchange.com/questions/55727/
73 // for htmlentities and/or unicode value
73 // for htmlentities and/or unicode value
74 'cmd':'⌘',
74 'cmd':'⌘',
75 'shift':'⇧',
75 'shift':'⇧',
76 'alt':'⌥',
76 'alt':'⌥',
77 'up':'↑',
77 'up':'↑',
78 'down':'↓',
78 'down':'↓',
79 'left':'←',
79 'left':'←',
80 'right':'→',
80 'right':'→',
81 'eject':'⏏',
81 'eject':'⏏',
82 'tab':'⇥',
82 'tab':'⇥',
83 'backtab':'⇤',
83 'backtab':'⇤',
84 'capslock':'⇪',
84 'capslock':'⇪',
85 'esc':'esc',
85 'esc':'esc',
86 'ctrl':'⌃',
86 'ctrl':'⌃',
87 'enter':'↩',
87 'enter':'↩',
88 'pageup':'⇞',
88 'pageup':'⇞',
89 'pagedown':'⇟',
89 'pagedown':'⇟',
90 'home':'↖',
90 'home':'↖',
91 'end':'↘',
91 'end':'↘',
92 'altenter':'⌤',
92 'altenter':'⌤',
93 'space':'␣',
93 'space':'␣',
94 'delete':'⌦',
94 'delete':'⌦',
95 'backspace':'⌫',
95 'backspace':'⌫',
96 'apple':'',
96 'apple':'',
97 };
97 };
98
98
99 var default_humanize_map = {
99 var default_humanize_map = {
100 'shift':'Shift',
100 'shift':'Shift',
101 'alt':'Alt',
101 'alt':'Alt',
102 'up':'Up',
102 'up':'Up',
103 'down':'Down',
103 'down':'Down',
104 'left':'Left',
104 'left':'Left',
105 'right':'Right',
105 'right':'Right',
106 'tab':'Tab',
106 'tab':'Tab',
107 'capslock':'Caps Lock',
107 'capslock':'Caps Lock',
108 'esc':'Esc',
108 'esc':'Esc',
109 'ctrl':'Ctrl',
109 'ctrl':'Ctrl',
110 'enter':'Enter',
110 'enter':'Enter',
111 'pageup':'Page Up',
111 'pageup':'Page Up',
112 'pagedown':'Page Down',
112 'pagedown':'Page Down',
113 'home':'Home',
113 'home':'Home',
114 'end':'End',
114 'end':'End',
115 'space':'Space',
115 'space':'Space',
116 'backspace':'Backspace',
116 'backspace':'Backspace',
117 };
117 };
118
118
119 var humanize_map;
119 var humanize_map;
120
120
121 if (platform === 'MacOS'){
121 if (platform === 'MacOS'){
122 humanize_map = mac_humanize_map;
122 humanize_map = mac_humanize_map;
123 } else {
123 } else {
124 humanize_map = default_humanize_map;
124 humanize_map = default_humanize_map;
125 }
125 }
126
126
127 function humanize_key(key){
127 function humanize_key(key){
128 if (key.length === 1){
128 if (key.length === 1){
129 key = key.toUpperCase();
129 key = key.toUpperCase();
130 }
130 }
131 return humanize_map[key.toLowerCase()]||key;
131 return humanize_map[key.toLowerCase()]||key;
132 }
132 }
133
133
134 function humanize_sequence(sequence){
134 function humanize_sequence(sequence){
135 var joinchar = ',';
135 var joinchar = ',';
136 var hum = _.map(sequence.replace(/meta/g, 'cmd').split(','), humanize_shortcut).join(joinchar);
136 var hum = _.map(sequence.replace(/meta/g, 'cmd').split(','), humanize_shortcut).join(joinchar);
137 return hum;
137 return hum;
138 }
138 }
139
139
140 function humanize_shortcut(shortcut){
140 function humanize_shortcut(shortcut){
141 var joinchar = '-';
141 var joinchar = '-';
142 if (platform === 'MacOS'){
142 if (platform === 'MacOS'){
143 joinchar = '';
143 joinchar = '';
144 }
144 }
145 var sh = _.map(shortcut.split('-'), humanize_key ).join(joinchar);
145 var sh = _.map(shortcut.split('-'), humanize_key ).join(joinchar);
146 return sh;
146 return sh;
147 }
147 }
148
148
149
149
150 QuickHelp.prototype.show_keyboard_shortcuts = function () {
150 QuickHelp.prototype.show_keyboard_shortcuts = function () {
151 /**
151 /**
152 * toggles display of keyboard shortcut dialog
152 * toggles display of keyboard shortcut dialog
153 */
153 */
154 var that = this;
154 var that = this;
155 if ( this.force_rebuild ) {
155 if ( this.force_rebuild ) {
156 this.shortcut_dialog.remove();
156 this.shortcut_dialog.remove();
157 delete(this.shortcut_dialog);
157 delete(this.shortcut_dialog);
158 this.force_rebuild = false;
158 this.force_rebuild = false;
159 }
159 }
160 if ( this.shortcut_dialog ){
160 if ( this.shortcut_dialog ){
161 // if dialog is already shown, close it
161 // if dialog is already shown, close it
162 $(this.shortcut_dialog).modal("toggle");
162 $(this.shortcut_dialog).modal("toggle");
163 return;
163 return;
164 }
164 }
165 var command_shortcuts = this.keyboard_manager.command_shortcuts.help();
165 var command_shortcuts = this.keyboard_manager.command_shortcuts.help();
166 var edit_shortcuts = this.keyboard_manager.edit_shortcuts.help();
166 var edit_shortcuts = this.keyboard_manager.edit_shortcuts.help();
167 var help, shortcut;
167 var help, shortcut;
168 var i, half, n;
168 var i, half, n;
169 var element = $('<div/>');
169 var element = $('<div/>');
170
170
171 // The documentation
171 // The documentation
172 var doc = $('<div/>').addClass('alert alert-warning');
172 var doc = $('<div/>').addClass('alert alert-warning');
173 doc.append(
173 doc.append(
174 $('<button/>').addClass('close').attr('data-dismiss','alert').html('&times;')
174 $('<button/>').addClass('close').attr('data-dismiss','alert').html('&times;')
175 ).append(
175 ).append(
176 'The IPython Notebook has two different keyboard input modes. <b>Edit mode</b> '+
176 'The IPython Notebook has two different keyboard input modes. <b>Edit mode</b> '+
177 'allows you to type code/text into a cell and is indicated by a green cell '+
177 'allows you to type code/text into a cell and is indicated by a green cell '+
178 'border. <b>Command mode</b> binds the keyboard to notebook level actions '+
178 'border. <b>Command mode</b> binds the keyboard to notebook level actions '+
179 'and is indicated by a grey cell border.'
179 'and is indicated by a grey cell border.'
180 );
180 );
181 if (platform === 'MacOS') {
181 if (platform === 'MacOS') {
182 var key_div = this.build_key_names();
182 var key_div = this.build_key_names();
183 doc.append(key_div);
183 doc.append(key_div);
184 }
184 }
185 element.append(doc);
185 element.append(doc);
186
186
187 // Command mode
187 // Command mode
188 var cmd_div = this.build_command_help();
188 var cmd_div = this.build_command_help();
189 element.append(cmd_div);
189 element.append(cmd_div);
190
190
191 // Edit mode
191 // Edit mode
192 var edit_div = this.build_edit_help(cm_shortcuts);
192 var edit_div = this.build_edit_help(cm_shortcuts);
193 element.append(edit_div);
193 element.append(edit_div);
194
194
195 this.shortcut_dialog = dialog.modal({
195 this.shortcut_dialog = dialog.modal({
196 title : "Keyboard shortcuts",
196 title : "Keyboard shortcuts",
197 body : element,
197 body : element,
198 destroy : false,
198 destroy : false,
199 buttons : {
199 buttons : {
200 Close : {}
200 Close : {}
201 },
201 },
202 notebook: this.notebook,
202 notebook: this.notebook,
203 keyboard_manager: this.keyboard_manager,
203 keyboard_manager: this.keyboard_manager,
204 });
204 });
205 this.shortcut_dialog.addClass("modal_stretch");
205 this.shortcut_dialog.addClass("modal_stretch");
206
206
207 this.events.on('rebuild.QuickHelp', function() { that.force_rebuild = true;});
207 this.events.on('rebuild.QuickHelp', function() { that.force_rebuild = true;});
208 };
208 };
209
209
210 QuickHelp.prototype.build_key_names = function () {
210 QuickHelp.prototype.build_key_names = function () {
211 var key_names_mac = [{ shortcut:"⌘", help:"Command" },
211 var key_names_mac = [{ shortcut:"⌘", help:"Command" },
212 { shortcut:"⌃", help:"Control" },
212 { shortcut:"⌃", help:"Control" },
213 { shortcut:"⌥", help:"Option" },
213 { shortcut:"⌥", help:"Option" },
214 { shortcut:"⇧", help:"Shift" },
214 { shortcut:"⇧", help:"Shift" },
215 { shortcut:"↩", help:"Return" },
215 { shortcut:"↩", help:"Return" },
216 { shortcut:"␣", help:"Space" },
216 { shortcut:"␣", help:"Space" },
217 { shortcut:"⇥", help:"Tab forward" },
217 { shortcut:"⇥", help:"Tab" }];
218 { shortcut:"⇤", help:"Tab back" }];
219 var i, half, n;
218 var i, half, n;
220 var div = $('<div/>').append('MacOS modifier keys:');
219 var div = $('<div/>').append('MacOS modifier keys:');
221 var sub_div = $('<div/>').addClass('container-fluid');
220 var sub_div = $('<div/>').addClass('container-fluid');
222 var col1 = $('<div/>').addClass('col-md-6');
221 var col1 = $('<div/>').addClass('col-md-6');
223 var col2 = $('<div/>').addClass('col-md-6');
222 var col2 = $('<div/>').addClass('col-md-6');
224 n = key_names_mac.length;
223 n = key_names_mac.length;
225 half = ~~(n/2);
224 half = ~~(n/2);
226 for (i=0; i<half; i++) { col1.append(
225 for (i=0; i<half; i++) { col1.append(
227 build_one(key_names_mac[i])
226 build_one(key_names_mac[i])
228 ); }
227 ); }
229 for (i=half; i<n; i++) { col2.append(
228 for (i=half; i<n; i++) { col2.append(
230 build_one(key_names_mac[i])
229 build_one(key_names_mac[i])
231 ); }
230 ); }
232 sub_div.append(col1).append(col2);
231 sub_div.append(col1).append(col2);
233 div.append(sub_div);
232 div.append(sub_div);
234 return div;
233 return div;
235 };
234 };
236
235
237
236
238 QuickHelp.prototype.build_command_help = function () {
237 QuickHelp.prototype.build_command_help = function () {
239 var command_shortcuts = this.keyboard_manager.command_shortcuts.help();
238 var command_shortcuts = this.keyboard_manager.command_shortcuts.help();
240 return build_div('<h4>Command Mode (press <code>Esc</code> to enable)</h4>', command_shortcuts);
239 return build_div('<h4>Command Mode (press <code>Esc</code> to enable)</h4>', command_shortcuts);
241 };
240 };
242
241
243 var special_case = { pageup: "PageUp", pagedown: "Page Down", 'minus': '-' };
242 var special_case = { pageup: "PageUp", pagedown: "Page Down", 'minus': '-' };
244 var prettify = function (s) {
243 var prettify = function (s) {
245 s = s.replace(/-$/, 'minus'); // catch shortcuts using '-' key
244 s = s.replace(/-$/, 'minus'); // catch shortcuts using '-' key
246 var keys = s.split('-');
245 var keys = s.split('-');
247 var k, i;
246 var k, i;
248 for (i=0; i < keys.length; i++) {
247 for (i=0; i < keys.length; i++) {
249 k = keys[i];
248 k = keys[i];
250 if ( k.length == 1 ) {
249 if ( k.length == 1 ) {
251 keys[i] = "<code><strong>" + k + "</strong></code>";
250 keys[i] = "<code><strong>" + k + "</strong></code>";
252 continue; // leave individual keys lower-cased
251 continue; // leave individual keys lower-cased
253 }
252 }
254 if (k.indexOf(',') === -1){
253 if (k.indexOf(',') === -1){
255 keys[i] = ( special_case[k] ? special_case[k] : k.charAt(0).toUpperCase() + k.slice(1) );
254 keys[i] = ( special_case[k] ? special_case[k] : k.charAt(0).toUpperCase() + k.slice(1) );
256 }
255 }
257 keys[i] = "<code><strong>" + keys[i] + "</strong></code>";
256 keys[i] = "<code><strong>" + keys[i] + "</strong></code>";
258 }
257 }
259 return keys.join('-');
258 return keys.join('-');
260
259
261
260
262 };
261 };
263
262
264 QuickHelp.prototype.build_edit_help = function (cm_shortcuts) {
263 QuickHelp.prototype.build_edit_help = function (cm_shortcuts) {
265 var edit_shortcuts = this.keyboard_manager.edit_shortcuts.help();
264 var edit_shortcuts = this.keyboard_manager.edit_shortcuts.help();
266 jQuery.merge(cm_shortcuts, edit_shortcuts);
265 jQuery.merge(cm_shortcuts, edit_shortcuts);
267 return build_div('<h4>Edit Mode (press <code>Enter</code> to enable)</h4>', cm_shortcuts);
266 return build_div('<h4>Edit Mode (press <code>Enter</code> to enable)</h4>', cm_shortcuts);
268 };
267 };
269
268
270 var build_one = function (s) {
269 var build_one = function (s) {
271 var help = s.help;
270 var help = s.help;
272 var shortcut = '';
271 var shortcut = '';
273 if(s.shortcut){
272 if(s.shortcut){
274 shortcut = prettify(humanize_sequence(s.shortcut));
273 shortcut = prettify(humanize_sequence(s.shortcut));
275 }
274 }
276 return $('<div>').addClass('quickhelp').
275 return $('<div>').addClass('quickhelp').
277 append($('<span/>').addClass('shortcut_key').append($(shortcut))).
276 append($('<span/>').addClass('shortcut_key').append($(shortcut))).
278 append($('<span/>').addClass('shortcut_descr').text(' : ' + help));
277 append($('<span/>').addClass('shortcut_descr').text(' : ' + help));
279
278
280 };
279 };
281
280
282 var build_div = function (title, shortcuts) {
281 var build_div = function (title, shortcuts) {
283 var i, half, n;
282 var i, half, n;
284 var div = $('<div/>').append($(title));
283 var div = $('<div/>').append($(title));
285 var sub_div = $('<div/>').addClass('container-fluid');
284 var sub_div = $('<div/>').addClass('container-fluid');
286 var col1 = $('<div/>').addClass('col-md-6');
285 var col1 = $('<div/>').addClass('col-md-6');
287 var col2 = $('<div/>').addClass('col-md-6');
286 var col2 = $('<div/>').addClass('col-md-6');
288 n = shortcuts.length;
287 n = shortcuts.length;
289 half = ~~(n/2); // Truncate :)
288 half = ~~(n/2); // Truncate :)
290 for (i=0; i<half; i++) { col1.append( build_one(shortcuts[i]) ); }
289 for (i=0; i<half; i++) { col1.append( build_one(shortcuts[i]) ); }
291 for (i=half; i<n; i++) { col2.append( build_one(shortcuts[i]) ); }
290 for (i=half; i<n; i++) { col2.append( build_one(shortcuts[i]) ); }
292 sub_div.append(col1).append(col2);
291 sub_div.append(col1).append(col2);
293 div.append(sub_div);
292 div.append(sub_div);
294 return div;
293 return div;
295 };
294 };
296
295
297 // Backwards compatability.
296 // Backwards compatability.
298 IPython.QuickHelp = QuickHelp;
297 IPython.QuickHelp = QuickHelp;
299
298
300 return {'QuickHelp': QuickHelp};
299 return {'QuickHelp': QuickHelp};
301 });
300 });
General Comments 0
You need to be logged in to leave comments. Login now