terminal_settings.rs

  1use gpui::{AppContext, FontFeatures, Pixels};
  2use schemars::JsonSchema;
  3use serde_derive::{Deserialize, Serialize};
  4use std::{collections::HashMap, path::PathBuf};
  5
  6#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
  7#[serde(rename_all = "snake_case")]
  8pub enum TerminalDockPosition {
  9    Left,
 10    Bottom,
 11    Right,
 12}
 13
 14#[derive(Deserialize)]
 15pub struct TerminalSettings {
 16    pub shell: Shell,
 17    pub working_directory: WorkingDirectory,
 18    pub font_size: Option<Pixels>,
 19    pub font_family: Option<String>,
 20    pub line_height: TerminalLineHeight,
 21    pub font_features: Option<FontFeatures>,
 22    pub env: HashMap<String, String>,
 23    pub blinking: TerminalBlink,
 24    pub alternate_scroll: AlternateScroll,
 25    pub option_as_meta: bool,
 26    pub copy_on_select: bool,
 27    pub dock: TerminalDockPosition,
 28    pub default_width: f32,
 29    pub default_height: f32,
 30    pub detect_venv: VenvSettings,
 31}
 32
 33#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
 34#[serde(rename_all = "snake_case")]
 35pub enum VenvSettings {
 36    #[default]
 37    Off,
 38    On {
 39        activate_script: Option<ActivateScript>,
 40        directories: Option<Vec<PathBuf>>,
 41    },
 42}
 43
 44pub struct VenvSettingsContent<'a> {
 45    pub activate_script: ActivateScript,
 46    pub directories: &'a [PathBuf],
 47}
 48
 49impl VenvSettings {
 50    pub fn as_option(&self) -> Option<VenvSettingsContent> {
 51        match self {
 52            VenvSettings::Off => None,
 53            VenvSettings::On {
 54                activate_script,
 55                directories,
 56            } => Some(VenvSettingsContent {
 57                activate_script: activate_script.unwrap_or(ActivateScript::Default),
 58                directories: directories.as_deref().unwrap_or(&[]),
 59            }),
 60        }
 61    }
 62}
 63
 64#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)]
 65#[serde(rename_all = "snake_case")]
 66pub enum ActivateScript {
 67    #[default]
 68    Default,
 69    Csh,
 70    Fish,
 71    Nushell,
 72}
 73
 74#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
 75pub struct TerminalSettingsContent {
 76    pub shell: Option<Shell>,
 77    pub working_directory: Option<WorkingDirectory>,
 78    pub font_size: Option<f32>,
 79    pub font_family: Option<String>,
 80    pub line_height: Option<TerminalLineHeight>,
 81    pub font_features: Option<FontFeatures>,
 82    pub env: Option<HashMap<String, String>>,
 83    pub blinking: Option<TerminalBlink>,
 84    pub alternate_scroll: Option<AlternateScroll>,
 85    pub option_as_meta: Option<bool>,
 86    pub copy_on_select: Option<bool>,
 87    pub dock: Option<TerminalDockPosition>,
 88    pub default_width: Option<f32>,
 89    pub default_height: Option<f32>,
 90    pub detect_venv: Option<VenvSettings>,
 91}
 92
 93impl settings::Settings for TerminalSettings {
 94    const KEY: Option<&'static str> = Some("terminal");
 95
 96    type FileContent = TerminalSettingsContent;
 97
 98    fn load(
 99        default_value: &Self::FileContent,
100        user_values: &[&Self::FileContent],
101        _: &mut AppContext,
102    ) -> anyhow::Result<Self> {
103        Self::load_via_json_merge(default_value, user_values)
104    }
105}
106
107#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
108#[serde(rename_all = "snake_case")]
109pub enum TerminalLineHeight {
110    #[default]
111    Comfortable,
112    Standard,
113    Custom(f32),
114}
115
116impl TerminalLineHeight {
117    pub fn value(&self) -> f32 {
118        match self {
119            TerminalLineHeight::Comfortable => 1.618,
120            TerminalLineHeight::Standard => 1.3,
121            TerminalLineHeight::Custom(line_height) => f32::max(*line_height, 1.),
122        }
123    }
124}
125
126#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
127#[serde(rename_all = "snake_case")]
128pub enum TerminalBlink {
129    Off,
130    TerminalControlled,
131    On,
132}
133
134#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
135#[serde(rename_all = "snake_case")]
136pub enum Shell {
137    System,
138    Program(String),
139    WithArguments { program: String, args: Vec<String> },
140}
141
142#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
143#[serde(rename_all = "snake_case")]
144pub enum AlternateScroll {
145    On,
146    Off,
147}
148
149#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
150#[serde(rename_all = "snake_case")]
151pub enum WorkingDirectory {
152    CurrentProjectDirectory,
153    FirstProjectDirectory,
154    AlwaysHome,
155    Always { directory: String },
156}