Add settings page with support for vim bindings toggle

This commit is contained in:
Jeremy Soller 2023-11-01 14:19:39 -06:00
parent f6abeb32e4
commit aee972e171
No known key found for this signature in database
GPG key ID: DCFCA852D3906975
7 changed files with 111 additions and 37 deletions

2
Cargo.lock generated
View file

@ -851,7 +851,7 @@ dependencies = [
[[package]]
name = "cosmic-text"
version = "0.10.0"
source = "git+https://github.com/pop-os/cosmic-text?branch=vi-editor#7855dce09d457ea6d516f621fdaafaa7ce78d9d4"
source = "git+https://github.com/pop-os/cosmic-text?branch=vi-editor#ca35e1f429af2ac3121f8afb0991963820dbd1bf"
dependencies = [
"fontdb 0.15.0",
"libm",

View file

@ -29,9 +29,5 @@ default-features = false
features = ["winit"]
#path = "../libcosmic"
[features]
default = []
vi = []
[patch.crates-io]
smithay-client-toolkit = { git = "https://github.com/pop-os/client-toolkit", branch = "wayland-resize" }

View file

@ -1,6 +1,15 @@
new-document = New document
open-project = Open project
# Context Pages
## Settings
settings = Settings
### Keyboard shortcuts
keyboard-shortcuts = Keyboard shortcuts
enable-vim-bindings = Enable Vim bindings
# Menu
## File
@ -44,6 +53,6 @@ word-wrap = Word wrap
show-line-numbers = Show line numbers
highlight-current-line = Highlight current line
syntax-highlighting = Syntax highlighting...
settings = Settings...
keyboard-shortcuts = Keyboard shortcuts...
menu-settings = Settings...
menu-keyboard-shortcuts = Keyboard shortcuts...
about-cosmic-text-editor = About COSMIC Text Editor

View file

@ -1,7 +1,7 @@
use cosmic::iced::keyboard::{KeyCode, Modifiers};
use std::{collections::HashMap, fmt};
use crate::Message;
use crate::{ContextPage, Message};
// Makes key binding definitions simpler
const CTRL: Modifiers = Modifiers::CTRL;
@ -20,26 +20,31 @@ impl KeyBind {
let mut keybinds = HashMap::new();
macro_rules! bind {
($modifiers:expr, $key_code:ident, $message:ident) => {{
($modifiers:expr, $key_code:ident, $message:expr) => {{
keybinds.insert(
KeyBind {
modifiers: $modifiers,
key_code: KeyCode::$key_code,
},
Message::$message,
$message,
);
}};
}
bind!(CTRL, X, Cut);
bind!(CTRL, C, Copy);
bind!(CTRL, V, Paste);
bind!(CTRL, N, NewFile);
bind!(CTRL | SHIFT, N, NewWindow);
bind!(CTRL, O, OpenFileDialog);
bind!(CTRL, S, Save);
bind!(CTRL, Q, Quit);
bind!(ALT, Z, ToggleWordWrap);
bind!(CTRL, X, Message::Cut);
bind!(CTRL, C, Message::Copy);
bind!(CTRL, V, Message::Paste);
bind!(CTRL, N, Message::NewFile);
bind!(CTRL | SHIFT, N, Message::NewWindow);
bind!(CTRL, O, Message::OpenFileDialog);
bind!(CTRL, S, Message::Save);
bind!(CTRL, Q, Message::Quit);
bind!(
CTRL,
Comma,
Message::ToggleContextPage(ContextPage::Settings)
);
bind!(ALT, Z, Message::ToggleWordWrap);
keybinds
}
@ -65,6 +70,7 @@ impl fmt::Display for KeyBind {
#[derive(Clone, Debug)]
pub struct Config {
pub vim_bindings: bool,
pub word_wrap: bool,
pub keybinds: HashMap<KeyBind, Message>,
}
@ -73,6 +79,7 @@ impl Config {
//TODO: load from cosmic-config
pub fn load() -> Self {
Self {
vim_bindings: false,
word_wrap: false,
keybinds: KeyBind::load(),
}

View file

@ -60,13 +60,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
pub struct App {
core: Core,
nav_model: segmented_button::SingleSelectModel,
tab_model: segmented_button::SingleSelectModel,
config: Config,
}
#[allow(dead_code)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Message {
@ -86,7 +79,30 @@ pub enum Message {
TabActivate(segmented_button::Entity),
TabClose(segmented_button::Entity),
Todo,
ToggleContextPage(ContextPage),
ToggleWordWrap,
VimBindings(bool),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ContextPage {
Settings,
}
impl ContextPage {
fn title(&self) -> String {
match self {
Self::Settings => fl!("settings"),
}
}
}
pub struct App {
core: Core,
nav_model: segmented_button::SingleSelectModel,
tab_model: segmented_button::SingleSelectModel,
config: Config,
context_page: ContextPage,
}
impl App {
@ -204,6 +220,16 @@ impl App {
.activate();
}
fn update_config(&mut self) {
//TODO: provide iterator over data
let entities: Vec<_> = self.tab_model.iter().collect();
for entity in entities {
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
tab.set_config(&self.config);
}
}
}
fn update_nav_bar_active(&mut self) {
let tab_path_opt = match self.active_tab() {
Some(tab) => tab.path_opt.clone(),
@ -301,6 +327,7 @@ impl cosmic::Application for App {
nav_model: nav_bar::Model::builder().build(),
tab_model: segmented_button::Model::builder().build(),
config: Config::load(),
context_page: ContextPage::Settings,
};
for arg in env::args().skip(1) {
@ -539,21 +566,52 @@ impl cosmic::Application for App {
Message::Todo => {
log::warn!("TODO");
}
Message::ToggleContextPage(context_page) => {
if self.context_page == context_page {
self.core.window.show_context = !self.core.window.show_context;
} else {
self.context_page = context_page;
self.core.window.show_context = true;
}
self.set_context_title(context_page.title());
// Hack to ensure tab redraws.
//TODO: tab does not redraw when using Close button!
return self.update_tab();
}
Message::ToggleWordWrap => {
self.config.word_wrap = !self.config.word_wrap;
//TODO: provide iterator over data
let entities: Vec<_> = self.tab_model.iter().collect();
for entity in entities {
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
tab.set_config(&self.config);
}
}
self.update_config();
}
Message::VimBindings(vim_bindings) => {
self.config.vim_bindings = vim_bindings;
self.update_config();
}
}
Command::none()
}
fn context_drawer(&self) -> Option<Element<Message>> {
if !self.core.window.show_context {
return None;
}
Some(match self.context_page {
ContextPage::Settings => {
widget::settings::view_column(vec![widget::settings::view_section(fl!(
"keyboard-shortcuts"
))
.add(
widget::settings::item::builder(fl!("enable-vim-bindings"))
.toggler(self.config.vim_bindings, Message::VimBindings),
)
.into()])
.into()
}
})
}
fn header_start(&self) -> Vec<Element<Message>> {
vec![menu_bar(&self.config)]
}

View file

@ -11,7 +11,7 @@ use cosmic::{
Element,
};
use crate::{fl, Config, Message};
use crate::{fl, Config, ContextPage, Message};
pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
//TODO: port to libcosmic
@ -157,9 +157,12 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
menu_checkbox(fl!("highlight-current-line"), false, Message::Todo),
menu_item(fl!("syntax-highlighting"), Message::Todo),
MenuTree::new(horizontal_rule(1)),
menu_key(fl!("settings"), "Ctrl + ,", Message::Todo),
menu_item(
fl!("menu-settings"),
Message::ToggleContextPage(ContextPage::Settings),
),
MenuTree::new(horizontal_rule(1)),
menu_item(fl!("keyboard-shortcuts"), Message::Todo),
menu_item(fl!("menu-keyboard-shortcuts"), Message::Todo),
MenuTree::new(horizontal_rule(1)),
menu_item(fl!("about-cosmic-text-editor"), Message::Todo),
],

View file

@ -32,7 +32,7 @@ impl Tab {
.unwrap();
let mut editor = ViEditor::new(editor);
editor.set_passthrough(!cfg!(feature = "vi"));
editor.set_passthrough(true);
Self {
path_opt: None,
@ -45,6 +45,7 @@ impl Tab {
let mut editor = self.editor.lock().unwrap();
let mut font_system = FONT_SYSTEM.lock().unwrap();
let mut editor = editor.borrow_with(&mut font_system);
editor.set_passthrough(!config.vim_bindings);
editor.buffer_mut().set_wrap(if config.word_wrap {
Wrap::Word
} else {