Skip to content

Commit

Permalink
Use etcetera instead of directories
Browse files Browse the repository at this point in the history
It provides more flexibility and it has a better default for cli tools.

Fixes #1107.
  • Loading branch information
lu-zero committed Dec 22, 2024
1 parent 515e464 commit f2b600a
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 56 deletions.
35 changes: 13 additions & 22 deletions 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 @@ -52,7 +52,7 @@ chrono-humanize = "0.2.3"
clap = { version = "4.2", features = ["derive"] }
colors-transform = "0.2.11"
criterion = "0.5"
directories = "4.0"
etcetera = "0.8.0"
futures = "0.3"
fuzzy-matcher = "0.3"
grep-matcher = "0.1"
Expand Down
6 changes: 3 additions & 3 deletions crates/cli/src/command/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl List {

if self.all {
writeln!(lock, "Cached entries:")?;
let mut entries = read_dir(&cache_dir)?
let mut entries = read_dir(cache_dir)?
.map(|res| {
res.map(|e| {
e.path()
Expand Down Expand Up @@ -81,7 +81,7 @@ impl Purge {
fn run(&self) -> Result<()> {
let cache_dir = Dirs::clap_cache_dir()?;

if let Ok(cache_size) = dir_size(&cache_dir) {
if let Ok(cache_size) = dir_size(cache_dir) {
let readable_size = if cache_size > 1024 * 1024 {
format!("{}MB", cache_size / 1024 / 1024)
} else if cache_size > 1024 {
Expand All @@ -99,7 +99,7 @@ impl Purge {
}
}

remove_dir_contents(&cache_dir)?;
remove_dir_contents(cache_dir)?;

println!(
"Current cache directory {} has been purged sucessfully",
Expand Down
2 changes: 1 addition & 1 deletion crates/dirs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ version.workspace = true
edition.workspace = true

[dependencies]
directories = { workspace = true }
etcetera = { workspace = true }
74 changes: 61 additions & 13 deletions crates/dirs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,81 @@
use directories::{BaseDirs, ProjectDirs};
use std::path::PathBuf;
use etcetera::app_strategy::choose_native_strategy;
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
use std::path::{Path, PathBuf};
use std::sync::OnceLock;

pub struct Dirs;

pub struct DirsProject {
home_dir: PathBuf,
config_dir: PathBuf,
cache_dir: PathBuf,
data_dir: PathBuf,
}

impl DirsProject {
fn new(app: impl AppStrategy) -> Self {
DirsProject {
home_dir: app.home_dir().to_path_buf(),
config_dir: app.config_dir(),
cache_dir: app.cache_dir(),
data_dir: app.data_dir(),
}
}
}

impl Dirs {
/// Project directory specifically for Vim Clap.
///
/// All the files created by vim-clap are stored there.
pub fn project() -> &'static ProjectDirs {
static CELL: OnceLock<ProjectDirs> = OnceLock::new();
fn project() -> &'static DirsProject {
static CELL: OnceLock<DirsProject> = OnceLock::new();

CELL.get_or_init(|| {
ProjectDirs::from("org", "vim", "Vim Clap")
.expect("Couldn't create project directory for vim-clap")
let app = AppStrategyArgs {
top_level_domain: "org".to_string(),
author: "vim".to_owned(),
app_name: "Vim Clap".to_owned(),
};

if cfg!(target_os = "macos") {
// SAFETY it does never fail
let apple =
choose_native_strategy(app.clone()).expect("Cannot find the home directory");

if apple.in_config_dir("config.toml").exists() {
return DirsProject::new(apple);
}
}
let xdg = choose_app_strategy(app).expect("Cannot find the home directory");

DirsProject::new(xdg)
})
}

/// Provides access to the standard directories that the operating system uses.
pub fn base() -> &'static BaseDirs {
static CELL: OnceLock<BaseDirs> = OnceLock::new();
/// Get the home directory
pub fn home_dir() -> &'static Path {
Self::project().home_dir.as_path()
}

/// Get the config directory
pub fn config_dir() -> &'static Path {
Self::project().config_dir.as_path()
}

/// Get the cache directory
pub fn cache_dir() -> &'static Path {
Self::project().cache_dir.as_path()
}

CELL.get_or_init(|| BaseDirs::new().expect("Failed to construct BaseDirs"))
/// Get the data directory
pub fn data_dir() -> &'static Path {
Self::project().data_dir.as_path()
}

/// Cache directory for Vim Clap project.
pub fn clap_cache_dir() -> std::io::Result<PathBuf> {
let cache_dir = Self::project().cache_dir();
pub fn clap_cache_dir() -> std::io::Result<&'static Path> {
let cache_dir = Self::cache_dir();
std::fs::create_dir_all(cache_dir)?;
Ok(cache_dir.to_path_buf())
Ok(cache_dir)
}
}
5 changes: 2 additions & 3 deletions crates/maple_config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ fn load_config(
specified_config_file: Option<PathBuf>,
) -> (Config, PathBuf, Option<toml::de::Error>) {
let config_file = specified_config_file.unwrap_or_else(|| {
// Linux: ~/.config/vimclap/config.toml
// macOS: ~/Library/Application\ Support/org.vim.Vim-Clap/config.toml
// Linux & macOS: ~/.config/vimclap/config.toml
// Windows: ~\AppData\Roaming\Vim\Vim Clap\config\config.toml
let config_file_path = Dirs::project().config_dir().join("config.toml");
let config_file_path = Dirs::config_dir().join("config.toml");

if !config_file_path.exists() {
std::fs::create_dir_all(&config_file_path).ok();
Expand Down
4 changes: 2 additions & 2 deletions crates/maple_core/src/datastore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ pub fn cache_metadata_path() -> Option<&'static PathBuf> {

/// Returns a `PathBuf` using given file name under the project data directory.
pub fn generate_data_file_path(filename: &str) -> std::io::Result<PathBuf> {
let data_dir = Dirs::project().data_dir();
let data_dir = Dirs::data_dir();
std::fs::create_dir_all(data_dir)?;
Ok(data_dir.join(filename))
}

/// Returns a `PathBuf` using given file name under the project cache directory.
pub fn generate_cache_file_path(filename: impl AsRef<Path>) -> std::io::Result<PathBuf> {
let cache_dir = Dirs::project().cache_dir();
let cache_dir = Dirs::cache_dir();
std::fs::create_dir_all(cache_dir)?;
Ok(cache_dir.join(filename))
}
Expand Down
2 changes: 1 addition & 1 deletion crates/maple_core/src/searcher/tagfiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl TagItem {
let mut home_path = PathBuf::new();
let path = Path::new(&self.path);
let path = path.strip_prefix(cwd).unwrap_or({
path.strip_prefix(Dirs::base().home_dir())
path.strip_prefix(Dirs::home_dir())
.map(|path| {
home_path.push("~");
home_path = home_path.join(path);
Expand Down
2 changes: 1 addition & 1 deletion crates/maple_core/src/stdio_server/winbar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub async fn update_winbar(
}
None => winwidth,
};
let path = if let Some(home) = dirs::Dirs::base().home_dir().to_str() {
let path = if let Some(home) = dirs::Dirs::home_dir().to_str() {
path.replacen(home, "~", 1)
} else {
path
Expand Down
2 changes: 1 addition & 1 deletion crates/maple_core/src/tools/ctags/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub static DEFAULT_EXCLUDE_OPT: Lazy<String> = Lazy::new(|| {

/// Directory for the `tags` files.
pub static CTAGS_TAGS_DIR: Lazy<PathBuf> = Lazy::new(|| {
let tags_dir = Dirs::project().data_dir().join("tags");
let tags_dir = Dirs::data_dir().join("tags");

std::fs::create_dir_all(&tags_dir).expect("Couldn't create tags directory for vim-clap");

Expand Down
2 changes: 1 addition & 1 deletion crates/maple_core/src/tools/gtags/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub static GTAGS_EXISTS: Lazy<bool> = Lazy::new(|| gtags_executable_exists().unw

/// Directory for `GTAGS`/`GRTAGS`.
pub static GTAGS_DIR: Lazy<PathBuf> = Lazy::new(|| {
let gtags_dir = Dirs::project().data_dir().join("gtags");
let gtags_dir = Dirs::data_dir().join("gtags");

std::fs::create_dir_all(&gtags_dir).expect("Couldn't create gtags directory for vim-clap");

Expand Down
11 changes: 4 additions & 7 deletions crates/paths/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl<'de> Deserialize<'de> for AbsPathBuf {
if path.is_absolute() {
Ok(Self(path))
} else if let Ok(stripped) = path.strip_prefix("~") {
let path = Dirs::base().home_dir().join(stripped);
let path = Dirs::home_dir().join(stripped);
// Resolve the symlink.
let path =
canonicalize(path).map_err(|err| DeserializeError::custom(err.to_string()))?;
Expand Down Expand Up @@ -124,7 +124,7 @@ pub fn expand_tilde(path: impl AsRef<str>) -> PathBuf {
.as_ref()
.strip_prefix(HOME_PREFIX.get_or_init(|| format!("~{MAIN_SEPARATOR}")))
{
Dirs::base().home_dir().join(stripped)
Dirs::home_dir().join(stripped)
} else {
path.as_ref().into()
}
Expand All @@ -135,7 +135,7 @@ pub fn truncate_absolute_path(abs_path: &str, max_len: usize) -> Cow<'_, str> {
if abs_path.len() > max_len {
let gap = abs_path.len() - max_len;

if let Some(home_dir) = Dirs::base().home_dir().to_str() {
if let Some(home_dir) = Dirs::home_dir().to_str() {
if abs_path.starts_with(home_dir) {
// ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/string.rs
if home_dir.len() > gap {
Expand Down Expand Up @@ -302,10 +302,7 @@ mod tests {
let p = ".rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/string.rs";
#[cfg(target_os = "windows")]
let p = r#".rustup\toolchains\stable-x86_64-unknown-linux-gnu\lib\rustlib\src\rust\library\alloc\src\string.rs"#;
let abs_path = format!(
"{}{MAIN_SEPARATOR}{p}",
Dirs::base().home_dir().to_str().unwrap(),
);
let abs_path = format!("{}{MAIN_SEPARATOR}{p}", Dirs::home_dir().to_str().unwrap(),);
let max_len = 60;
#[cfg(not(target_os = "windows"))]
let expected = "~/.rustup/.../src/rust/library/alloc/src/string.rs";
Expand Down

0 comments on commit f2b600a

Please sign in to comment.