Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep the support of ~/Library/Application\ Support/org.vim.Vim-Clap/config.toml on macOS? This will ensure compatibility for existing macOS users, preventing any complaints about their current configuration file no longer working.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add the logic to look on both places.


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