mirror of
https://github.com/youwen5/iamb.git
synced 2025-08-04 19:48:28 -07:00
Compare commits
5 commits
3886fdde43
...
1f88ef6e02
Author | SHA1 | Date | |
---|---|---|---|
1f88ef6e02 | |||
e222912acf | |||
![]() |
34d3b844af | ||
![]() |
52010d44d7 | ||
![]() |
0ef5c39f7f |
7 changed files with 104 additions and 68 deletions
48
Cargo.lock
generated
48
Cargo.lock
generated
|
@ -1442,6 +1442,41 @@ dependencies = [
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "editor-types"
|
||||||
|
version = "0.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9e9e99679670f67825fcd24a23cb4eb655a0f92c82bd4d1c1a1357c0cd71e87"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"editor-types-macros",
|
||||||
|
"keybindings",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "editor-types-macros"
|
||||||
|
version = "0.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42680de76cf91f231abd90cc623750d39077f7d2fadb7962325fb082871f4c66"
|
||||||
|
dependencies = [
|
||||||
|
"editor-types-parser",
|
||||||
|
"nom",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.101",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "editor-types-parser"
|
||||||
|
version = "0.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cac4b91fe830fbbe0a60c37ba0264b6e9ffc70e3664c028234dac59e79299ad4"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
|
@ -2706,9 +2741,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keybindings"
|
name = "keybindings"
|
||||||
version = "0.0.1"
|
version = "0.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "680e4699c91c0622dd70da32c274881aadb1ac86252d738c3641266e90e4ca15"
|
checksum = "19a726307ed87e05155c31329676130e6a237e62dda80211f7e1ed811e47630f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
|
@ -3292,15 +3327,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "modalkit"
|
name = "modalkit"
|
||||||
version = "0.0.21"
|
version = "0.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc7599fc1bcd2f0a0b4598f23433b45613345a46419ab27d3a9adecb57acd648"
|
checksum = "6ed06f32b03a7504acadcb0d95d06f3d55258934c34b620ed95e3dae24f081a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anymap2",
|
"anymap2",
|
||||||
"arboard",
|
"arboard",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
"editor-types",
|
||||||
"intervaltree",
|
"intervaltree",
|
||||||
"keybindings",
|
"keybindings",
|
||||||
"nom",
|
"nom",
|
||||||
|
@ -3314,9 +3350,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "modalkit-ratatui"
|
name = "modalkit-ratatui"
|
||||||
version = "0.0.21"
|
version = "0.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd3d88c86435d4b1fb22c7c0f978b09cb888338cafc10336715aa5070e92b6f6"
|
checksum = "a33bd64f6dd0011ee88f4f12b28108d3e63df0a5c86fe595d24561be9522f6ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"intervaltree",
|
"intervaltree",
|
||||||
|
|
|
@ -77,13 +77,13 @@ features = ["zbus", "serde"]
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.modalkit]
|
[dependencies.modalkit]
|
||||||
version = "0.0.21"
|
version = "0.0.23"
|
||||||
default-features = false
|
default-features = false
|
||||||
#git = "https://github.com/ulyssa/modalkit"
|
#git = "https://github.com/ulyssa/modalkit"
|
||||||
#rev = "e40dbb0bfeabe4cfd08facd2acb446080a330d75"
|
#rev = "e40dbb0bfeabe4cfd08facd2acb446080a330d75"
|
||||||
|
|
||||||
[dependencies.modalkit-ratatui]
|
[dependencies.modalkit-ratatui]
|
||||||
version = "0.0.21"
|
version = "0.0.23"
|
||||||
#git = "https://github.com/ulyssa/modalkit"
|
#git = "https://github.com/ulyssa/modalkit"
|
||||||
#rev = "e40dbb0bfeabe4cfd08facd2acb446080a330d75"
|
#rev = "e40dbb0bfeabe4cfd08facd2acb446080a330d75"
|
||||||
|
|
||||||
|
|
62
src/base.rs
62
src/base.rs
|
@ -74,7 +74,7 @@ use modalkit::{
|
||||||
ApplicationStore,
|
ApplicationStore,
|
||||||
ApplicationWindowId,
|
ApplicationWindowId,
|
||||||
},
|
},
|
||||||
completion::{complete_path, CompletionMap},
|
completion::{complete_path, Completer, CompletionMap},
|
||||||
context::EditContext,
|
context::EditContext,
|
||||||
cursor::Cursor,
|
cursor::Cursor,
|
||||||
rope::EditRope,
|
rope::EditRope,
|
||||||
|
@ -1914,11 +1914,20 @@ impl ApplicationInfo for IambInfo {
|
||||||
type WindowId = IambId;
|
type WindowId = IambId;
|
||||||
type ContentId = IambBufferId;
|
type ContentId = IambBufferId;
|
||||||
|
|
||||||
|
fn content_of_command(ct: CommandType) -> IambBufferId {
|
||||||
|
IambBufferId::Command(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IambCompleter;
|
||||||
|
|
||||||
|
impl Completer<IambInfo> for IambCompleter {
|
||||||
fn complete(
|
fn complete(
|
||||||
|
&mut self,
|
||||||
text: &EditRope,
|
text: &EditRope,
|
||||||
cursor: &mut Cursor,
|
cursor: &mut Cursor,
|
||||||
content: &IambBufferId,
|
content: &IambBufferId,
|
||||||
store: &mut ProgramStore,
|
store: &mut ChatStore,
|
||||||
) -> Vec<String> {
|
) -> Vec<String> {
|
||||||
match content {
|
match content {
|
||||||
IambBufferId::Command(CommandType::Command) => complete_cmdbar(text, cursor, store),
|
IambBufferId::Command(CommandType::Command) => complete_cmdbar(text, cursor, store),
|
||||||
|
@ -1936,21 +1945,16 @@ impl ApplicationInfo for IambInfo {
|
||||||
IambBufferId::UnreadList => vec![],
|
IambBufferId::UnreadList => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn content_of_command(ct: CommandType) -> IambBufferId {
|
|
||||||
IambBufferId::Command(ct)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for user IDs.
|
/// Tab completion for user IDs.
|
||||||
fn complete_users(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -> Vec<String> {
|
fn complete_users(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||||
let id = text
|
let id = text
|
||||||
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
||||||
.unwrap_or_else(EditRope::empty);
|
.unwrap_or_else(EditRope::empty);
|
||||||
let id = Cow::from(&id);
|
let id = Cow::from(&id);
|
||||||
|
|
||||||
store
|
store
|
||||||
.application
|
|
||||||
.presences
|
.presences
|
||||||
.complete(id.as_ref())
|
.complete(id.as_ref())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1959,7 +1963,7 @@ fn complete_users(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion within the message bar.
|
/// Tab completion within the message bar.
|
||||||
fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -> Vec<String> {
|
fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||||
let id = text
|
let id = text
|
||||||
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
||||||
.unwrap_or_else(EditRope::empty);
|
.unwrap_or_else(EditRope::empty);
|
||||||
|
@ -1968,13 +1972,12 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
||||||
match id.chars().next() {
|
match id.chars().next() {
|
||||||
// Complete room aliases.
|
// Complete room aliases.
|
||||||
Some('#') => {
|
Some('#') => {
|
||||||
return store.application.names.complete(id.as_ref());
|
return store.names.complete(id.as_ref());
|
||||||
},
|
},
|
||||||
|
|
||||||
// Complete room identifiers.
|
// Complete room identifiers.
|
||||||
Some('!') => {
|
Some('!') => {
|
||||||
return store
|
return store
|
||||||
.application
|
|
||||||
.rooms
|
.rooms
|
||||||
.complete(id.as_ref())
|
.complete(id.as_ref())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1984,7 +1987,7 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
||||||
|
|
||||||
// Complete Emoji shortcodes.
|
// Complete Emoji shortcodes.
|
||||||
Some(':') => {
|
Some(':') => {
|
||||||
let list = store.application.emojis.complete(&id[1..]);
|
let list = store.emojis.complete(&id[1..]);
|
||||||
let iter = list.into_iter().take(200).map(|s| format!(":{}:", s));
|
let iter = list.into_iter().take(200).map(|s| format!(":{}:", s));
|
||||||
|
|
||||||
return iter.collect();
|
return iter.collect();
|
||||||
|
@ -1993,7 +1996,6 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
||||||
// Complete usernames for @ and empty strings.
|
// Complete usernames for @ and empty strings.
|
||||||
Some('@') | None => {
|
Some('@') | None => {
|
||||||
return store
|
return store
|
||||||
.application
|
|
||||||
.presences
|
.presences
|
||||||
.complete(id.as_ref())
|
.complete(id.as_ref())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -2007,28 +2009,23 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for Matrix identifiers (usernames, room aliases, etc.)
|
/// Tab completion for Matrix identifiers (usernames, room aliases, etc.)
|
||||||
fn complete_matrix_names(
|
fn complete_matrix_names(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||||
text: &EditRope,
|
|
||||||
cursor: &mut Cursor,
|
|
||||||
store: &ProgramStore,
|
|
||||||
) -> Vec<String> {
|
|
||||||
let id = text
|
let id = text
|
||||||
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
||||||
.unwrap_or_else(EditRope::empty);
|
.unwrap_or_else(EditRope::empty);
|
||||||
let id = Cow::from(&id);
|
let id = Cow::from(&id);
|
||||||
|
|
||||||
let list = store.application.names.complete(id.as_ref());
|
let list = store.names.complete(id.as_ref());
|
||||||
if !list.is_empty() {
|
if !list.is_empty() {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
let list = store.application.presences.complete(id.as_ref());
|
let list = store.presences.complete(id.as_ref());
|
||||||
if !list.is_empty() {
|
if !list.is_empty() {
|
||||||
return list.into_iter().map(|i| i.to_string()).collect();
|
return list.into_iter().map(|i| i.to_string()).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
store
|
store
|
||||||
.application
|
|
||||||
.rooms
|
.rooms
|
||||||
.complete(id.as_ref())
|
.complete(id.as_ref())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -2037,12 +2034,12 @@ fn complete_matrix_names(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for Emoji shortcode names.
|
/// Tab completion for Emoji shortcode names.
|
||||||
fn complete_emoji(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -> Vec<String> {
|
fn complete_emoji(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||||
let sc = text.get_prefix_word_mut(cursor, &WordStyle::Little);
|
let sc = text.get_prefix_word_mut(cursor, &WordStyle::Little);
|
||||||
let sc = sc.unwrap_or_else(EditRope::empty);
|
let sc = sc.unwrap_or_else(EditRope::empty);
|
||||||
let sc = Cow::from(&sc);
|
let sc = Cow::from(&sc);
|
||||||
|
|
||||||
store.application.emojis.complete(sc.as_ref())
|
store.emojis.complete(sc.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for command names.
|
/// Tab completion for command names.
|
||||||
|
@ -2050,11 +2047,11 @@ fn complete_cmdname(
|
||||||
desc: CommandDescription,
|
desc: CommandDescription,
|
||||||
text: &EditRope,
|
text: &EditRope,
|
||||||
cursor: &mut Cursor,
|
cursor: &mut Cursor,
|
||||||
store: &ProgramStore,
|
store: &ChatStore,
|
||||||
) -> Vec<String> {
|
) -> Vec<String> {
|
||||||
// Complete command name and set cursor position.
|
// Complete command name and set cursor position.
|
||||||
let _ = text.get_prefix_word_mut(cursor, &WordStyle::Little);
|
let _ = text.get_prefix_word_mut(cursor, &WordStyle::Little);
|
||||||
store.application.cmds.complete_name(desc.command.as_str())
|
store.cmds.complete_name(desc.command.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for command arguments.
|
/// Tab completion for command arguments.
|
||||||
|
@ -2062,9 +2059,9 @@ fn complete_cmdarg(
|
||||||
desc: CommandDescription,
|
desc: CommandDescription,
|
||||||
text: &EditRope,
|
text: &EditRope,
|
||||||
cursor: &mut Cursor,
|
cursor: &mut Cursor,
|
||||||
store: &ProgramStore,
|
store: &ChatStore,
|
||||||
) -> Vec<String> {
|
) -> Vec<String> {
|
||||||
let cmd = match store.application.cmds.get(desc.command.as_str()) {
|
let cmd = match store.cmds.get(desc.command.as_str()) {
|
||||||
Ok(cmd) => cmd,
|
Ok(cmd) => cmd,
|
||||||
Err(_) => return vec![],
|
Err(_) => return vec![],
|
||||||
};
|
};
|
||||||
|
@ -2087,12 +2084,7 @@ fn complete_cmdarg(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for commands.
|
/// Tab completion for commands.
|
||||||
fn complete_cmd(
|
fn complete_cmd(cmd: &str, text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||||
cmd: &str,
|
|
||||||
text: &EditRope,
|
|
||||||
cursor: &mut Cursor,
|
|
||||||
store: &ProgramStore,
|
|
||||||
) -> Vec<String> {
|
|
||||||
match CommandDescription::from_str(cmd) {
|
match CommandDescription::from_str(cmd) {
|
||||||
Ok(desc) => {
|
Ok(desc) => {
|
||||||
if desc.arg.untrimmed.is_empty() {
|
if desc.arg.untrimmed.is_empty() {
|
||||||
|
@ -2109,7 +2101,7 @@ fn complete_cmd(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab completion for the command bar.
|
/// Tab completion for the command bar.
|
||||||
fn complete_cmdbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -> Vec<String> {
|
fn complete_cmdbar(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||||
let eo = text.cursor_to_offset(cursor);
|
let eo = text.cursor_to_offset(cursor);
|
||||||
let slice = text.slice(..eo);
|
let slice = text.slice(..eo);
|
||||||
let cow = Cow::from(&slice);
|
let cow = Cow::from(&slice);
|
||||||
|
@ -2289,6 +2281,7 @@ pub mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_complete_msgbar() {
|
async fn test_complete_msgbar() {
|
||||||
let store = mock_store().await;
|
let store = mock_store().await;
|
||||||
|
let store = store.application;
|
||||||
|
|
||||||
let text = EditRope::from("going for a walk :walk ");
|
let text = EditRope::from("going for a walk :walk ");
|
||||||
let mut cursor = Cursor::new(0, 22);
|
let mut cursor = Cursor::new(0, 22);
|
||||||
|
@ -2312,6 +2305,7 @@ pub mod tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_complete_cmdbar() {
|
async fn test_complete_cmdbar() {
|
||||||
let store = mock_store().await;
|
let store = mock_store().await;
|
||||||
|
let store = store.application;
|
||||||
let users = vec![
|
let users = vec![
|
||||||
"@user1:example.com",
|
"@user1:example.com",
|
||||||
"@user2:example.com",
|
"@user2:example.com",
|
||||||
|
|
|
@ -353,29 +353,31 @@ pub struct UserDisplayTunables {
|
||||||
|
|
||||||
pub type UserOverrides = HashMap<OwnedUserId, UserDisplayTunables>;
|
pub type UserOverrides = HashMap<OwnedUserId, UserDisplayTunables>;
|
||||||
|
|
||||||
fn merge_sorts(a: SortOverrides, b: SortOverrides) -> SortOverrides {
|
fn merge_sorts(profile: SortOverrides, global: SortOverrides) -> SortOverrides {
|
||||||
SortOverrides {
|
SortOverrides {
|
||||||
chats: b.chats.or(a.chats),
|
chats: profile.chats.or(global.chats),
|
||||||
dms: b.dms.or(a.dms),
|
dms: profile.dms.or(global.dms),
|
||||||
rooms: b.rooms.or(a.rooms),
|
rooms: profile.rooms.or(global.rooms),
|
||||||
spaces: b.spaces.or(a.spaces),
|
spaces: profile.spaces.or(global.spaces),
|
||||||
members: b.members.or(a.members),
|
members: profile.members.or(global.members),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_maps<K, V>(a: Option<HashMap<K, V>>, b: Option<HashMap<K, V>>) -> Option<HashMap<K, V>>
|
fn merge_maps<K, V>(
|
||||||
|
profile: Option<HashMap<K, V>>,
|
||||||
|
global: Option<HashMap<K, V>>,
|
||||||
|
) -> Option<HashMap<K, V>>
|
||||||
where
|
where
|
||||||
K: Eq + Hash,
|
K: Eq + Hash,
|
||||||
{
|
{
|
||||||
match (a, b) {
|
match (global, profile) {
|
||||||
(Some(a), None) => Some(a),
|
(Some(m), None) | (None, Some(m)) => Some(m),
|
||||||
(None, Some(b)) => Some(b),
|
(Some(mut global), Some(profile)) => {
|
||||||
(Some(mut a), Some(b)) => {
|
for (k, v) in profile {
|
||||||
for (k, v) in b {
|
global.insert(k, v);
|
||||||
a.insert(k, v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(a)
|
Some(global)
|
||||||
},
|
},
|
||||||
(None, None) => None,
|
(None, None) => None,
|
||||||
}
|
}
|
||||||
|
@ -918,7 +920,7 @@ impl ApplicationSettings {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let macros = merge_maps(macros, profile.macros.take()).unwrap_or_default();
|
let macros = merge_maps(profile.macros.take(), macros).unwrap_or_default();
|
||||||
let layout = profile.layout.take().or(layout).unwrap_or_default();
|
let layout = profile.layout.take().or(layout).unwrap_or_default();
|
||||||
|
|
||||||
let tunables = global.unwrap_or_default();
|
let tunables = global.unwrap_or_default();
|
||||||
|
@ -1131,10 +1133,10 @@ mod tests {
|
||||||
assert_eq!(res, Some(b.clone()));
|
assert_eq!(res, Some(b.clone()));
|
||||||
|
|
||||||
let res = merge_maps(Some(b.clone()), Some(c.clone()));
|
let res = merge_maps(Some(b.clone()), Some(c.clone()));
|
||||||
assert_eq!(res, Some(c.clone()));
|
assert_eq!(res, Some(b.clone()));
|
||||||
|
|
||||||
let res = merge_maps(Some(c.clone()), Some(b.clone()));
|
let res = merge_maps(Some(c.clone()), Some(b.clone()));
|
||||||
assert_eq!(res, Some(b.clone()));
|
assert_eq!(res, Some(c.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -62,7 +62,7 @@ use modalkit::crossterm::{
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
backend::CrosstermBackend,
|
backend::CrosstermBackend,
|
||||||
layout::Rect,
|
layout::Rect,
|
||||||
style::{Color, Style},
|
style::{Color, Modifier, Style},
|
||||||
text::Span,
|
text::Span,
|
||||||
widgets::Paragraph,
|
widgets::Paragraph,
|
||||||
Terminal,
|
Terminal,
|
||||||
|
@ -89,6 +89,7 @@ use crate::{
|
||||||
ChatStore,
|
ChatStore,
|
||||||
HomeserverAction,
|
HomeserverAction,
|
||||||
IambAction,
|
IambAction,
|
||||||
|
IambCompleter,
|
||||||
IambError,
|
IambError,
|
||||||
IambId,
|
IambId,
|
||||||
IambInfo,
|
IambInfo,
|
||||||
|
@ -327,6 +328,9 @@ impl Application {
|
||||||
.show_dialog(dialogstr)
|
.show_dialog(dialogstr)
|
||||||
.show_mode(modestr)
|
.show_mode(modestr)
|
||||||
.borders(true)
|
.borders(true)
|
||||||
|
.border_style(Style::default().add_modifier(Modifier::DIM))
|
||||||
|
.tab_style(Style::default().add_modifier(Modifier::DIM))
|
||||||
|
.tab_style_focused(Style::default().remove_modifier(Modifier::DIM))
|
||||||
.focus(focused);
|
.focus(focused);
|
||||||
f.render_stateful_widget(screen, area, sstate);
|
f.render_stateful_widget(screen, area, sstate);
|
||||||
|
|
||||||
|
@ -529,7 +533,7 @@ impl Application {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Unimplemented.
|
// Unimplemented.
|
||||||
Action::KeywordLookup => {
|
Action::KeywordLookup(_) => {
|
||||||
// XXX: implement
|
// XXX: implement
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
@ -1011,7 +1015,9 @@ async fn run(settings: ApplicationSettings) -> IambResult<()> {
|
||||||
// Set up the async worker thread and global store.
|
// Set up the async worker thread and global store.
|
||||||
let worker = ClientWorker::spawn(client.clone(), settings.clone()).await;
|
let worker = ClientWorker::spawn(client.clone(), settings.clone()).await;
|
||||||
let store = ChatStore::new(worker.clone(), settings.clone());
|
let store = ChatStore::new(worker.clone(), settings.clone());
|
||||||
let store = Store::new(store);
|
let mut store = Store::new(store);
|
||||||
|
store.completer = Box::new(IambCompleter);
|
||||||
|
|
||||||
let store = Arc::new(AsyncMutex::new(store));
|
let store = Arc::new(AsyncMutex::new(store));
|
||||||
worker.init(store.clone());
|
worker.init(store.clone());
|
||||||
|
|
||||||
|
|
|
@ -864,16 +864,16 @@ impl PromptActions<ProgramContext, ProgramStore, IambInfo> for ChatState {
|
||||||
|
|
||||||
fn recall(
|
fn recall(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
filter: &RecallFilter,
|
||||||
dir: &MoveDir1D,
|
dir: &MoveDir1D,
|
||||||
count: &Count,
|
count: &Count,
|
||||||
prefixed: bool,
|
|
||||||
ctx: &ProgramContext,
|
ctx: &ProgramContext,
|
||||||
_: &mut ProgramStore,
|
_: &mut ProgramStore,
|
||||||
) -> EditResult<Vec<(ProgramAction, ProgramContext)>, IambInfo> {
|
) -> EditResult<Vec<(ProgramAction, ProgramContext)>, IambInfo> {
|
||||||
let count = ctx.resolve(count);
|
let count = ctx.resolve(count);
|
||||||
let rope = self.tbox.get();
|
let rope = self.tbox.get();
|
||||||
|
|
||||||
let text = self.sent.recall(&rope, &mut self.sent_scrollback, *dir, prefixed, count);
|
let text = self.sent.recall(&rope, &mut self.sent_scrollback, filter, *dir, count);
|
||||||
|
|
||||||
if let Some(text) = text {
|
if let Some(text) = text {
|
||||||
self.tbox.set_text(text);
|
self.tbox.set_text(text);
|
||||||
|
@ -897,9 +897,7 @@ impl Promptable<ProgramContext, ProgramStore, IambInfo> for ChatState {
|
||||||
match act {
|
match act {
|
||||||
PromptAction::Submit => self.submit(ctx, store),
|
PromptAction::Submit => self.submit(ctx, store),
|
||||||
PromptAction::Abort(empty) => self.abort(*empty, ctx, store),
|
PromptAction::Abort(empty) => self.abort(*empty, ctx, store),
|
||||||
PromptAction::Recall(dir, count, prefixed) => {
|
PromptAction::Recall(filter, dir, count) => self.recall(filter, dir, count, ctx, store),
|
||||||
self.recall(dir, count, *prefixed, ctx, store)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -840,8 +840,8 @@ impl EditorActions<ProgramContext, ProgramStore, IambInfo> for ScrollbackState {
|
||||||
|
|
||||||
fn complete(
|
fn complete(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
_: &CompletionStyle,
|
||||||
_: &CompletionType,
|
_: &CompletionType,
|
||||||
_: &CompletionSelection,
|
|
||||||
_: &CompletionDisplay,
|
_: &CompletionDisplay,
|
||||||
_: &ProgramContext,
|
_: &ProgramContext,
|
||||||
_: &mut ProgramStore,
|
_: &mut ProgramStore,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue