diff --git a/.gitignore b/.gitignore index 11b3a99..5a6fc9f 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ dist/java/bin/ dist/java/gradle/ dist/java/gradlew dist/java/gradlew.bat +dist/java/.factorypath diff --git a/dist/java/src/mp/code/Extensions.java b/dist/java/src/mp/code/Extensions.java index 93e141a..ff4a1b7 100644 --- a/dist/java/src/mp/code/Extensions.java +++ b/dist/java/src/mp/code/Extensions.java @@ -12,7 +12,13 @@ public final class Extensions { static final Cleaner CLEANER = Cleaner.create(); /** - * Hashes the given {@link String} using CodeMP's hashing algorithm (xxh3). + * Returns the version of the Rust crate as a String. + * @return the current version + */ + public static native String version(); + + /** + * Hashes the given String using CodeMP's hashing algorithm (xxh3). * @param input the string to hash * @return the hash */ diff --git a/dist/java/src/mp/code/Workspace.java b/dist/java/src/mp/code/Workspace.java index 33f2de3..62a6e49 100644 --- a/dist/java/src/mp/code/Workspace.java +++ b/dist/java/src/mp/code/Workspace.java @@ -80,6 +80,16 @@ public final class Workspace { return active_buffers(this.ptr); } + private static native String[] user_list(long self); + + /** + * Returns the users currently in the workspace. + * @return an array containing the names of the users in the workspace + */ + public String[] userList() { + return user_list(this.ptr); + } + private static native void create_buffer(long self, String path) throws ConnectionRemoteException; /** diff --git a/dist/lua/annotations.lua b/dist/lua/annotations.lua index 0e9ee31..9cce3a8 100644 --- a/dist/lua/annotations.lua +++ b/dist/lua/annotations.lua @@ -222,7 +222,7 @@ function Workspace:get_buffer(path) end function Workspace:attach(path) end ---@param path string relative path ("name") of buffer to detach from ----@return boolean +---@return boolean success ---detach from an active buffer, closing all streams. returns false if buffer was no longer active function Workspace:detach(path) end @@ -297,7 +297,7 @@ function BufferController:recv() end ---block until next text change without returning it function BufferController:poll() end ----@return boolean +---@return boolean success ---stop buffer worker and disconnect, returns false if was already stopped function BufferController:stop() end @@ -354,7 +354,7 @@ function CursorController:recv() end ---block until next cursor event without returning it function CursorController:poll() end ----@return boolean +---@return boolean success ---stop cursor worker and disconnect, returns false if was already stopped function CursorController:stop() end @@ -396,6 +396,10 @@ function Codemp.poll_callback() end ---use xxh3 hash, returns an i64 from any string function Codemp.hash(data) end +---@return string +---get current library version as string, in semver format +function Codemp.version() end + ---@class (exact) RuntimeDriver local RuntimeDriver = {} @@ -411,6 +415,6 @@ function Codemp.setup_driver(block) end ---@param printer? string | fun(string) | nil log sink used for printing, if string will go to file, otherwise use given function ---@param debug? boolean show more verbose debug logs, default false ----@return boolean true if logger was setup correctly, false otherwise +---@return boolean success if logger was setup correctly, false otherwise ---setup a global logger for codemp, note that can only be done once function Codemp.setup_tracing(printer, debug) end diff --git a/dist/lua/codemp-0.7.0-1.rockspec b/dist/lua/codemp-0.7.0-1.rockspec index 7e10e79..db2ce77 100644 --- a/dist/lua/codemp-0.7.0-1.rockspec +++ b/dist/lua/codemp-0.7.0-1.rockspec @@ -31,6 +31,6 @@ build = { modules = { "codemp" }, target_path = "../..", include = { - ["codemp-annotations.lua"] = "dist/lua/annotations.lua", + ["dist/lua/annotations.lua"] = "codemp-annotations.lua", } } diff --git a/src/ffi/java/ext.rs b/src/ffi/java/ext.rs index e509b64..2729e97 100644 --- a/src/ffi/java/ext.rs +++ b/src/ffi/java/ext.rs @@ -1,5 +1,12 @@ use jni_toolbox::jni; +/// Gets the current version of the Rust crate. +#[allow(non_snake_case)] +#[jni(package = "mp.code", class = "Extensions")] +fn version() -> String { + crate::version() +} + /// Calculate the XXH3 hash for a given String. #[jni(package = "mp.code", class = "Extensions")] fn hash(content: String) -> i64 { diff --git a/src/ffi/java/workspace.rs b/src/ffi/java/workspace.rs index 06d8df4..5732397 100644 --- a/src/ffi/java/workspace.rs +++ b/src/ffi/java/workspace.rs @@ -31,6 +31,12 @@ fn active_buffers(workspace: &mut Workspace) -> Vec { workspace.buffer_list() } +/// Gets a list of the active buffers. +#[jni(package = "mp.code", class = "Workspace")] +fn user_list(workspace: &mut Workspace) -> Vec { + workspace.user_list() +} + /// Create a new buffer. #[jni(package = "mp.code", class = "Workspace")] fn create_buffer(workspace: &mut Workspace, path: String) -> Result<(), RemoteError> { diff --git a/src/ffi/js/ext.rs b/src/ffi/js/ext.rs index 56d8789..a9a94d6 100644 --- a/src/ffi/js/ext.rs +++ b/src/ffi/js/ext.rs @@ -1,8 +1,12 @@ use napi_derive::napi; -use crate::ext::hash; #[napi(js_name = "hash")] pub fn js_hash(str : String) -> napi::Result{ - Ok(hash(str)) + Ok(crate::ext::hash(str)) } + +#[napi(js_name = "version")] +pub fn js_version(str : String) -> napi::Result{ + Ok(crate::version()) +} \ No newline at end of file diff --git a/src/ffi/lua/mod.rs b/src/ffi/lua/mod.rs index d170915..f6d0788 100644 --- a/src/ffi/lua/mod.rs +++ b/src/ffi/lua/mod.rs @@ -27,6 +27,10 @@ fn entrypoint(lua: &Lua) -> LuaResult { Ok(crate::ext::hash(txt)) )?)?; + exports.set("version", lua.create_function(|_, ()| + Ok(crate::version()) + )?)?; + // runtime exports.set("setup_driver", lua.create_function(ext::a_sync::setup_driver)?)?; exports.set("poll_callback", lua.create_function(|lua, ()| { diff --git a/src/ffi/python/mod.rs b/src/ffi/python/mod.rs index d1c7105..0956b8b 100644 --- a/src/ffi/python/mod.rs +++ b/src/ffi/python/mod.rs @@ -132,6 +132,11 @@ impl Driver { } } +#[pyfunction] +fn version() -> String { + crate::version() +} + #[pyfunction] fn init() -> PyResult { let (rt_stop_tx, mut rt_stop_rx) = oneshot::channel::<()>(); @@ -257,6 +262,7 @@ impl IntoPy for crate::api::User { #[pymodule] fn codemp(m: &Bound<'_, PyModule>) -> PyResult<()> { + m.add_function(wrap_pyfunction!(version, m)?)?; m.add_function(wrap_pyfunction!(init, m)?)?; m.add_function(wrap_pyfunction!(get_default_config, m)?)?; m.add_function(wrap_pyfunction!(connect, m)?)?; diff --git a/src/lib.rs b/src/lib.rs index c60ac2f..f9172e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ //! The library also provides ready-to-use bindings in a growing number of other programming languages, //! to support a potentially infinite number of editors. //! -//! # Overview +//! # Overview //! The main entrypoint is [`Client::connect`], which establishes an authenticated connection with //! a supported remote server and returns a [`Client`] handle to interact with it. //! @@ -75,7 +75,7 @@ //! # }; //! ``` //! -//! ## FFI +//! ## FFI //! As mentioned, we provide bindings in various programming languages. To obtain them, you can //! compile with the appropriate feature flag. Currently, the following are supported: //! * `lua` @@ -121,3 +121,8 @@ pub mod ffi; /// internal network services and interceptors pub(crate) mod network; + +/// Get the current version of the client +pub fn version() -> String { + env!("CARGO_PKG_VERSION").to_owned() +}