chore: define CompletionConfig at config.rs

This commit is contained in:
ynqa
2025-03-24 04:05:24 +09:00
parent f52c2a7c77
commit bf64782915
2 changed files with 84 additions and 56 deletions

View File

@@ -187,6 +187,71 @@ impl JsonTheme {
}
}
#[derive(Clone, Serialize, Deserialize, Builder)]
#[builder(derive(Serialize, Deserialize))]
#[builder(name = "CompletionConfigFromFile")]
pub(crate) struct CompletionConfig {
pub lines: Option<usize>,
#[builder_field_attr(serde(default))]
pub search_result_chunk_size: usize,
#[builder_field_attr(serde(default))]
pub search_load_chunk_size: usize,
#[serde(with = "content_style_serde")]
#[builder_field_attr(serde(default, with = "option_content_style_serde"))]
pub active_item_style: ContentStyle,
#[serde(with = "content_style_serde")]
#[builder_field_attr(serde(default, with = "option_content_style_serde"))]
pub inactive_item_style: ContentStyle,
}
impl Default for CompletionConfig {
fn default() -> Self {
Self {
lines: Some(3),
search_result_chunk_size: 100,
search_load_chunk_size: 50000,
active_item_style: StyleBuilder::new()
.fgc(Color::Grey)
.bgc(Color::Yellow)
.build(),
inactive_item_style: StyleBuilder::new().fgc(Color::Grey).build(),
}
}
}
impl CompletionConfigFromFile {
/// Load the config from a string.
pub fn load_from(content: &str) -> anyhow::Result<Self> {
toml::from_str(content).map_err(Into::into)
}
}
impl CompletionConfig {
pub fn patch_with(&mut self, config: CompletionConfigFromFile) {
// TODO: This is awful verbose. Can we do better?
match config.lines {
Some(val) => self.lines = val,
None => self.lines = None,
}
if let Some(val) = config.search_result_chunk_size {
self.search_result_chunk_size = val;
}
if let Some(val) = config.search_load_chunk_size {
self.search_load_chunk_size = val;
}
if let Some(val) = config.active_item_style {
self.active_item_style = val;
}
if let Some(val) = config.inactive_item_style {
self.inactive_item_style = val;
}
}
}
#[derive(Serialize, Deserialize, Builder)]
#[builder(derive(Serialize, Deserialize))]
#[builder(name = "ConfigFromFile")]
@@ -202,34 +267,14 @@ pub(crate) struct Config {
#[serde(with = "duration_serde")]
#[builder_field_attr(serde(default, with = "option_duration_serde"))]
pub spin_duration: Duration,
#[builder_field_attr(serde(default))]
pub search_result_chunk_size: usize,
#[builder_field_attr(serde(default))]
pub search_load_chunk_size: usize,
#[serde(with = "content_style_serde")]
#[builder_field_attr(serde(default, with = "option_content_style_serde"))]
pub active_item_style: ContentStyle,
#[serde(with = "content_style_serde")]
#[builder_field_attr(serde(default, with = "option_content_style_serde"))]
pub inactive_item_style: ContentStyle,
}
impl Default for Config {
fn default() -> Self {
Self {
active_item_style: StyleBuilder::new()
.fgc(Color::Grey)
.bgc(Color::Yellow)
.build(),
inactive_item_style: StyleBuilder::new().fgc(Color::Grey).build(),
search_result_chunk_size: 100,
query_debounce_duration: Duration::from_millis(600),
resize_debounce_duration: Duration::from_millis(200),
spin_duration: Duration::from_millis(300),
search_load_chunk_size: 50000,
}
}
}
@@ -252,18 +297,6 @@ impl Config {
if let Some(val) = config.spin_duration {
self.spin_duration = val;
}
if let Some(val) = config.search_result_chunk_size {
self.search_result_chunk_size = val;
}
if let Some(val) = config.search_load_chunk_size {
self.search_load_chunk_size = val;
}
if let Some(val) = config.active_item_style {
self.active_item_style = val;
}
if let Some(val) = config.inactive_item_style {
self.inactive_item_style = val;
}
}
}

View File

@@ -7,8 +7,8 @@ use std::{
use anyhow::anyhow;
use clap::Parser;
use config::{
Config, ConfigFromFile, EditorConfig, EditorConfigFromFile, JsonTheme, JsonThemeFromFile,
Keybinds, KeybindsFromFile,
CompletionConfig, CompletionConfigFromFile, Config, ConfigFromFile, EditorConfig,
EditorConfigFromFile, JsonTheme, JsonThemeFromFile, Keybinds, KeybindsFromFile,
};
use crossterm::style::Attribute;
use promkit::{
@@ -109,18 +109,6 @@ pub struct Args {
"
)]
pub max_streams: Option<usize>,
#[arg(
long = "suggestions",
default_value = "3",
help = "Number of autocomplete suggestions to show",
long_help = "
Sets the number of autocomplete suggestions displayed during incremental search.
Higher values show more suggestions but may occupy more screen space.
Adjust this value based on your screen size and preference.
"
)]
pub suggestions: usize,
}
fn edit_mode_validator(val: &str) -> anyhow::Result<text_editor::Mode> {
@@ -208,11 +196,19 @@ async fn main() -> anyhow::Result<()> {
let args = Args::parse();
let input = parse_input(&args)?;
let (mut config, mut keybinds, mut editor_config, mut json_theme) = (
#[rustfmt::skip]
let (
mut config,
mut keybinds,
mut editor_config,
mut json_theme,
mut comp_config,
) = (
Config::default(),
Keybinds::default(),
EditorConfig::default(),
JsonTheme::default(),
CompletionConfig::default(),
);
if let Ok(config_file) = determine_config_file(args.config_file, &config) {
// Note that the configuration file absolutely exists.
@@ -221,31 +217,29 @@ async fn main() -> anyhow::Result<()> {
let keybinds_from_file = KeybindsFromFile::load_from(&content)?;
let editor_config_from_file = EditorConfigFromFile::load_from(&content)?;
let json_theme_from_file = JsonThemeFromFile::load_from(&content)?;
let comp_config_from_file = CompletionConfigFromFile::load_from(&content)?;
config.patch_with(config_from_file);
keybinds.patch_with(keybinds_from_file);
editor_config.patch_with(editor_config_from_file);
json_theme.patch_with(json_theme_from_file);
comp_config.patch_with(comp_config_from_file);
}
let config::Config {
search_result_chunk_size,
query_debounce_duration,
resize_debounce_duration,
search_load_chunk_size,
active_item_style,
inactive_item_style,
spin_duration,
} = config;
let listbox_state = listbox::State {
listbox: Listbox::default(),
cursor: String::from(" "),
active_item_style: Some(active_item_style),
inactive_item_style: Some(inactive_item_style),
lines: Some(args.suggestions),
active_item_style: Some(comp_config.active_item_style),
inactive_item_style: Some(comp_config.inactive_item_style),
lines: comp_config.lines,
};
let searcher = IncrementalSearcher::new(listbox_state, search_result_chunk_size);
let searcher = IncrementalSearcher::new(listbox_state, comp_config.search_result_chunk_size);
let text_editor_state = text_editor::State {
texteditor: Default::default(),
@@ -278,7 +272,8 @@ async fn main() -> anyhow::Result<()> {
let item = Box::leak(input.into_boxed_str());
let loading_suggestions_task = searcher.spawn_load_task(provider, item, search_load_chunk_size);
let loading_suggestions_task =
searcher.spawn_load_task(provider, item, comp_config.search_load_chunk_size);
let editor = Editor::new(
text_editor_state,