From f878b7729b859ec3621c7cf25cfc3a452b1ef8cd Mon Sep 17 00:00:00 2001 From: Eric Rawn Date: Wed, 30 Sep 2026 16:48:36 -0700 Subject: [PATCH 1/3] full top, scroll to code --- .gitignore | 3 ++- DEVELOPMENT.md | 26 +++++++++----------------- nodpy/__main__.py | 0 src/codeViewers.ts | 32 ++++++++++++++++++++++++-------- src/kernelHelpers.ts | 31 ++++++++++++------------------- 5 files changed, 47 insertions(+), 45 deletions(-) create mode 100644 nodpy/__main__.py diff --git a/.gitignore b/.gitignore index 49a6f62..0cacf8a 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,5 @@ dmypy.json # Yarn cache .yarn/ -nodpy/tests/nod/** \ No newline at end of file +nodpy/tests/nod/** +demos/** \ No newline at end of file diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index c0045dd..0df696a 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -21,24 +21,16 @@ NODCONFIG - add restart time to nodConfig? (hmm maybe) -Nod Tracking - -- set tracking where? - -- notebook() - - NodInfo (but with code transformed) - - NodLog (but with code transformed) -- write request - - Program info before (but with code transformed) - - Program info after (but with code transformed) -- execute cell -- navigate stackframe -- save notebook -- restart - - whether we write or not TODO - +- dont change cwd +- quit if program finishes without calling notebook? +— display all code above +— Highlight editable code on the scrollbar +— Bash command issue +— Multiple Nod instances +— Modules not available higher up in call stack? +- Nod log — quotes around variable name - add dependency for ipython - path concat bug - run restarts in jupyter terminal window? @@ -62,7 +54,7 @@ TODO 0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation. Nice to have - +- edit function arguments - persist lock through reload? - - clear old kernels from jupyter (get shutdown registering properly??) - layoutrestorer, restorablepool diff --git a/nodpy/__main__.py b/nodpy/__main__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/codeViewers.ts b/src/codeViewers.ts index e53140b..250db09 100644 --- a/src/codeViewers.ts +++ b/src/codeViewers.ts @@ -27,7 +27,7 @@ const NOD_FUNC_CLASS = 'jp-nod-Function'; function addCodeViewers(panel: NotebookPanel) { const innerPanel = panel.node.getElementsByClassName( - 'jp-WindowedPanel-inner' + 'jp-WindowedPanel-viewport' )[0] as HTMLElement; const parentNode = innerPanel.parentElement; const currentFrame = nodState.Instance().getFrameFromPath(panel.context.path); @@ -43,16 +43,32 @@ function addCodeViewers(panel: NotebookPanel) { if (parentNode) { if (panel.isAttached) { - Widget.attach(header, parentNode, innerPanel); - Widget.attach(func, parentNode, innerPanel); - Widget.attach(footer, parentNode); + let ref = panel.content.viewportNode.children[0]; + header.processMessage(Widget.Msg.BeforeAttach) + func.processMessage(Widget.Msg.BeforeAttach) + footer.processMessage(Widget.Msg.BeforeAttach) + panel.content.viewportNode.insertBefore(header.node, ref) + panel.content.viewportNode.insertBefore(func.node, ref) + panel.content.viewportNode.appendChild(footer.node) + header.processMessage(Widget.Msg.AfterAttach) + func.processMessage(Widget.Msg.AfterAttach) + footer.processMessage(Widget.Msg.AfterAttach) } else { panel.revealed.then(() => { - Widget.attach(header, parentNode, innerPanel); - Widget.attach(func, parentNode, innerPanel); - Widget.attach(footer, parentNode); + let ref = panel.content.viewportNode.children[0]; + header.processMessage(Widget.Msg.BeforeAttach) + func.processMessage(Widget.Msg.BeforeAttach) + footer.processMessage(Widget.Msg.BeforeAttach) + panel.content.viewportNode.insertBefore(header.node, ref) + panel.content.viewportNode.insertBefore(func.node, ref) + panel.content.viewportNode.appendChild(footer.node) + header.processMessage(Widget.Msg.AfterAttach) + func.processMessage(Widget.Msg.AfterAttach) + footer.processMessage(Widget.Msg.AfterAttach) }); } + panel.update() + panel.content.update() } return [header, footer, func]; } @@ -99,7 +115,7 @@ export function makeCodeViewer( switch (className) { case NOD_HEADER_CLASS: { const text_above = currentFrame.file_info.text_above; - source = text_above.slice(-10).join('').split('\\n').join('\n'); + source = text_above.join('').split('\\n').join('\n'); if (source.startsWith('\n')) { source = source.slice(source.indexOf('\n')); } diff --git a/src/kernelHelpers.ts b/src/kernelHelpers.ts index 0331948..bd198c5 100644 --- a/src/kernelHelpers.ts +++ b/src/kernelHelpers.ts @@ -24,30 +24,23 @@ export async function openNotebookWithNodKernel( await state.app.serviceManager.kernels.refreshRunning(); const nodKernelId = await getNodKernel(); - + console.log("finding notebook:", notebookFile) + state.tracker.forEach(panel => { console.log(panel.context.sessionContext.path); console.log(panel.context.sessionContext.path === notebookFile) }) const existingNotebook = state.tracker.find( - panel => panel.context.sessionContext.path === notebookFile + panel => panel.context.sessionContext.path === normalized ); + console.log('opening', normalized, nodKernelId); + const newNotebook = docManager.openOrReveal(normalized, 'default', { + name: 'nod', + id: nodKernelId + }) if (existingNotebook) { console.log('Existing Notebook with Path', existingNotebook); - existingNotebook.sessionContext.kernelPreference = { - // autoStartDefault: false, - name: 'nod', - id: nodKernelId, - shutdownOnDispose: false - }; - state.app.shell.activateById(existingNotebook.id); - // state.sessionManager.connectTo - existingNotebook.context.sessionContext.changeKernel({ - name: 'nod', - id: state.nodKernelId - }); } else { - console.log('opening', normalized, nodKernelId); - docManager.openOrReveal(normalized, 'default', { - name: 'nod', - id: nodKernelId - }); + + newNotebook?.revealed.then(() => { + nodState.Instance().tracker.currentWidget?.content.activeCell!.node.scrollIntoView({ block: 'center' }) + }) } } export async function getNodKernel(): Promise { From 89c20448dd071312e680cc7faf13b5cabb1dc6ac Mon Sep 17 00:00:00 2001 From: Eric Rawn Date: Wed, 30 Sep 2026 16:51:37 -0700 Subject: [PATCH 2/3] update test --- nodpy/tests/simpletest.py | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/nodpy/tests/simpletest.py b/nodpy/tests/simpletest.py index 068817c..c35d6ce 100644 --- a/nodpy/tests/simpletest.py +++ b/nodpy/tests/simpletest.py @@ -6,7 +6,84 @@ x = 0 +# **test comment +# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# **test comment + +# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test# **test comment + + +# test +# test def baller(a, b: int, c: int): global x global z From 4f69d15b489289ec346925948439a3557ffebed8 Mon Sep 17 00:00:00 2001 From: Eric Rawn Date: Wed, 30 Sep 2026 18:02:02 -0700 Subject: [PATCH 3/3] bug fix --- src/codeViewers.ts | 52 ++++++++++++++++++++++++-------------------- src/kernelHelpers.ts | 18 ++++++++++----- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/codeViewers.ts b/src/codeViewers.ts index 250db09..823dadb 100644 --- a/src/codeViewers.ts +++ b/src/codeViewers.ts @@ -14,10 +14,10 @@ import { } from '@jupyterlab/cells'; import { nodState } from './state'; import { NotebookPanel, INotebookModel } from '@jupyterlab/notebook'; -import { Widget } from '@lumino/widgets'; import { IDisposable, DisposableDelegate } from '@lumino/disposable'; import { DocumentRegistry } from '@jupyterlab/docregistry'; import { hasFileInfo } from './types'; +import { Widget } from '@lumino/widgets'; // const INPUT_AREA_CLASS = 'jp-InputArea'; // const INPUT_AREA_EDITOR_CLASS = 'jp-InputArea-editor'; const NOD_VIEWER_CLASS = 'jp-nod-viewer'; @@ -27,7 +27,7 @@ const NOD_FUNC_CLASS = 'jp-nod-Function'; function addCodeViewers(panel: NotebookPanel) { const innerPanel = panel.node.getElementsByClassName( - 'jp-WindowedPanel-viewport' + 'jp-WindowedPanel-inner' )[0] as HTMLElement; const parentNode = innerPanel.parentElement; const currentFrame = nodState.Instance().getFrameFromPath(panel.context.path); @@ -43,32 +43,36 @@ function addCodeViewers(panel: NotebookPanel) { if (parentNode) { if (panel.isAttached) { - let ref = panel.content.viewportNode.children[0]; - header.processMessage(Widget.Msg.BeforeAttach) - func.processMessage(Widget.Msg.BeforeAttach) - footer.processMessage(Widget.Msg.BeforeAttach) - panel.content.viewportNode.insertBefore(header.node, ref) - panel.content.viewportNode.insertBefore(func.node, ref) - panel.content.viewportNode.appendChild(footer.node) - header.processMessage(Widget.Msg.AfterAttach) - func.processMessage(Widget.Msg.AfterAttach) - footer.processMessage(Widget.Msg.AfterAttach) + const ref = panel.content.viewportNode.children[0] as HTMLElement; + header.processMessage(Widget.Msg.BeforeAttach); + func.processMessage(Widget.Msg.BeforeAttach); + footer.processMessage(Widget.Msg.BeforeAttach); + panel.content.viewportNode.insertBefore(header.node, ref); + panel.content.viewportNode.insertBefore(func.node, ref); + Widget.attach(footer, parentNode); + header.node.dataset.windowedListIndex = `-1`; + func.node.dataset.windowedListIndex = `-1`; + footer.node.dataset.windowedListIndex = `-1`; + header.processMessage(Widget.Msg.AfterAttach); + func.processMessage(Widget.Msg.AfterAttach); + footer.processMessage(Widget.Msg.AfterAttach); } else { panel.revealed.then(() => { - let ref = panel.content.viewportNode.children[0]; - header.processMessage(Widget.Msg.BeforeAttach) - func.processMessage(Widget.Msg.BeforeAttach) - footer.processMessage(Widget.Msg.BeforeAttach) - panel.content.viewportNode.insertBefore(header.node, ref) - panel.content.viewportNode.insertBefore(func.node, ref) - panel.content.viewportNode.appendChild(footer.node) - header.processMessage(Widget.Msg.AfterAttach) - func.processMessage(Widget.Msg.AfterAttach) - footer.processMessage(Widget.Msg.AfterAttach) + const ref = panel.content.viewportNode.children[0] as HTMLElement; + header.processMessage(Widget.Msg.BeforeAttach); + func.processMessage(Widget.Msg.BeforeAttach); + footer.processMessage(Widget.Msg.BeforeAttach); + panel.content.viewportNode.insertBefore(header.node, ref); + panel.content.viewportNode.insertBefore(func.node, ref); + Widget.attach(footer, parentNode); + header.node.dataset.windowedListIndex = `-1`; + func.node.dataset.windowedListIndex = `-1`; + footer.node.dataset.windowedListIndex = `-1`; + header.processMessage(Widget.Msg.AfterAttach); + func.processMessage(Widget.Msg.AfterAttach); + footer.processMessage(Widget.Msg.AfterAttach); }); } - panel.update() - panel.content.update() } return [header, footer, func]; } diff --git a/src/kernelHelpers.ts b/src/kernelHelpers.ts index bd198c5..9a6ddf1 100644 --- a/src/kernelHelpers.ts +++ b/src/kernelHelpers.ts @@ -24,8 +24,11 @@ export async function openNotebookWithNodKernel( await state.app.serviceManager.kernels.refreshRunning(); const nodKernelId = await getNodKernel(); - console.log("finding notebook:", notebookFile) - state.tracker.forEach(panel => { console.log(panel.context.sessionContext.path); console.log(panel.context.sessionContext.path === notebookFile) }) + console.log('finding notebook:', notebookFile); + state.tracker.forEach(panel => { + console.log(panel.context.sessionContext.path); + console.log(panel.context.sessionContext.path === notebookFile); + }); const existingNotebook = state.tracker.find( panel => panel.context.sessionContext.path === normalized ); @@ -33,14 +36,17 @@ export async function openNotebookWithNodKernel( const newNotebook = docManager.openOrReveal(normalized, 'default', { name: 'nod', id: nodKernelId - }) + }); if (existingNotebook) { console.log('Existing Notebook with Path', existingNotebook); } else { - newNotebook?.revealed.then(() => { - nodState.Instance().tracker.currentWidget?.content.activeCell!.node.scrollIntoView({ block: 'center' }) - }) + nodState + .Instance() + .tracker.currentWidget?.content.activeCell!.node.scrollIntoView({ + block: 'center' + }); + }); } } export async function getNodKernel(): Promise {