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