Skip to content

Commit

Permalink
Refactor (#37)
Browse files Browse the repository at this point in the history
* Patch refactor render/input/plugin (#22)

重新构建整体架构,包括:

渲染模块
输入处理模块
新增插件系统框架

* Feat insert (#23)

* Insert mode

* 完善render_lexme (#24)

* 完善render_lexme换行和\t

* 解决退出时屏幕没有刷新的问题

---------

Co-authored-by: sparkzky <[email protected]>

* 优化渲染模块,采用局部渲染提高渲染速度 (#26)

* insertMode添加tab处理 (#25)

* 修复buffer在最后个字符cursor右移时崩溃的问题 (#27)

* worksapce模式,支持查看工作区内容,动态打开工作区文件等操作 (#33)

* 将共用结构体移动到held_core中,增加部分插件相关的interface (#34)

- 增加插件系统
- 更改部分项目结构

* normal mode (#28)

* normal mode

* 实现了功能的自定义(除了delete_some)

* 纠正default.yaml: 'G' -> 'shift-G'

* 删除单词,移动到下一单词

* 移动undo, redo等到buffer模块

移动到前一单词,下一单词末尾

* CMD_COUNTER作为Application的成员变量

* Feat search (#32)

* feat search

* 修改default.yaml

* 修改usize溢出bug,修改exec_search前后部分按键不能使用

---------

Co-authored-by: zhuweihao12138 <[email protected]>
Co-authored-by: GnoCiYeH <[email protected]>

* Feat Command (#29)

* Add command mode

* modified to resolve the conflict

* get command mode modified

* worksapce模式,支持查看工作区内容,动态打开工作区文件等操作 (#33)

* 将共用结构体移动到held_core中,增加部分插件相关的interface (#34)

- 增加插件系统
- 更改部分项目结构

---------

Co-authored-by: GnoCiYeH <[email protected]>

* patch the error of command mode (#35)

* feat-replace (#31)

* 增加Replace模式
---------

Co-authored-by: sparkzky <[email protected]>
Co-authored-by: GnoCiYeH <[email protected]>

* Patch fix (#36)

* patch the error of command mode

* 进一步修复文件移动引起的错误

* 修改import, default.yaml

---------

Co-authored-by: zhou <[email protected]>

---------

Co-authored-by: Z YS <[email protected]>
Co-authored-by: sparkzky <[email protected]>
Co-authored-by: sparkzky <[email protected]>
Co-authored-by: Weihao Zhu <[email protected]>
Co-authored-by: zhuweihao12138 <[email protected]>
Co-authored-by: laokengwt <[email protected]>
Co-authored-by: 火花 <[email protected]>
Co-authored-by: zhou <[email protected]>
  • Loading branch information
9 people authored Dec 23, 2024
1 parent c2100e2 commit 5d785d9
Show file tree
Hide file tree
Showing 102 changed files with 8,822 additions and 107 deletions.
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

0 comments on commit 5d785d9

Please sign in to comment.