diff --git a/.cache/pip/http-v2/0/4/1/8/c/0418c83b80f7f7bfaec2738bfbbee53d2c1562196c0781702f6eddc8 b/.cache/pip/http-v2/0/4/1/8/c/0418c83b80f7f7bfaec2738bfbbee53d2c1562196c0781702f6eddc8 new file mode 100644 index 0000000000000000000000000000000000000000..c2b242a36e05f03af4111c5e192fbdb5540f2aa6 Binary files /dev/null and b/.cache/pip/http-v2/0/4/1/8/c/0418c83b80f7f7bfaec2738bfbbee53d2c1562196c0781702f6eddc8 differ diff --git a/.cache/pip/http-v2/0/4/1/8/c/0418c83b80f7f7bfaec2738bfbbee53d2c1562196c0781702f6eddc8.body b/.cache/pip/http-v2/0/4/1/8/c/0418c83b80f7f7bfaec2738bfbbee53d2c1562196c0781702f6eddc8.body new file mode 100644 index 0000000000000000000000000000000000000000..43e66323542b3ad76a399b7d1aac5f24af459ed4 Binary files /dev/null and b/.cache/pip/http-v2/0/4/1/8/c/0418c83b80f7f7bfaec2738bfbbee53d2c1562196c0781702f6eddc8.body differ diff --git a/.cache/pip/http-v2/0/7/5/9/3/07593bb905dded4b84aacb1d96c1e64704669d6bab658dcaeab79c36 b/.cache/pip/http-v2/0/7/5/9/3/07593bb905dded4b84aacb1d96c1e64704669d6bab658dcaeab79c36 new file mode 100644 index 0000000000000000000000000000000000000000..9774b8eada013882f7fc7df91766f4e2b7da9d44 Binary files /dev/null and b/.cache/pip/http-v2/0/7/5/9/3/07593bb905dded4b84aacb1d96c1e64704669d6bab658dcaeab79c36 differ diff --git a/.cache/pip/http-v2/0/7/5/9/3/07593bb905dded4b84aacb1d96c1e64704669d6bab658dcaeab79c36.body b/.cache/pip/http-v2/0/7/5/9/3/07593bb905dded4b84aacb1d96c1e64704669d6bab658dcaeab79c36.body new file mode 100644 index 0000000000000000000000000000000000000000..9af5f813f65b21398d2b76b66ad1c3c1bb5464e4 Binary files /dev/null and b/.cache/pip/http-v2/0/7/5/9/3/07593bb905dded4b84aacb1d96c1e64704669d6bab658dcaeab79c36.body differ diff --git a/.cache/pip/http-v2/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52 b/.cache/pip/http-v2/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52 new file mode 100644 index 0000000000000000000000000000000000000000..c5c76ebe1ec5a3e8870b10369cfe93b3a18bd32e Binary files /dev/null and b/.cache/pip/http-v2/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52 differ diff --git a/.cache/pip/http-v2/0/c/f/6/e/0cf6e817e2c5554000c735ecab0f3cf492f7d33b50d5a474a801ba24.body b/.cache/pip/http-v2/0/c/f/6/e/0cf6e817e2c5554000c735ecab0f3cf492f7d33b50d5a474a801ba24.body new file mode 100644 index 0000000000000000000000000000000000000000..59b5d08064db003dbae936cfa9c00264ccafa641 Binary files /dev/null and b/.cache/pip/http-v2/0/c/f/6/e/0cf6e817e2c5554000c735ecab0f3cf492f7d33b50d5a474a801ba24.body differ diff --git a/.cache/pip/http-v2/1/2/e/6/c/12e6c0100f8dcc54f1445b9845cfdcecf519882e2fe2767cf43bd439 b/.cache/pip/http-v2/1/2/e/6/c/12e6c0100f8dcc54f1445b9845cfdcecf519882e2fe2767cf43bd439 new file mode 100644 index 0000000000000000000000000000000000000000..215b3754c7587a429e5ee53f783973b8a10dd0cf Binary files /dev/null and b/.cache/pip/http-v2/1/2/e/6/c/12e6c0100f8dcc54f1445b9845cfdcecf519882e2fe2767cf43bd439 differ diff --git a/.cache/pip/http-v2/1/6/9/3/2/1693297fb9daf7bfe370bf51d371acfeb8ff40759bf8650dfd404ba4 b/.cache/pip/http-v2/1/6/9/3/2/1693297fb9daf7bfe370bf51d371acfeb8ff40759bf8650dfd404ba4 new file mode 100644 index 0000000000000000000000000000000000000000..e1740602aa29444bad5f6c314a02fa85962879c8 Binary files /dev/null and b/.cache/pip/http-v2/1/6/9/3/2/1693297fb9daf7bfe370bf51d371acfeb8ff40759bf8650dfd404ba4 differ diff --git a/.local/share/jupyter/nbextensions/codefolding/main.js b/.local/share/jupyter/nbextensions/codefolding/main.js new file mode 100644 index 0000000000000000000000000000000000000000..6c512db130b85ca8ef4a361cb5448cf5c4f8c282 --- /dev/null +++ b/.local/share/jupyter/nbextensions/codefolding/main.js @@ -0,0 +1,282 @@ +// Allow codefolding in code cells +// +// This extension enables the CodeMirror feature +// It works by adding a gutter area to each code cell. +// Fold-able code is marked using small triangles in the gutter. +// +// The current folding state is saved in the cell metadata as an array +// of line numbers. +// Format: cell.metadata.code_folding = [ line1, line2, line3, ...] +// + +define([ + 'base/js/namespace', + 'jquery', + 'require', + 'base/js/events', + 'services/config', + 'notebook/js/codecell', + 'codemirror/lib/codemirror', + 'codemirror/addon/fold/foldcode', + 'codemirror/addon/fold/foldgutter', + 'codemirror/addon/fold/brace-fold', + 'codemirror/addon/fold/indent-fold' +], function (Jupyter, $, requirejs, events, configmod, codecell, CodeMirror) { + "use strict"; + + // define default config parameter values + var params = { + codefolding_hotkey : 'Alt-f', + init_delay : 1000 + }; + + // updates default params with any specified in the provided config data + var update_params = function (config_data) { + for (var key in params) { + if (config_data.hasOwnProperty(key)) { + params[key] = config_data[key]; + } + } + }; + + var on_config_loaded = function () { + if (Jupyter.notebook !== undefined) { + // register actions with ActionHandler instance + var prefix = 'auto'; + var name = 'toggle-codefolding'; + var action = { + icon: 'fa-comment-o', + help : 'Toggle codefolding', + help_index : 'ec', + id : 'toggle_codefolding', + handler : toggleFolding + }; + var action_full_name = Jupyter.keyboard_manager.actions.register(action, name, prefix); + + // define keyboard shortcuts + var edit_mode_shortcuts = {}; + edit_mode_shortcuts[params.codefolding_hotkey] = action_full_name; + + // register keyboard shortcuts with keyboard_manager + Jupyter.notebook.keyboard_manager.edit_shortcuts.add_shortcuts(edit_mode_shortcuts); + Jupyter.notebook.keyboard_manager.command_shortcuts.add_shortcuts(edit_mode_shortcuts); + } + else { + // we're in edit view + var extraKeys = Jupyter.editor.codemirror.getOption('extraKeys'); + extraKeys[params.codefolding_hotkey] = toggleFolding; + CodeMirror.normalizeKeyMap(extraKeys); + console.log('[codefolding] binding hotkey', params.codefolding_hotkey); + Jupyter.editor.codemirror.setOption('extraKeys', extraKeys); + } + }; + + /* + * Toggle folding on/off at current line + * + * @param cm CodeMirror instance + * + */ + function toggleFolding () { + var cm; + var pos = {line: 0, ch: 0, xRel: 0}; + if (Jupyter.notebook !== undefined) { + cm = Jupyter.notebook.get_selected_cell().code_mirror; + if (Jupyter.notebook.mode === 'edit') { + pos = cm.getCursor(); + } + } + else { + cm = Jupyter.editor.codemirror; + pos = cm.getCursor(); + } + var opts = cm.state.foldGutter.options; + cm.foldCode(pos, opts.rangeFinder); + } + + /** + * Update cell metadata with folding info, so folding state can be restored after reloading notebook + * + * @param cm CodeMirror instance + */ + function updateMetadata (cm) { + var list = cm.getAllMarks(); + var lines = []; + for (var i = 0; i < list.length; i++) { + if (list[i].__isFold) { + var range = list[i].find(); + lines.push(range.from.line); + } + } + /* User can click on gutter of unselected cells, so make sure we store metadata in the correct cell */ + var cell = Jupyter.notebook.get_selected_cell(); + if (cell.code_mirror !== cm) { + var cells = Jupyter.notebook.get_cells(); + var ncells = Jupyter.notebook.ncells(); + for (var k = 0; k < ncells; k++) { + var _cell = cells[k]; + if (_cell.code_mirror === cm ) { cell = _cell; break; } + } + } + cell.metadata.code_folding = lines; + } + + /** + * Activate codefolding in CodeMirror options, don't overwrite other settings + * + * @param cm codemirror instance + */ + function activate_cm_folding (cm) { + var gutters = cm.getOption('gutters').slice(); + if ( $.inArray("CodeMirror-foldgutter", gutters) < 0) { + gutters.push('CodeMirror-foldgutter'); + cm.setOption('gutters', gutters); + } + + /* set indent or brace folding */ + var opts = true; + if (Jupyter.notebook) { + opts = { + rangeFinder: new CodeMirror.fold.combine( + CodeMirror.fold.firstline, + CodeMirror.fold.magic, + CodeMirror.fold.blockcomment, + cm.getMode().fold === 'indent' ? CodeMirror.fold.indent : CodeMirror.fold.brace + ) + }; + } + cm.setOption('foldGutter', opts); + } + + /** + * Restore folding status from metadata + * @param cell + */ + var restoreFolding = function (cell) { + if (cell.metadata.code_folding === undefined || !(cell instanceof codecell.CodeCell)) { + return; + } + // visit in reverse order, as otherwise nested folds un-fold outer ones + var lines = cell.metadata.code_folding.slice().sort(); + for (var idx = lines.length - 1; idx >= 0; idx--) { + var line = lines[idx]; + var opts = cell.code_mirror.state.foldGutter.options; + var linetext = cell.code_mirror.getLine(line); + if (linetext !== undefined) { + cell.code_mirror.foldCode(CodeMirror.Pos(line, 0), opts.rangeFinder); + } + else { + // the line doesn't exist, so we should remove it from metadata + cell.metadata.code_folding = lines.slice(0, idx); + } + cell.code_mirror.refresh(); + } + }; + + /** + * Add codefolding gutter to a new cell + * + * @param event + * @param nbcell + * + */ + var createCell = function (event, nbcell) { + var cell = nbcell.cell; + if ((cell instanceof codecell.CodeCell)) { + activate_cm_folding(cell.code_mirror); + cell.code_mirror.on('fold', updateMetadata); + cell.code_mirror.on('unfold', updateMetadata); + // queue restoring folding, to run once metadata is set, hopefully. + // This can be useful if cells are un-deleted, for example. + setTimeout(function () { restoreFolding(cell); }, 500); + } + }; + + /* + * Initialize gutter in existing cells + * + */ + var initExistingCells = function () { + var cells = Jupyter.notebook.get_cells(); + var ncells = Jupyter.notebook.ncells(); + for (var i = 0; i < ncells; i++) { + var cell = cells[i]; + if ((cell instanceof codecell.CodeCell)) { + activate_cm_folding(cell.code_mirror); + /* restore folding state if previously saved */ + restoreFolding(cell); + cell.code_mirror.on('fold', updateMetadata); + cell.code_mirror.on('unfold', updateMetadata); + } + } + events.on('create.Cell', createCell); + }; + + /** + * Load my own CSS file + * + * @param name off CSS file + * + */ + var load_css = function (name) { + var link = document.createElement("link"); + link.type = "text/css"; + link.rel = "stylesheet"; + link.href = requirejs.toUrl(name, 'css'); + document.getElementsByTagName("head")[0].appendChild(link); + }; + + /** + * Initialize extension + * + */ + var load_extension = function () { + // first, check which view we're in, in order to decide whether to load + var conf_sect; + if (Jupyter.notebook) { + // we're in notebook view + conf_sect = Jupyter.notebook.config; + } + else if (Jupyter.editor) { + // we're in file-editor view + conf_sect = new configmod.ConfigSection('notebook', {base_url: Jupyter.editor.base_url}); + conf_sect.load(); + } + else { + // we're some other view like dashboard, terminal, etc, so bail now + return; + } + + load_css('codemirror/addon/fold/foldgutter.css'); + /* change default gutter width */ + load_css( './foldgutter.css'); + + conf_sect.loaded + .then(function () { update_params(conf_sect.data); }) + .then(on_config_loaded); + + if (Jupyter.notebook) { + /* require our additional custom codefolding modes before initialising fully */ + requirejs(['./firstline-fold', './magic-fold', './blockcomment-fold'], function () { + if (Jupyter.notebook._fully_loaded) { + setTimeout(function () { + console.log('Codefolding: Wait for', params.init_delay, 'ms'); + initExistingCells(); + }, params.init_delay); + } + else { + events.one('notebook_loaded.Notebook', initExistingCells); + } + }); + } + else { + activate_cm_folding(Jupyter.editor.codemirror); + setTimeout(function () { + console.log('Codefolding: Wait for', params.init_delay, 'ms'); + Jupyter.editor.codemirror.refresh(); + }, params.init_delay); + } + }; + + return {load_ipython_extension : load_extension}; +}); diff --git a/.local/share/jupyter/nbextensions/codemirror_mode_extensions/main.js b/.local/share/jupyter/nbextensions/codemirror_mode_extensions/main.js new file mode 100644 index 0000000000000000000000000000000000000000..d960d1ffd2ab9e0556d2b96232f4e08df61c423a --- /dev/null +++ b/.local/share/jupyter/nbextensions/codemirror_mode_extensions/main.js @@ -0,0 +1,11 @@ +define(['codemirror/lib/codemirror'], function (CodeMirror) { + "use strict"; + return { + load_ipython_extension : function () { + CodeMirror.extendMode('octave', { + lineComment: '%', + fold: 'indent', + }); + } + }; +}); diff --git a/.local/share/jupyter/nbextensions/comment-uncomment/comment-uncomment.yaml b/.local/share/jupyter/nbextensions/comment-uncomment/comment-uncomment.yaml new file mode 100644 index 0000000000000000000000000000000000000000..62bc0886fc841ed63c014e31f2708bbe286adb1c --- /dev/null +++ b/.local/share/jupyter/nbextensions/comment-uncomment/comment-uncomment.yaml @@ -0,0 +1,16 @@ +Type: IPython Notebook Extension +Compatibility: 4.x, 5.x +Name: Comment/Uncomment Hotkey +Main: main.js +Description: add new configurable hotkey binding to toggle comments +Icon: icon.png +Link: readme.md +Parameters: +- name: comment_uncomment_keybinding + description: keybinding for toggling comments + input_type: hotkey + default: alt-c +- name: comment_uncomment_indent + description: indent comment at current indent level instead of at beginning of line + default: false + input_type: checkbox diff --git a/.local/share/jupyter/nbextensions/comment-uncomment/main.js b/.local/share/jupyter/nbextensions/comment-uncomment/main.js new file mode 100644 index 0000000000000000000000000000000000000000..3aea80867b625bbf40c209166719c99401e79c05 --- /dev/null +++ b/.local/share/jupyter/nbextensions/comment-uncomment/main.js @@ -0,0 +1,63 @@ +// add new configurable hotkey binding to toggle comments + +define([ + 'base/js/namespace', +], function( + IPython +) { + "use strict"; + + // define default config parameter values + var params = { + comment_uncomment_keybinding : 'alt-c', + comment_uncomment_indent: false, + }; + + // updates default params with any specified in the server's config + var update_params = function() { + var config = IPython.notebook.config; + for (var key in params){ + if (config.data.hasOwnProperty(key) ){ + params[key] = config.data[key]; + } + } + }; + + var initialize = function () { + // update defaults + update_params(); + + // register actions with ActionHandler instance + var prefix = 'auto'; + var name = 'toggle-comment'; + var action = { + icon: 'fa-comment-o', + help : 'Toggle comments', + help_index : 'eb', + id : 'read_only_codecell', + handler : toggle_comment + }; + var action_full_name = IPython.keyboard_manager.actions.register(action, name, prefix); + + // define keyboard shortcuts + var edit_mode_shortcuts = {}; + edit_mode_shortcuts[params.comment_uncomment_keybinding] = action_full_name; + + // register keyboard shortcuts with keyboard_manager + IPython.notebook.keyboard_manager.edit_shortcuts.add_shortcuts(edit_mode_shortcuts); + }; + + var toggle_comment = function() { + var cm = IPython.notebook.get_selected_cell().code_mirror; + cm.toggleComment({ indent: params.comment_uncomment_indent }); + return false; + }; + + var load_ipython_extension = function () { + return IPython.notebook.config.loaded.then(initialize); + }; + + return { + load_ipython_extension : load_ipython_extension + }; +}); diff --git a/.local/share/jupyter/nbextensions/contrib_nbextensions_help_item/README.md b/.local/share/jupyter/nbextensions/contrib_nbextensions_help_item/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d4ce0987af19bbe98160699da6bffeac6b88290d --- /dev/null +++ b/.local/share/jupyter/nbextensions/contrib_nbextensions_help_item/README.md @@ -0,0 +1,6 @@ +Help menu entry +=============== + +The `contrib_nbextensions_help_item` is a tiny nbextension that just adds an +item to the notebook's help menu, pointing to the docs at readthedocs: +[jupyter_contrib_nbextensions.readthedocs.io](https://jupyter_contrib_nbextensions.readthedocs.io) diff --git a/.local/share/jupyter/nbextensions/datestamper/readme.md b/.local/share/jupyter/nbextensions/datestamper/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..494755112c96ef9b04c5e21b681e7e448c1be098 --- /dev/null +++ b/.local/share/jupyter/nbextensions/datestamper/readme.md @@ -0,0 +1,6 @@ +Datestamper +=========== + +Adds a toolbar button which pastes the current time & date into the current cell: + + diff --git a/.local/share/jupyter/nbextensions/equation-numbering/button.png b/.local/share/jupyter/nbextensions/equation-numbering/button.png new file mode 100644 index 0000000000000000000000000000000000000000..08ed05aa4dca6a45599b231b7096d76ddc5a1b0d Binary files /dev/null and b/.local/share/jupyter/nbextensions/equation-numbering/button.png differ diff --git a/.local/share/jupyter/nbextensions/equation-numbering/main.js b/.local/share/jupyter/nbextensions/equation-numbering/main.js new file mode 100644 index 0000000000000000000000000000000000000000..6d4289ba0814cdb0ec7fc2d42e93c44225414c4d --- /dev/null +++ b/.local/share/jupyter/nbextensions/equation-numbering/main.js @@ -0,0 +1,39 @@ +// Copyright (c) IPython-Contrib Team. +// Distributed under the terms of the Modified BSD License. + +define([ + 'base/js/namespace', + 'jquery', + 'require', + 'notebook/js/textcell', + 'base/js/utils', +], function(Jupyter, $, requirejs, textcell, utils) { + "use strict"; + + var MathJax = window.MathJax; + + var load_ipython_extension = function() { + var btn_grp = Jupyter.toolbar.add_buttons_group([ + Jupyter.keyboard_manager.actions.register ({ + help : 'Reset equation numbering', + icon : 'fa-sort-numeric-asc', + handler: function () { + MathJax.Hub.Queue( + ["resetEquationNumbers", MathJax.InputJax.TeX], + ["PreProcess", MathJax.Hub], + ["Reprocess", MathJax.Hub] + ); + $('#reset_numbering').blur(); + } + }, 'reset-numbering', 'equation_numbering') + ]); + $(btn_grp).find('.btn').attr('id', 'reset_numbering'); + MathJax.Hub.Config({ + TeX: { equationNumbers: { autoNumber: "AMS" } } + }); + }; + + return { + load_ipython_extension : load_ipython_extension + }; +}); diff --git a/.local/share/jupyter/nbextensions/execute_time/ExecuteTime.css b/.local/share/jupyter/nbextensions/execute_time/ExecuteTime.css new file mode 100644 index 0000000000000000000000000000000000000000..4ad3c4b0fa83864d023b0be21f4e697a14d2b512 --- /dev/null +++ b/.local/share/jupyter/nbextensions/execute_time/ExecuteTime.css @@ -0,0 +1,6 @@ +.timing_area { + padding: 0 5px; + border: none; + border-top: 1px solid #CFCFCF; + font-size: 80%; +} diff --git a/.local/share/jupyter/nbextensions/execute_time/execution-timings-box.png b/.local/share/jupyter/nbextensions/execute_time/execution-timings-box.png new file mode 100644 index 0000000000000000000000000000000000000000..ea845ed14406a3b5788ab2e2f1c3079108019eef Binary files /dev/null and b/.local/share/jupyter/nbextensions/execute_time/execution-timings-box.png differ diff --git a/.local/share/jupyter/nbextensions/exercise/image.gif b/.local/share/jupyter/nbextensions/exercise/image.gif new file mode 100644 index 0000000000000000000000000000000000000000..0fe22308b600e50d9f51ebe6a7164475ddb81c4e Binary files /dev/null and b/.local/share/jupyter/nbextensions/exercise/image.gif differ diff --git a/.local/share/jupyter/nbextensions/exercise/readme.md b/.local/share/jupyter/nbextensions/exercise/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..54eb1d426e8e3714466df48fc3a7f8da683a9564 --- /dev/null +++ b/.local/share/jupyter/nbextensions/exercise/readme.md @@ -0,0 +1,52 @@ +Exercise +======== + +These are two extensions for Jupyter, for hiding/showing solutions cells. +They use the same approach and codebase and differ only by the type of +`cell widget` used the show/hide the solutions. The two extensions can be used +simultaneously. They require the `rubberband` extension to be installed and +enabled. + +The example below demonstrates some of the features of the exercise extensions. + +- First, an solution or "details" cell is created by (a) selecting two cells with the rubberband and (b) clicking on the menu-button [exercise extension] +- Second, the two next cells are selected using a keyboard shortcut, and a solution is created using the shortcut Alt-D [exercise2 extension] +- Third, the two solutions are expanded by clicking on the corresponding widgets +- Fourth, the solutions are removed by selecting them and clicking on the buttons in the toolbar. + + + + +The extensions provide +---------------------- + +- a menubar button +- a cell widget -- A plus/minus button in `exercise` and a sliding checkbox in `exercise2`. + +The menubar button is devoted to the creation or removing of the solution. The solution consists in several consecutive cells that can be selected by the usual notebook multicell selection methods (e.g. *Shift-down* (select next) or *Shift-up* (select previous) keyboard shortcuts, or using the rubberband extension. + + +### Creating a solution + +Several cells being selected, pressing the menubar button adds a `cell widget` and hides the cells excepted the first one which serves as a heading cell. *Do not forget to keep the Shift key pressed down while clicking on the menu button +(otherwise selected cells will be lost)*. It is also possible to use a keyboard shortcut for creating the solution from selected cells: Alt-S for exercise extension and Alt-D for exercise2. + + +### Removing a solution + +If a solution heading (first) cell is selected, then clicking the menu bar button removes this solution and its solutions cells are shown. Using the keyboard shortcut has the same effect. + + +### Showing/hiding solution + +At creation of the solution, the solution cells are hidden. Clicking the `cell widget` toggles the hidden/shown state of the solution. + + +### Persistence + +The state of solutions, hidden or shown, is preserved and automatically restored at startup and on reload. + + +### Internals + +exercise and exercise2 add respectively a solution and solution2 metadata to solution cells, with for value the current state hidden/shown of the solution. For exercise, a div with the plus/minus character is prepended to the solution heading cell. For exercise2, a flex-wrap style is added to the solution heading cell and a checkbox widget, with some css styling, is appended to the cell. A solution[.2]_first metadada is also added to enable an easy detection of the first cell in an "exercise" and then allow several consecutive exercises. diff --git a/.local/share/jupyter/nbextensions/go_to_current_running_cell/README.md b/.local/share/jupyter/nbextensions/go_to_current_running_cell/README.md new file mode 100644 index 0000000000000000000000000000000000000000..067691526a2821ad8b0ab8e2f44b11c2ef30e26b --- /dev/null +++ b/.local/share/jupyter/nbextensions/go_to_current_running_cell/README.md @@ -0,0 +1,22 @@ +Go to Running Cell +================== + +This is an extension allows you to jump to the current running cell. You can also activate this functionality automatically, i.e., your view is always scolling to the current cell. + +Button: A button with eye icon that you can go to the first running cell. + + +Keyboard shortcuts: +------------------- +__*Alt-I*__ (Jump to first running cell) +__*Meta-[*__ (Follow executing cell On) +__*Meta-]*__(Follow executing cell Off) + +Demo +---- +### Jump to first running cell + + +### Follow executing cell + + \ No newline at end of file diff --git a/.local/share/jupyter/nbextensions/go_to_current_running_cell/go_to_current_running_cell.yaml b/.local/share/jupyter/nbextensions/go_to_current_running_cell/go_to_current_running_cell.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4bfcb6ebe59be3a5ee894f846bb327dc5855fdb2 --- /dev/null +++ b/.local/share/jupyter/nbextensions/go_to_current_running_cell/go_to_current_running_cell.yaml @@ -0,0 +1,26 @@ +Type: Jupyter Notebook Extension +Name: Go to Current Running Cells +Description: Go to Running cell and always scroll into current running cell view +Link: README.md +Main: main.js +Compatibility: 4.x, 5.x + +Parameters: +- name: is_follow_cell + description: Activate follow executing cells, default behavior is false. + input_type: checkbox +- name: go_to_running_cell_shortcut + description: Go to first running cell + input_type: input + default: Alt-I +- name: follow_cell_on_shortcut + description: Enable following running cell + input_type: input + default: Alt-; +- name: follow_cell_off_shortcut + description: Disable following running cell + input_type: input + default: Alt-' +- name: button_icon + description: Button for go to first running cell + default: fa-anchor \ No newline at end of file diff --git a/.local/share/jupyter/nbextensions/go_to_current_running_cell/jump_to_cell.gif b/.local/share/jupyter/nbextensions/go_to_current_running_cell/jump_to_cell.gif new file mode 100644 index 0000000000000000000000000000000000000000..b26c08bdd324cffbb19627ae9284172311ce9363 Binary files /dev/null and b/.local/share/jupyter/nbextensions/go_to_current_running_cell/jump_to_cell.gif differ diff --git a/.local/share/jupyter/nbextensions/help_panel/help_panel.yaml b/.local/share/jupyter/nbextensions/help_panel/help_panel.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b70506151aa7c0dbf2187593dc1fc000463a7296 --- /dev/null +++ b/.local/share/jupyter/nbextensions/help_panel/help_panel.yaml @@ -0,0 +1,12 @@ +Type: IPython Notebook Extension +Compatibility: 3.x, 4.x, 5.x +Name: Help panel +Main: help_panel.js +Icon: icon.png +Link: readme.md +Description: Add a toolbar button to display a help panel showing shortcuts to the right side of the notebook +Parameters: +- name: help_panel_add_toolbar_button + description: add a toolbar button to open the shortcuts dialog/panel + input_type: checkbox + default: false diff --git a/.local/share/jupyter/nbextensions/hide_input_all/hide_input_all_hide.png b/.local/share/jupyter/nbextensions/hide_input_all/hide_input_all_hide.png new file mode 100644 index 0000000000000000000000000000000000000000..a15486a95ff60094c749e4154c92f2b566085210 Binary files /dev/null and b/.local/share/jupyter/nbextensions/hide_input_all/hide_input_all_hide.png differ diff --git a/.local/share/jupyter/nbextensions/highlight_selected_word/README.md b/.local/share/jupyter/nbextensions/highlight_selected_word/README.md new file mode 100644 index 0000000000000000000000000000000000000000..70e59a30ba19563c4aca0e8eb21aae1587ac2d5b --- /dev/null +++ b/.local/share/jupyter/nbextensions/highlight_selected_word/README.md @@ -0,0 +1,117 @@ +Highlight selected word +======================= + +[](https://gitter.im/jcb91/jupyter_highlight_selected_word?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[](https://github.com/jcb91/jupyter_highlight_selected_word/issues) + + +This nbextension highlights all instances of the selected word in either the +current cell's editor, or in all cells in the notebook. +It is based on the CodeMirror addon +[Match Highlighter](https://codemirror.net/demo/matchhighlighter.html), +but now uses its own codebase in order to permit matching across multiple +editors. + +There are a few configurable [options](#Options), all of which sit under the +config key `highlight_selected_word` in the `notebook` config section. + + +Options +------- + +Options are stored in the notebook section of the nbconfig. +The easiest way to configure these is using the +[jupyter_nbextensions_configurator](https://github.com/Jupyter-contrib/jupyter_nbextensions_configurator) +serverextension, but you can also configure them directly with a few lines of +python. + +The available options are: + +* `highlight_selected_word.highlight_across_all_cells` - if `true`, (default) + highlight matches across all cells. If `false`, only matches within the + currently selected cell will be highlighted. + +* `highlight_selected_word.code_cells_only` - Only apply highlights to editors + for Code cells, not, for example, Markdown or Raw cells + +* `highlight_selected_word.highlight_color` - Color used to highlight matching + words in the focused (active) cell + +* `highlight_selected_word.highlight_color_blurred` - Color used to highlight + matching words in blurred (non-active) cells + +* `highlight_selected_word.outlines_only` - Highlight words using just an + outline, rather than the background color. In contrast to the default + background-color highlight, the outline-only is also applied to the + currently-selected word + +* `highlight_selected_word.outline_width` - Width, in pixels, of the outline + used to highlight words when the outline-only setting (above) is selected. + Defaults to 1. + +* `highlight_selected_word.delay` - Wait time (in milliseconds) before + highlighting the matches + +* `highlight_selected_word.words_only` - If true, only highlight matches if the + selected text is a word + +* `highlight_selected_word.highlight_only_whole_words` - Only highlight matches + which are surrounded by non-word characters. This will use the token + `highlight_selected_word.show_token` to identify word characters, if it's + set, otherwise the regular expression `[\w$]` will be used. + +* `highlight_selected_word.show_token` - Token (regex) to identify word + characters, used to determine what to highlight when nothing is selected. + If blank, nothing is highlighted when nothing is selected. + This regex is also used to determine word boundaries for + `highlight_selected_word.highlight_only_whole_words`. + +* `highlight_selected_word.min_chars` - Minimum number of characters that must + be selected for the highlighting behavior to occur + +* `highlight_selected_word.use_toggle_hotkey` - Bind the + `highlight_selected_word.toggle` action to a hotkey. Defaults to `false`. + +* `highlight_selected_word.toggle_hotkey` - Which hotkey to bind to the + `highlight_selected_word.toggle` action (if set to use, see item above). + Defaults to `alt-h` + +* `highlight_selected_word.only_cells_in_scroll` - Only apply highlights to + editors which are visible in the scrolled view. This may offer performance + benefits for larger notebooks, but may be annoying if you're doing a lot of + scrolling :/ + +* `highlight_selected_word.scroll_min_delay` - Minimum delay in ms between + updating highlights on scrolling the notebook (used only if + `highlight_selected_word.only_cells_in_scroll` is `true`). + If set to zero, no update is done on scroll. + +* `highlight_selected_word.hide_selections_in_unfocussed` - Hide any text + selection in non-focussed cells. Otherwise, each cell can show a text + selection even when its editor is not focussed, which can be confused with + match highlights. + +For example, to set the delay to half a second, and limit highlighting to code +cells, we can use the following python snippet: + +```python +from notebook.services.config import ConfigManager +cm = ConfigManager() +cm.update('notebook', {'highlight_selected_word': { + 'delay': 500, + 'code_cells_only': True, +}}) +``` + + +Feedback +-------- + +If you have any feedback, or have any problems, please let me know by +[opening an issue](https://github.com/jcb91/jupyter_highlight_selected_word/issues/new) +at the project's +[github repository](https://github.com/jcb91/jupyter_highlight_selected_word). + +Thanks! + +Josh. diff --git a/.local/share/jupyter/nbextensions/highlight_selected_word/main.js b/.local/share/jupyter/nbextensions/highlight_selected_word/main.js new file mode 100644 index 0000000000000000000000000000000000000000..f290546e844450ae00211fe38fe4ca8cdafaf139 --- /dev/null +++ b/.local/share/jupyter/nbextensions/highlight_selected_word/main.js @@ -0,0 +1,419 @@ +/** + * Enable highlighting of matching words in cells' CodeMirror editors. + * + * This extension was adapted from the CodeMirror addon + * codemirror/addon/search/match-highlighter.js + */ + +define([ + 'require', + 'jquery', + 'base/js/namespace', + 'notebook/js/cell', + 'notebook/js/codecell', + 'codemirror/lib/codemirror', + // The mark-selection addon is need to ensure that the highlighting styles + // are *not* applied to the actual selection, as otherwise it can become + // difficult to see which is selected vs just highlighted. + 'codemirror/addon/selection/mark-selection' +], function ( + requirejs, + $, + Jupyter, + cell, + codecell, + CodeMirror +) { + 'use strict'; + + var Cell = cell.Cell; + var CodeCell = codecell.CodeCell; + + var mod_name = 'highlight_selected_word'; + var log_prefix = '[' + mod_name + ']'; + var menu_toggle_class = 'highlight_selected_word_toggle'; + + // Parameters (potentially) stored in server config. + // This object gets updated on config load. + var params = { + highlight_across_all_cells: true, + enable_on_load : true, + code_cells_only: false, + delay: 100, + words_only: false, + highlight_only_whole_words: true, + min_chars: 2, + show_token: '[\\w$]', + highlight_color: '#90EE90', + highlight_color_blurred: '#BBFFBB', + highlight_style: 'matchhighlight', + trim: true, + use_toggle_hotkey: false, + toggle_hotkey: 'alt-h', + outlines_only: false, + outline_width: 2, + only_cells_in_scroll: true, + scroll_min_delay: 100, + hide_selections_in_unfocussed: false, + }; + + // these are set on registering the action(s) + var action_names = { + toggle: '', + }; + + /** + * the codemirror matchHighlighter has a separate state object for each cm + * instance, but since our state is global over all cells' editors, we can + * use a single object for simplicity, and don't need to store options + * inside the state, since we have closure-level access to the params + * object above. + */ + var globalState = { + active: false, + timeout: null, // only want one timeout + scrollTimeout: null, + overlay: null, // one overlay suffices, as all cells use the same one + }; + + // define a CodeMirror option for highlighting matches in all cells + CodeMirror.defineOption("highlightSelectionMatchesInJupyterCells", false, function (cm, val, old) { + if (old && old != CodeMirror.Init) { + globalState.active = false; + // remove from all relevant, this can fail gracefully if not present + get_relevant_cells().forEach(function (cell, idx, array) { + cell.code_mirror.removeOverlay(mod_name); + }); + globalState.overlay = null; + clearTimeout(globalState.timeout); + globalState.timeout = null; + cm.off("cursorActivity", callbackCursorActivity); + cm.off("focus", callbackOnFocus); + } + if (val) { + if (cm.hasFocus()) { + globalState.active = true; + highlightMatchesInAllRelevantCells(cm); + } + else { + cm.on("focus", callbackOnFocus); + } + cm.on("cursorActivity", callbackCursorActivity); + } + }); + + /** + * The functions callbackCursorActivity, callbackOnFocus and + * scheduleHighlight are taken without major modification from cm's + * match-highlighter. + * The main difference is using our global state rather than + * match-highlighter's per-cm state, and a different highlighting function + * is scheduled. + */ + function callbackCursorActivity (cm) { + if (globalState.active || cm.hasFocus()) { + scheduleHighlight(cm); + } + } + + function callbackOnFocus (cm) { + // unlike cm match-highlighter, we *do* want to schedule a highight on + // focussing the editor + globalState.active = true; + scheduleHighlight(cm); + } + + function scheduleHighlight (cm) { + clearTimeout(globalState.timeout); + globalState.timeout = setTimeout(function () { highlightMatchesInAllRelevantCells(cm); }, params.delay); + } + + /** + * Adapted from cm match-highlighter's highlightMatches, but adapted to + * use our global state and parameters, plus work either for only the + * current editor, or multiple cells' editors. + */ + function highlightMatchesInAllRelevantCells (cm) { + var newOverlay = null; + + var re = params.show_token === true ? /[\w$]/ : params.show_token; + var from = cm.getCursor('from'); + if (!cm.somethingSelected() && params.show_token) { + var line = cm.getLine(from.line), start = from.ch, end = start; + while (start && re.test(line.charAt(start - 1))) { + --start; + } + while (end < line.length && re.test(line.charAt(end))) { + ++end; + } + if (start < end) { + newOverlay = makeOverlay(line.slice(start, end), re, params.highlight_style); + } + } + else { + var to = cm.getCursor("to"); + if (from.line == to.line) { + if (!params.words_only || isWord(cm, from, to)) { + var selection = cm.getRange(from, to); + if (params.trim) { + selection = selection.replace(/^\s+|\s+$/g, ""); + } + if (selection.length >= params.min_chars) { + var hasBoundary = params.highlight_only_whole_words ? (re instanceof RegExp ? re : /[\w$]/) : false; + newOverlay = makeOverlay(selection, hasBoundary, params.highlight_style); + } + } + } + } + + var siterect = document.getElementById('site').getBoundingClientRect(); + var viewtop = siterect.top, viewbot = siterect.bottom; + var cells = params.highlight_across_all_cells ? get_relevant_cells() : [ + $(cm.getWrapperElement()).closest('.cell').data('cell') + ]; + cells.forEach(function (cell, idx, array) { + // cm.operation to delay updating DOM until all work is done + cell.code_mirror.operation(function () { + cell.code_mirror.removeOverlay(mod_name); + if (newOverlay && is_in_view(cell.element[0], viewtop, viewbot)) { + cell.code_mirror.addOverlay(newOverlay); + } + }); + }); + } + + /** + * isWord, boundariesAround and makeOverlay come pretty much directly from + * Codemirror/addon/search/matchHighlighter + * since they don't use state or config values. + */ + function isWord (cm, from, to) { + var str = cm.getRange(from, to); + if (str.match(/^\w+$/) !== null) { + var pos, chr; + if (from.ch > 0) { + pos = {line: from.line, ch: from.ch - 1}; + chr = cm.getRange(pos, from); + if (chr.match(/\W/) === null) { + return false; + } + } + if (to.ch < cm.getLine(from.line).length) { + pos = {line: to.line, ch: to.ch + 1}; + chr = cm.getRange(to, pos); + if (chr.match(/\W/) === null) { + return false; + } + } + return true; + } + return false; + } + function boundariesAround (stream, re) { + return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && + (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); + } + function makeOverlay (query, hasBoundary, style) { + return { + name: mod_name, + token: function (stream) { + if (stream.match(query) && + (!hasBoundary || boundariesAround(stream, hasBoundary))) { + return style; + } + stream.next(); + if (!stream.skipTo(query.charAt(0))) { + stream.skipToEnd(); + } + } + }; + } + + /** + * Returns true if part of elem is visible between viewtop & viewbot + */ + var is_in_view = function (elem, viewtop, viewbot) { + var rect = elem.getBoundingClientRect(); + // hidden elements show height 0 + return (rect.top < viewbot) && (rect.bottom > viewtop) && rect.height; + } + + /** + * Return an array of cells to which match highlighting is relevant, + * dependent on the code_cells_only parameter + */ + function get_relevant_cells () { + var cells = Jupyter.notebook.get_cells(); + return params.code_cells_only ? cells.filter(function (c) { return (c instanceof CodeCell); }) : cells; + } + + function add_menu_item () { + if ($('#view_menu').find('.' + menu_toggle_class).length < 1) { + var menu_item = $('
') + .appendTo('#view_menu'); + var menu_link = $('') + .text('Highlight selected word') + .addClass(menu_toggle_class) + .attr({ + title: 'Highlight all instances of the selected word in the current editor', + href: '#', + }) + .on('click', function () { toggle_highlight_selected(); }) + .appendTo(menu_item); + $('') + .addClass('fa menu-icon pull-right') + .css({'margin-top': '-2px', 'margin-right': '-16px'}) + .prependTo(menu_link); + } + } + + var throttled_highlight = (function () { + var last, throttle_timeout; + return function throttled_highlight (cm) { + var now = Number(new Date()); + var do_it = function () { + last = Number(new Date()); + highlightMatchesInAllRelevantCells(cm); + }; + var remaining = last + params.scroll_min_delay - now; + if (last && remaining > 0) { + clearTimeout(throttle_timeout); + throttle_timeout = setTimeout(do_it, remaining); + } + else { + last = undefined; // so we will do it first time next streak + do_it(); + } + } + })(); + + function scroll_handler (evt) { + if (globalState.active && Jupyter.notebook.mode === 'edit' && globalState.overlay) { + // add overlay to cells now in view which don't already have it. + // Don't bother removing from those no longer in view, as it would just + // cause more work for the browser, without any benefit + var siterect = document.getElementById('site').getBoundingClientRect(); + get_relevant_cells().forEach(function (cell) { + var cm = cell.code_mirror; + if (is_in_view(cell.element, siterect.top, siterect.bot)) { + var need_it = !cm.state.overlays.some(function(ovr) { + return ovr.modeSpec.name === mod_name; }); + if (need_it) cm.addOverlay(globalState.overlay); + } + }); + } + } + + function toggle_highlight_selected (set_on) { + set_on = (set_on !== undefined) ? set_on : !params.enable_on_load; + // update config to make changes persistent + if (set_on !== params.enable_on_load) { + params.enable_on_load = set_on; + Jupyter.notebook.config.update({highlight_selected_word: {enable_on_load: set_on}}); + } + + // Change defaults for new cells: + var cm_conf = (params.code_cells_only ? CodeCell : Cell).options_default.cm_config; + cm_conf.highlightSelectionMatchesInJupyterCells = cm_conf.styleSelectedText = set_on; + + // And change any existing cells: + get_relevant_cells().forEach(function (cell, idx, array) { + cell.code_mirror.setOption('highlightSelectionMatchesInJupyterCells', set_on); + cell.code_mirror.setOption('styleSelectedText', set_on); + }); + // update menu class + $('.' + menu_toggle_class + ' > .fa').toggleClass('fa-check', set_on); + // bind/unbind scroll handler + $('#site')[ + (params.only_cells_in_scroll && params.scroll_min_delay > 0) ? 'on' : 'off' + ]('scroll', scroll_handler); + console.log(log_prefix, 'toggled', set_on ? 'on' : 'off'); + return set_on; + } + + function register_new_actions () { + action_names.toggle = Jupyter.keyboard_manager.actions.register({ + handler : function (env) { toggle_highlight_selected(); }, + help : "Toggle highlighting of selected word", + icon : 'fa-language', + help_index: 'c1' + }, 'toggle', mod_name); + } + + function bind_hotkeys () { + if (params.use_toggle_hotkey && params.toggle_hotkey) { + Jupyter.keyboard_manager.command_shortcuts.add_shortcut(params.toggle_hotkey, action_names.toggle); + Jupyter.keyboard_manager.edit_shortcuts.add_shortcut(params.toggle_hotkey, action_names.toggle); + } + } + + function insert_css () { + var css = [// in unselected cells, matches have blurred color + // in selected cells, we keep CodeMirror highlight for the actual selection to avoid confusion + '.edit_mode .unselected .CodeMirror .cm-matchhighlight {', + ' background-color: ' + params.highlight_color_blurred + ';', + '}', + + // in active cell, matches which are not the current selection have focussed color + '.edit_mode .CodeMirror.CodeMirror-focused :not(.CodeMirror-selectedtext).cm-matchhighlight {', + ' background-color: ' + params.highlight_color + ';', + '}', + + // in all cells, outline matches have blurred color + '.edit_mode .CodeMirror .cm-matchhighlight-outline {', + ' outline-style: solid;', + ' outline-width: ' + params.outline_width + 'px;', + ' outline-color: ' + params.highlight_color_blurred + ';', + '}', + + // in active cell, outline matches have focussed color + '.edit_mode .CodeMirror.CodeMirror-focused .cm-matchhighlight-outline {', + ' outline-color: ' + params.highlight_color + ';', + '}' + ].join('\n'); + + if (params.hide_selections_in_unfocussed) { + css += [ + // in unselected cells, selections which are not matches should have no background + '.unselected .CodeMirror :not(.cm-matchhighlight).CodeMirror-selected,', + '.unselected .CodeMirror :not(.cm-matchhighlight).CodeMirror-selectedtext {', + ' background: initial;', + '}', + ].join('\n'); + } + + $(' + + + + + + + + + + + + + + + + + +highlighter.css
. The last button enables to remove all highlightings in the current cell. The extension can be installed with the nice UI available on jupyter_contrib_nbextensions website, which also allows to enable/disable the extension.
+You may also install the extension from the original repo: issue
+jupyter nbextension install https://rawgit.com/jfbercher/small_nbextensions/master/highlighter.zip --user
+
at the command line.
+Use a code cell with
+%%javascript
+require("base/js/utils").load_extensions("highlighter/highlighter")
+
You may also automatically load the extension for any notebook via
+jupyter nbextension enable highlighter/highlighter
+
%%javascript
+require("base/js/utils").load_extensions("highlighter/highlighter")
+