🐝 My patches for macos etc...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.5 KiB

  1. /*
  2. * meli - configuration module.
  3. *
  4. * Copyright 2019 Manos Pitsidianakis
  5. *
  6. * This file is part of meli.
  7. *
  8. * meli is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * meli is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with meli. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. //! Settings for terminal display
  22. use super::deserializers::non_empty_string;
  23. use super::DotAddressable;
  24. use super::Themes;
  25. use melib::{MeliError, Result, ToggleFlag};
  26. /// Settings for terminal display
  27. #[derive(Debug, Deserialize, Clone, Serialize)]
  28. #[serde(default, deny_unknown_fields)]
  29. pub struct TerminalSettings {
  30. /// light, dark
  31. pub theme: String,
  32. pub themes: Themes,
  33. pub ascii_drawing: bool,
  34. pub use_color: ToggleFlag,
  35. /// Use mouse events. This will disable text selection, but you will be able to resize some
  36. /// widgets.
  37. /// Default: False
  38. pub use_mouse: ToggleFlag,
  39. /// String to show in status bar if mouse is active.
  40. /// Default: "🖱️ "
  41. #[serde(deserialize_with = "non_empty_string")]
  42. pub mouse_flag: Option<String>,
  43. #[serde(deserialize_with = "non_empty_string")]
  44. pub window_title: Option<String>,
  45. #[serde(deserialize_with = "non_empty_string")]
  46. pub file_picker_command: Option<String>,
  47. /// Choose between 30-something built in sequences (integers between 0-30) or define your own
  48. /// list of strings for the progress spinner animation.
  49. /// Default: 0
  50. #[serde(default)]
  51. pub progress_spinner_sequence: Option<ProgressSpinnerSequence>,
  52. }
  53. impl Default for TerminalSettings {
  54. fn default() -> Self {
  55. TerminalSettings {
  56. theme: "dark".to_string(),
  57. themes: Themes::default(),
  58. ascii_drawing: false,
  59. use_color: ToggleFlag::InternalVal(true),
  60. use_mouse: ToggleFlag::InternalVal(false),
  61. mouse_flag: Some("🖱️ ".to_string()),
  62. window_title: Some("meli".to_string()),
  63. file_picker_command: None,
  64. progress_spinner_sequence: None,
  65. }
  66. }
  67. }
  68. impl TerminalSettings {
  69. pub fn use_color(&self) -> bool {
  70. /* Don't use color if
  71. * - Either NO_COLOR is set and user hasn't explicitly set use_colors or
  72. * - User has explicitly set use_colors to false
  73. */
  74. !((std::env::var("NO_COLOR").is_ok()
  75. && (self.use_color.is_false() || self.use_color.is_internal()))
  76. || (self.use_color.is_false() && !self.use_color.is_internal()))
  77. }
  78. }
  79. impl DotAddressable for TerminalSettings {
  80. fn lookup(&self, parent_field: &str, path: &[&str]) -> Result<String> {
  81. match path.first() {
  82. Some(field) => {
  83. let tail = &path[1..];
  84. match *field {
  85. "theme" => self.theme.lookup(field, tail),
  86. "themes" => Err(MeliError::new("unimplemented")),
  87. "ascii_drawing" => self.ascii_drawing.lookup(field, tail),
  88. "use_color" => self.use_color.lookup(field, tail),
  89. "use_mouse" => self.use_mouse.lookup(field, tail),
  90. "mouse_flag" => self.mouse_flag.lookup(field, tail),
  91. "window_title" => self.window_title.lookup(field, tail),
  92. "file_picker_command" => self.file_picker_command.lookup(field, tail),
  93. "progress_spinner_sequence" => {
  94. self.progress_spinner_sequence.lookup(field, tail)
  95. }
  96. other => Err(MeliError::new(format!(
  97. "{} has no field named {}",
  98. parent_field, other
  99. ))),
  100. }
  101. }
  102. None => Ok(toml::to_string(self).map_err(|err| err.to_string())?),
  103. }
  104. }
  105. }
  106. #[derive(Debug, Deserialize, Clone, Serialize)]
  107. #[serde(untagged)]
  108. pub enum ProgressSpinnerSequence {
  109. Integer(usize),
  110. Custom {
  111. frames: Vec<String>,
  112. #[serde(default = "interval_ms_val")]
  113. interval_ms: u64,
  114. },
  115. }
  116. const fn interval_ms_val() -> u64 {
  117. crate::components::utilities::ProgressSpinner::INTERVAL_MS
  118. }
  119. impl DotAddressable for ProgressSpinnerSequence {}