=> {
+ console.log(target.innerHTML);
+ console.log(new_element.value);
+ if (target.innerHTML !== new_element.value) {
+ const newPath = 'snippets/' + new_element.value + '.json';
+ try {
+ await contentsService.rename(oldPath, newPath);
+ } catch (error) {
+ new_element.replaceWith(target);
+
+ await showDialog({
+ title: 'Duplicate Name of Code Snippet',
+ body: {`"${newPath}" already exists.`}
,
+ buttons: [Dialog.okButton({ label: 'Dismiss' })]
+ });
+ return;
+ }
+ this.props._codeSnippetWidgetModel.renameSnippet(
+ target.innerHTML,
+ new_element.value
+ );
+ target.innerHTML = new_element.value;
+ }
+ new_element.replaceWith(target);
+ };
+ new_element.onkeydown = (event: KeyboardEvent): void => {
+ switch (event.code) {
+ case 'Enter' || 'NumpadEnter': // Enter
+ event.stopPropagation();
+ event.preventDefault();
+ new_element.blur();
+ break;
+ case 'Escape': // Escape
+ event.stopPropagation();
+ event.preventDefault();
+ new_element.blur();
+ break;
+ case 'ArrowUp': // Up arrow
+ event.stopPropagation();
+ event.preventDefault();
+ new_element.selectionStart = new_element.selectionEnd = 0;
+ break;
+ case 'ArrowDown': // Down arrow
+ event.stopPropagation();
+ event.preventDefault();
+ new_element.selectionStart = new_element.selectionEnd =
+ new_element.value.length;
+ break;
+ default:
+ break;
+ }
+ };
+ }
+
private handleDragSnippet(
event: React.MouseEvent
): void {
diff --git a/src/CodeSnippetWidgetModel.ts b/src/CodeSnippetWidgetModel.ts
index d4dc7e7..8998c1e 100644
--- a/src/CodeSnippetWidgetModel.ts
+++ b/src/CodeSnippetWidgetModel.ts
@@ -33,6 +33,19 @@ export class CodeSnippetWidgetModel implements ICodeSnippetWidgetModel {
}
}
+ renameSnippet(oldName: string, newName: string): void {
+ for (const snippet of this._snippets) {
+ if (snippet.name === oldName) {
+ snippet.name = newName;
+ CodeSnippetContentsService.getInstance().save(
+ 'snippets/' + snippet.name + '.json',
+ { type: 'file', format: 'text', content: JSON.stringify(snippet) }
+ );
+ break;
+ }
+ }
+ }
+
addSnippet(newSnippet: ICodeSnippet, index: number): void {
// append a new snippet created from input form to the end
if (newSnippet.id === -1) {
diff --git a/src/index.ts b/src/index.ts
index 67a226d..8dd8f1d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,6 +4,8 @@ import {
ILayoutRestorer
} from '@jupyterlab/application';
import { ICommandPalette, WidgetTracker } from '@jupyterlab/apputils';
+import { ISettingRegistry } from '@jupyterlab/settingregistry';
+
import { IEditorServices } from '@jupyterlab/codeeditor';
import { LabIcon } from '@jupyterlab/ui-components';
@@ -23,6 +25,7 @@ import {
const CODE_SNIPPET_EXTENSION_ID = 'code-snippet-extension';
+const CODE_SNIPPET_SETTING_ID = 'jupyterlab-code-snippets:settings';
/**
* Snippet Editor Icon
*/
@@ -150,7 +153,7 @@ function activateCodeSnippet(
});
//Add an application command
- const saveCommand = 'save as code snippet';
+ const saveCommand = 'codeSnippet:save-as-snippet';
const toggled = false;
app.commands.addCommand(saveCommand, {
label: 'Save As Code Snippet',
@@ -169,18 +172,16 @@ function activateCodeSnippet(
}
});
- //Put the command above in context menu
+ // Put the saveCommand above in context menu
app.contextMenu.addItem({
command: saveCommand,
selector: '.jp-Cell'
});
- // Add keybinding to save
- app.commands.addKeyBinding({
+ // Put the saveCommand in non-notebook file context menu
+ app.contextMenu.addItem({
command: saveCommand,
- args: {},
- keys: ['Accel Shift S'],
- selector: '.jp-Cell'
+ selector: '.jp-FileEditor'
});
// Track and restore the widget state
@@ -211,6 +212,18 @@ function activateCodeSnippet(
});
}
+const codeSnippetExtensionSetting: JupyterFrontEndPlugin = {
+ id: CODE_SNIPPET_SETTING_ID,
+ autoStart: true,
+ requires: [ISettingRegistry],
+ activate: (app: JupyterFrontEnd, settingRegistry: ISettingRegistry) => {
+ void settingRegistry
+ .load(CODE_SNIPPET_SETTING_ID)
+ .then(_ => console.log('settingRegistry successfully loaded!'))
+ .catch(e => console.log(e));
+ }
+};
+
function getSelectedText(): string {
let selectedText;
// window.getSelection
@@ -224,4 +237,4 @@ function getSelectedText(): string {
return selectedText.toString();
}
-export default code_snippet_extension;
+export default [code_snippet_extension, codeSnippetExtensionSetting];
diff --git a/style/index.css b/style/index.css
index 60bc2c4..e9a8857 100644
--- a/style/index.css
+++ b/style/index.css
@@ -42,6 +42,7 @@
text-overflow: ellipsis;
color: var(--jp-ui-font-color0);
display: flex;
+ align-items: center;
}
.jp-codeSnippetsContainer-button {
@@ -69,6 +70,15 @@
background-color: var(--jp-layout-color2);
}
+#jp-codeSnippet-rename {
+ background-color: var(--jp-layout-color2);
+ border: 1px solid var(--jp-layout-color1);
+ border-radius: 4px;
+ font-size: var(--jp-ui-font-size1);
+ box-sizing: border-box;
+ margin: 0px;
+}
+
.jp-codeSnippet-metadata {
flex-basis: 95%;
width: 100%;