Skip to content

Commit

Permalink
Merge pull request #168 from curlpipe/dev
Browse files Browse the repository at this point in the history
0.6.6
  • Loading branch information
curlpipe authored Oct 12, 2024
2 parents d5b4bf8 + 1a4d8c3 commit 39ba0df
Show file tree
Hide file tree
Showing 22 changed files with 1,207 additions and 215 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exclude = ["cactus"]

[package]
name = "ox"
version = "0.6.5"
version = "0.6.6"
edition = "2021"
authors = ["Curlpipe <[email protected]>"]
description = "A Rust powered text editor."
Expand Down
4 changes: 2 additions & 2 deletions config/.oxrc
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ commands = {
end
end,
["filetype"] = function(arguments)
ext = arguments[1]
editor:set_file_type(ext)
local file_type_name = arguments[1]
editor:set_file_type(file_type_name)
end,
["reload"] = function(arguments)
editor:reload_config()
Expand Down
41 changes: 37 additions & 4 deletions kaolinite/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,10 +767,6 @@ impl Document {
/// Function to select to a specific x position
pub fn select_to_x(&mut self, x: usize) {
let line = self.line(self.loc().y).unwrap_or_default();
// If we're already at this x coordinate, just exit
if self.char_ptr == x {
return;
}
// If the move position is out of bounds, move to the end of the line
if line.chars().count() < x {
let line = self.line(self.loc().y).unwrap_or_default();
Expand Down Expand Up @@ -810,6 +806,43 @@ impl Document {
self.load_to(self.offset.y + self.size.h);
}

/// Select a word at a location
pub fn select_word_at(&mut self, loc: &Loc) {
let y = loc.y;
let x = self.character_idx(loc);
let re = format!("(\t| {{{}}}|^|\\W| )", self.tab_width);
let start = if let Some(mut mtch) = self.prev_match(&re) {
let len = mtch.text.chars().count();
let same = mtch.loc.x + len == x;
if !same {
mtch.loc.x += len;
}
self.move_to(&mtch.loc);
if same && self.loc().x != 0 {
self.move_prev_word();
}
mtch.loc.x
} else {
0
};
let re = format!("(\t| {{{}}}|\\W|$|^ +| )", self.tab_width);
let end = if let Some(mtch) = self.next_match(&re, 0) {
mtch.loc.x
} else {
self.line(y).unwrap_or_default().chars().count()
};
self.move_to(&Loc { x: start, y });
self.select_to(&Loc { x: end, y });
self.old_cursor = self.loc().x;
}

/// Select a line at a location
pub fn select_line_at(&mut self, y: usize) {
let len = self.line(y).unwrap_or_default().chars().count();
self.move_to(&Loc { x: 0, y });
self.select_to(&Loc { x: len, y });
}

/// Brings the cursor into the viewport so it can be seen
pub fn bring_cursor_in_viewport(&mut self) {
if self.offset.y > self.cursor.loc.y {
Expand Down
21 changes: 21 additions & 0 deletions kaolinite/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,27 @@ fn document_selection() {
assert!(!doc.is_loc_selected(Loc { x: 0, y: 0 }));
assert!(!doc.is_loc_selected(Loc { x: 2, y: 0 }));
assert!(!doc.is_loc_selected(Loc { x: 3, y: 0 }));
doc.select_line_at(1);
assert_eq!(
doc.selection_loc_bound(),
(Loc { x: 0, y: 1 }, Loc { x: 31, y: 1 })
);
doc.remove_selection();
doc.exe(Event::InsertLine(1, "hello there world".to_string()));
doc.exe(Event::InsertLine(2, "hello".to_string()));
doc.move_to(&Loc { x: 8, y: 1 });
doc.select_word_at(&Loc { x: 8, y: 1 });
assert_eq!(
doc.selection_loc_bound(),
(Loc { x: 6, y: 1 }, Loc { x: 11, y: 1 })
);
doc.remove_selection();
doc.move_to(&Loc { x: 0, y: 2 });
doc.select_word_at(&Loc { x: 0, y: 2 });
assert_eq!(
doc.selection_loc_bound(),
(Loc { x: 0, y: 2 }, Loc { x: 5, y: 2 })
);
}

#[test]
Expand Down
25 changes: 19 additions & 6 deletions plugins/autoindent.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--[[
Auto Indent v0.7
Auto Indent v0.8
Helps you when programming by guessing where indentation should go
and then automatically applying these guesses as you program
Expand Down Expand Up @@ -170,10 +170,23 @@ event_mapping["enter"] = function()
autoindent:disperse_block()
end

event_mapping["*"] = function()
-- Dedent where appropriate
if autoindent:causes_dedent(editor.cursor.y) then
local new_level = autoindent:get_indent(editor.cursor.y) - 1
autoindent:set_indent(editor.cursor.y, new_level)
-- For each ascii characters and punctuation
was_dedenting = false
for i = 32, 126 do
local char = string.char(i)
-- ... excluding the global event binding
if char ~= "*" then
-- Keep track of whether the line was previously dedenting beforehand
event_mapping["before:" .. char] = function()
was_dedenting = autoindent:causes_dedent(editor.cursor.y)
end
-- Trigger dedent checking
event_mapping[char] = function()
-- Dedent where appropriate
if autoindent:causes_dedent(editor.cursor.y) and not was_dedenting then
local new_level = autoindent:get_indent(editor.cursor.y) - 1
autoindent:set_indent(editor.cursor.y, new_level)
end
end
end
end
14 changes: 7 additions & 7 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ Ox: A lightweight and flexible text editor
USAGE: ox [options] [files]
OPTIONS:
--help, -h : Show this help message
--version, -v : Show the version number
--config [path], -c [path] : Specify the configuration file
--readonly, -r : Prevent opened files from writing
--filetype [ext], -f [ext] : Set the file type of files opened
--stdin : Reads file from the stdin
--help, -h : Show this help message
--version, -v : Show the version number
--config [path], -c [path] : Specify the configuration file
--readonly, -r : Prevent opened files from writing
--filetype [name], -f [name] : Set the file type of files opened
--stdin : Reads file from the stdin
EXAMPLES:
ox
ox test.txt
ox test.txt test2.txt
ox /home/user/docs/test.txt
ox -c config.lua test.txt
ox -r -c ~/.config/.oxrc -f lua my_file.lua
ox -r -c ~/.config/.oxrc -f Lua my_file.lua
tree | ox -r --stdin\
";

Expand Down
19 changes: 10 additions & 9 deletions src/config/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl LuaUserData for Editor {
});
fields.add_field_method_get("version", |_, _| Ok(VERSION));
fields.add_field_method_get("current_document_id", |_, editor| Ok(editor.ptr));
fields.add_field_method_get("document_count", |_, editor| Ok(editor.doc.len()));
fields.add_field_method_get("document_count", |_, editor| Ok(editor.files.len()));
fields.add_field_method_get("document_type", |_, editor| {
let ext = editor
.doc()
Expand Down Expand Up @@ -437,14 +437,15 @@ impl LuaUserData for Editor {
editor.doc_mut().info.read_only = status;
Ok(())
});
methods.add_method_mut("set_file_type", |_, editor, ext: String| {
let mut highlighter = editor
.config
.syntax_highlighting
.borrow()
.get_highlighter(&ext);
highlighter.run(&editor.doc().lines);
editor.highlighter[editor.ptr] = highlighter;
methods.add_method_mut("set_file_type", |_, editor, name: String| {
if let Some(file_type) = editor.config.document.borrow().file_types.get_name(&name) {
let mut highlighter = file_type.get_highlighter(&editor.config, 4);
highlighter.run(&editor.doc().lines);
editor.files[editor.ptr].highlighter = highlighter;
editor.files[editor.ptr].file_type = Some(file_type);
} else {
editor.feedback = Feedback::Error(format!("Invalid file type: {name}"));
}
Ok(())
});
// Rerendering
Expand Down
68 changes: 28 additions & 40 deletions src/config/highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::error::{OxError, Result};
use crossterm::style::Color as CColor;
use mlua::prelude::*;
use std::collections::HashMap;
use synoptic::{from_extension, Highlighter};
use synoptic::Highlighter;

use super::Color;

Expand All @@ -27,14 +27,6 @@ impl SyntaxHighlighting {
)))
}
}

/// Get a highlighter given a file extension
pub fn get_highlighter(&self, ext: &str) -> Highlighter {
self.user_rules.get(ext).map_or_else(
|| from_extension(ext, 4).unwrap_or_else(|| Highlighter::new(4)),
std::clone::Clone::clone,
)
}
}

impl LuaUserData for SyntaxHighlighting {
Expand Down Expand Up @@ -84,40 +76,36 @@ impl LuaUserData for SyntaxHighlighting {
);
methods.add_method_mut(
"new",
|_, syntax_highlighting, (extensions, rules): (LuaTable, LuaTable)| {
// Make note of the highlighter
for ext_idx in 1..=(extensions.len()?) {
// Create highlighter
let mut highlighter = Highlighter::new(4);
// Add rules one by one
for rule_idx in 1..=(rules.len()?) {
// Get rule
let rule = rules.get::<i64, HashMap<String, String>>(rule_idx)?;
// Find type of rule and attatch it to the highlighter
match rule["kind"].as_str() {
"keyword" => {
highlighter.keyword(rule["name"].clone(), &rule["pattern"]);
}
"bounded" => highlighter.bounded(
rule["name"].clone(),
rule["start"].clone(),
rule["end"].clone(),
rule["escape"] == "true",
),
"bounded_interpolation" => highlighter.bounded_interp(
rule["name"].clone(),
rule["start"].clone(),
rule["end"].clone(),
rule["i_start"].clone(),
rule["i_end"].clone(),
rule["escape"] == "true",
),
_ => unreachable!(),
|_, syntax_highlighting, (name, rules): (String, LuaTable)| {
// Create highlighter
let mut highlighter = Highlighter::new(4);
// Add rules one by one
for rule_idx in 1..=(rules.len()?) {
// Get rule
let rule = rules.get::<i64, HashMap<String, String>>(rule_idx)?;
// Find type of rule and attatch it to the highlighter
match rule["kind"].as_str() {
"keyword" => {
highlighter.keyword(rule["name"].clone(), &rule["pattern"]);
}
"bounded" => highlighter.bounded(
rule["name"].clone(),
rule["start"].clone(),
rule["end"].clone(),
rule["escape"] == "true",
),
"bounded_interpolation" => highlighter.bounded_interp(
rule["name"].clone(),
rule["start"].clone(),
rule["end"].clone(),
rule["i_start"].clone(),
rule["i_end"].clone(),
rule["escape"] == "true",
),
_ => unreachable!(),
}
let ext = extensions.get::<i64, String>(ext_idx)?;
syntax_highlighting.user_rules.insert(ext, highlighter);
}
syntax_highlighting.user_rules.insert(name, highlighter);
Ok(())
},
);
Expand Down
32 changes: 15 additions & 17 deletions src/config/interface.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::cli::VERSION;
use crate::editor::{which_extension, Editor};
use crate::editor::{Editor, FileContainer};
use crate::error::Result;
use crossterm::style::SetForegroundColor as Fg;
use kaolinite::searching::Searcher;
use kaolinite::utils::{filetype, get_absolute_path, get_file_name, icon};
use kaolinite::Document;
use kaolinite::utils::{get_absolute_path, get_file_ext, get_file_name};
use mlua::prelude::*;

use super::{issue_warning, Colors};
Expand Down Expand Up @@ -218,16 +217,17 @@ impl Default for TabLine {

impl TabLine {
/// Take the configuration information and render the tab line
pub fn render(&self, document: &Document) -> String {
let path = document
pub fn render(&self, file: &FileContainer) -> String {
let path = file
.doc
.file_name
.clone()
.unwrap_or_else(|| "[No Name]".to_string());
let file_extension = which_extension(document).unwrap_or_else(|| "Unknown".to_string());
let file_extension = get_file_ext(&path).unwrap_or_else(|| "Unknown".to_string());
let absolute_path = get_absolute_path(&path).unwrap_or_else(|| "[No Name]".to_string());
let file_name = get_file_name(&path).unwrap_or_else(|| "[No Name]".to_string());
let icon = icon(&filetype(&file_extension).unwrap_or_default());
let modified = if document.info.modified { "[+]" } else { "" };
let icon = file.file_type.clone().map_or("󰈙 ".to_string(), |t| t.icon);
let modified = if file.doc.info.modified { "[+]" } else { "" };
let mut result = self.format.clone();
result = result
.replace("{file_extension}", &file_extension)
Expand Down Expand Up @@ -277,23 +277,21 @@ impl Default for StatusLine {
impl StatusLine {
/// Take the configuration information and render the status line
pub fn render(&self, editor: &Editor, lua: &Lua, w: usize) -> String {
let file = &editor.files[editor.ptr];
let mut result = vec![];
let path = editor
.doc()
.file_name
.clone()
.unwrap_or_else(|| "[No Name]".to_string());
let file_extension = which_extension(editor.doc()).unwrap_or_else(|| "Unknown".to_string());
let file_extension = get_file_ext(&path).unwrap_or_else(|| "Unknown".to_string());
let absolute_path = get_absolute_path(&path).unwrap_or_else(|| "[No Name]".to_string());
let file_name = get_file_name(&path).unwrap_or_else(|| "[No Name]".to_string());
let file_type = filetype(&file_extension).unwrap_or_else(|| {
if file_extension.is_empty() {
"Unknown".to_string()
} else {
file_extension.to_string()
}
});
let icon = icon(&filetype(&file_extension).unwrap_or_default());
let file_type = file
.file_type
.clone()
.map_or("Unknown".to_string(), |t| t.name);
let icon = file.file_type.clone().map_or("󰈙 ".to_string(), |t| t.icon);
let modified = if editor.doc().info.modified {
"[+]"
} else {
Expand Down
Loading

0 comments on commit 39ba0df

Please sign in to comment.