Compare commits
7 Commits
d76f279a05
...
42c5a58e6c
Author | SHA1 | Date |
---|---|---|
Benedikt Peetz | 42c5a58e6c | |
Benedikt Peetz | ebc336faa3 | |
Benedikt Peetz | 0fe5fe8b59 | |
Benedikt Peetz | 23e98fc474 | |
Benedikt Peetz | 7fdc752490 | |
Benedikt Peetz | 88f323d030 | |
Benedikt Peetz | e8a3370dce |
4
.envrc
4
.envrc
|
@ -1,6 +1,10 @@
|
|||
use flake || use nix
|
||||
watch_file flake.nix
|
||||
|
||||
PATH_add ./target/debug
|
||||
PATH_add ./target/release
|
||||
PATH_add ./scripts
|
||||
|
||||
if on_git_branch; then
|
||||
echo && git status --short --branch &&
|
||||
echo && git fetch --verbose
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2023 - 2024:
|
||||
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of the Trixy crate for Trinitrix.
|
||||
*
|
||||
* Trixy is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Lesser GNU General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* and the Lesser GNU General Public License along with this program.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use trixy::macros::config::trixy::TrixyConfig;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=./dist/*");
|
||||
println!("cargo:rerun-if-changed=./src/app/command_interface/command_list/api.tri");
|
||||
let file_tree = TrixyConfig::new("handle_cmd")
|
||||
.trixy_path("./src/app/command_interface/command_list/api.tri")
|
||||
.dist_dir_path("./dist")
|
||||
.generate();
|
||||
|
||||
file_tree.materialize().unwrap();
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (C) 2023 - 2024:
|
||||
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of the Trixy crate for Trinitrix.
|
||||
*
|
||||
* Trixy is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Lesser GNU General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* and the Lesser GNU General Public License along with this program.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../../dist/interface.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define println(args...) \
|
||||
fprintf(log_file, "\33[32;1m(plugin):\33[0m \33[34;1m"); \
|
||||
fprintf(log_file, args); \
|
||||
fprintf(log_file, "\n\33[0m"); \
|
||||
fflush(log_file);
|
||||
|
||||
#define eprintln(args...) \
|
||||
fprintf(log_file, "\33[32;1m(plugin):\33[0m\33[31;1m "); \
|
||||
fprintf(log_file, args); \
|
||||
fprintf(log_file, "\n\33[0m"); \
|
||||
fflush(log_file);
|
||||
|
||||
int is_first_log_file_open = 1;
|
||||
FILE *get_log_file() {
|
||||
FILE *log_file;
|
||||
|
||||
if (is_first_log_file_open) {
|
||||
is_first_log_file_open = 0;
|
||||
log_file = fopen("plugin.txt", "w");
|
||||
} else {
|
||||
log_file = fopen("plugin.txt", "wa");
|
||||
}
|
||||
|
||||
if (log_file == NULL) {
|
||||
printf("Error opening file!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return log_file;
|
||||
}
|
||||
|
||||
void handle_error() {
|
||||
FILE *log_file = get_log_file();
|
||||
eprintln("GOT an error");
|
||||
|
||||
int error_length = last_error_length();
|
||||
char *error = malloc(error_length);
|
||||
last_error_message(error, error_length);
|
||||
eprintln("Encountered error: %s", error);
|
||||
free(error);
|
||||
}
|
||||
|
||||
void set_normal_mode() {
|
||||
if (!trinitrix.api.ui.set_mode(Normal))
|
||||
handle_error();
|
||||
}
|
||||
void set_command_mode() {
|
||||
if (!trinitrix.api.ui.set_mode(Command))
|
||||
handle_error();
|
||||
}
|
||||
void set_insert_mode() {
|
||||
if (!trinitrix.api.ui.set_mode(Insert))
|
||||
handle_error();
|
||||
}
|
||||
void print_hi() {
|
||||
if (!trinitrix.api.raw.raise_error("hi!"))
|
||||
handle_error();
|
||||
}
|
||||
void print_warning() {
|
||||
if (!trinitrix.api.raw.raise_error(
|
||||
"To exit trinitrix use 'trinitrix.api.exit()' instead!"))
|
||||
handle_error();
|
||||
}
|
||||
|
||||
int plugin_main() {
|
||||
FILE *log_file = get_log_file();
|
||||
|
||||
println("Hi, setting first keymap!");
|
||||
if (!trinitrix.api.keymaps.add("ci", "<ESC>", set_normal_mode))
|
||||
handle_error();
|
||||
println("Done setting that keymap");
|
||||
|
||||
if (!trinitrix.api.keymaps.add("n", ":", set_command_mode))
|
||||
handle_error();
|
||||
|
||||
trinitrix.api.keymaps.add("n", "i", set_insert_mode);
|
||||
trinitrix.api.keymaps.add("n", "<TAB>", trinitrix.api.ui.cycle_planes);
|
||||
|
||||
// a simple test to prove that key chords work
|
||||
trinitrix.api.keymaps.add("ni", "jj", print_hi);
|
||||
|
||||
trinitrix.api.keymaps.add("n", "q", trinitrix.api.exit);
|
||||
|
||||
// Help people
|
||||
trinitrix.api.keymaps.add("n", "<C-c>", print_warning);
|
||||
|
||||
// workaround to avoid c de-allocating our nice strings
|
||||
while (1) {
|
||||
};
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -100,6 +100,8 @@
|
|||
rust
|
||||
cargo-edit
|
||||
cargo-expand
|
||||
|
||||
valgrind
|
||||
];
|
||||
inherit nativeBuildInputs buildInputs;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# Copyright (C) 2023 - 2024:
|
||||
# The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
# This file is part of the Trixy crate for Trinitrix.
|
||||
#
|
||||
# Trixy is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the Lesser GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# and the Lesser GNU General Public License along with this program.
|
||||
# If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BIN_NAME := ./target/plugin.so
|
||||
|
||||
BUILD_DIR := ./target/c_build/
|
||||
|
||||
# SRC := $(wildcard c/*.c)
|
||||
SRC := ./config/c/plugin.c
|
||||
OBJ := $(SRC:.c=.o)
|
||||
DEP := $(OBJ:.o=.d)
|
||||
|
||||
LIBS :=
|
||||
|
||||
ALL_CFLAGS := -fPIC -O3 -MMD -Wall -Wextra -Wno-unused-parameter $(CFLAGS) $(CPPFLAGS)
|
||||
ALL_LDFLAGS := $(addprefix -l,$(LIBS)) -L $(LD_LIBRARY_PATH) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
|
||||
$(BIN_NAME): $(OBJ)
|
||||
gcc $(addprefix $(BUILD_DIR),$(notdir $(OBJ))) -shared -o $(addprefix $(BUILD_DIR),$(notdir $(BIN_NAME))) $(ALL_CFLAGS) $(ALL_LDFLAGS)
|
||||
|
||||
$(OBJ): $(SRC)
|
||||
mkdir --parents $(BUILD_DIR)
|
||||
$(CC) -c $< -o $(addprefix $(BUILD_DIR),$(notdir $(OBJ))) $(ALL_CFLAGS)
|
||||
|
||||
.PHONY : clean options
|
||||
options:
|
||||
@echo "CC = $(CC)"
|
||||
@echo "CFLAGS = $(ALL_CFLAGS)"
|
||||
@echo "LDFLAGS = $(ALL_LDFLAGS)"
|
||||
@echo "SRC = $(SRC)"
|
||||
@echo "OBJ = $(OBJ)"
|
||||
@echo "DEP = $(DEP)"
|
||||
@echo ""
|
||||
|
||||
clean :
|
||||
rm $(BIN_NAME) $(OBJ) $(DEP)
|
||||
rm -r $(BUILD_DIR)
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#! /usr/bin/env sh
|
||||
# Copyright (C) 2023 - 2024:
|
||||
# The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
# This file is part of the Trixy crate for Trinitrix.
|
||||
#
|
||||
# Trixy is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the Lesser GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# and the Lesser GNU General Public License along with this program.
|
||||
# If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
cd "$(dirname "$0")" || {
|
||||
echo "BUG: There is no parent dirname!";
|
||||
exit 1
|
||||
}
|
||||
cd ..
|
||||
|
||||
make
|
||||
cargo build
|
||||
|
||||
export TRINITRIX_LOG=info
|
||||
|
||||
valgrind --leak-check=full \
|
||||
--show-leak-kinds=all \
|
||||
--show-error-list=yes \
|
||||
--track-origins=yes \
|
||||
--log-file=./target/valgrind_out.txt \
|
||||
./target/debug/trinitrix --plugin-path ./target/c_build/plugin.so
|
||||
|
||||
cat ./target/valgrind_out.txt
|
|
@ -1,12 +1,17 @@
|
|||
use std::{ffi::c_int, path::Path};
|
||||
use std::{
|
||||
ffi::c_int,
|
||||
path::PathBuf,
|
||||
thread::{self},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use cli_log::info;
|
||||
use libloading::{Library, Symbol};
|
||||
|
||||
pub fn load(plugin: &Path) -> Result<()> {
|
||||
pub fn load(plugin: PathBuf) -> Result<()> {
|
||||
info!("Loading a plugin from '{}'", plugin.display());
|
||||
|
||||
let _handle = thread::spawn(move || -> Result<()> {
|
||||
unsafe {
|
||||
let lib = Library::new(plugin).context("Failed to load plugin")?;
|
||||
let func: Symbol<unsafe fn() -> c_int> = lib
|
||||
|
@ -17,6 +22,8 @@ pub fn load(plugin: &Path) -> Result<()> {
|
|||
let out = func();
|
||||
info!("Plugin finished with: {}", out);
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -179,7 +179,6 @@ pub async fn handle<U: TrinitrixUi>(
|
|||
}
|
||||
Raw::send_input_unprocessed { input } => {
|
||||
let key = Key::from_str(input.as_str())?;
|
||||
// let cross_input: Event = key.try_into()?;
|
||||
|
||||
match app.status.state() {
|
||||
State::Insert | State::Command => {
|
||||
|
|
|
@ -6,7 +6,7 @@ pub mod status;
|
|||
use std::{collections::HashMap, path::PathBuf, sync::OnceLock};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use cli_log::warn;
|
||||
use cli_log::{debug, warn};
|
||||
use directories::ProjectDirs;
|
||||
use keymaps::trie::Node;
|
||||
use tokio::sync::mpsc::{self, Sender};
|
||||
|
@ -93,7 +93,7 @@ impl<U: TrinitrixUi> App<U> {
|
|||
}
|
||||
|
||||
if let Some(plugin) = plugin_path {
|
||||
config::shared_objects::load(&plugin)
|
||||
config::shared_objects::load(plugin.clone())
|
||||
.with_context(|| format!("Failed to load a pluging at '{}'", plugin.display()))?;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ mod app;
|
|||
mod cli;
|
||||
mod ui;
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
|
||||
use crate::{
|
||||
|
@ -18,13 +19,13 @@ async fn main() -> anyhow::Result<()> {
|
|||
match command {
|
||||
Command::Start {} => {
|
||||
todo!("The full ui is not yet finished");
|
||||
let mut app = app::App::new(Repl::new())?;
|
||||
let mut app = app::App::new(Repl::new()?)?;
|
||||
|
||||
// NOTE(@soispha): The `None` here is temporary <2024-05-03>
|
||||
app.run(None, args.plugin_path).await?;
|
||||
}
|
||||
Command::Repl {} => {
|
||||
let mut app = app::App::new(Repl::new())?;
|
||||
let mut app = app::App::new(Repl::new().context("Failed to setup repl")?)?;
|
||||
|
||||
// NOTE(@soispha): The `None` here is temporary <2024-05-03>
|
||||
app.run(None, args.plugin_path).await?;
|
||||
|
|
|
@ -1,51 +1,128 @@
|
|||
use anyhow::Result;
|
||||
use cli_log::info;
|
||||
use std::io::{self, Stdout, Write};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use cli_log::{debug, info};
|
||||
use crossterm::{
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnableLineWrap},
|
||||
};
|
||||
use keymaps::key_repr::{Key, KeyValue};
|
||||
|
||||
use crate::app::status::Status;
|
||||
use crate::app::status::{State, Status};
|
||||
|
||||
use super::ui_trait::TrinitrixUi;
|
||||
|
||||
pub struct Repl {
|
||||
current_written_buffer: String,
|
||||
current_input: String,
|
||||
enter_new_line: bool,
|
||||
stdout: Stdout,
|
||||
}
|
||||
|
||||
impl Repl {
|
||||
pub fn new() -> Self {
|
||||
println!("Welcome to the Trinitrix repl! You can now enter trinitry commands.");
|
||||
print!("{}", Self::prompt(&Status::new()));
|
||||
pub fn new() -> Result<Self> {
|
||||
enable_raw_mode().context("Failed to enable raw mode")?;
|
||||
let mut stdout = io::stdout();
|
||||
|
||||
Repl {
|
||||
write!(
|
||||
stdout,
|
||||
"Welcome to the Trinitrix repl! You can now enter trinitry commands."
|
||||
)?;
|
||||
write!(stdout, "\n\r{}", Self::prompt(&Status::new()))?;
|
||||
stdout.flush()?;
|
||||
|
||||
Ok(Repl {
|
||||
current_written_buffer: String::new(),
|
||||
current_input: String::new(),
|
||||
enter_new_line: false,
|
||||
}
|
||||
stdout,
|
||||
})
|
||||
}
|
||||
pub fn prompt(status: &Status) -> String {
|
||||
format!("{}> ", status.state())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Repl {
|
||||
fn drop(&mut self) {
|
||||
disable_raw_mode().expect("Must work in drop");
|
||||
execute!(io::stdout(), EnableLineWrap).expect("Must also work");
|
||||
|
||||
writeln!(self.stdout, "\n\rBye!").expect("Must also work");
|
||||
}
|
||||
}
|
||||
|
||||
impl TrinitrixUi for Repl {
|
||||
async fn update(&mut self, status: &Status) -> Result<()> {
|
||||
if self.enter_new_line {
|
||||
info!("Got '{}' from user in repl.", self.current_input);
|
||||
info!("Got '{}' from user in repl.", self.current_written_buffer);
|
||||
|
||||
if status.state() == &State::Command {
|
||||
write!(
|
||||
self.stdout,
|
||||
"\n\rEvaluating: '{}' ..",
|
||||
self.current_written_buffer
|
||||
)?;
|
||||
} else {
|
||||
write!(
|
||||
self.stdout,
|
||||
"\n\rCan't insert anything in the repl besides in command mode!",
|
||||
)?;
|
||||
}
|
||||
|
||||
self.enter_new_line = false;
|
||||
self.current_input = String::new();
|
||||
self.current_written_buffer.clear();
|
||||
|
||||
print!("{}", Self::prompt(status));
|
||||
write!(self.stdout, "\n\r{}", Self::prompt(status))?;
|
||||
} else {
|
||||
write!(
|
||||
self.stdout,
|
||||
"\r{}{}{}",
|
||||
Self::prompt(status),
|
||||
self.current_written_buffer,
|
||||
self.current_input
|
||||
)?;
|
||||
|
||||
self.current_written_buffer += self.current_input.as_str();
|
||||
self.current_input.clear();
|
||||
}
|
||||
self.stdout.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn input(&mut self, input: Key) {
|
||||
debug!("Input received at repl: {}", input);
|
||||
|
||||
if let Some(value) = input.value() {
|
||||
if let KeyValue::Char(ch) = value {
|
||||
self.current_input.push(*ch);
|
||||
} else if let KeyValue::Enter = value {
|
||||
self.enter_new_line = true;
|
||||
match value {
|
||||
KeyValue::Backspace => {
|
||||
self.current_written_buffer.pop();
|
||||
}
|
||||
KeyValue::Enter => self.enter_new_line = true,
|
||||
KeyValue::Left => todo!(),
|
||||
KeyValue::Right => todo!(),
|
||||
KeyValue::Up => todo!(),
|
||||
KeyValue::Down => todo!(),
|
||||
KeyValue::Home => todo!(),
|
||||
KeyValue::End => todo!(),
|
||||
KeyValue::PageUp => todo!(),
|
||||
KeyValue::PageDown => todo!(),
|
||||
KeyValue::Tab => todo!(),
|
||||
KeyValue::BackTab => todo!(),
|
||||
KeyValue::Delete => todo!(),
|
||||
KeyValue::Insert => todo!(),
|
||||
KeyValue::F(_) => todo!(),
|
||||
KeyValue::Char(ch) => self.current_input.push(*ch),
|
||||
KeyValue::Null => todo!(),
|
||||
KeyValue::Esc => todo!(),
|
||||
KeyValue::CapsLock => todo!(),
|
||||
KeyValue::ScrollLock => todo!(),
|
||||
KeyValue::NumLock => todo!(),
|
||||
KeyValue::PrintScreen => todo!(),
|
||||
KeyValue::Pause => todo!(),
|
||||
KeyValue::Menu => todo!(),
|
||||
KeyValue::KeypadBegin => todo!(),
|
||||
}
|
||||
} else {
|
||||
info!("User wrote: '{}'", input.to_string_repr());
|
||||
|
|
Reference in New Issue