use serde::Deserialize;
use std::collections::HashMap;
const DEFAULT_CTAGS_TIMEOUT_MS: u64 = 500;
#[derive(Clone, Debug, Deserialize, Default)]
pub struct PicklsConfig {
#[serde(default)]
pub languages: HashMap<String, PicklsLanguageConfig>,
pub symbols: Option<PicklsSymbolsConfig>,
#[serde(default)]
pub ai: PicklsAIConfig,
}
fn default_ctags_timeout_ms() -> u64 {
DEFAULT_CTAGS_TIMEOUT_MS
}
#[derive(Eq, PartialEq, Clone, Debug, Deserialize)]
pub struct PicklsSymbolsConfig {
pub source: PicklsSymbolsSource,
#[serde(default = "default_ctags_timeout_ms")]
pub ctags_timeout_ms: u64,
}
#[derive(Eq, PartialEq, Clone, Debug, Deserialize)]
pub enum PicklsSymbolsSource {
#[serde(rename = "universal-ctags")]
UniversalCtags,
}
#[derive(Clone, Debug, Default, Deserialize)]
pub struct PicklsLanguageConfig {
#[serde(default)]
pub root_markers: Vec<String>,
#[serde(default)]
pub linters: Vec<PicklsLinterConfig>,
#[serde(default)]
pub formatters: Vec<PicklsFormatterConfig>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct PicklsLinterConfig {
pub program: String,
#[serde(default = "Vec::new")]
pub args: Vec<String>,
pub use_stdin: bool,
pub pattern: String,
pub filename_match: Option<usize>,
pub line_match: usize,
pub start_col_match: Option<usize>,
pub end_col_match: Option<usize>,
pub severity_match: Option<usize>,
pub description_match: Option<isize>,
#[serde(default = "default_false")]
pub use_stderr: bool,
}
fn default_false() -> bool {
false
}
fn default_true() -> bool {
true
}
#[derive(Clone, Debug, Deserialize)]
pub struct PicklsFormatterConfig {
pub program: String,
pub args: Vec<String>,
#[serde(default = "default_true")]
pub use_stdin: bool,
#[serde(default = "default_false")]
pub stderr_indicates_error: bool,
}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct PicklsAIConfig {
#[serde(default = "default_inline_assist_system_prompt")]
pub system_prompt: String,
pub inline_assist_provider: PicklsAIProvider,
#[serde(default = "default_inline_assist_prompt_template")]
pub inline_assist_prompt_template: String,
pub openai: Option<OpenAIConfig>,
pub ollama: Option<OllamaConfig>,
}
#[derive(Clone, Debug, Deserialize, Default)]
pub struct OllamaConfig {
pub model: String,
pub api_address: String,
}
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum PicklsAIProvider {
#[default]
OpenAI,
Ollama,
}
#[derive(Clone, Debug, Deserialize)]
pub struct OpenAIConfig {
pub model: String,
#[serde(default = "default_openai_api_key_cmd")]
pub api_key_cmd: Vec<String>,
}
impl Default for OpenAIConfig {
fn default() -> Self {
OpenAIConfig {
model: "gpt-4o".to_string(),
api_key_cmd: default_openai_api_key_cmd(),
}
}
}
fn default_openai_api_key_cmd() -> Vec<String> {
["sh", "-c", "echo $OPENAI_API_KEY"]
.into_iter()
.map(|s| s.to_string())
.collect()
}
fn default_inline_assist_prompt_template() -> String {
"I'm working within the {{language_id}} language. If I show you code below, then please \
rewrite it to make improvements as you see fit. If I show you a question or directive, \
write code to satisfy the question or directive. Never use markdown to format your response. \
For example, do not use triple backticks (```). Always include type annotations where possible.\n\n\
{{text}}\n"
.to_string()
}
fn default_inline_assist_system_prompt() -> String {
"You are an inline assistant for a code editor. Your response to user prompts will be used \
to replace code in the editor."
.to_string()
}