mirror of https://github.com/helix-editor/helix
Merge e33e8a678c
into 362e97e927
commit
db90220fb5
|
@ -195,6 +195,7 @@ All git related options are only enabled in a git repository.
|
||||||
| Key | Description | Default |
|
| Key | Description | Default |
|
||||||
|--|--|---------|
|
|--|--|---------|
|
||||||
|`hidden` | Enables ignoring hidden files | `true`
|
|`hidden` | Enables ignoring hidden files | `true`
|
||||||
|
|`binary` | Enables ignoring binary files | `false`
|
||||||
|`follow-symlinks` | Follow symlinks instead of ignoring them | `true`
|
|`follow-symlinks` | Follow symlinks instead of ignoring them | `true`
|
||||||
|`deduplicate-links` | Ignore symlinks that point at files already shown in the picker | `true`
|
|`deduplicate-links` | Ignore symlinks that point at files already shown in the picker | `true`
|
||||||
|`parents` | Enables reading ignore files from parent directories | `true`
|
|`parents` | Enables reading ignore files from parent directories | `true`
|
||||||
|
|
|
@ -2552,7 +2552,7 @@ fn global_search(cx: &mut Context) {
|
||||||
.git_exclude(config.file_picker_config.git_exclude)
|
.git_exclude(config.file_picker_config.git_exclude)
|
||||||
.max_depth(config.file_picker_config.max_depth)
|
.max_depth(config.file_picker_config.max_depth)
|
||||||
.filter_entry(move |entry| {
|
.filter_entry(move |entry| {
|
||||||
filter_picker_entry(entry, &absolute_root, dedup_symlinks)
|
filter_picker_entry(entry, &absolute_root, dedup_symlinks, false)
|
||||||
})
|
})
|
||||||
.add_custom_ignore_filename(helix_loader::config_dir().join("ignore"))
|
.add_custom_ignore_filename(helix_loader::config_dir().join("ignore"))
|
||||||
.add_custom_ignore_filename(".helix/ignore")
|
.add_custom_ignore_filename(".helix/ignore")
|
||||||
|
|
|
@ -12,7 +12,11 @@ pub mod job;
|
||||||
pub mod keymap;
|
pub mod keymap;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{self, Read},
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
use futures_util::Future;
|
use futures_util::Future;
|
||||||
mod handlers;
|
mod handlers;
|
||||||
|
@ -44,8 +48,24 @@ fn true_color() -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_binary(path: &Path, read_buffer: &mut Vec<u8>) -> io::Result<bool> {
|
||||||
|
let content_type = File::open(path).and_then(|file| {
|
||||||
|
// Read up to 1kb to detect the content type
|
||||||
|
let n = file.take(1024).read_to_end(read_buffer)?;
|
||||||
|
let content_type = content_inspector::inspect(&read_buffer[..n]);
|
||||||
|
read_buffer.clear();
|
||||||
|
Ok(content_type)
|
||||||
|
})?;
|
||||||
|
Ok(content_type.is_binary())
|
||||||
|
}
|
||||||
|
|
||||||
/// Function used for filtering dir entries in the various file pickers.
|
/// Function used for filtering dir entries in the various file pickers.
|
||||||
fn filter_picker_entry(entry: &DirEntry, root: &Path, dedup_symlinks: bool) -> bool {
|
fn filter_picker_entry(
|
||||||
|
entry: &DirEntry,
|
||||||
|
root: &Path,
|
||||||
|
dedup_symlinks: bool,
|
||||||
|
ignore_binary_files: bool,
|
||||||
|
) -> bool {
|
||||||
// We always want to ignore popular VCS directories, otherwise if
|
// We always want to ignore popular VCS directories, otherwise if
|
||||||
// `ignore` is turned off, we end up with a lot of noise
|
// `ignore` is turned off, we end up with a lot of noise
|
||||||
// in our picker.
|
// in our picker.
|
||||||
|
@ -66,6 +86,12 @@ fn filter_picker_entry(entry: &DirEntry, root: &Path, dedup_symlinks: bool) -> b
|
||||||
.is_some_and(|path| !path.starts_with(root));
|
.is_some_and(|path| !path.starts_with(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ignore_binary_files {
|
||||||
|
if let Ok(is_binary) = is_binary(entry.path(), &mut Vec::new()) {
|
||||||
|
return !is_binary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,8 +205,8 @@ pub fn file_picker(editor: &Editor, root: PathBuf) -> FilePicker {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
let dedup_symlinks = config.file_picker.deduplicate_links;
|
let dedup_symlinks = config.file_picker.deduplicate_links;
|
||||||
|
let ignore_binaries = config.file_picker.binary_files;
|
||||||
let absolute_root = root.canonicalize().unwrap_or_else(|_| root.clone());
|
let absolute_root = root.canonicalize().unwrap_or_else(|_| root.clone());
|
||||||
|
|
||||||
let mut walk_builder = WalkBuilder::new(&root);
|
let mut walk_builder = WalkBuilder::new(&root);
|
||||||
walk_builder
|
walk_builder
|
||||||
.hidden(config.file_picker.hidden)
|
.hidden(config.file_picker.hidden)
|
||||||
|
@ -218,7 +218,9 @@ pub fn file_picker(editor: &Editor, root: PathBuf) -> FilePicker {
|
||||||
.git_exclude(config.file_picker.git_exclude)
|
.git_exclude(config.file_picker.git_exclude)
|
||||||
.sort_by_file_name(|name1, name2| name1.cmp(name2))
|
.sort_by_file_name(|name1, name2| name1.cmp(name2))
|
||||||
.max_depth(config.file_picker.max_depth)
|
.max_depth(config.file_picker.max_depth)
|
||||||
.filter_entry(move |entry| filter_picker_entry(entry, &absolute_root, dedup_symlinks));
|
.filter_entry(move |entry| {
|
||||||
|
filter_picker_entry(entry, &absolute_root, dedup_symlinks, ignore_binaries)
|
||||||
|
});
|
||||||
|
|
||||||
walk_builder.add_custom_ignore_filename(helix_loader::config_dir().join("ignore"));
|
walk_builder.add_custom_ignore_filename(helix_loader::config_dir().join("ignore"));
|
||||||
walk_builder.add_custom_ignore_filename(".helix/ignore");
|
walk_builder.add_custom_ignore_filename(".helix/ignore");
|
||||||
|
|
|
@ -4,7 +4,7 @@ mod query;
|
||||||
use crate::{
|
use crate::{
|
||||||
alt,
|
alt,
|
||||||
compositor::{self, Component, Compositor, Context, Event, EventResult},
|
compositor::{self, Component, Compositor, Context, Event, EventResult},
|
||||||
ctrl, key, shift,
|
ctrl, is_binary, key, shift,
|
||||||
ui::{
|
ui::{
|
||||||
self,
|
self,
|
||||||
document::{render_document, LinePos, TextRenderer},
|
document::{render_document, LinePos, TextRenderer},
|
||||||
|
@ -31,7 +31,6 @@ use tui::widgets::Widget;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io::Read,
|
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{self, AtomicUsize},
|
atomic::{self, AtomicUsize},
|
||||||
|
@ -612,17 +611,11 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||||
if metadata.len() > MAX_FILE_SIZE_FOR_PREVIEW {
|
if metadata.len() > MAX_FILE_SIZE_FOR_PREVIEW {
|
||||||
return Ok(CachedPreview::LargeFile);
|
return Ok(CachedPreview::LargeFile);
|
||||||
}
|
}
|
||||||
let content_type = std::fs::File::open(&path).and_then(|file| {
|
|
||||||
// Read up to 1kb to detect the content type
|
if is_binary(&path, &mut self.read_buffer)? {
|
||||||
let n = file.take(1024).read_to_end(&mut self.read_buffer)?;
|
|
||||||
let content_type =
|
|
||||||
content_inspector::inspect(&self.read_buffer[..n]);
|
|
||||||
self.read_buffer.clear();
|
|
||||||
Ok(content_type)
|
|
||||||
})?;
|
|
||||||
if content_type.is_binary() {
|
|
||||||
return Ok(CachedPreview::Binary);
|
return Ok(CachedPreview::Binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut doc = Document::open(
|
let mut doc = Document::open(
|
||||||
&path,
|
&path,
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -746,7 +746,7 @@ async fn test_hardlink_write() -> anyhow::Result<()> {
|
||||||
async fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> {
|
async fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> {
|
||||||
let mut file = tempfile::NamedTempFile::new()?;
|
let mut file = tempfile::NamedTempFile::new()?;
|
||||||
|
|
||||||
file.as_file_mut().write_all(&file_content)?;
|
file.as_file_mut().write_all(file_content)?;
|
||||||
|
|
||||||
helpers::test_key_sequence(
|
helpers::test_key_sequence(
|
||||||
&mut helpers::AppBuilder::new()
|
&mut helpers::AppBuilder::new()
|
||||||
|
|
|
@ -425,7 +425,7 @@ pub fn reload_file(file: &mut NamedTempFile) -> anyhow::Result<()> {
|
||||||
let f = std::fs::OpenOptions::new()
|
let f = std::fs::OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
.read(true)
|
.read(true)
|
||||||
.open(&path)?;
|
.open(path)?;
|
||||||
*file.as_file_mut() = f;
|
*file.as_file_mut() = f;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,9 @@ pub struct FilePickerConfig {
|
||||||
/// Enables ignoring hidden files.
|
/// Enables ignoring hidden files.
|
||||||
/// Whether to hide hidden files in file picker and global search results. Defaults to true.
|
/// Whether to hide hidden files in file picker and global search results. Defaults to true.
|
||||||
pub hidden: bool,
|
pub hidden: bool,
|
||||||
|
/// Enables ignoring binary files.
|
||||||
|
/// Whether to hide binary files in file picker. Defaults to false.
|
||||||
|
pub binary_files: bool,
|
||||||
/// Enables following symlinks.
|
/// Enables following symlinks.
|
||||||
/// Whether to follow symbolic links in file picker and file or directory completions. Defaults to true.
|
/// Whether to follow symbolic links in file picker and file or directory completions. Defaults to true.
|
||||||
pub follow_symlinks: bool,
|
pub follow_symlinks: bool,
|
||||||
|
@ -218,6 +221,7 @@ impl Default for FilePickerConfig {
|
||||||
git_global: true,
|
git_global: true,
|
||||||
git_exclude: true,
|
git_exclude: true,
|
||||||
max_depth: None,
|
max_depth: None,
|
||||||
|
binary_files: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue