Compare commits
2 Commits
779872b2f6
...
01de2390ac
| Author | SHA1 | Date | |
|---|---|---|---|
| 01de2390ac | |||
| 784592658a |
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1170,6 +1170,7 @@ name = "libclide"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"devicons",
|
||||
"log",
|
||||
"strum",
|
||||
]
|
||||
|
||||
@@ -11,6 +11,7 @@ members = [".", "libclide", "libclide-macros", ]
|
||||
anyhow = "1.0.100"
|
||||
strum = "0.27.2"
|
||||
log = { version = "0.4.27", features = [] }
|
||||
devicons = "0.6.12"
|
||||
|
||||
[dependencies]
|
||||
cxx = "1.0.95"
|
||||
@@ -23,12 +24,12 @@ ratatui = "0.30.0"
|
||||
tui-tree-widget = "0.24.0"
|
||||
tui-logger = "0.18.1"
|
||||
edtui = "0.11.1"
|
||||
devicons = "0.6.12"
|
||||
libclide = { path = "./libclide" }
|
||||
libclide-macros = { path = "./libclide-macros" }
|
||||
anyhow = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
log = { workspace = true }
|
||||
devicons = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
# The link_qt_object_files feature is required for statically linking Qt 6.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2026, Shaun Reed <shaunrd0@gmail.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GNU General Public License v3.0 or later
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{ItemStruct, parse_macro_input};
|
||||
|
||||
@@ -7,3 +7,4 @@ edition = "2024"
|
||||
anyhow = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
log = { workspace = true }
|
||||
devicons = { workspace = true }
|
||||
|
||||
@@ -3,3 +3,16 @@
|
||||
// SPDX-License-Identifier: GNU General Public License v3.0 or later
|
||||
|
||||
pub mod entry_meta;
|
||||
|
||||
use devicons::FileIcon;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn icon<P: AsRef<str>>(p: P) -> FileIcon {
|
||||
let path = p.as_ref();
|
||||
if Path::new(&path).is_dir() {
|
||||
// Ensures directories are given a folder icon and not mistakenly resolved to a language.
|
||||
// For example, a directory named `cpp` would otherwise return a C++ icon.
|
||||
return FileIcon::from("dir/");
|
||||
}
|
||||
FileIcon::from(path)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// SPDX-License-Identifier: GNU General Public License v3.0 or later
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use devicons::FileIcon;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -10,6 +11,7 @@ pub struct EntryMeta {
|
||||
pub abs_path: String,
|
||||
pub file_name: String,
|
||||
pub is_dir: bool,
|
||||
pub icon: FileIcon,
|
||||
}
|
||||
|
||||
impl EntryMeta {
|
||||
@@ -41,10 +43,12 @@ impl EntryMeta {
|
||||
.context(format!("Failed to get file name for path: {abs_path:?}"))?
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
let icon = crate::fs::icon(&abs_path);
|
||||
Ok(EntryMeta {
|
||||
abs_path,
|
||||
file_name,
|
||||
is_dir,
|
||||
icon,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,40 @@
|
||||
// SPDX-FileCopyrightText: 2026, Shaun Reed <shaunrd0@gmail.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GNU General Public License v3.0 or later
|
||||
|
||||
//! Logging targets allow filtering of log messages by their source. By default, the log crate sets
|
||||
//! the target to the module path where the log macro was invoked if no target is provided.
|
||||
//!
|
||||
//! These macros essentially disable using the default target and instead require the target to be
|
||||
//! explicitly set. This is to avoid implicit pooling of log messages under the same default target,
|
||||
//! which can make it difficult to filter log messages by their source.
|
||||
//!
|
||||
//! The target argument can be overridden using one of the following macros.
|
||||
//! ```
|
||||
//! libclide::log!(target: "CustomTarget", "This log message will have the target 'CustomTarget'");
|
||||
//! ```
|
||||
//!
|
||||
//! The target argument will default to Self::ID if not provided.
|
||||
//! This is an error if Self::ID is not defined, forcing you to use the explicit form.
|
||||
//! ```
|
||||
//! libclide::log!("This log message will use target Self::ID, the name of the struct it was invoked in");
|
||||
//! ```
|
||||
//!
|
||||
//! Self::ID can be defined using the `#[log_id]` attribute macro, which will automatically generate
|
||||
//! a constant ID field with the name of the struct as its value.
|
||||
//! ```
|
||||
//! #[log_id]
|
||||
//! struct MyStruct;
|
||||
//! impl MyStruct {
|
||||
//! fn my_method(&self) {
|
||||
//! libclide::log!("This log message will use target Self::ID, which is 'MyStruct'");
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
// The target argument can be overridden using one of the following macros.
|
||||
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
|
||||
log::info!(logger: $logger, target: $target, $($arg)+)
|
||||
});
|
||||
@@ -16,8 +43,6 @@ macro_rules! info {
|
||||
log::info!(target: $target, $($arg)+)
|
||||
});
|
||||
|
||||
// The target argument will default to Self::ID if not provided.
|
||||
// Obviously, this is an error if Self::ID is not defined, forcing you to use the explicit form.
|
||||
(logger: $logger:expr, $($arg:tt)+) => ({
|
||||
log::info!(logger: $logger, target: Self::ID, $($arg)+)
|
||||
});
|
||||
@@ -27,7 +52,6 @@ macro_rules! info {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
// The target argument can be overridden using one of the following macros.
|
||||
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
|
||||
log::debug!(logger: $logger, target: $target, $($arg)+)
|
||||
});
|
||||
@@ -36,8 +60,6 @@ macro_rules! debug {
|
||||
log::debug!(target: $target, $($arg)+)
|
||||
});
|
||||
|
||||
// The target argument will default to Self::ID if not provided.
|
||||
// Obviously, this is an error if Self::ID is not defined, forcing you to use the explicit form.
|
||||
(logger: $logger:expr, $($arg:tt)+) => ({
|
||||
log::debug!(logger: $logger, target: Self::ID, $($arg)+)
|
||||
});
|
||||
@@ -47,7 +69,6 @@ macro_rules! debug {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warn {
|
||||
// The target argument can be overridden using one of the following macros.
|
||||
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
|
||||
log::warn!(logger: $logger, target: $target, $($arg)+)
|
||||
});
|
||||
@@ -56,8 +77,6 @@ macro_rules! warn {
|
||||
log::warn!(target: $target, $($arg)+)
|
||||
});
|
||||
|
||||
// The target argument will default to Self::ID if not provided.
|
||||
// Obviously, this is an error if Self::ID is not defined, forcing you to use the explicit form.
|
||||
(logger: $logger:expr, $($arg:tt)+) => ({
|
||||
log::warn!(logger: $logger, target: Self::ID, $($arg)+)
|
||||
});
|
||||
@@ -67,7 +86,6 @@ macro_rules! warn {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
// The target argument can be overridden using one of the following macros.
|
||||
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
|
||||
log::error!(logger: $logger, target: $target, $($arg)+)
|
||||
});
|
||||
@@ -76,8 +94,6 @@ macro_rules! error {
|
||||
log::error!(target: $target, $($arg)+)
|
||||
});
|
||||
|
||||
// The target argument will default to Self::ID if not provided.
|
||||
// Obviously, this is an error if Self::ID is not defined, forcing you to use the explicit form.
|
||||
(logger: $logger:expr, $($arg:tt)+) => ({
|
||||
log::error!(logger: $logger, target: Self::ID, $($arg)+)
|
||||
});
|
||||
@@ -87,7 +103,6 @@ macro_rules! error {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! trace {
|
||||
// The target argument can be overridden using one of the following macros.
|
||||
(logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({
|
||||
log::trace!(logger: $logger, target: $target, $($arg)+)
|
||||
});
|
||||
@@ -96,8 +111,6 @@ macro_rules! trace {
|
||||
log::trace!(target: $target, $($arg)+)
|
||||
});
|
||||
|
||||
// The target argument will default to Self::ID if not provided.
|
||||
// Obviously, this is an error if Self::ID is not defined, forcing you to use the explicit form.
|
||||
(logger: $logger:expr, $($arg:tt)+) => ({
|
||||
log::trace!(logger: $logger, target: Self::ID, $($arg)+)
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// SPDX-License-Identifier: GNU General Public License v3.0 or later
|
||||
|
||||
use cxx_qt_lib::{QModelIndex, QString};
|
||||
use devicons::FileIcon;
|
||||
use dirs;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
@@ -142,13 +141,6 @@ impl qobject::FileSystem {
|
||||
}
|
||||
|
||||
fn icon(self: std::pin::Pin<&mut Self>, path: &QString) -> QString {
|
||||
let str = path.to_string();
|
||||
if Path::new(&str).is_dir() {
|
||||
// Ensures directories are given a folder icon and not mistakenly resolved to a language.
|
||||
// For example, a directory named `cpp` would otherwise return a C++ icon.
|
||||
return QString::from(FileIcon::from("dir/").to_string());
|
||||
}
|
||||
let icon = FileIcon::from(str);
|
||||
QString::from(icon.to_string())
|
||||
QString::from(libclide::fs::icon(path.to_string().as_str()).to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use clap::Parser;
|
||||
use log::{info, trace};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
pub mod gui;
|
||||
@@ -56,7 +55,7 @@ impl AppContext {
|
||||
// If no path was provided, use the current directory.
|
||||
None => std::env::current_dir().context("Failed to obtain current directory")?,
|
||||
};
|
||||
info!(target:"main()", "Root path detected: {path:?}");
|
||||
libclide::info!(target:"main()", "Root path detected: {path:?}");
|
||||
|
||||
Ok(Self {
|
||||
path,
|
||||
@@ -80,7 +79,7 @@ fn main() -> Result<()> {
|
||||
RunMode::GuiAttached => gui::run(app_context),
|
||||
RunMode::Tui => tui::run(app_context),
|
||||
RunMode::Gui => {
|
||||
trace!(target:"main()", "Starting GUI in a new process");
|
||||
libclide::trace!(target:"main()", "Starting GUI in a new process");
|
||||
Command::new(std::env::current_exe()?)
|
||||
.args(["--gui", app_context.path.to_str().unwrap()])
|
||||
.stdout(Stdio::null())
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<'a> Explorer<'a> {
|
||||
} else {
|
||||
children.push(TreeItem::new_leaf(
|
||||
entry_meta.abs_path.clone(),
|
||||
entry_meta.file_name.clone(),
|
||||
format!("{} {}", entry_meta.icon.icon, entry_meta.file_name.as_str()),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ impl<'a> Explorer<'a> {
|
||||
// For a file tree this is fine because we shouldn't list the same object twice.
|
||||
TreeItem::new(
|
||||
path_meta.abs_path.clone(),
|
||||
path_meta.file_name.clone(),
|
||||
format!("{} {}", path_meta.icon.icon, path_meta.file_name.as_str()),
|
||||
children,
|
||||
)
|
||||
.context(format!(
|
||||
|
||||
Reference in New Issue
Block a user