mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-21 23:04:49 +01:00
feat: added maturin wheel building config as completely separate "project",
feat: added stubs for python glue, bundled in the wheel, feat: the python glue now uses less stupid names.
This commit is contained in:
parent
f9784e961d
commit
bdbd94879b
7 changed files with 170 additions and 13 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,6 +4,9 @@ Cargo.lock
|
||||||
.vscode/
|
.vscode/
|
||||||
*.sublime-*
|
*.sublime-*
|
||||||
|
|
||||||
|
.venv
|
||||||
|
wheels/
|
||||||
|
|
||||||
# js
|
# js
|
||||||
node_modules/
|
node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
1
dist/py/.python-version
vendored
Normal file
1
dist/py/.python-version
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3.8
|
7
dist/py/build.sh
vendored
Executable file
7
dist/py/build.sh
vendored
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
ROOT_DIR="$(pwd)"
|
||||||
|
WHEEL_DIR="$ROOT_DIR/wheels"
|
||||||
|
|
||||||
|
PYO3_PYTHON="$(pyenv which python)"
|
||||||
|
TARGET_EXT="$($PYO3_PYTHON -c 'import sysconfig; print(sysconfig.get_config_var("EXT_SUFFIX"))')"
|
||||||
|
|
||||||
|
maturin build -i "$PYO3_PYTHON" --out "$WHEEL_DIR"
|
65
dist/py/codemp.pyi
vendored
Normal file
65
dist/py/codemp.pyi
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
def init_logger(debug: bool | None) -> PyLogger: ...
|
||||||
|
|
||||||
|
def codemp_init() -> Client: ...
|
||||||
|
|
||||||
|
class PyLogger:
|
||||||
|
async def message(self) -> str | None: ...
|
||||||
|
|
||||||
|
|
||||||
|
class CodempTextChange:
|
||||||
|
start_incl: int
|
||||||
|
end_excl: int
|
||||||
|
content: str
|
||||||
|
|
||||||
|
def is_deletion(self) -> bool: ...
|
||||||
|
def is_addition(self) -> bool: ...
|
||||||
|
def is_empty(self) -> bool: ...
|
||||||
|
def apply(self, txt: str) -> str: ...
|
||||||
|
def from_diff(self, before: str, after: str) -> CodempTextChange: ...
|
||||||
|
def index_to_rowcol(self, txt: str, index: int) -> Tuple[int, int]: ...
|
||||||
|
|
||||||
|
|
||||||
|
class CodempBufferController:
|
||||||
|
def content(self) -> str: ...
|
||||||
|
def send(self, start: int, end: int, txt: str) -> None: ...
|
||||||
|
async def try_recv(self) -> CodempTextChange | None: ...
|
||||||
|
async def recv(self) -> CodempTextChange: ...
|
||||||
|
async def poll(self) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
class CodempCursor:
|
||||||
|
start: Tuple[int, int]
|
||||||
|
end: Tuple[int, int]
|
||||||
|
buffer: str
|
||||||
|
user: str # can be an empty string
|
||||||
|
|
||||||
|
|
||||||
|
class CodempCursorController:
|
||||||
|
def send(self, path: str, start: Tuple[int, int], end: Tuple[int, int]) -> None: ...
|
||||||
|
def try_recv(self) -> CodempCursor | None: ...
|
||||||
|
async def recv(self) -> CodempCursor: ...
|
||||||
|
async def poll(self) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
class CodempWorkspace:
|
||||||
|
async def create(self, path: str) -> None: ...
|
||||||
|
async def attach(self, path: str) -> CodempBufferController: ...
|
||||||
|
async def fetch_buffers(self) -> None: ...
|
||||||
|
async def fetch_users(self) -> None: ...
|
||||||
|
async def list_buffer_users(self, path: str) -> list[str]: ...
|
||||||
|
async def delete(self, path: str) -> None: ...
|
||||||
|
def id(self) -> str: ...
|
||||||
|
def cursor(self) -> CodempCursorController: ...
|
||||||
|
def buffer_by_name(self, path: str) -> CodempBufferController: ...
|
||||||
|
def filetree(self) -> list[str]: ...
|
||||||
|
|
||||||
|
|
||||||
|
class Client:
|
||||||
|
def __init__(self) -> None: ...
|
||||||
|
async def connect(self, host: str) -> None: ...
|
||||||
|
async def login(self, user: str, password: str, workspace: str | None) -> None: ...
|
||||||
|
async def join_workspace(self, workspace: str) -> CodempWorkspace: ...
|
||||||
|
async def get_workspace(self, id: str) -> CodempWorkspace: ...
|
||||||
|
async def user_id(self) -> str: ...
|
30
dist/py/pyproject.toml
vendored
Normal file
30
dist/py/pyproject.toml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
[project]
|
||||||
|
name = "codemp"
|
||||||
|
version = "0.6.2"
|
||||||
|
description = "Cooperative multi-player coding"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
license = {file = "../../LICENSE"}
|
||||||
|
keywords = ["codemp", "ffi", "rust", "python"]
|
||||||
|
authors = [
|
||||||
|
{email = "cschen@codemp.dev"}
|
||||||
|
]
|
||||||
|
maintainers = [
|
||||||
|
{name = "Camillo Schenone", email = "cschen@codemp.dev"}
|
||||||
|
]
|
||||||
|
classifiers = [
|
||||||
|
"Programming Language :: Python"
|
||||||
|
]
|
||||||
|
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
repository = "github.com/hexedtech/codemp.git"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["maturin>=1.0,<2.0"]
|
||||||
|
build-backend = "maturin"
|
||||||
|
|
||||||
|
[tool.maturin]
|
||||||
|
features = ["python"]
|
||||||
|
manifest-path = "../../Cargo.toml"
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
//! information about their identity
|
//! information about their identity
|
||||||
|
|
||||||
use codemp_proto as proto;
|
use codemp_proto as proto;
|
||||||
// use pyo3::prelude::*;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
/// user cursor position in a buffer
|
/// user cursor position in a buffer
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use pyo3::types::PyList;
|
use pyo3::types::{PyList, PyTuple};
|
||||||
use std::{format, sync::Arc};
|
use std::{format, sync::Arc};
|
||||||
use tokio::sync::{mpsc, Mutex, RwLock};
|
use tokio::sync::{mpsc, Mutex, RwLock};
|
||||||
use tracing;
|
use tracing;
|
||||||
|
@ -73,8 +73,8 @@ impl PyLogger {
|
||||||
// 5. Create a new buffer/attach to an existing one
|
// 5. Create a new buffer/attach to an existing one
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn codemp_init<'a>(py: Python<'a>) -> PyResult<Py<PyClient>> {
|
fn codemp_init<'a>(py: Python<'a>) -> PyResult<Py<Client>> {
|
||||||
Ok(Py::new(py, PyClient::default())?)
|
Ok(Py::new(py, Client::default())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
|
@ -108,22 +108,22 @@ fn init_logger(py: Python<'_>, debug: Option<bool>) -> PyResult<Py<PyLogger>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
struct PyClient(Arc<RwLock<Option<CodempClient>>>);
|
struct Client(Arc<RwLock<Option<CodempClient>>>);
|
||||||
|
|
||||||
impl Default for PyClient {
|
impl Default for Client {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
PyClient(Arc::new(RwLock::new(None)))
|
Client(Arc::new(RwLock::new(None)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<CodempClient> for PyClient {
|
impl From<CodempClient> for Client {
|
||||||
fn from(value: CodempClient) -> Self {
|
fn from(value: CodempClient) -> Self {
|
||||||
PyClient(RwLock::new(Some(value)).into())
|
Client(RwLock::new(Some(value)).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl PyClient {
|
impl Client {
|
||||||
fn connect<'a>(&'a self, py: Python<'a>, dest: String) -> PyResult<&'a PyAny> {
|
fn connect<'a>(&'a self, py: Python<'a>, dest: String) -> PyResult<&'a PyAny> {
|
||||||
let cli = self.0.clone();
|
let cli = self.0.clone();
|
||||||
|
|
||||||
|
@ -217,6 +217,7 @@ impl PyClient {
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl CodempWorkspace {
|
impl CodempWorkspace {
|
||||||
// join a workspace
|
// join a workspace
|
||||||
|
#[pyo3(name = "create")]
|
||||||
fn pycreate<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
fn pycreate<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
||||||
let ws = self.clone();
|
let ws = self.clone();
|
||||||
|
|
||||||
|
@ -225,7 +226,7 @@ impl CodempWorkspace {
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
#[pyo3(name = "attach")]
|
||||||
fn pyattach<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
fn pyattach<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
||||||
let ws = self.clone();
|
let ws = self.clone();
|
||||||
|
|
||||||
|
@ -235,6 +236,7 @@ impl CodempWorkspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "fetch_buffers")]
|
||||||
fn pyfetch_buffers<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
fn pyfetch_buffers<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
||||||
let ws = self.clone();
|
let ws = self.clone();
|
||||||
|
|
||||||
|
@ -244,6 +246,7 @@ impl CodempWorkspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "fetch_users")]
|
||||||
fn pyfetch_users<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
fn pyfetch_users<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
||||||
let ws = self.clone();
|
let ws = self.clone();
|
||||||
|
|
||||||
|
@ -253,6 +256,7 @@ impl CodempWorkspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "list_buffer_users")]
|
||||||
fn pylist_buffer_users<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
fn pylist_buffer_users<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
||||||
let ws = self.clone();
|
let ws = self.clone();
|
||||||
|
|
||||||
|
@ -268,6 +272,7 @@ impl CodempWorkspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "delete")]
|
||||||
fn pydelete<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
fn pydelete<'a>(&'a self, py: Python<'a>, path: String) -> PyResult<&'a PyAny> {
|
||||||
let ws = self.clone();
|
let ws = self.clone();
|
||||||
|
|
||||||
|
@ -277,14 +282,17 @@ impl CodempWorkspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "id")]
|
||||||
fn pyid(&self, py: Python<'_>) -> Py<PyString> {
|
fn pyid(&self, py: Python<'_>) -> Py<PyString> {
|
||||||
PyString::new(py, self.id().as_str()).into()
|
PyString::new(py, self.id().as_str()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "cursor")]
|
||||||
fn pycursor(&self, py: Python<'_>) -> PyResult<Py<CodempCursorController>> {
|
fn pycursor(&self, py: Python<'_>) -> PyResult<Py<CodempCursorController>> {
|
||||||
Ok(Py::new(py, CodempCursorController::from(self.cursor()))?)
|
Ok(Py::new(py, CodempCursorController::from(self.cursor()))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "buffer_by_name")]
|
||||||
fn pybuffer_by_name(
|
fn pybuffer_by_name(
|
||||||
&self,
|
&self,
|
||||||
py: Python<'_>,
|
py: Python<'_>,
|
||||||
|
@ -297,6 +305,7 @@ impl CodempWorkspace {
|
||||||
Ok(Some(Py::new(py, CodempBufferController::from(bufctl))?))
|
Ok(Some(Py::new(py, CodempBufferController::from(bufctl))?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "filetree")]
|
||||||
fn pyfiletree(&self, py: Python<'_>) -> Py<PyList> {
|
fn pyfiletree(&self, py: Python<'_>) -> Py<PyList> {
|
||||||
PyList::new(py, self.filetree()).into_py(py)
|
PyList::new(py, self.filetree()).into_py(py)
|
||||||
}
|
}
|
||||||
|
@ -306,6 +315,7 @@ impl CodempWorkspace {
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl CodempCursorController {
|
impl CodempCursorController {
|
||||||
|
#[pyo3(name = "send")]
|
||||||
fn pysend<'a>(&'a self, path: String, start: (i32, i32), end: (i32, i32)) -> PyResult<()> {
|
fn pysend<'a>(&'a self, path: String, start: (i32, i32), end: (i32, i32)) -> PyResult<()> {
|
||||||
let pos = CodempCursor {
|
let pos = CodempCursor {
|
||||||
start: start.into(),
|
start: start.into(),
|
||||||
|
@ -317,6 +327,7 @@ impl CodempCursorController {
|
||||||
Ok(self.send(pos)?)
|
Ok(self.send(pos)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "try_recv")]
|
||||||
fn pytry_recv(&self, py: Python<'_>) -> PyResult<PyObject> {
|
fn pytry_recv(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||||
match self.try_recv()? {
|
match self.try_recv()? {
|
||||||
Some(cur_event) => {
|
Some(cur_event) => {
|
||||||
|
@ -327,6 +338,7 @@ impl CodempCursorController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "recv")]
|
||||||
fn pyrecv<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
fn pyrecv<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
||||||
let rc = self.clone();
|
let rc = self.clone();
|
||||||
|
|
||||||
|
@ -336,6 +348,7 @@ impl CodempCursorController {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "poll")]
|
||||||
fn pypoll<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
fn pypoll<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
||||||
let rc = self.clone();
|
let rc = self.clone();
|
||||||
|
|
||||||
|
@ -343,12 +356,40 @@ impl CodempCursorController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl CodempCursor {
|
||||||
|
#[getter(start)]
|
||||||
|
fn pystart(&self, py: Python<'_>) -> Py<PyTuple> {
|
||||||
|
self.start.into_py(py)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter(end)]
|
||||||
|
fn pyend(&self, py: Python<'_>) -> Py<PyTuple> {
|
||||||
|
self.end.into_py(py)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter(buffer)]
|
||||||
|
fn pybuffer(&self, py: Python<'_>) -> Py<PyString> {
|
||||||
|
PyString::new(py, self.buffer.as_str()).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter(user)]
|
||||||
|
fn pyuser(&self, py: Python<'_>) -> Py<PyString> {
|
||||||
|
match self.user {
|
||||||
|
Some(user) => PyString::new(py, user.to_string().as_str()).into(),
|
||||||
|
None => "".into_py(py),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl CodempBufferController {
|
impl CodempBufferController {
|
||||||
|
#[pyo3(name = "content")]
|
||||||
fn pycontent<'a>(&self, py: Python<'a>) -> &'a PyString {
|
fn pycontent<'a>(&self, py: Python<'a>) -> &'a PyString {
|
||||||
PyString::new(py, self.content().as_str())
|
PyString::new(py, self.content().as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "send")]
|
||||||
fn pysend(&self, start: usize, end: usize, txt: String) -> PyResult<()> {
|
fn pysend(&self, start: usize, end: usize, txt: String) -> PyResult<()> {
|
||||||
let op = CodempTextChange {
|
let op = CodempTextChange {
|
||||||
span: start..end,
|
span: start..end,
|
||||||
|
@ -357,6 +398,7 @@ impl CodempBufferController {
|
||||||
Ok(self.send(op)?)
|
Ok(self.send(op)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "try_recv")]
|
||||||
fn pytry_recv(&self, py: Python<'_>) -> PyResult<PyObject> {
|
fn pytry_recv(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||||
match self.try_recv()? {
|
match self.try_recv()? {
|
||||||
Some(txt_change) => {
|
Some(txt_change) => {
|
||||||
|
@ -367,6 +409,7 @@ impl CodempBufferController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "recv")]
|
||||||
fn pyrecv<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
fn pyrecv<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
||||||
let rc = self.clone();
|
let rc = self.clone();
|
||||||
|
|
||||||
|
@ -376,6 +419,7 @@ impl CodempBufferController {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "poll")]
|
||||||
fn pypoll<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
fn pypoll<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> {
|
||||||
let rc = self.clone();
|
let rc = self.clone();
|
||||||
|
|
||||||
|
@ -386,42 +430,51 @@ impl CodempBufferController {
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl CodempTextChange {
|
impl CodempTextChange {
|
||||||
#[getter]
|
#[getter]
|
||||||
|
#[pyo3(name = "start_incl")]
|
||||||
fn pystart_incl(&self) -> PyResult<usize> {
|
fn pystart_incl(&self) -> PyResult<usize> {
|
||||||
Ok(self.span.start)
|
Ok(self.span.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
|
#[pyo3(name = "end_excl")]
|
||||||
fn pyend_excl(&self) -> PyResult<usize> {
|
fn pyend_excl(&self) -> PyResult<usize> {
|
||||||
Ok(self.span.end)
|
Ok(self.span.end)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
|
#[pyo3(name = "content")]
|
||||||
fn pycontent(&self) -> PyResult<String> {
|
fn pycontent(&self) -> PyResult<String> {
|
||||||
Ok(self.content.clone())
|
Ok(self.content.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "is_deletion")]
|
||||||
fn pyis_deletion(&self) -> bool {
|
fn pyis_deletion(&self) -> bool {
|
||||||
self.is_deletion()
|
self.is_deletion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "is_addition")]
|
||||||
fn pyis_addition(&self) -> bool {
|
fn pyis_addition(&self) -> bool {
|
||||||
self.is_addition()
|
self.is_addition()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "is_empty")]
|
||||||
fn pyis_empty(&self) -> bool {
|
fn pyis_empty(&self) -> bool {
|
||||||
self.is_empty()
|
self.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "apply")]
|
||||||
fn pyapply(&self, txt: &str) -> String {
|
fn pyapply(&self, txt: &str) -> String {
|
||||||
self.apply(txt)
|
self.apply(txt)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[classmethod]
|
#[classmethod]
|
||||||
|
#[pyo3(name = "from_diff")]
|
||||||
fn pyfrom_diff(_cls: &PyType, before: &str, after: &str) -> CodempTextChange {
|
fn pyfrom_diff(_cls: &PyType, before: &str, after: &str) -> CodempTextChange {
|
||||||
CodempTextChange::from_diff(before, after)
|
CodempTextChange::from_diff(before, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[classmethod]
|
#[classmethod]
|
||||||
|
#[pyo3(name = "index_to_rowcol")]
|
||||||
fn pyindex_to_rowcol(_cls: &PyType, txt: &str, index: usize) -> (i32, i32) {
|
fn pyindex_to_rowcol(_cls: &PyType, txt: &str, index: usize) -> (i32, i32) {
|
||||||
CodempTextChange::index_to_rowcol(txt, index).into()
|
CodempTextChange::index_to_rowcol(txt, index).into()
|
||||||
}
|
}
|
||||||
|
@ -432,13 +485,12 @@ impl CodempTextChange {
|
||||||
fn codemp(_py: Python, m: &PyModule) -> PyResult<()> {
|
fn codemp(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
m.add_function(wrap_pyfunction!(codemp_init, m)?)?;
|
m.add_function(wrap_pyfunction!(codemp_init, m)?)?;
|
||||||
m.add_function(wrap_pyfunction!(init_logger, m)?)?;
|
m.add_function(wrap_pyfunction!(init_logger, m)?)?;
|
||||||
m.add_class::<PyClient>()?;
|
m.add_class::<Client>()?;
|
||||||
m.add_class::<PyLogger>()?;
|
m.add_class::<PyLogger>()?;
|
||||||
m.add_class::<CodempWorkspace>()?;
|
m.add_class::<CodempWorkspace>()?;
|
||||||
m.add_class::<CodempCursorController>()?;
|
m.add_class::<CodempCursorController>()?;
|
||||||
m.add_class::<CodempBufferController>()?;
|
m.add_class::<CodempBufferController>()?;
|
||||||
|
|
||||||
// m.add_class::<PyId>()?;
|
|
||||||
m.add_class::<CodempCursor>()?;
|
m.add_class::<CodempCursor>()?;
|
||||||
m.add_class::<CodempTextChange>()?;
|
m.add_class::<CodempTextChange>()?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue