mod.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. use std::collections::HashMap;
  2. use crate::errors::*;
  3. use crate::{view::monitor::Monitor, workspace::Workspace};
  4. use command::{CommandData, CommandRenderer};
  5. use delete::DeleteRenderer;
  6. use error::ErrorRenderer;
  7. use error_chain::bail;
  8. use insert::InsertRenderer;
  9. use linked_hash_map::LinkedHashMap;
  10. use normal::NormalRenderer;
  11. use search::{SearchData, SearchRenderer};
  12. use replace::ReplaceRenderer;
  13. use smallvec::SmallVec;
  14. use strum::EnumIter;
  15. use workspace::{WorkspaceModeData, WorkspaceRender};
  16. use yaml_rust::Yaml;
  17. use super::handler::handle_map;
  18. use super::Application;
  19. pub mod command;
  20. pub mod motion;
  21. pub mod delete;
  22. pub mod error;
  23. mod insert;
  24. pub mod normal;
  25. pub mod workspace;
  26. pub mod search;
  27. mod replace;
  28. pub enum ModeData {
  29. Normal,
  30. Error(Error),
  31. Exit,
  32. Insert,
  33. Command(CommandData),
  34. Workspace(WorkspaceModeData),
  35. Search(SearchData),
  36. Delete, Replace, // Other(OtherData)
  37. }
  38. #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, EnumIter)]
  39. pub enum ModeKey {
  40. Normal,
  41. Error,
  42. Exit,
  43. Insert,
  44. Command,
  45. Workspace,
  46. Search,
  47. Delete,
  48. Replace,
  49. }
  50. impl ModeKey {
  51. pub fn to_string(&self) -> Option<String> {
  52. match self {
  53. ModeKey::Normal => Some("normal".into()),
  54. ModeKey::Insert => Some("insert".into()),
  55. ModeKey::Command => Some("command".into()),
  56. ModeKey::Workspace => Some("workspace".into()),
  57. ModeKey::Search => Some("search".into()),
  58. ModeKey::Delete => Some("delete".into()),
  59. ModeKey::Replace => Some("replace".into()),
  60. _ => None,
  61. }
  62. }
  63. pub fn generate_handle_map(
  64. &self,
  65. mode_map: &mut HashMap<
  66. String,
  67. HashMap<String, SmallVec<[fn(&mut Application) -> Result<()>; 4]>>,
  68. >,
  69. extra: Option<&LinkedHashMap<Yaml, Yaml>>,
  70. default: &LinkedHashMap<Yaml, Yaml>,
  71. ) -> Result<()> {
  72. let handle_map = handle_map();
  73. let mut command_map =
  74. HashMap::<String, SmallVec<[fn(&mut Application) -> Result<()>; 4]>>::new();
  75. if let Some(mode) = self.to_string() {
  76. if let Some(yaml) = default.get(&Yaml::String(mode.clone())) {
  77. if let Some(keys) = yaml.as_hash() {
  78. self.parse_mode_keybindings(keys, &handle_map, &mut command_map)?;
  79. }
  80. }
  81. if let Some(extra) = extra {
  82. if let Some(yaml) = extra.get(&Yaml::String(mode.clone())) {
  83. if let Some(keys) = yaml.as_hash() {
  84. self.parse_mode_keybindings(keys, &handle_map, &mut command_map)?;
  85. }
  86. }
  87. }
  88. mode_map.insert(mode, command_map);
  89. }
  90. Ok(())
  91. }
  92. fn parse_mode_keybindings(
  93. &self,
  94. keybindings: &LinkedHashMap<Yaml, Yaml>,
  95. handle_map: &HashMap<&str, fn(&mut Application) -> Result<()>>,
  96. result: &mut HashMap<String, SmallVec<[fn(&mut Application) -> Result<()>; 4]>>,
  97. ) -> Result<()> {
  98. for (key, handle) in keybindings {
  99. if let Some(key) = key.as_str() {
  100. let mut closures = SmallVec::new();
  101. match handle {
  102. Yaml::String(command_key) => {
  103. closures.push(
  104. *handle_map
  105. .get(command_key.as_str())
  106. .ok_or_else(|| format!("command \"{command_key:?}\" not found"))?,
  107. );
  108. }
  109. Yaml::Array(commands) => {
  110. for command in commands {
  111. let command_key = command.as_str().ok_or_else(|| {
  112. format!(
  113. "Keymap command \"{:?}\" couldn't be parsed as a string",
  114. command
  115. )
  116. })?;
  117. closures.push(
  118. *handle_map.get(command_key).ok_or_else(|| {
  119. format!("command \"{command_key:?}\" not found")
  120. })?,
  121. );
  122. }
  123. }
  124. _ => {
  125. bail!(format!("conmand: \"{handle:?}\" couldn't be parsed"));
  126. }
  127. }
  128. result.insert(key.to_string(), closures);
  129. }
  130. }
  131. Ok(())
  132. }
  133. }
  134. pub trait ModeRenderer {
  135. fn render(workspace: &mut Workspace, monitor: &mut Monitor, mode: &mut ModeData) -> Result<()>;
  136. }
  137. pub struct ModeRouter;
  138. impl ModeRenderer for ModeRouter {
  139. fn render(workspace: &mut Workspace, monitor: &mut Monitor, mode: &mut ModeData) -> Result<()> {
  140. match mode {
  141. ModeData::Normal => NormalRenderer::render(workspace, monitor, mode),
  142. ModeData::Error(_) => ErrorRenderer::render(workspace, monitor, mode),
  143. ModeData::Insert => InsertRenderer::render(workspace, monitor, mode),
  144. ModeData::Command(_) => CommandRenderer::render(workspace, monitor, mode),
  145. ModeData::Workspace(_) => WorkspaceRender::render(workspace, monitor, mode),
  146. ModeData::Search(_) => SearchRenderer::render(workspace, monitor, mode),
  147. ModeData::Replace => ReplaceRenderer::render(workspace, monitor, mode),
  148. ModeData::Exit => todo!(),
  149. ModeData::Delete => DeleteRenderer::render(workspace, monitor, mode),
  150. }
  151. }
  152. }