mirror of
https://github.com/hexedtech/codemp-vscode.git
synced 2024-11-22 15:34:49 +01:00
New features: receiving and sending cursor events
This commit is contained in:
parent
62eb461d67
commit
9e2d372e5e
4 changed files with 104 additions and 38 deletions
|
@ -10,6 +10,7 @@ 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", tag = "v0.4.5", 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"
|
||||||
uuid = { version = "1.3.1", features = ["v4"] }
|
uuid = { version = "1.3.1", features = ["v4"] }
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
// 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 * as codempp from '/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node';
|
//import * as types from 'index';
|
||||||
const codemp = require("/home/***REMOVED***/projects/codemp/mine/codempvscode/index.node");
|
//import * as codemp from '..';
|
||||||
// import * as codemp from "/home/***REMOVED***/projects/codemp/mine/vscode/target/debug/libcodemp_vscode.node";
|
//import * as codemp from '/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node';
|
||||||
|
const codemp = require("/home/***REMOVED***/projects/codemp/mine/codempvscode/codemp.node");
|
||||||
|
|
||||||
|
var CACHE : string = "";
|
||||||
|
//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
|
||||||
// Your extension is activated the very first time the command is executed
|
// Your extension is activated the very first time the command is executed
|
||||||
|
@ -35,54 +39,92 @@ async function connect() {
|
||||||
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:50051"
|
||||||
await codemp.connect(host);
|
await codemp.connect(host);
|
||||||
vscode.window.showInformationMessage(`Connected to codemp ***REMOVED*** @[${host}]`);
|
vscode.window.showInformationMessage(`Connected to codemp @[${host}]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function join() {
|
async function join() {
|
||||||
let workspace = await vscode.window.showInputBox({prompt: "workspace to attach (default to default)"})
|
let workspace = await vscode.window.showInputBox({prompt: "workspace to attach (default to default)"});
|
||||||
let buffer = await vscode.window.showInputBox({prompt: "buffer name for the file needed to update other clients cursors"})
|
let buffer : string = (await vscode.window.showInputBox({prompt: "buffer name for the file needed to update other clients cursors"}))!;
|
||||||
|
let editor = vscode.window.activeTextEditor;
|
||||||
|
//let editor = activeEditor.document.getText();
|
||||||
|
//let doc = editor?.document;
|
||||||
if (workspace === undefined) return // user cancelled with ESC
|
if (workspace === undefined) return // user cancelled with ESC
|
||||||
if (workspace.length == 0) workspace = "default"
|
if (workspace.length == 0) workspace = "default"
|
||||||
|
|
||||||
if (buffer === undefined) return // user cancelled with ESC
|
if (buffer === undefined) return // user cancelled with ESC
|
||||||
if (buffer.length == 0) workspace = "test"
|
if (buffer.length == 0) {workspace = "test"; buffer="test"; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let controller = await codemp.join(workspace)
|
let controller = await codemp.join(workspace)
|
||||||
controller.callback((event:any) => {
|
try{
|
||||||
console.log(event);
|
controller.callback(( event:any) => {
|
||||||
|
try{
|
||||||
|
//console.log(event);
|
||||||
|
let curPos = vscode.window.activeTextEditor?.selection.active;
|
||||||
|
let PosNumber = curPos?.line as number;
|
||||||
|
let posizione = new vscode.Position(0, PosNumber);
|
||||||
|
//console.log("posizione", posizione, "\n");
|
||||||
|
let range_start = new vscode.Position(event.start.row , event.start.col); // -1?
|
||||||
|
let range_end = new vscode.Position(event.end.row, event.end.col); // -1? idk if this works it's kinda funny, should test with someone with a working version of codemp
|
||||||
|
/*console.log("range_start" ,range_start, "\n");
|
||||||
|
console.log("range_end" ,range_end, "\n");*/
|
||||||
|
const decorationRange = new vscode.Range(range_start, range_end);
|
||||||
|
const smallNumberDecorationType = vscode.window.createTextEditorDecorationType({
|
||||||
|
borderWidth: '5px',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
overviewRulerColor: 'blue',
|
||||||
|
overviewRulerLane: vscode.OverviewRulerLane.Right,
|
||||||
|
light: {
|
||||||
|
// this color will be used in light color themes
|
||||||
|
borderColor: 'darkblue'
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
// this color will be used in dark color themes
|
||||||
|
borderColor: 'lightblue'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//let DECORATION = vscode.window.createTextEditorDecorationType({backgroundColor: 'red', color: 'white'});
|
||||||
|
/*console.log("Editor" ,editor, "\n");
|
||||||
|
console.log("Decoration range " , [decorationRange], "\n");*/
|
||||||
|
editor?.setDecorations(smallNumberDecorationType, [decorationRange]);
|
||||||
|
}catch(e){
|
||||||
|
console.log("Error", e, "\n");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}catch(e){
|
||||||
|
console.log("Error", e, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
vscode.window.onDidChangeTextEditorSelection((event: vscode.TextEditorSelectionChangeEvent)=>{
|
vscode.window.onDidChangeTextEditorSelection((event: vscode.TextEditorSelectionChangeEvent)=>{
|
||||||
if(event.kind==1 || event.kind ==2){
|
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!!
|
||||||
//let anchor = [selection.anchor.line+1, selection.anchor.character]
|
//let anchor = [selection.anchor.line+1, selection.anchor.character]
|
||||||
//let position = [selection.active.line+1, selection.active.character+1]
|
//let position = [selection.active.line+1, selection.active.character+1]
|
||||||
let anchor = [selection.anchor.line, selection.anchor.character]
|
let anchor : [number, number] = [selection.anchor.line, selection.anchor.character];
|
||||||
let position = [selection.active.line, selection.active.character+1]
|
let position : [number, number] = [selection.active.line, selection.active.character+1];
|
||||||
console.log("Buffer from selection" + buffer+"\n");
|
/*console.log("Buffer from selection" + buffer+"\n");
|
||||||
console.log("selection " + selection+"\n");
|
console.log("selection " + selection+"\n");
|
||||||
console.log("Anchor selection" + anchor+"\n");
|
console.log("Anchor selection" + anchor+"\n");
|
||||||
console.log("position selection" + position+"\n");
|
console.log("position selection" + position+"\n");*/
|
||||||
controller.send(buffer, anchor, position);
|
controller.send(buffer, anchor, position);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
vscode.window.showInformationMessage(`Connected to workspace @[${workspace}]`);
|
vscode.window.showInformationMessage(`Connected to workspace @[${workspace}]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*async function attach() {
|
|
||||||
let workspace = await vscode.window.showInputBox({prompt: "workspace to attach (default to default)"})
|
|
||||||
if (workspace === undefined) return // user cancelled with ESC
|
|
||||||
if (workspace.length == 0) workspace = "default"
|
|
||||||
await codemp.attach(workspace);
|
|
||||||
vscode.window.showInformationMessage(`Connected to codemp ***REMOVED*** @[${workspace}]`);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This method is called when your extension is deactivated
|
// This method is called when your extension is deactivated
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use futures::prelude::*;
|
|
||||||
use codemp::{
|
use codemp::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
proto::{RowCol, CursorEvent},
|
proto::{RowCol, CursorEvent},
|
||||||
buffer::factory::OperationFactory, ot::OperationSeq
|
buffer::factory::OperationFactory, ot::OperationSeq
|
||||||
};
|
};
|
||||||
use napi_derive::napi;
|
use napi_derive::napi;
|
||||||
use napi::{CallContext, Status, threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode, ErrorStrategy::{CalleeHandled, Fatal}, ThreadsafeFunction}};
|
use napi::{Status, threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode, ErrorStrategy::Fatal, ThreadsafeFunction}, JsBoolean};
|
||||||
use napi::tokio::{self, fs};
|
use napi::tokio;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct JsCodempError(CodempError);
|
struct JsCodempError(CodempError);
|
||||||
|
|
||||||
|
@ -18,18 +15,16 @@ struct JsCodempError(CodempError);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl From::<JsCodempError> for napi::Error {
|
impl From::<JsCodempError> for napi::Error {
|
||||||
fn from(value: JsCodempError) -> Self {
|
fn from(value: JsCodempError) -> Self {
|
||||||
napi::Error::new(Status::GenericFailure, &format!("CodempError: {:?}", value))
|
napi::Error::new(Status::GenericFailure, &format!("CodempError: {:?}", value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub async fn connect(addr: String) -> napi::Result<()> {
|
pub async fn connect(addr: String) -> napi::Result<()> {
|
||||||
let f = std::fs::File::create("/home/***REMOVED***/projects/codemp/mine/vscode/***REMOVED***.txt").unwrap();
|
let f = std::fs::File::create("/home/***REMOVED***/projects/codemp/mine/codempvscode/***REMOVED***.txt").unwrap();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_ansi(false)
|
.with_ansi(false)
|
||||||
.with_max_level(tracing::Level::INFO)
|
.with_max_level(tracing::Level::INFO)
|
||||||
|
@ -157,11 +152,11 @@ impl From::<RowCol> for JsRowCol {
|
||||||
/// BUFFER
|
/// BUFFER
|
||||||
#[napi(object)]
|
#[napi(object)]
|
||||||
pub struct JsTextChange {
|
pub struct JsTextChange {
|
||||||
pub span: JSRange,
|
pub span: JsRange,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
#[napi(object)]
|
#[napi(object)]
|
||||||
pub struct JSRange{
|
pub struct JsRange{
|
||||||
pub start: i32,
|
pub start: i32,
|
||||||
pub end: Option<i32>,
|
pub end: Option<i32>,
|
||||||
}
|
}
|
||||||
|
@ -170,7 +165,7 @@ 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: Some(value.span.end as i32) },
|
||||||
content: value.content,
|
content: value.content,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,16 +192,44 @@ pub struct JsBufferController(Arc<CodempBufferController>);
|
||||||
pub struct JsCodempOperationSeq(CodempOperationSeq);
|
pub struct JsCodempOperationSeq(CodempOperationSeq);
|
||||||
|
|
||||||
|
|
||||||
|
/*#[napi]
|
||||||
|
pub fn delta(string : String, start: i64, txt: String, end: i64 ) -> Option<JsCodempOperationSeq> {
|
||||||
|
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]
|
#[napi]
|
||||||
pub fn delta(&self, start: i64, txt: String, end: i64) -> Option<JsCodempOperationSeq> {
|
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())
|
self.0.delta(start as usize, &txt, end as usize).map(|x| x.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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!!!
|
||||||
|
let tsfn : ThreadsafeFunction<CodempTextChange, Fatal> =
|
||||||
|
fun.create_threadsafe_function(0,
|
||||||
|
|ctx : ThreadSafeCallContext<CodempTextChange>| {
|
||||||
|
Ok(vec![JsTextChange::from(ctx.value)])
|
||||||
|
}
|
||||||
|
)?;
|
||||||
|
let _controller = self.0.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
let event = _controller.recv().await.expect("could not receive buffer event!");
|
||||||
|
tsfn.call(event, ThreadsafeFunctionCallMode::NonBlocking); //check this shit with tracing also we could use Ok(event) to get the error
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
pub async fn recv(&self) -> napi::Result<JsTextChange> {
|
pub async fn recv(&self) -> napi::Result<JsTextChange> {
|
||||||
Ok(
|
Ok(
|
||||||
|
@ -238,3 +261,4 @@ pub async fn attach(path: String) -> napi::Result<JsBufferController> {
|
||||||
.into()
|
.into()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,5 +14,4 @@
|
||||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||||
},
|
},
|
||||||
"exclude": ["index.d.ts"]
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue