Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use in-n-out for plugin dependency #36

Merged
merged 1 commit into from
Feb 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 1 addition & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,15 @@ pip install jpterm --no-cache-dir

## Usage

To run jpterm without a server:

```bash
jpterm
```

To run jpterm as a client to a Jupyter server, you need, well, jupyter-server :) You can install it through JupyterLab:

```bash
pip install --pre jupyterlab
```

Then launch it with:

```bash
jupyter lab --port=8000 --no-browser

# it will print a URL like: http://127.0.0.1:8000/lab?token=972cbd440db4b35581b25f90c0a88e3a1095534e18251ca8
# you will need the token when launching jpterm, but if you don't want to bother with authentication:
# jupyter lab --port=8000 --no-browser --ServerApp.token='' --ServerApp.password=''
```

Then launch jpterm in another terminal:

```bash
jpterm --server http://127.0.0.1:8000/?token=972cbd440db4b35581b25f90c0a88e3a1095534e18251ca8

# if you launched JupyterLab without authentication:
# jpterm --server http://127.0.0.1:8000
```

If JupyterLab and jpterm are launched with `--collaborative`, you can open a document in
JupyterLab (go to http://127.0.0.1:8000 in your browser), modify it, and see the changes live
in jpterm.

## Development install

jpterm uses [hatch](https://hatch.pypa.io):

```bash
pip install hatch
hatch run dev:jpterm
```

To run a command, you need to point `hatch` to the `dev` environment, e.g. `hatch run dev:jpterm`.
40 changes: 0 additions & 40 deletions jpterm/cli.py

This file was deleted.

4 changes: 2 additions & 2 deletions plugins/cell/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ dynamic = ["version"]
[project.urls]
Source = "https://github.com/davidbrochart/jpterm/plugins/cell"

[project.entry-points.txl_component]
txl_cell = "txl_cell.components"
[project.entry-points.txl]
cell = "txl_cell.main"

[tool.hatch.version]
path = "txl_cell/__init__.py"
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
from functools import partial

import in_n_out as ino
import pkg_resources
import y_py as Y
from asphalt.core import Component, Context
from rich.markdown import Markdown
from rich.panel import Panel
from rich.syntax import Syntax
Expand All @@ -12,7 +12,6 @@
from textual.widgets import Static

from txl.base import Cell, CellFactory, Kernel, Widgets
from txl.hooks import register_component

YDOCS = {
ep.name: ep.load() for ep in pkg_resources.iter_entry_points(group="ypywidgets")
Expand Down Expand Up @@ -161,14 +160,9 @@ def get_output_widget(self, output):
return output_widget


class CellComponent(Component):
async def start(
self,
ctx: Context,
) -> None:
widgets = await ctx.request_resource(Widgets, "widgets")
cell_factory = partial(_Cell, widgets=widgets)
ctx.add_resource(cell_factory, name="cell", types=CellFactory)
@ino.inject
def cell_factory(widgets: Widgets) -> CellFactory:
return partial(_Cell, widgets=widgets)


c = register_component("cell", CellComponent)
ino.register_provider(cell_factory)
4 changes: 2 additions & 2 deletions plugins/editors/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ dynamic = ["version"]
[project.urls]
Source = "https://github.com/davidbrochart/jpterm/plugins/editors"

[project.entry-points.txl_component]
txl_editors = "txl_editors.components"
[project.entry-points.txl]
editors = "txl_editors.main"

[tool.hatch.version]
path = "txl_editors/__init__.py"
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from pathlib import Path
from typing import Callable, Dict, List

from asphalt.core import Component, Context
import in_n_out as ino
from textual.containers import Container
from textual.widgets._header import HeaderTitle

from txl.base import Editor, Editors, FileOpenEvent, Footer, Header, MainArea
from txl.hooks import register_component
from txl.base import Editor, Editors, Footer, Header, MainArea


class EditorsMeta(type(Editors), type(Container)):
Expand Down Expand Up @@ -38,8 +37,8 @@ def register_editor_factory(
self.ext_editor_factories[ext] = []
self.ext_editor_factories[ext].append(editor_factory)

async def on_open(self, event: FileOpenEvent) -> None:
path = Path(event.path)
async def on_open(self, path: str) -> None:
path = Path(path)
extension = path.suffix
for ext, editor_factories in self.ext_editor_factories.items():
if ext == extension:
Expand All @@ -61,16 +60,10 @@ async def on_open(self, event: FileOpenEvent) -> None:
preferred_editor.refresh(layout=True)


class EditorsComponent(Component):
async def start(
self,
ctx: Context,
) -> None:
header = await ctx.request_resource(Header, "header")
footer = await ctx.request_resource(Footer, "footer")
main_area = await ctx.request_resource(MainArea, "main_area")
editors = _Editors(header, footer, main_area)
ctx.add_resource(editors, name="editors", types=Editors)
@ino.inject
@ino.inject_processors
def editors(header: Header, footer: Footer, main_area: MainArea) -> Editors:
return _Editors(header, footer, main_area)


c = register_component("editors", EditorsComponent)
ino.register_provider(editors)
4 changes: 2 additions & 2 deletions plugins/file_browser/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ dynamic = ["version"]
[project.urls]
Source = "https://github.com/davidbrochart/jpterm/plugins/file_browser"

[project.entry-points.txl_component]
txl_filebrowser = "txl_filebrowser.components"
[project.entry-points.txl]
filebrowser = "txl_filebrowser.main"

[tool.hatch.version]
path = "txl_filebrowser/__init__.py"
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
from dataclasses import dataclass
from typing import ClassVar

from asphalt.core import Component, Context
import in_n_out as ino
from rich.style import Style
from rich.text import Text, TextType
from textual._types import MessageTarget
from textual.message import Message
from textual.widgets._tree import TOGGLE_STYLE, Tree, TreeNode

from txl.base import Contents, FileBrowser
from txl.hooks import register_component


@dataclass
Expand Down Expand Up @@ -73,8 +72,14 @@ def __init__(
self.path = os.path.expanduser(path.rstrip("/"))
name = os.path.basename(self.path)
self.contents = contents
super().__init__(
self.path, data=DirEntry(self.path, True), name=name, id=id, classes=classes
FileBrowser.__init__(self)
Tree.__init__(
self,
self.path,
data=DirEntry(self.path, True),
name=name,
id=id,
classes=classes,
)

def process_label(self, label: TextType):
Expand Down Expand Up @@ -149,25 +154,22 @@ async def on_tree_node_expanded(self, event: Tree.NodeSelected) -> None:
if not dir_entry.loaded:
await self.load_directory(event.node)
else:
self.open_file_signal.dispatch(dir_entry.path)
for cb in self.open_file_callbacks:
await cb(dir_entry.path)

def on_tree_node_selected(self, event: Tree.NodeSelected) -> None:
async def on_tree_node_selected(self, event: Tree.NodeSelected) -> None:
event.stop()
dir_entry = event.node.data
if dir_entry is None:
return
if not dir_entry.is_dir:
self.open_file_signal.dispatch(dir_entry.path)
for cb in self.open_file_callbacks:
await cb(dir_entry.path)


class FileBrowserComponent(Component):
async def start(
self,
ctx: Context,
) -> None:
contents = await ctx.request_resource(Contents, "contents")
file_browser = DirectoryTree(".", contents, id="browser-view")
ctx.add_resource(file_browser, name="file_browser", types=FileBrowser)
@ino.inject
def file_browser(contents: Contents) -> FileBrowser:
return DirectoryTree(".", contents, id="browser-view")


c = register_component("file_browser", FileBrowserComponent)
ino.register_provider(file_browser)
4 changes: 2 additions & 2 deletions plugins/image_viewer/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ dynamic = ["version"]
[project.urls]
Source = "https://github.com/davidbrochart/jpterm/plugins/image_viewer"

[project.entry-points.txl_component]
txl_image_viewer = "txl_image_viewer.components"
[project.entry-points.txl]
image_viewer = "txl_image_viewer.main"

[tool.hatch.version]
path = "txl_image_viewer/__init__.py"
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import os
import tempfile
from functools import partial

from asphalt.core import Component, Context
import in_n_out as ino
from PIL import Image
from textual.widget import Widget
from textual_imageview.viewer import ImageViewer

from txl.base import Contents, Editor, Editors, FileOpenEvent
from txl.hooks import register_component
from txl.base import Contents, Editor, Editors


class ImageViewerMeta(type(Editor), type(Widget)):
Expand All @@ -24,9 +24,6 @@ def __init__(self, contents: Contents) -> None:
self.contents = contents
self.image_viewer = None

async def on_open(self, event: FileOpenEvent) -> None:
await self.open(event.path)

async def open(self, path: str) -> None:
self.ydoc = await self.contents.get(path, type="blob")
self.data = self.ydoc.source
Expand All @@ -53,28 +50,13 @@ def on_change(self, target, event):
self.update_viewer()


class ImageViewerComponent(Component):
def __init__(self, register: bool = True):
super().__init__()
self.register = register

async def start(
self,
ctx: Context,
) -> None:
contents = await ctx.request_resource(Contents, "contents")

def image_viewer_factory():
return _ImageViewer(contents)
def register_image_viewer(editors: Editors):
@ino.inject
def inner(contents: Contents):
image_viewer_factory = partial(_ImageViewer, contents)
editors.register_editor_factory(image_viewer_factory, [".png", ".jpg", ".jpeg"])

if self.register:
editors = await ctx.request_resource(Editors, "editors")
editors.register_editor_factory(
image_viewer_factory, [".png", ".jpg", ".jpeg"]
)
else:
image_viewer = image_viewer_factory()
ctx.add_resource(image_viewer, name="image_viewer", types=Editor)
inner()


c = register_component("image_viewer", ImageViewerComponent)
ino.register_processor(register_image_viewer)
4 changes: 2 additions & 2 deletions plugins/jpterm/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ dynamic = ["version"]
[project.urls]
Source = "https://github.com/davidbrochart/jpterm/plugins/jpterm"

[project.entry-points.txl_component]
txl_jpterm = "txl_jpterm.components"
[project.entry-points.txl]
jpterm = "txl_jpterm.main"

[tool.hatch.version]
path = "txl_jpterm/__init__.py"
Loading