1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! `xrl` is a Tokio based library to build clients for the Xi editor. The
//! challenge with Xi RPC is that endpoints are both client (sending
//! requests/notifications) and server (handling incoming
//! requests/notifications).
//!
//!
//! ```rust
//!
//! #![allow(unused_variables)]
//! extern crate futures;
//! extern crate tokio;
//! extern crate xrl;
//!
//! use futures::{future, Future, Stream};
//! use xrl::*;
//!
//!
//! // Type that represent our client
//! struct MyFrontend {
//!     client: Client,
//! }
//!
//! // Implement how our client handles notifications & requests from the core.
//! impl Frontend for MyFrontend {
//!
//!     fn handle_notification(&mut self, notification: XiNotification) -> ServerResult<()> {
//!         use XiNotification::*;
//!         match notification {
//!             Update(update) => println!("received `update` from Xi core:\n{:?}", update),
//!             ScrollTo(scroll) => println!("received `scroll_to` from Xi core:\n{:?}", scroll),
//!             DefStyle(style) => println!("received `def_style` from Xi core:\n{:?}", style),
//!             AvailablePlugins(plugins) => println!("received `available_plugins` from Xi core:\n{:?}", plugins),
//!             UpdateCmds(cmds) => println!("received `update_cmds` from Xi core:\n{:?}", cmds),
//!             PluginStarted(plugin) => println!("received `plugin_started` from Xi core:\n{:?}", plugin),
//!             PluginStoped(plugin) => println!("received `plugin_stoped` from Xi core:\n{:?}", plugin),
//!             ConfigChanged(config) => println!("received `config_changed` from Xi core:\n{:?}", config),
//!             ThemeChanged(theme) => println!("received `theme_changed` from Xi core:\n{:?}", theme),
//!             Alert(alert) => println!("received `alert` from Xi core:\n{:?}", alert),
//!             AvailableThemes(themes) => println!("received `available_themes` from Xi core:\n{:?}", themes),
//!             FindStatus(status) => println!("received `find_status` from Xi core:\n{:?}", status),
//!             ReplaceStatus(status) => println!("received `replace_status` from Xi core:\n{:?}", status),
//!             AvailableLanguages(langs) => println!("received `available_languages` from Xi core:\n{:?}", langs), 
//!             LanguageChanged(lang) => println!("received `language_changed` from Xi core:\n{:?}", lang),
//!         }
//!         Box::new(future::ok(()))
//!     }
//!
//!     fn handle_measure_width(&mut self, request: MeasureWidth) -> ServerResult<Vec<Vec<f32>>> {
//!         Box::new(future::ok(Vec::new()))
//!     }
//! }
//!
//! struct MyFrontendBuilder;
//!
//! impl FrontendBuilder<MyFrontend> for MyFrontendBuilder {
//!     fn build(self, client: Client) -> MyFrontend {
//!         MyFrontend { client: client }
//!     }
//! }
//!
//! fn main() {
//!
//!     // spawn Xi core
//!     let (mut client, core_stderr) = spawn("xi-core", MyFrontendBuilder {});
//!
//!     // All clients must send client_started notification first
//!     tokio::run(client.client_started(None, None).map_err(|_|()));
//!     // start logging Xi core's stderr
//!     let log_core_errors = core_stderr
//!         .for_each(|msg| {
//!             println!("xi-core stderr: {}", msg);
//!             Ok(())
//!         })
//!         .map_err(|_| ());
//!
//!     ::std::thread::spawn(move || {
//!         tokio::run(log_core_errors);
//!     });
//!
//!     // Send a request to open a new view, and print the result
//!     let open_new_view = client
//!         .new_view(None)
//!         .map(|view_name| println!("opened new view: {}", view_name));
//!     tokio::run(open_new_view.map_err(|_| ()));
//! }
//! ```

#![deny(clippy::all)]
#![allow(clippy::type_complexity)]

#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;


mod protocol;
mod client;
mod errors;
mod structs;
mod frontend;
mod core;
mod cache;

pub use crate::cache::LineCache;
pub use crate::frontend::{XiNotification, Frontend, FrontendBuilder, ServerResult};
pub use crate::client::{Client, ClientResult};
pub use crate::errors::{ClientError, ServerError};
pub use crate::core::{spawn, CoreStderr};
pub use crate::structs::{
    AvailablePlugins, PluginStarted, PluginStoped, ThemeChanged,
    ThemeSettings, Query, Status, Alert, AvailableThemes, AvailableLanguages,
    UpdateCmds, ConfigChanged, ConfigChanges, ScrollTo, Position,
    Update, Style, Operation, OperationType, Line, StyleDef, LanguageChanged,
    ViewId, ModifySelection, FindStatus, ReplaceStatus, MeasureWidth,
};