aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--book/src/configuration.md12
-rw-r--r--helix-term/src/application.rs2
-rw-r--r--helix-term/src/commands.rs79
-rw-r--r--helix-term/src/ui/mod.rs11
-rw-r--r--helix-view/src/editor.rs42
5 files changed, 112 insertions, 34 deletions
diff --git a/book/src/configuration.md b/book/src/configuration.md
index be25441f..2ed48d51 100644
--- a/book/src/configuration.md
+++ b/book/src/configuration.md
@@ -24,6 +24,18 @@ To override global configuration parameters, create a `config.toml` file located
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `auto-info` | Whether to display infoboxes | `true` |
+`[editor.filepicker]` section of the config. Sets options for file picker and global search. All but the last key listed in the default file-picker configuration below are IgnoreOptions: whether hidden files and files listed within ignore files are ignored by (not visible in) the helix file picker and global search. There is also one other key, `max-depth` available, which is not defined by default.
+
+| Key | Description | Default |
+|--|--|---------|
+|`hidden` | Enables ignoring hidden files. | true
+|`parents` | Enables reading ignore files from parent directories. | true
+|`ignore` | Enables reading `.ignore` files. | true
+|`git-ignore` | Enables reading `.gitignore` files. | true
+|`git-global` | Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option. | true
+|`git-exclude` | Enables reading `.git/info/exclude` files. | true
+|`max-depth` | Set with an integer value for maximum depth to recurse. | Defaults to `None`.
+
## LSP
To display all language server messages in the status line add the following to your `config.toml`:
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 78b93cd9..a795a56e 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -120,7 +120,7 @@ impl Application {
if first.is_dir() {
std::env::set_current_dir(&first)?;
editor.new_file(Action::VerticalSplit);
- compositor.push(Box::new(ui::file_picker(".".into())));
+ compositor.push(Box::new(ui::file_picker(".".into(), &config.editor)));
} else {
let nr_of_files = args.files.len();
editor.open(first.to_path_buf(), Action::VerticalSplit)?;
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index e70773eb..fde505fd 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1440,6 +1440,7 @@ fn global_search(cx: &mut Context) {
let (all_matches_sx, all_matches_rx) =
tokio::sync::mpsc::unbounded_channel::<(usize, PathBuf)>();
let smart_case = cx.editor.config.smart_case;
+ let file_picker_config = cx.editor.config.file_picker.clone();
let completions = search_completions(cx, None);
let prompt = ui::regex_prompt(
@@ -1468,41 +1469,55 @@ fn global_search(cx: &mut Context) {
let search_root = std::env::current_dir()
.expect("Global search error: Failed to get current dir");
- WalkBuilder::new(search_root).build_parallel().run(|| {
- let mut searcher_cl = searcher.clone();
- let matcher_cl = matcher.clone();
- let all_matches_sx_cl = all_matches_sx.clone();
- Box::new(move |dent: Result<DirEntry, ignore::Error>| -> WalkState {
- let dent = match dent {
- Ok(dent) => dent,
- Err(_) => return WalkState::Continue,
- };
-
- match dent.file_type() {
- Some(fi) => {
- if !fi.is_file() {
- return WalkState::Continue;
+ WalkBuilder::new(search_root)
+ .hidden(file_picker_config.hidden)
+ .parents(file_picker_config.parents)
+ .ignore(file_picker_config.ignore)
+ .git_ignore(file_picker_config.git_ignore)
+ .git_global(file_picker_config.git_global)
+ .git_exclude(file_picker_config.git_exclude)
+ .max_depth(file_picker_config.max_depth)
+ .build_parallel()
+ .run(|| {
+ let mut searcher_cl = searcher.clone();
+ let matcher_cl = matcher.clone();
+ let all_matches_sx_cl = all_matches_sx.clone();
+ Box::new(move |dent: Result<DirEntry, ignore::Error>| -> WalkState {
+ let dent = match dent {
+ Ok(dent) => dent,
+ Err(_) => return WalkState::Continue,
+ };
+
+ match dent.file_type() {
+ Some(fi) => {
+ if !fi.is_file() {
+ return WalkState::Continue;
+ }
}
+ None => return WalkState::Continue,
}
- None => return WalkState::Continue,
- }
- let result_sink = sinks::UTF8(|line_num, _| {
- match all_matches_sx_cl
- .send((line_num as usize - 1, dent.path().to_path_buf()))
- {
- Ok(_) => Ok(true),
- Err(_) => Ok(false),
+ let result_sink = sinks::UTF8(|line_num, _| {
+ match all_matches_sx_cl
+ .send((line_num as usize - 1, dent.path().to_path_buf()))
+ {
+ Ok(_) => Ok(true),
+ Err(_) => Ok(false),
+ }
+ });
+ let result =
+ searcher_cl.search_path(&matcher_cl, dent.path(), result_sink);
+
+ if let Err(err) = result {
+ log::error!(
+ "Global search error: {}, {}",
+ dent.path().display(),
+ err
+ );
}
- });
- let result = searcher_cl.search_path(&matcher_cl, dent.path(), result_sink);
-
- if let Err(err) = result {
- log::error!("Global search error: {}, {}", dent.path().display(), err);
- }
- WalkState::Continue
- })
- });
+ WalkState::Continue
+ })
+ });
} else {
// Otherwise do nothing
// log::warn!("Global Search Invalid Pattern")
@@ -2742,7 +2757,7 @@ fn command_mode(cx: &mut Context) {
fn file_picker(cx: &mut Context) {
let root = find_root(None).unwrap_or_else(|| PathBuf::from("./"));
- let picker = ui::file_picker(root);
+ let picker = ui::file_picker(root, &cx.editor.config);
cx.push_layer(Box::new(picker));
}
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index 62da0dce..cdf42311 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -93,13 +93,22 @@ pub fn regex_prompt(
)
}
-pub fn file_picker(root: PathBuf) -> FilePicker<PathBuf> {
+pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePicker<PathBuf> {
use ignore::{types::TypesBuilder, WalkBuilder};
use std::time;
// We want to exclude files that the editor can't handle yet
let mut type_builder = TypesBuilder::new();
let mut walk_builder = WalkBuilder::new(&root);
+ walk_builder
+ .hidden(config.file_picker.hidden)
+ .parents(config.file_picker.parents)
+ .ignore(config.file_picker.ignore)
+ .git_ignore(config.file_picker.git_ignore)
+ .git_global(config.file_picker.git_global)
+ .git_exclude(config.file_picker.git_exclude)
+ .max_depth(config.file_picker.max_depth);
+
let walk_builder = match type_builder.add(
"compressed",
"*.{zip,gz,bz2,zst,lzo,sz,tgz,tbz2,lz,lz4,lzma,lzo,z,Z,xz,7z,rar,cab}",
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 364865d9..1ce33760 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -37,6 +37,46 @@ where
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "kebab-case", default, deny_unknown_fields)]
+pub struct FilePickerConfig {
+ /// IgnoreOptions
+ /// Enables ignoring hidden files.
+ /// Whether to hide hidden files in file picker and global search results. Defaults to true.
+ pub hidden: bool,
+ /// Enables reading ignore files from parent directories. Defaults to true.
+ pub parents: bool,
+ /// Enables reading `.ignore` files.
+ /// Whether to hide files listed in .ignore in file picker and global search results. Defaults to true.
+ pub ignore: bool,
+ /// Enables reading `.gitignore` files.
+ /// Whether to hide files listed in .gitignore in file picker and global search results. Defaults to true.
+ pub git_ignore: bool,
+ /// Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option.
+ /// Whether to hide files listed in global .gitignore in file picker and global search results. Defaults to true.
+ pub git_global: bool,
+ /// Enables reading `.git/info/exclude` files.
+ /// Whether to hide files listed in .git/info/exclude in file picker and global search results. Defaults to true.
+ pub git_exclude: bool,
+ /// WalkBuilder options
+ /// Maximum Depth to recurse directories in file picker and global search. Defaults to `None`.
+ pub max_depth: Option<usize>,
+}
+
+impl Default for FilePickerConfig {
+ fn default() -> Self {
+ Self {
+ hidden: true,
+ parents: true,
+ ignore: true,
+ git_ignore: true,
+ git_global: true,
+ git_exclude: true,
+ max_depth: None,
+ }
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Deserialize)]
+#[serde(rename_all = "kebab-case", default, deny_unknown_fields)]
pub struct Config {
/// Padding to keep between the edge of the screen and the cursor when scrolling. Defaults to 5.
pub scrolloff: usize,
@@ -62,6 +102,7 @@ pub struct Config {
pub completion_trigger_len: u8,
/// Whether to display infoboxes. Defaults to true.
pub auto_info: bool,
+ pub file_picker: FilePickerConfig,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
@@ -93,6 +134,7 @@ impl Default for Config {
idle_timeout: Duration::from_millis(400),
completion_trigger_len: 2,
auto_info: true,
+ file_picker: FilePickerConfig::default(),
}
}
}