diff --git a/src/bridge/ui_commands.rs b/src/bridge/ui_commands.rs index 6da5764..e709e9e 100644 --- a/src/bridge/ui_commands.rs +++ b/src/bridge/ui_commands.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use log::error; use log::trace; -use nvim_rs::Neovim; +use nvim_rs::{Neovim, call_args, rpc::model::IntoVal}; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver}; use crate::bridge::TxWrapper; @@ -15,7 +15,9 @@ use crate::windows_utils::{ }; // Serial commands are any commands which must complete before the next value is sent. This -// includes keyboard and mouse input which would cuase problems if sent out of order. +// includes keyboard and mouse input which would cause problems if sent out of order. +// +// When in doubt, use Parallel Commands. #[derive(Debug, Clone)] pub enum SerialCommand { Keyboard(String), @@ -113,6 +115,7 @@ pub enum ParallelCommand { FileDrop(String), FocusLost, FocusGained, + DisplayAvailableFonts(Vec), #[cfg(windows)] RegisterRightClick, #[cfg(windows)] @@ -140,6 +143,44 @@ impl ParallelCommand { ParallelCommand::FileDrop(path) => { nvim.command(format!("e {}", path).as_str()).await.ok(); } + ParallelCommand::DisplayAvailableFonts(fonts) => { + let mut content: Vec = vec![ + "What follows are the font names available for guifont. To use one of these, type:", + "", + " :set guifont=:h", + "", + "where is one of the following with spaces escaped", + "and is the desired font size. As an example:", + "", + " :set guifont=Cascadia\\ Code\\ PL:h12", + "", + "You may specify multiple fonts separated by commas like so:", + "", + " :set guifont=Cascadia\\ Code\\ PL,Delugia\\ Nerd\\ Font:h12", + "", + "------------------------------", + "Available Fonts on this System", + "------------------------------", + ].into_iter().map(|text| text.to_owned()).collect(); + content.extend(fonts); + + nvim.command("split").await.ok(); + nvim.command("noswapfile hide enew").await.ok(); + nvim.command("setlocal buftype=nofile").await.ok(); + nvim.command("setlocal bufhidden=hide").await.ok(); + nvim.command("\"setlocal nobuflisted").await.ok(); + nvim.command("\"lcd ~").await.ok(); + nvim.command("file scratch").await.ok(); + nvim.call( + "nvim_buf_set_lines", + call_args![ + 0i64, + 0i64, + -1i64, + false, + content + ]).await.ok(); + } #[cfg(windows)] ParallelCommand::RegisterRightClick => { if unregister_rightclick() { diff --git a/src/editor/mod.rs b/src/editor/mod.rs index 6d048e1..319caa4 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -63,6 +63,7 @@ pub enum DrawCommand { pub enum WindowCommand { TitleChanged(String), SetMouseEnabled(bool), + ListAvailableFonts, } pub struct Editor { @@ -421,9 +422,16 @@ impl Editor { fn set_option(&mut self, gui_option: GuiOption) { trace!("Option set {:?}", &gui_option); if let GuiOption::GuiFont(guifont) = gui_option { + if guifont == "*".to_owned() { + self.window_command_sender + .send(WindowCommand::ListAvailableFonts) + .ok(); + } + self.draw_command_batcher .queue(DrawCommand::FontChanged(guifont)) .ok(); + for window in self.windows.values() { window.redraw(); } diff --git a/src/renderer/fonts/caching_shaper.rs b/src/renderer/fonts/caching_shaper.rs index fce3788..c554ba5 100644 --- a/src/renderer/fonts/caching_shaper.rs +++ b/src/renderer/fonts/caching_shaper.rs @@ -106,6 +106,10 @@ impl CachingShaper { self.blob_cache.clear(); } + pub fn font_names(&self) -> Vec { + self.font_loader.font_names() + } + fn info(&mut self) -> (Metrics, f32) { let font_pair = self.current_font_pair(); let size = self.current_size(); diff --git a/src/renderer/fonts/font_loader.rs b/src/renderer/fonts/font_loader.rs index 6d35a1f..bf21481 100644 --- a/src/renderer/fonts/font_loader.rs +++ b/src/renderer/fonts/font_loader.rs @@ -162,4 +162,8 @@ impl FontLoader { Some(font_arc) } + + pub fn font_names(&self) -> Vec { + self.font_mgr.family_names().collect() + } } diff --git a/src/renderer/grid_renderer.rs b/src/renderer/grid_renderer.rs index 4a141f8..828ae7f 100644 --- a/src/renderer/grid_renderer.rs +++ b/src/renderer/grid_renderer.rs @@ -41,6 +41,10 @@ impl GridRenderer { } } + pub fn font_names(&self) -> Vec { + self.shaper.font_names() + } + /// Convert PhysicalSize to grid size pub fn convert_physical_to_grid(&self, physical: PhysicalSize) -> Dimensions { Dimensions::from(physical) / self.font_dimensions diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 90ef956..90736cd 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -75,6 +75,10 @@ impl Renderer { } } + pub fn font_names(&self) -> Vec { + self.grid_renderer.font_names() + } + /// Draws frame /// /// # Returns diff --git a/src/window/mod.rs b/src/window/mod.rs index a5ae9f0..f530fae 100644 --- a/src/window/mod.rs +++ b/src/window/mod.rs @@ -88,7 +88,8 @@ impl GlutinWindowWrapper { WindowCommand::TitleChanged(new_title) => self.handle_title_changed(new_title), WindowCommand::SetMouseEnabled(mouse_enabled) => { self.mouse_manager.enabled = mouse_enabled - } + }, + WindowCommand::ListAvailableFonts => self.send_font_names(), } } } @@ -98,6 +99,11 @@ impl GlutinWindowWrapper { self.windowed_context.window().set_title(&self.title); } + pub fn send_font_names(&self) { + let font_names = self.renderer.font_names(); + self.ui_command_sender.send(UiCommand::Parallel(ParallelCommand::DisplayAvailableFonts(font_names))).unwrap(); + } + pub fn handle_quit(&mut self) { if SETTINGS.get::().remote_tcp.is_none() { self.ui_command_sender