mirror of
https://github.com/hexedtech/codemp-vscode.git
synced 2024-11-22 15:34:49 +01:00
slotted WOOT in, kind of works
This commit is contained in:
parent
00e29ee975
commit
aca8d31e1e
3 changed files with 56 additions and 53 deletions
|
@ -9,7 +9,7 @@ crate-type = ["cdylib"]
|
||||||
path = "src/rust/lib.rs"
|
path = "src/rust/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codemp = { git = "ssh://git@github.com/codewithotherpeopleandchangenamelater/codemp.git", tag = "v0.4.5", features = ["global"] }
|
codemp = { git = "ssh://git@github.com/codewithotherpeopleandchangenamelater/codemp.git", rev = "7fc03e3fd936240fdbadd368bfce38832ce34767", features = ["global"] }
|
||||||
#codemp = { git = "ssh://git@github.com/codewithotherpeopleandchangenamelater/codemp.git", features = ["global"] }
|
#codemp = { git = "ssh://git@github.com/codewithotherpeopleandchangenamelater/codemp.git", features = ["global"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3.17"
|
tracing-subscriber = "0.3.17"
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
// The module 'vscode' contains the VS Code extensibility API
|
// The module 'vscode' contains the VS Code extensibility API
|
||||||
// Import the module and reference it with the alias vscode in your code below
|
// Import the module and reference it with the alias vscode in your code below
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
import { JsTextChange } from '..';
|
||||||
//import * as types from 'index';
|
//import * as types from 'index';
|
||||||
//import * as codemp from '..';
|
//import * as codemp from '..';
|
||||||
//import * as codemp from '/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node';
|
//import * as codemp from '/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node';
|
||||||
const codemp = require("/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node");
|
const codemp = require("/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node");
|
||||||
|
|
||||||
var CACHE : string = "";
|
var CACHE : string = "";
|
||||||
|
let smallNumberDecorationType = vscode.window.createTextEditorDecorationType({});
|
||||||
//import * as codemp from "/home/***REMOVED***/projects/codemp/mine/vscode/target/debug/libcodemp_vscode.node";
|
//import * as codemp from "/home/***REMOVED***/projects/codemp/mine/vscode/target/debug/libcodemp_vscode.node";
|
||||||
|
|
||||||
// This method is called when your extension is activated
|
// This method is called when your extension is activated
|
||||||
|
@ -41,9 +43,9 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
|
|
||||||
|
|
||||||
async function connect() {
|
async function connect() {
|
||||||
let host = await vscode.window.showInputBox({prompt: "server host (default to http://alemi.dev:50051)"})
|
let host = await vscode.window.showInputBox({prompt: "server host (default to http://alemi.dev:50052)"})
|
||||||
if (host === undefined) return // user cancelled with ESC
|
if (host === undefined) return // user cancelled with ESC
|
||||||
if (host.length == 0) host = "http://alemi.dev:50051"
|
if (host.length == 0) host = "http://alemi.dev:50052"
|
||||||
await codemp.connect(host);
|
await codemp.connect(host);
|
||||||
vscode.window.showInformationMessage(`Connected to codemp @[${host}]`);
|
vscode.window.showInformationMessage(`Connected to codemp @[${host}]`);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +77,8 @@ async function join() {
|
||||||
/*console.log("range_start" ,range_start, "\n");
|
/*console.log("range_start" ,range_start, "\n");
|
||||||
console.log("range_end" ,range_end, "\n");*/
|
console.log("range_end" ,range_end, "\n");*/
|
||||||
const decorationRange = new vscode.Range(range_start, range_end);
|
const decorationRange = new vscode.Range(range_start, range_end);
|
||||||
const smallNumberDecorationType = vscode.window.createTextEditorDecorationType({ //should remove the highlighted text after a while
|
smallNumberDecorationType.dispose();
|
||||||
|
smallNumberDecorationType = vscode.window.createTextEditorDecorationType({ //should remove the highlighted text after a while
|
||||||
borderWidth: '5px',
|
borderWidth: '5px',
|
||||||
borderStyle: 'solid',
|
borderStyle: 'solid',
|
||||||
overviewRulerColor: 'blue',
|
overviewRulerColor: 'blue',
|
||||||
|
@ -102,7 +105,7 @@ async function join() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vscode.window.onDidChangeTextEditorSelection((event: vscode.TextEditorSelectionChangeEvent)=>{
|
vscode.window.onDidChangeTextEditorSelection((event: vscode.TextEditorSelectionChangeEvent) => {
|
||||||
if (event.kind == vscode.TextEditorSelectionChangeKind.Command) return; // TODO commands might move cursor too
|
if (event.kind == vscode.TextEditorSelectionChangeKind.Command) return; // TODO commands might move cursor too
|
||||||
let buf = event.textEditor.document.uri.toString()
|
let buf = event.textEditor.document.uri.toString()
|
||||||
let selection = event.selections[0] // TODO there may be more than one cursor!!
|
let selection = event.selections[0] // TODO there may be more than one cursor!!
|
||||||
|
@ -120,7 +123,7 @@ async function join() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function createBuffer(){
|
async function createBuffer() {
|
||||||
let workspace="test";//ask which workspace
|
let workspace="test";//ask which workspace
|
||||||
let buffer : any = (await vscode.window.showInputBox({prompt: "path of the buffer to create"}))!;
|
let buffer : any = (await vscode.window.showInputBox({prompt: "path of the buffer to create"}))!;
|
||||||
console.log("new buffer created ", buffer, "\n");
|
console.log("new buffer created ", buffer, "\n");
|
||||||
|
@ -151,26 +154,27 @@ async function attach() {
|
||||||
|
|
||||||
if (editor === undefined) { return } // TODO say something!!!!!!
|
if (editor === undefined) { return } // TODO say something!!!!!!
|
||||||
|
|
||||||
let range = new vscode.Range(
|
|
||||||
editor.document.positionAt(0),
|
|
||||||
editor.document.positionAt(editor.document.getText().length)
|
|
||||||
)
|
|
||||||
await editor.edit(editBuilder => editBuilder.replace(range, buffer.content()))
|
|
||||||
|
|
||||||
console.log("Buffer = ", buffer, "\n");
|
console.log("Buffer = ", buffer, "\n");
|
||||||
vscode.window.showInformationMessage(`Connected to codemp workspace buffer @[${workspace}]`);
|
vscode.window.showInformationMessage(`Connected to codemp workspace buffer @[${workspace}]`);
|
||||||
|
|
||||||
vscode.workspace.onDidChangeTextDocument((event:vscode.TextDocumentChangeEvent) =>{
|
vscode.workspace.onDidChangeTextDocument((event:vscode.TextDocumentChangeEvent) => {
|
||||||
console.log(event.reason);
|
console.log(event.reason);
|
||||||
for (let change of event.contentChanges) {
|
for (let change of event.contentChanges) {
|
||||||
if (`${change.rangeOffset}${change.text}${change.rangeOffset+change.rangeLength}` === CACHE) continue;
|
if (`${change.rangeOffset}${change.text}${change.rangeOffset+change.rangeLength}` === CACHE) continue; // LMAO
|
||||||
let op = buffer.delta(change.rangeOffset,change.text,change.rangeOffset+change.rangeLength)
|
buffer.send({
|
||||||
if (op != null) { buffer.send(op) }
|
span: {
|
||||||
else { console.log("change is empty") }
|
start: change.rangeOffset,
|
||||||
|
end: change.rangeOffset+change.rangeLength
|
||||||
|
},
|
||||||
|
content: change.text
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
buffer.callback((event:any) =>{
|
//await new Promise((resolve) => setTimeout(resolve, 200)); // tonioware
|
||||||
|
console.log("test");
|
||||||
|
|
||||||
|
buffer.callback((event: any) => {
|
||||||
CACHE = `${event.span.start}${event.content}${event.span.end}`; //what's the difference between e.text and e.content like it's on lib.rs?
|
CACHE = `${event.span.start}${event.content}${event.span.end}`; //what's the difference between e.text and e.content like it's on lib.rs?
|
||||||
|
|
||||||
if (editor === undefined) { return } // TODO say something!!!!!!
|
if (editor === undefined) { return } // TODO say something!!!!!!
|
||||||
|
@ -182,7 +186,7 @@ async function attach() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function disconnectBuffer(){
|
async function disconnectBuffer() {
|
||||||
let buffer : string = (await vscode.window.showInputBox({prompt: "buffer name for the file to disconnect from"}))!;
|
let buffer : string = (await vscode.window.showInputBox({prompt: "buffer name for the file to disconnect from"}))!;
|
||||||
codemp.disconnect(buffer);
|
codemp.disconnect(buffer);
|
||||||
vscode.window.showInformationMessage(`Disconnected from codemp workspace buffer @[${buffer}]`);
|
vscode.window.showInformationMessage(`Disconnected from codemp workspace buffer @[${buffer}]`);
|
||||||
|
@ -197,3 +201,4 @@ async function disconnectBuffer(){
|
||||||
export function deactivate() {
|
export function deactivate() {
|
||||||
//Maybe i should disconnect from every workspace and buffer ??? // TODO
|
//Maybe i should disconnect from every workspace and buffer ??? // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,9 @@ use std::sync::Arc;
|
||||||
use codemp::{
|
use codemp::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
proto::{RowCol, CursorEvent},
|
proto::{RowCol, CursorEvent},
|
||||||
buffer::factory::OperationFactory, ot::OperationSeq
|
|
||||||
};
|
};
|
||||||
use napi_derive::napi;
|
use napi_derive::napi;
|
||||||
use napi::{Status, threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode, ErrorStrategy::Fatal, ThreadsafeFunction}, JsBoolean};
|
use napi::{Status, threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode, ErrorStrategy::Fatal, ThreadsafeFunction}};
|
||||||
use napi::tokio;
|
use napi::tokio;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct JsCodempError(CodempError);
|
struct JsCodempError(CodempError);
|
||||||
|
@ -76,7 +75,7 @@ impl JsCursorController {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
#[napi(ts_args_type = "fun: (event: JsCursorEvent) => void")]
|
#[napi(ts_args_type = "fun: (event: JsCursorEvent) => void")]
|
||||||
pub fn callback(&self, fun: napi::JsFunction) -> napi::Result<()>{ //TODO it sucks but v0.5 will improve it!!!
|
pub fn callback(&self, fun: napi::JsFunction) -> napi::Result<()>{
|
||||||
let tsfn : ThreadsafeFunction<CodempCursorEvent, Fatal> =
|
let tsfn : ThreadsafeFunction<CodempCursorEvent, Fatal> =
|
||||||
fun.create_threadsafe_function(0,
|
fun.create_threadsafe_function(0,
|
||||||
|ctx : ThreadSafeCallContext<CodempCursorEvent>| {
|
|ctx : ThreadSafeCallContext<CodempCursorEvent>| {
|
||||||
|
@ -86,8 +85,13 @@ impl JsCursorController {
|
||||||
let _controller = self.0.clone();
|
let _controller = self.0.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let event = _controller.recv().await.expect("could not receive cursor event!");
|
match _controller.recv().await {
|
||||||
|
Ok(event) => {
|
||||||
tsfn.call(event.clone(), ThreadsafeFunctionCallMode::NonBlocking); //check this shit with tracing also we could use Ok(event) to get the error
|
tsfn.call(event.clone(), ThreadsafeFunctionCallMode::NonBlocking); //check this shit with tracing also we could use Ok(event) to get the error
|
||||||
|
},
|
||||||
|
Err(CodempError::Deadlocked) => continue,
|
||||||
|
Err(e) => break tracing::warn!("error receiving: {}", e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -169,25 +173,19 @@ pub struct JsTextChange {
|
||||||
#[napi(object)]
|
#[napi(object)]
|
||||||
pub struct JsRange{
|
pub struct JsRange{
|
||||||
pub start: i32,
|
pub start: i32,
|
||||||
pub end: Option<i32>,
|
pub end: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From::<CodempTextChange> for JsTextChange {
|
impl From::<CodempTextChange> for JsTextChange {
|
||||||
fn from(value: CodempTextChange) -> Self {
|
fn from(value: CodempTextChange) -> Self {
|
||||||
JsTextChange {
|
JsTextChange {
|
||||||
// TODO how is x.. represented ? span.end can never be None
|
// TODO how is x.. represented ? span.end can never be None
|
||||||
span: JsRange { start: value.span.start as i32, end: Some(value.span.end as i32) },
|
span: JsRange { start: value.span.start as i32, end: value.span.end as i32 },
|
||||||
content: value.content,
|
content: value.content,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From::<OperationSeq> for JsCodempOperationSeq{
|
|
||||||
fn from(value: OperationSeq) -> Self {
|
|
||||||
JsCodempOperationSeq(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl From::<Arc<CodempBufferController>> for JsBufferController {
|
impl From::<Arc<CodempBufferController>> for JsBufferController {
|
||||||
fn from(value: Arc<CodempBufferController>) -> Self {
|
fn from(value: Arc<CodempBufferController>) -> Self {
|
||||||
|
@ -199,34 +197,23 @@ impl From::<Arc<CodempBufferController>> for JsBufferController {
|
||||||
#[napi]
|
#[napi]
|
||||||
pub struct JsBufferController(Arc<CodempBufferController>);
|
pub struct JsBufferController(Arc<CodempBufferController>);
|
||||||
|
|
||||||
#[napi(js_name = "CodempOperationSeq")]
|
|
||||||
pub struct JsCodempOperationSeq(CodempOperationSeq);
|
|
||||||
|
|
||||||
|
|
||||||
/*#[napi]
|
/*#[napi]
|
||||||
pub fn delta(string : String, start: i64, txt: String, end: i64 ) -> Option<JsCodempOperationSeq> {
|
pub fn delta(string : String, start: i64, txt: String, end: i64 ) -> Option<JsCodempOperationSeq> {
|
||||||
Some(JsCodempOperationSeq(string.diff(start as usize, &txt, end as usize)?))
|
Some(JsCodempOperationSeq(string.diff(start as usize, &txt, end as usize)?))
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
impl JsBufferController {
|
impl JsBufferController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn content(&self) -> String{
|
|
||||||
self.0.content()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn delta(&self, start: i64, txt: String, end: i64) -> Option<JsCodempOperationSeq> {
|
|
||||||
self.0.delta(start as usize, &txt, end as usize).map(|x| x.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi(ts_args_type = "fun: (event: JsTextChange) => void")]
|
#[napi(ts_args_type = "fun: (event: JsTextChange) => void")]
|
||||||
pub fn callback(&self, fun: napi::JsFunction) -> napi::Result<()>{ //TODO it sucks but v0.5 will improve it!!!
|
pub fn callback(&self, fun: napi::JsFunction) -> napi::Result<()>{
|
||||||
let tsfn : ThreadsafeFunction<CodempTextChange, Fatal> =
|
let tsfn : ThreadsafeFunction<CodempTextChange, Fatal> =
|
||||||
fun.create_threadsafe_function(0,
|
fun.create_threadsafe_function(0,
|
||||||
|ctx : ThreadSafeCallContext<CodempTextChange>| {
|
|ctx : ThreadSafeCallContext<CodempTextChange>| {
|
||||||
|
@ -235,14 +222,21 @@ impl JsBufferController {
|
||||||
)?;
|
)?;
|
||||||
let _controller = self.0.clone();
|
let _controller = self.0.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
|
||||||
loop {
|
loop {
|
||||||
let event = _controller.recv().await.expect("could not receive buffer event!");
|
match _controller.recv().await {
|
||||||
tsfn.call(event, ThreadsafeFunctionCallMode::NonBlocking); //check this shit with tracing also we could use Ok(event) to get the error
|
Ok(event) => {
|
||||||
|
tsfn.call(event.clone(), ThreadsafeFunctionCallMode::NonBlocking); //check this shit with tracing also we could use Ok(event) to get the error
|
||||||
|
},
|
||||||
|
Err(CodempError::Deadlocked) => continue,
|
||||||
|
Err(e) => break tracing::warn!("error receiving: {}", e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub async fn recv(&self) -> napi::Result<JsTextChange> {
|
pub async fn recv(&self) -> napi::Result<JsTextChange> {
|
||||||
Ok(
|
Ok(
|
||||||
|
@ -253,9 +247,13 @@ impl JsBufferController {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn send(&self, op: &JsCodempOperationSeq) -> napi::Result<()> {
|
pub fn send(&self, op: JsTextChange) -> napi::Result<()> {
|
||||||
// TODO might be nice to take ownership of the opseq
|
// TODO might be nice to take ownership of the opseq
|
||||||
self.0.send(op.0.clone())
|
let new_text_change = CodempTextChange {
|
||||||
|
span: op.span.start as usize .. op.span.end as usize,
|
||||||
|
content: op.content,
|
||||||
|
};
|
||||||
|
self.0.send(new_text_change)
|
||||||
.map_err(|e| napi::Error::from(JsCodempError(e)))
|
.map_err(|e| napi::Error::from(JsCodempError(e)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue