quickhelp.js
300 lines
| 10.1 KiB
| application/javascript
|
JavascriptLexer
MinRK
|
r16141 | // Copyright (c) IPython Development Team. | ||
// Distributed under the terms of the Modified BSD License. | ||||
Fernando Perez
|
r5023 | |||
Jonathan Frederic
|
r17197 | define([ | ||
'base/js/namespace', | ||||
Jonathan Frederic
|
r17200 | 'jquery', | ||
Jonathan Frederic
|
r17197 | 'base/js/utils', | ||
'base/js/dialog', | ||||
Jonathan Frederic
|
r17202 | ], function(IPython, $, utils, dialog) { | ||
Matthias BUSSONNIER
|
r12103 | "use strict"; | ||
Jonathan Frederic
|
r17198 | var platform = utils.platform; | ||
Fernando Perez
|
r5023 | |||
jon
|
r17210 | var QuickHelp = function (options) { | ||
Jonathan Frederic
|
r19176 | /** | ||
* Constructor | ||||
* | ||||
* Parameters: | ||||
* options: dictionary | ||||
* Dictionary of keyword arguments. | ||||
* events: $(Events) instance | ||||
* keyboard_manager: KeyboardManager instance | ||||
* notebook: Notebook instance | ||||
*/ | ||||
jon
|
r17210 | this.keyboard_manager = options.keyboard_manager; | ||
Jonathan Frederic
|
r17212 | this.notebook = options.notebook; | ||
jon
|
r17210 | this.keyboard_manager.quick_help = this; | ||
this.events = options.events; | ||||
Fernando Perez
|
r5023 | }; | ||
Paul Ivanov
|
r16045 | var cmd_ctrl = 'Ctrl-'; | ||
Paul Ivanov
|
r16034 | var platform_specific; | ||
Paul Ivanov
|
r16029 | |||
if (platform === 'MacOS') { | ||||
Paul Ivanov
|
r16032 | // Mac OS X specific | ||
Paul Ivanov
|
r16045 | cmd_ctrl = 'Cmd-'; | ||
Paul Ivanov
|
r16034 | platform_specific = [ | ||
Paul Ivanov
|
r16032 | { shortcut: "Cmd-Up", help:"go to cell start" }, | ||
{ shortcut: "Cmd-Down", help:"go to cell end" }, | ||||
Matthias Bussonnier
|
r18390 | { shortcut: "Alt-Left", help:"go one word left" }, | ||
{ shortcut: "Alt-Right", help:"go one word right" }, | ||||
abalkin
|
r20460 | { shortcut: "Alt-Backspace", help:"delete word before" }, | ||
{ shortcut: "Alt-Delete", help:"delete word after" }, | ||||
Paul Ivanov
|
r16034 | ]; | ||
Paul Ivanov
|
r16032 | } else { | ||
// PC specific | ||||
Paul Ivanov
|
r16034 | platform_specific = [ | ||
Paul Ivanov
|
r16032 | { shortcut: "Ctrl-Home", help:"go to cell start" }, | ||
Paul Ivanov
|
r16051 | { shortcut: "Ctrl-Up", help:"go to cell start" }, | ||
Paul Ivanov
|
r16032 | { shortcut: "Ctrl-End", help:"go to cell end" }, | ||
{ shortcut: "Ctrl-Down", help:"go to cell end" }, | ||||
{ shortcut: "Ctrl-Left", help:"go one word left" }, | ||||
{ shortcut: "Ctrl-Right", help:"go one word right" }, | ||||
abalkin
|
r20461 | { shortcut: "Ctrl-Backspace", help:"delete word before" }, | ||
{ shortcut: "Ctrl-Delete", help:"delete word after" }, | ||||
Paul Ivanov
|
r16034 | ]; | ||
Paul Ivanov
|
r16029 | } | ||
Fernando Perez
|
r5023 | |||
Paul Ivanov
|
r16032 | var cm_shortcuts = [ | ||
Paul Ivanov
|
r16034 | { shortcut:"Tab", help:"code completion or indent" }, | ||
{ shortcut:"Shift-Tab", help:"tooltip" }, | ||||
Paul Ivanov
|
r16045 | { shortcut: cmd_ctrl + "]", help:"indent" }, | ||
{ shortcut: cmd_ctrl + "[", help:"dedent" }, | ||||
{ shortcut: cmd_ctrl + "a", help:"select all" }, | ||||
{ shortcut: cmd_ctrl + "z", help:"undo" }, | ||||
{ shortcut: cmd_ctrl + "Shift-z", help:"redo" }, | ||||
{ shortcut: cmd_ctrl + "y", help:"redo" }, | ||||
Paul Ivanov
|
r16032 | ].concat( platform_specific ); | ||
Bussonnier Matthias
|
r19425 | |||
var mac_humanize_map = { | ||||
// all these are unicode, will probably display badly on anything except macs. | ||||
// these are the standard symbol that are used in MacOS native menus | ||||
Bussonnier Matthias
|
r19426 | // cf http://apple.stackexchange.com/questions/55727/ | ||
// for htmlentities and/or unicode value | ||||
Bussonnier Matthias
|
r19425 | 'cmd':'⌘', | ||
'shift':'⇧', | ||||
'alt':'⌥', | ||||
'up':'↑', | ||||
'down':'↓', | ||||
'left':'←', | ||||
'right':'→', | ||||
'eject':'⏏', | ||||
'tab':'⇥', | ||||
Bussonnier Matthias
|
r19426 | 'backtab':'⇤', | ||
'capslock':'⇪', | ||||
Andrew Dawes
|
r20054 | 'esc':'esc', | ||
Bussonnier Matthias
|
r19425 | 'ctrl':'⌃', | ||
'enter':'↩', | ||||
'pageup':'⇞', | ||||
'pagedown':'⇟', | ||||
'home':'↖', | ||||
'end':'↘', | ||||
'altenter':'⌤', | ||||
'space':'␣', | ||||
Bussonnier Matthias
|
r19426 | 'delete':'⌦', | ||
'backspace':'⌫', | ||||
Bussonnier Matthias
|
r19425 | 'apple':'', | ||
}; | ||||
var default_humanize_map = { | ||||
'shift':'Shift', | ||||
'alt':'Alt', | ||||
'up':'Up', | ||||
'down':'Down', | ||||
'left':'Left', | ||||
'right':'Right', | ||||
'tab':'Tab', | ||||
'capslock':'Caps Lock', | ||||
'esc':'Esc', | ||||
'ctrl':'Ctrl', | ||||
'enter':'Enter', | ||||
'pageup':'Page Up', | ||||
'pagedown':'Page Down', | ||||
'home':'Home', | ||||
'end':'End', | ||||
'space':'Space', | ||||
Matthias Bussonnier
|
r19427 | 'backspace':'Backspace', | ||
Bussonnier Matthias
|
r19425 | }; | ||
var humanize_map; | ||||
if (platform === 'MacOS'){ | ||||
humanize_map = mac_humanize_map; | ||||
} else { | ||||
humanize_map = default_humanize_map; | ||||
} | ||||
Paul Ivanov
|
r16032 | |||
Matthias Bussonnier
|
r19422 | function humanize_key(key){ | ||
if (key.length === 1){ | ||||
key = key.toUpperCase(); | ||||
} | ||||
Bussonnier Matthias
|
r19425 | return humanize_map[key.toLowerCase()]||key; | ||
Matthias Bussonnier
|
r19422 | } | ||
function humanize_sequence(sequence){ | ||||
Bussonnier Matthias
|
r19424 | var joinchar = ','; | ||
Matthias Bussonnier
|
r19422 | var hum = _.map(sequence.replace(/meta/g, 'cmd').split(','), humanize_shortcut).join(joinchar); | ||
return hum; | ||||
} | ||||
function humanize_shortcut(shortcut){ | ||||
var joinchar = '-'; | ||||
if (platform === 'MacOS'){ | ||||
joinchar = ''; | ||||
} | ||||
var sh = _.map(shortcut.split('-'), humanize_key ).join(joinchar); | ||||
return sh; | ||||
} | ||||
Paul Ivanov
|
r16032 | |||
Brian Granger
|
r5858 | QuickHelp.prototype.show_keyboard_shortcuts = function () { | ||
Jonathan Frederic
|
r19176 | /** | ||
* toggles display of keyboard shortcut dialog | ||||
*/ | ||||
Fernando Perez
|
r5023 | var that = this; | ||
Paul Ivanov
|
r15771 | if ( this.force_rebuild ) { | ||
Paul Ivanov
|
r15844 | this.shortcut_dialog.remove(); | ||
Paul Ivanov
|
r15771 | delete(this.shortcut_dialog); | ||
this.force_rebuild = false; | ||||
} | ||||
Brian Granger
|
r5858 | if ( this.shortcut_dialog ){ | ||
// if dialog is already shown, close it | ||||
MinRK
|
r10939 | $(this.shortcut_dialog).modal("toggle"); | ||
Brian Granger
|
r5858 | return; | ||
} | ||||
Jonathan Frederic
|
r17203 | var command_shortcuts = this.keyboard_manager.command_shortcuts.help(); | ||
var edit_shortcuts = this.keyboard_manager.edit_shortcuts.help(); | ||||
Brian E. Granger
|
r14037 | var help, shortcut; | ||
Brian E. Granger
|
r14093 | var i, half, n; | ||
Brian E. Granger
|
r14037 | var element = $('<div/>'); | ||
Brian E. Granger
|
r14066 | // The documentation | ||
Jonathan Frederic
|
r16957 | var doc = $('<div/>').addClass('alert alert-warning'); | ||
Brian E. Granger
|
r14066 | doc.append( | ||
Matthias BUSSONNIER
|
r14634 | $('<button/>').addClass('close').attr('data-dismiss','alert').html('×') | ||
Brian E. Granger
|
r14066 | ).append( | ||
'The IPython Notebook has two different keyboard input modes. <b>Edit mode</b> '+ | ||||
Preston Holmes
|
r14949 | 'allows you to type code/text into a cell and is indicated by a green cell '+ | ||
Brian E. Granger
|
r14093 | 'border. <b>Command mode</b> binds the keyboard to notebook level actions '+ | ||
'and is indicated by a grey cell border.' | ||||
Paul Ivanov
|
r15840 | ); | ||
Andrew Dawes
|
r20054 | if (platform === 'MacOS') { | ||
Andrew Dawes
|
r20067 | var key_div = this.build_key_names(); | ||
doc.append(key_div); | ||||
Andrew Dawes
|
r20054 | } | ||
Brian E. Granger
|
r14066 | element.append(doc); | ||
Brian E. Granger
|
r14037 | // Command mode | ||
Brian E. Granger
|
r14096 | var cmd_div = this.build_command_help(); | ||
element.append(cmd_div); | ||||
// Edit mode | ||||
Paul Ivanov
|
r16034 | var edit_div = this.build_edit_help(cm_shortcuts); | ||
Brian E. Granger
|
r14096 | element.append(edit_div); | ||
Jonathan Frederic
|
r17202 | this.shortcut_dialog = dialog.modal({ | ||
Brian E. Granger
|
r14096 | title : "Keyboard shortcuts", | ||
body : element, | ||||
destroy : false, | ||||
buttons : { | ||||
Close : {} | ||||
Jonathan Frederic
|
r17212 | }, | ||
notebook: this.notebook, | ||||
keyboard_manager: this.keyboard_manager, | ||||
Brian E. Granger
|
r14096 | }); | ||
MinRK
|
r16023 | this.shortcut_dialog.addClass("modal_stretch"); | ||
Paul Ivanov
|
r15771 | |||
Jonathan Frederic
|
r17197 | this.events.on('rebuild.QuickHelp', function() { that.force_rebuild = true;}); | ||
Brian E. Granger
|
r14096 | }; | ||
Andrew Dawes
|
r20057 | QuickHelp.prototype.build_key_names = function () { | ||
Andrew Dawes
|
r20068 | var key_names_mac = [{ shortcut:"⌘", help:"Command" }, | ||
Andrew Dawes
|
r20067 | { shortcut:"⌃", help:"Control" }, | ||
{ shortcut:"⌥", help:"Option" }, | ||||
{ shortcut:"⇧", help:"Shift" }, | ||||
{ shortcut:"↩", help:"Return" }, | ||||
{ shortcut:"␣", help:"Space" }, | ||||
Andrew Dawes
|
r20094 | { shortcut:"⇥", help:"Tab" }]; | ||
Andrew Dawes
|
r20067 | var i, half, n; | ||
Andrew Dawes
|
r20068 | var div = $('<div/>').append('MacOS modifier keys:'); | ||
Andrew Dawes
|
r20067 | var sub_div = $('<div/>').addClass('container-fluid'); | ||
var col1 = $('<div/>').addClass('col-md-6'); | ||||
var col2 = $('<div/>').addClass('col-md-6'); | ||||
n = key_names_mac.length; | ||||
Andrew Dawes
|
r20068 | half = ~~(n/2); | ||
Andrew Dawes
|
r20067 | for (i=0; i<half; i++) { col1.append( | ||
build_one(key_names_mac[i]) | ||||
); } | ||||
for (i=half; i<n; i++) { col2.append( | ||||
build_one(key_names_mac[i]) | ||||
); } | ||||
sub_div.append(col1).append(col2); | ||||
div.append(sub_div); | ||||
return div; | ||||
Andrew Dawes
|
r20057 | }; | ||
Brian E. Granger
|
r14096 | QuickHelp.prototype.build_command_help = function () { | ||
Jonathan Frederic
|
r17203 | var command_shortcuts = this.keyboard_manager.command_shortcuts.help(); | ||
Paul Ivanov
|
r15801 | return build_div('<h4>Command Mode (press <code>Esc</code> to enable)</h4>', command_shortcuts); | ||
Paul Ivanov
|
r15840 | }; | ||
Brian E. Granger
|
r14096 | |||
Paul Ivanov
|
r15876 | var special_case = { pageup: "PageUp", pagedown: "Page Down", 'minus': '-' }; | ||
Paul Ivanov
|
r15782 | var prettify = function (s) { | ||
Paul Ivanov
|
r15877 | s = s.replace(/-$/, 'minus'); // catch shortcuts using '-' key | ||
Paul Ivanov
|
r15873 | var keys = s.split('-'); | ||
Paul Ivanov
|
r15782 | var k, i; | ||
Paul Ivanov
|
r16227 | for (i=0; i < keys.length; i++) { | ||
Paul Ivanov
|
r15782 | k = keys[i]; | ||
Paul Ivanov
|
r15801 | if ( k.length == 1 ) { | ||
keys[i] = "<code><strong>" + k + "</strong></code>"; | ||||
continue; // leave individual keys lower-cased | ||||
} | ||||
Matthias Bussonnier
|
r18390 | if (k.indexOf(',') === -1){ | ||
keys[i] = ( special_case[k] ? special_case[k] : k.charAt(0).toUpperCase() + k.slice(1) ); | ||||
} | ||||
Paul Ivanov
|
r15801 | keys[i] = "<code><strong>" + keys[i] + "</strong></code>"; | ||
Paul Ivanov
|
r15782 | } | ||
return keys.join('-'); | ||||
Paul Ivanov
|
r15781 | |||
}; | ||||
Paul Ivanov
|
r16034 | QuickHelp.prototype.build_edit_help = function (cm_shortcuts) { | ||
Jonathan Frederic
|
r17203 | var edit_shortcuts = this.keyboard_manager.edit_shortcuts.help(); | ||
Nile Geisinger
|
r16279 | jQuery.merge(cm_shortcuts, edit_shortcuts); | ||
Paul Ivanov
|
r16034 | return build_div('<h4>Edit Mode (press <code>Enter</code> to enable)</h4>', cm_shortcuts); | ||
Paul Ivanov
|
r15840 | }; | ||
Paul Ivanov
|
r15801 | |||
var build_one = function (s) { | ||||
Paul Ivanov
|
r15840 | var help = s.help; | ||
Matthias Bussonnier
|
r19422 | var shortcut = ''; | ||
if(s.shortcut){ | ||||
shortcut = prettify(humanize_sequence(s.shortcut)); | ||||
} | ||||
Paul Ivanov
|
r15801 | return $('<div>').addClass('quickhelp'). | ||
append($('<span/>').addClass('shortcut_key').append($(shortcut))). | ||||
Paul Ivanov
|
r15840 | append($('<span/>').addClass('shortcut_descr').text(' : ' + help)); | ||
Paul Ivanov
|
r15801 | |||
Paul Ivanov
|
r15840 | }; | ||
Paul Ivanov
|
r15801 | |||
var build_div = function (title, shortcuts) { | ||||
var i, half, n; | ||||
var div = $('<div/>').append($(title)); | ||||
Matthias Bussonnier
|
r19718 | var sub_div = $('<div/>').addClass('container-fluid'); | ||
var col1 = $('<div/>').addClass('col-md-6'); | ||||
var col2 = $('<div/>').addClass('col-md-6'); | ||||
Paul Ivanov
|
r15801 | n = shortcuts.length; | ||
Brian E. Granger
|
r14093 | half = ~~(n/2); // Truncate :) | ||
Paul Ivanov
|
r15840 | for (i=0; i<half; i++) { col1.append( build_one(shortcuts[i]) ); } | ||
for (i=half; i<n; i++) { col2.append( build_one(shortcuts[i]) ); } | ||||
Paul Ivanov
|
r15801 | sub_div.append(col1).append(col2); | ||
div.append(sub_div); | ||||
return div; | ||||
Paul Ivanov
|
r15840 | }; | ||
Fernando Perez
|
r5023 | |||
Jonathan Frederic
|
r17197 | // Backwards compatability. | ||
MinRK
|
r5066 | IPython.QuickHelp = QuickHelp; | ||
Fernando Perez
|
r5023 | |||
Jonathan Frederic
|
r17201 | return {'QuickHelp': QuickHelp}; | ||
Jonathan Frederic
|
r17197 | }); | ||