Custom IPython Notebook keyboard shortcut to duplicate current line in edit mode
Step1.
Create a new JS file under ~/.jupyter/custom/custom.js
if it does not exist and add the next code:
/**
*
* Duplicate a current line in the Jupyter Notebook
* Used only CodeMirror API - https://codemirror.net
*
**/
CodeMirror.keyMap.pcDefault["Ctrl-Down"] = function(cm){
// get a position of a current cursor in a current cell
var current_cursor = cm.doc.getCursor();
// read a content from a line where is the current cursor
var line_content = cm.doc.getLine(current_cursor.line);
// go to the end the current line
CodeMirror.commands.goLineEnd(cm);
// make a break for a new line
CodeMirror.commands.newlineAndIndent(cm);
// filled a content of the new line content from line above it
cm.doc.replaceSelection(line_content);
// restore position cursor on the new line
cm.doc.setCursor(current_cursor.line + 1, current_cursor.ch);
};
Step 2.
Restart Jupyter
Result
Tested in a next environment
wlysenko@wlysenko-Aspire ~ $ google-chrome --version
Google Chrome 53.0.2785.116
wlysenko@wlysenko-Aspire ~ $ jupyter --version
4.1.0
wlysenko@wlysenko-Aspire ~ $ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
This is a simple adjustment to this great answer, fulfilling dasWesen's request to avoid doubling tabs. This version uses CodeMirror's goLineStartSmart function to go to just the start of the current line's text, so that when it copies the text, it doesn't grab leading spaces or tabs.
As mentioned in Seti's post, put the code in the file ~/.jupyter/custom/custom.js
On Windows, I found the .jupyter folder in C:\Users\YourUserName
, and then had to create the \custom
folder and the custom.js
file. Restarting Jupyter picked up the changes.
CodeMirror.keyMap.pcDefault["Ctrl-Down"] = function(cm){
// get current cursor position
var current_cursor = cm.doc.getCursor();
// First go to end of line, to avoid the problem where if cursor was at start
// of indented text, goLineStartSmart would go to very beginning of line,
// and so we'd get unwanted tabs/spaces in the getRange function.
CodeMirror.commands.goLineEnd(cm);
// now we can safely call goLineStartSmart
CodeMirror.commands.goLineStartSmart(cm);
var start_cursor = cm.doc.getCursor();
var start = {'line': start_cursor.line, 'ch': start_cursor.ch};
// go to the end of line
CodeMirror.commands.goLineEnd(cm);
var end_cursor = cm.doc.getCursor();
var end = {'line': end_cursor.line, 'ch': end_cursor.ch};
// get content
var line_content = cm.doc.getRange(start, end);
// make a break for a new line
CodeMirror.commands.newlineAndIndent(cm);
// filled a content of the new line content from line above it
cm.doc.replaceSelection(line_content);
// restore position cursor on the new line
cm.doc.setCursor(current_cursor.line + 1, current_cursor.ch);
};