Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[workspace]
members = ["held_core", "test/test_render_plugin"]

[features]
dragonos = []

Expand All @@ -26,3 +29,20 @@ serde_yaml = "0.9"

# 定义标志位
bitflags = "2.4.2"

walkdir = "2.5.0"

held_core = { path = "./held_core" }
unicode-segmentation = "1.12.0"
syntect = "5.2.0"
error-chain = "0.12.4"
yaml-rust = "0.4.5"
app_dirs2 = "2.5.5"
linked-hash-map = "0.5.6"
strum = { version = "^0.26.3", features = ["std","derive"] }
smallvec = "1.13.2"
dlopen2 = "0.7.0"

[build-dependencies]
regex = "1.10"

73 changes: 73 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::{
env,
fs::{read_dir, read_to_string, File},
io::Write,
path::PathBuf,
};

use regex::Regex;

const COMMAND_REGEX: &str = r"pub fn (.*)\(app: &mut Application\) -> Result<\(\)>";

fn main() {
generate_handler();
}

fn generate_handler() {
let out_dir = env::var("OUT_DIR").unwrap();
let out_file_pathbuf = PathBuf::new().join(out_dir).join("handle_map");

let mut out_file = File::create(out_file_pathbuf).unwrap();
out_file
.write(
r"{
let mut handles: HashMap<&'static str, fn(&mut Application) -> Result<()>> = HashMap::new();
"
.as_bytes(),
)
.unwrap();

let expression = Regex::new(COMMAND_REGEX).expect("Failed to compile command matching regex");
let readdir = read_dir("./src/application/handler/").unwrap();

for entry in readdir {
if let Ok(entry) = entry {
let path = entry.path();
let module_name = entry
.file_name()
.into_string()
.unwrap()
.split('.')
.next()
.unwrap()
.to_owned();

let content = read_to_string(path).unwrap();
for captures in expression.captures_iter(&content) {
let function_name = captures.get(1).unwrap().as_str();
write(&mut out_file, &module_name, function_name);
}
}
}

out_file
.write(
r"
handles
}"
.as_bytes(),
)
.unwrap();
}

fn write(output: &mut File, module_name: &str, function_name: &str) {
output
.write(
format!(
" handles.insert(\"{}::{}\", {}::{});\n",
module_name, function_name, module_name, function_name
)
.as_bytes(),
)
.unwrap();
}
7 changes: 7 additions & 0 deletions held_core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "held_core"
version = "0.1.0"
edition = "2021"

[dependencies]
crossterm = "0.27"
1 change: 1 addition & 0 deletions held_core/src/control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

21 changes: 21 additions & 0 deletions held_core/src/interface/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use super::{get_application, APPLICATION};

pub trait App {
fn exit(&mut self);

fn to_insert_mode(&mut self);

fn to_normal_mode(&mut self);
}

pub fn exit() {
get_application().exit();
}

pub fn to_insert_mode() {
get_application().to_insert_mode();
}

pub fn to_normal_mode() {
get_application().to_normal_mode();
}
7 changes: 7 additions & 0 deletions held_core/src/interface/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub trait Buffer {
fn insert_char(&mut self);

fn new_line(&mut self);

fn insert_tab(&mut self);
}
41 changes: 41 additions & 0 deletions held_core/src/interface/cursor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::utils::position::Position;

use super::get_application;

pub trait Cursor {
fn move_left(&mut self);

fn move_right(&mut self);

fn move_up(&mut self);

fn move_down(&mut self);

fn move_to_start_of_line(&mut self);

fn screen_cursor_position(&self) -> Position;
}

pub fn screen_cursor_position() -> Position {
get_application().screen_cursor_position()
}

pub fn move_down() {
get_application().move_down()
}

pub fn move_up() {
get_application().move_up()
}

pub fn move_left() {
get_application().move_left()
}

pub fn move_right() {
get_application().move_right()
}

pub fn move_to_start_of_line() {
get_application().move_to_start_of_line()
}
24 changes: 24 additions & 0 deletions held_core/src/interface/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use app::App;
use buffer::Buffer;
use cursor::Cursor;
use monitor::Monitor;
use workspace::Workspace;

pub mod app;
pub mod buffer;
pub mod cursor;
pub mod monitor;
pub mod render;
pub mod terminal;
pub mod workspace;

pub trait ApplicationInterface: App + Buffer + Cursor + Monitor + Workspace {}
pub static mut APPLICATION: Option<&'static mut dyn ApplicationInterface> = None;

pub(crate) fn get_application() -> &'static mut &'static mut dyn ApplicationInterface {
unsafe {
APPLICATION
.as_mut()
.expect("The application has not been initialized!")
}
}
5 changes: 5 additions & 0 deletions held_core/src/interface/monitor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub trait Monitor {
fn scroll_to_cursor(&mut self);

fn scroll_to_center(&mut self);
}
1 change: 1 addition & 0 deletions held_core/src/interface/render.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

4 changes: 4 additions & 0 deletions held_core/src/interface/terminal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub trait TerminalInfo {
fn width() -> usize;
fn height() -> usize;
}
5 changes: 5 additions & 0 deletions held_core/src/interface/workspace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub trait Workspace {
fn save_file(&mut self);

fn undo(&mut self);
}
30 changes: 30 additions & 0 deletions held_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
pub mod control;
pub mod interface;
pub mod plugin;
pub mod theme;
pub mod utils;
pub mod view;

#[macro_export]
macro_rules! declare_plugin {
($app:ty, $constructor:path) => {
use held_core::interface::ApplicationInterface;
use held_core::interface::APPLICATION;

#[no_mangle]
pub unsafe extern "C" fn init_plugin_application(
app: &'static mut dyn ApplicationInterface,
) {
APPLICATION = Some(app);
}

#[no_mangle]
pub extern "C" fn plugin_create() -> *mut dyn $crate::plugin::Plugin {
// 确保构造器正确,所以做了这一步骤,来显示声明签名
let constructor: fn() -> $app = $constructor;
let object = constructor();
let boxed: Box<dyn $crate::plugin::Plugin> = Box::new(object);
Box::into_raw(boxed)
}
};
}
14 changes: 14 additions & 0 deletions held_core/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::view::render::ContentRenderBuffer;

pub trait Plugin {
fn name(&self) -> &'static str;

fn init(&self);

fn deinit(&self);

// 渲染文本内容部分时会触发该回调,可以返回想要在content中渲染的buffer
fn on_render_content(&self) -> Vec<ContentRenderBuffer> {
vec![]
}
}
1 change: 1 addition & 0 deletions held_core/src/theme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

27 changes: 27 additions & 0 deletions held_core/src/utils/distance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Distance {
pub lines: usize,
pub offset: usize,
}

impl Distance {
/// 计算字符串覆盖的距离
///
/// /// # Examples
///
/// ```
/// use crate::buffer::distance::Distance;
///
/// let data = "data\ndistance";
/// assert_eq!(Distance::of_str(data), Distance{
/// lines: 1,
/// offset: 8
/// });
/// ```
pub fn of_str(from: &str) -> Distance {
Distance {
lines: from.chars().filter(|&c| c == '\n').count(),
offset: from.split('\n').last().map(|l| l.len()).unwrap_or(0),
}
}
}
4 changes: 4 additions & 0 deletions held_core/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod distance;
pub mod position;
pub mod range;
pub mod rectangle;
69 changes: 69 additions & 0 deletions held_core/src/utils/position.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::{
cmp::Ordering,
ops::{Add, AddAssign},
};

use super::distance::Distance;

#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Position {
pub line: usize,
pub offset: usize,
}

impl Position {
pub fn new(line: usize, offset: usize) -> Position {
Position { line, offset }
}
}

impl PartialOrd for Position {
fn partial_cmp(&self, other: &Position) -> Option<Ordering> {
Some(if self.line < other.line {
Ordering::Less
} else if self.line > other.line {
Ordering::Greater
} else if self.offset < other.offset {
Ordering::Less
} else if self.offset > other.offset {
Ordering::Greater
} else {
Ordering::Equal
})
}
}

impl Add<Distance> for Position {
type Output = Position;

fn add(self, distance: Distance) -> Self::Output {
let offset = if distance.lines > 0 {
distance.offset
} else {
self.offset + distance.offset
};

Position {
line: self.line + distance.lines,
offset,
}
}
}

impl AddAssign<Distance> for Position {
fn add_assign(&mut self, distance: Distance) {
self.line += distance.lines;
self.offset = if distance.lines > 0 {
distance.offset
} else {
self.offset + distance.offset
};
}
}

impl From<(usize, usize)> for Position {
fn from(tuple: (usize, usize)) -> Self {
let (line, offset) = tuple;
Position::new(line, offset)
}
}
Loading
Loading