Would be nice to have an IDE-like ctrl-D shortcut to duplicate a line.
Otherwise, best tool ever ! Thanks to all of you.
It looks like the notebook does not currently provide a "duplicate line" or "duplicate cell" feature. However, if it did then you could define a custom keyboard shortcut by following these instructions. FYI, notebook uses Codemirror for the text editor, so any features that it supports are also supported in notebook.
I have done it
http://stackoverflow.com/a/40505055/6003870
Nice work, @setivolkylany! I have copied and pasted your code here for future reference. Add the following to your custom.js:
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);
};
Thanks a lot. Excuse my ignorance, but how do you load CodeMirror from custom.js ?
$.getScript("codemirror.js", function(){
});
but not to avail. Any feedback would be greatly appreciated.
I suppose my request wont be implemented in a future version of Jupyter ?
@clementlefevre You want to use the notebook's CodeMirror module vs. importing your own (which is conveniently available as a global CodeMirror). However, setting CodeMirror.keyMap.pcDefault["Ctrl-Down"] in custom.js will affect the global CodeMirror but none of the instances used by the Cell objects in the notebook (because custom.js is being executed after the notebook is loaded), so if you want to add this keymap to work in your cells, you will need to get all of the cells and modify their code_mirror instances. An example custom.js:
// Get instances of `Cell` in the notebook
var cells = $('#notebook-container').find('.cell').map(function() {
return $(this).data('cell')
});
// For each instance of `Cell`, add a keymap to `Cell.code_mirror`
cells.each(function(index) {
this.code_mirror.addKeyMap({
'Ctrl-Down': function(cm) {
var current_cursor = cm.doc.getCursor();
var line_content = cm.doc.getLine(current_cursor.line);
CodeMirror.commands.goLineEnd(cm);
CodeMirror.commands.newlineAndIndent(cm);
cm.doc.replaceSelection(line_content);
cm.doc.setCursor(current_cursor.line + 1, current_cursor.ch);
}
});
});
This should be in the core!
Another ref: https://github.com/codemirror/CodeMirror/issues/5141
I wanted to duplicate lines above or below and I also wanted to duplicate selected lines rather than just a single line. I have edited the code above to do so:
// create the extra keys in CodeMirror to call duplicate lines
"Shift-Alt-Up": function(cm) { duplicateLines(cm, true); };
"Shift-Alt-Down": function(cm) { duplicateLines(cm, false); };
// create the functions that duplicates a line or selected lines in codemirror
function duplicateLines(cm, above) {
// get selection or cursor start and end position
var startPosition = cm.doc.getCursor(true);
var endPosition = cm.doc.getCursor(false);
// gets the start cursor position without the beginning tabs
cm.doc.setCursor(startPosition.line, startPosition.ch);
CodeMirror.commands.goLineEnd(cm);
CodeMirror.commands.goLineStartSmart(cm);
var startCursor = cm.doc.getCursor();
var start = {"line": startCursor.line, "ch": startCursor.ch};
// gets the end cursor position
cm.doc.setCursor(endPosition.line, endPosition.ch);
CodeMirror.commands.goLineEnd(cm);
var endCursor = cm.doc.getCursor();
var end = {"line": endCursor.line, "ch": endCursor.ch};
// gets the content of the line or selected lines
var content = cm.doc.getRange(start, end);
// checks if the code is duplicated above
if (above) {
// handles duplication on the first line
if (startPosition.line == 0) {
// sets the cursor to the beginning, duplicates the content, then adds a new line
cm.doc.setCursor(0, 0);
cm.doc.replaceSelection(content);
CodeMirror.commands.newlineAndIndent(cm);
// handles duplication on all other lines
} else {
// sets the cursor to the end of the line, adds a new line, then duplicates the content
cm.doc.setCursor(startPosition.line - 1);
CodeMirror.commands.goLineEnd(cm);
CodeMirror.commands.newlineAndIndent(cm);
cm.doc.replaceSelection(content);
}
// adds a new line and duplicates the content below
} else {
CodeMirror.commands.newlineAndIndent(cm);
cm.doc.replaceSelection(content);
}
// restores the cursor position if duplicating above
if (above) {
cm.doc.setSelection(startPosition, endPosition);
// restores the cursor position if duplicating one line below
} else if (endPosition.line == startPosition.line) {
cm.doc.setCursor(endPosition.line + 1, endPosition.ch);
// restores the cursor position if duplicating more than one line below
} else {
var lineCount = endPosition.line - startPosition.line + 1;
startPosition.line += lineCount;
endPosition.line += lineCount;
cm.doc.setSelection(startPosition, endPosition);
}
}
I hope this goes into the core.
What's the status of this? Did it made it into the core?
please make this a core feature!
I have done it
http://stackoverflow.com/a/40505055/6003870
```js
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 & removes indentation
var line_content = cm.doc.getLine(current_cursor.line).replaceAll("\t", "").replaceAll(" ", "");
// removes tabs for proper identations in Jupyter
line_content.replaceAll("\t", "")
// 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);
};
```
Slightly adapted the code for proper indentatin in Jupyter notebook (removing tabs from copied line)
Most helpful comment
I have done it
http://stackoverflow.com/a/40505055/6003870