mirror of
https://github.com/youwen5/iamb.git
synced 2025-08-03 19:18:28 -07:00
Compare commits
5 commits
3886fdde43
...
1f88ef6e02
Author | SHA1 | Date | |
---|---|---|---|
1f88ef6e02 | |||
e222912acf | |||
![]() |
34d3b844af | ||
![]() |
52010d44d7 | ||
![]() |
0ef5c39f7f |
8 changed files with 133 additions and 68 deletions
48
Cargo.lock
generated
48
Cargo.lock
generated
|
@ -1442,6 +1442,41 @@ dependencies = [
|
|||
"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]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
|
@ -2706,9 +2741,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "keybindings"
|
||||
version = "0.0.1"
|
||||
version = "0.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "680e4699c91c0622dd70da32c274881aadb1ac86252d738c3641266e90e4ca15"
|
||||
checksum = "19a726307ed87e05155c31329676130e6a237e62dda80211f7e1ed811e47630f"
|
||||
dependencies = [
|
||||
"textwrap",
|
||||
"unicode-segmentation",
|
||||
|
@ -3292,15 +3327,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "modalkit"
|
||||
version = "0.0.21"
|
||||
version = "0.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc7599fc1bcd2f0a0b4598f23433b45613345a46419ab27d3a9adecb57acd648"
|
||||
checksum = "6ed06f32b03a7504acadcb0d95d06f3d55258934c34b620ed95e3dae24f081a5"
|
||||
dependencies = [
|
||||
"anymap2",
|
||||
"arboard",
|
||||
"bitflags 2.9.1",
|
||||
"crossterm",
|
||||
"derive_more",
|
||||
"editor-types",
|
||||
"intervaltree",
|
||||
"keybindings",
|
||||
"nom",
|
||||
|
@ -3314,9 +3350,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "modalkit-ratatui"
|
||||
version = "0.0.21"
|
||||
version = "0.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd3d88c86435d4b1fb22c7c0f978b09cb888338cafc10336715aa5070e92b6f6"
|
||||
checksum = "a33bd64f6dd0011ee88f4f12b28108d3e63df0a5c86fe595d24561be9522f6ea"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
"intervaltree",
|
||||
|
|
|
@ -77,13 +77,13 @@ features = ["zbus", "serde"]
|
|||
optional = true
|
||||
|
||||
[dependencies.modalkit]
|
||||
version = "0.0.21"
|
||||
version = "0.0.23"
|
||||
default-features = false
|
||||
#git = "https://github.com/ulyssa/modalkit"
|
||||
#rev = "e40dbb0bfeabe4cfd08facd2acb446080a330d75"
|
||||
|
||||
[dependencies.modalkit-ratatui]
|
||||
version = "0.0.21"
|
||||
version = "0.0.23"
|
||||
#git = "https://github.com/ulyssa/modalkit"
|
||||
#rev = "e40dbb0bfeabe4cfd08facd2acb446080a330d75"
|
||||
|
||||
|
|
62
src/base.rs
62
src/base.rs
|
@ -74,7 +74,7 @@ use modalkit::{
|
|||
ApplicationStore,
|
||||
ApplicationWindowId,
|
||||
},
|
||||
completion::{complete_path, CompletionMap},
|
||||
completion::{complete_path, Completer, CompletionMap},
|
||||
context::EditContext,
|
||||
cursor::Cursor,
|
||||
rope::EditRope,
|
||||
|
@ -1914,11 +1914,20 @@ impl ApplicationInfo for IambInfo {
|
|||
type WindowId = IambId;
|
||||
type ContentId = IambBufferId;
|
||||
|
||||
fn content_of_command(ct: CommandType) -> IambBufferId {
|
||||
IambBufferId::Command(ct)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IambCompleter;
|
||||
|
||||
impl Completer<IambInfo> for IambCompleter {
|
||||
fn complete(
|
||||
&mut self,
|
||||
text: &EditRope,
|
||||
cursor: &mut Cursor,
|
||||
content: &IambBufferId,
|
||||
store: &mut ProgramStore,
|
||||
store: &mut ChatStore,
|
||||
) -> Vec<String> {
|
||||
match content {
|
||||
IambBufferId::Command(CommandType::Command) => complete_cmdbar(text, cursor, store),
|
||||
|
@ -1936,21 +1945,16 @@ impl ApplicationInfo for IambInfo {
|
|||
IambBufferId::UnreadList => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn content_of_command(ct: CommandType) -> IambBufferId {
|
||||
IambBufferId::Command(ct)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
||||
.unwrap_or_else(EditRope::empty);
|
||||
let id = Cow::from(&id);
|
||||
|
||||
store
|
||||
.application
|
||||
.presences
|
||||
.complete(id.as_ref())
|
||||
.into_iter()
|
||||
|
@ -1959,7 +1963,7 @@ fn complete_users(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) ->
|
|||
}
|
||||
|
||||
/// 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
|
||||
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
||||
.unwrap_or_else(EditRope::empty);
|
||||
|
@ -1968,13 +1972,12 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
|||
match id.chars().next() {
|
||||
// Complete room aliases.
|
||||
Some('#') => {
|
||||
return store.application.names.complete(id.as_ref());
|
||||
return store.names.complete(id.as_ref());
|
||||
},
|
||||
|
||||
// Complete room identifiers.
|
||||
Some('!') => {
|
||||
return store
|
||||
.application
|
||||
.rooms
|
||||
.complete(id.as_ref())
|
||||
.into_iter()
|
||||
|
@ -1984,7 +1987,7 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
|||
|
||||
// Complete Emoji shortcodes.
|
||||
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));
|
||||
|
||||
return iter.collect();
|
||||
|
@ -1993,7 +1996,6 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ProgramStore) -
|
|||
// Complete usernames for @ and empty strings.
|
||||
Some('@') | None => {
|
||||
return store
|
||||
.application
|
||||
.presences
|
||||
.complete(id.as_ref())
|
||||
.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.)
|
||||
fn complete_matrix_names(
|
||||
text: &EditRope,
|
||||
cursor: &mut Cursor,
|
||||
store: &ProgramStore,
|
||||
) -> Vec<String> {
|
||||
fn complete_matrix_names(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||
let id = text
|
||||
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
|
||||
.unwrap_or_else(EditRope::empty);
|
||||
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() {
|
||||
return list;
|
||||
}
|
||||
|
||||
let list = store.application.presences.complete(id.as_ref());
|
||||
let list = store.presences.complete(id.as_ref());
|
||||
if !list.is_empty() {
|
||||
return list.into_iter().map(|i| i.to_string()).collect();
|
||||
}
|
||||
|
||||
store
|
||||
.application
|
||||
.rooms
|
||||
.complete(id.as_ref())
|
||||
.into_iter()
|
||||
|
@ -2037,12 +2034,12 @@ fn complete_matrix_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 = sc.unwrap_or_else(EditRope::empty);
|
||||
let sc = Cow::from(&sc);
|
||||
|
||||
store.application.emojis.complete(sc.as_ref())
|
||||
store.emojis.complete(sc.as_ref())
|
||||
}
|
||||
|
||||
/// Tab completion for command names.
|
||||
|
@ -2050,11 +2047,11 @@ fn complete_cmdname(
|
|||
desc: CommandDescription,
|
||||
text: &EditRope,
|
||||
cursor: &mut Cursor,
|
||||
store: &ProgramStore,
|
||||
store: &ChatStore,
|
||||
) -> Vec<String> {
|
||||
// Complete command name and set cursor position.
|
||||
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.
|
||||
|
@ -2062,9 +2059,9 @@ fn complete_cmdarg(
|
|||
desc: CommandDescription,
|
||||
text: &EditRope,
|
||||
cursor: &mut Cursor,
|
||||
store: &ProgramStore,
|
||||
store: &ChatStore,
|
||||
) -> 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,
|
||||
Err(_) => return vec![],
|
||||
};
|
||||
|
@ -2087,12 +2084,7 @@ fn complete_cmdarg(
|
|||
}
|
||||
|
||||
/// Tab completion for commands.
|
||||
fn complete_cmd(
|
||||
cmd: &str,
|
||||
text: &EditRope,
|
||||
cursor: &mut Cursor,
|
||||
store: &ProgramStore,
|
||||
) -> Vec<String> {
|
||||
fn complete_cmd(cmd: &str, text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
|
||||
match CommandDescription::from_str(cmd) {
|
||||
Ok(desc) => {
|
||||
if desc.arg.untrimmed.is_empty() {
|
||||
|
@ -2109,7 +2101,7 @@ fn complete_cmd(
|
|||
}
|
||||
|
||||
/// 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 slice = text.slice(..eo);
|
||||
let cow = Cow::from(&slice);
|
||||
|
@ -2289,6 +2281,7 @@ pub mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_complete_msgbar() {
|
||||
let store = mock_store().await;
|
||||
let store = store.application;
|
||||
|
||||
let text = EditRope::from("going for a walk :walk ");
|
||||
let mut cursor = Cursor::new(0, 22);
|
||||
|
@ -2312,6 +2305,7 @@ pub mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_complete_cmdbar() {
|
||||
let store = mock_store().await;
|
||||
let store = store.application;
|
||||
let users = vec![
|
||||
"@user1:example.com",
|
||||
"@user2:example.com",
|
||||
|
|
|
@ -353,29 +353,31 @@ pub struct UserDisplayTunables {
|
|||
|
||||
pub type UserOverrides = HashMap<OwnedUserId, UserDisplayTunables>;
|
||||
|
||||
fn merge_sorts(a: SortOverrides, b: SortOverrides) -> SortOverrides {
|
||||
fn merge_sorts(profile: SortOverrides, global: SortOverrides) -> SortOverrides {
|
||||
SortOverrides {
|
||||
chats: b.chats.or(a.chats),
|
||||
dms: b.dms.or(a.dms),
|
||||
rooms: b.rooms.or(a.rooms),
|
||||
spaces: b.spaces.or(a.spaces),
|
||||
members: b.members.or(a.members),
|
||||
chats: profile.chats.or(global.chats),
|
||||
dms: profile.dms.or(global.dms),
|
||||
rooms: profile.rooms.or(global.rooms),
|
||||
spaces: profile.spaces.or(global.spaces),
|
||||
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
|
||||
K: Eq + Hash,
|
||||
{
|
||||
match (a, b) {
|
||||
(Some(a), None) => Some(a),
|
||||
(None, Some(b)) => Some(b),
|
||||
(Some(mut a), Some(b)) => {
|
||||
for (k, v) in b {
|
||||
a.insert(k, v);
|
||||
match (global, profile) {
|
||||
(Some(m), None) | (None, Some(m)) => Some(m),
|
||||
(Some(mut global), Some(profile)) => {
|
||||
for (k, v) in profile {
|
||||
global.insert(k, v);
|
||||
}
|
||||
|
||||
Some(a)
|
||||
Some(global)
|
||||
},
|
||||
(None, None) => None,
|
||||
}
|
||||
|
@ -397,6 +399,9 @@ pub enum UserDisplayStyle {
|
|||
// it can wind up being the Matrix username if there are display name collisions in the room,
|
||||
// in order to avoid any confusion.
|
||||
DisplayName,
|
||||
|
||||
// Acts like Username, except when the username matches given regex, then acts like DisplayName
|
||||
Regex,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
|
@ -566,6 +571,7 @@ pub struct TunableValues {
|
|||
pub typing_notice_display: bool,
|
||||
pub users: UserOverrides,
|
||||
pub username_display: UserDisplayStyle,
|
||||
pub username_display_regex: Option<String>,
|
||||
pub message_user_color: bool,
|
||||
pub default_room: Option<String>,
|
||||
pub open_command: Option<Vec<String>>,
|
||||
|
@ -593,6 +599,7 @@ pub struct Tunables {
|
|||
pub typing_notice_display: Option<bool>,
|
||||
pub users: Option<UserOverrides>,
|
||||
pub username_display: Option<UserDisplayStyle>,
|
||||
pub username_display_regex: Option<String>,
|
||||
pub message_user_color: Option<bool>,
|
||||
pub default_room: Option<String>,
|
||||
pub open_command: Option<Vec<String>>,
|
||||
|
@ -624,6 +631,7 @@ impl Tunables {
|
|||
typing_notice_display: self.typing_notice_display.or(other.typing_notice_display),
|
||||
users: merge_maps(self.users, other.users),
|
||||
username_display: self.username_display.or(other.username_display),
|
||||
username_display_regex: self.username_display_regex.or(other.username_display_regex),
|
||||
message_user_color: self.message_user_color.or(other.message_user_color),
|
||||
default_room: self.default_room.or(other.default_room),
|
||||
open_command: self.open_command.or(other.open_command),
|
||||
|
@ -653,6 +661,7 @@ impl Tunables {
|
|||
typing_notice_display: self.typing_notice_display.unwrap_or(true),
|
||||
users: self.users.unwrap_or_default(),
|
||||
username_display: self.username_display.unwrap_or_default(),
|
||||
username_display_regex: self.username_display_regex,
|
||||
message_user_color: self.message_user_color.unwrap_or(false),
|
||||
default_room: self.default_room,
|
||||
open_command: self.open_command,
|
||||
|
@ -911,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 tunables = global.unwrap_or_default();
|
||||
|
@ -1046,6 +1055,20 @@ impl ApplicationSettings {
|
|||
Cow::Borrowed(user_id.as_str())
|
||||
}
|
||||
},
|
||||
(None, UserDisplayStyle::Regex) => {
|
||||
let re = regex::Regex::new(
|
||||
&self.tunables.username_display_regex.clone().unwrap_or("*".into()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if !re.is_match(user_id.as_str()) {
|
||||
Cow::Borrowed(user_id.as_str())
|
||||
} else if let Some(display) = info.display_names.get(user_id) {
|
||||
Cow::Borrowed(display.as_str())
|
||||
} else {
|
||||
Cow::Borrowed(user_id.as_str())
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Span::styled(name, style)
|
||||
|
@ -1110,10 +1133,10 @@ mod tests {
|
|||
assert_eq!(res, Some(b.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()));
|
||||
assert_eq!(res, Some(b.clone()));
|
||||
assert_eq!(res, Some(c.clone()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1162,6 +1185,13 @@ mod tests {
|
|||
let res: Tunables =
|
||||
serde_json::from_str("{\"username_display\": \"displayname\"}").unwrap();
|
||||
assert_eq!(res.username_display, Some(UserDisplayStyle::DisplayName));
|
||||
|
||||
let res: Tunables = serde_json::from_str(
|
||||
"{\"username_display\": \"regex\",\n\"username_display_regex\": \"foo\"}",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(res.username_display, Some(UserDisplayStyle::Regex));
|
||||
assert_eq!(res.username_display_regex.unwrap_or("FAILED".into()), "foo".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -62,7 +62,7 @@ use modalkit::crossterm::{
|
|||
use ratatui::{
|
||||
backend::CrosstermBackend,
|
||||
layout::Rect,
|
||||
style::{Color, Style},
|
||||
style::{Color, Modifier, Style},
|
||||
text::Span,
|
||||
widgets::Paragraph,
|
||||
Terminal,
|
||||
|
@ -89,6 +89,7 @@ use crate::{
|
|||
ChatStore,
|
||||
HomeserverAction,
|
||||
IambAction,
|
||||
IambCompleter,
|
||||
IambError,
|
||||
IambId,
|
||||
IambInfo,
|
||||
|
@ -327,6 +328,9 @@ impl Application {
|
|||
.show_dialog(dialogstr)
|
||||
.show_mode(modestr)
|
||||
.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);
|
||||
f.render_stateful_widget(screen, area, sstate);
|
||||
|
||||
|
@ -529,7 +533,7 @@ impl Application {
|
|||
},
|
||||
|
||||
// Unimplemented.
|
||||
Action::KeywordLookup => {
|
||||
Action::KeywordLookup(_) => {
|
||||
// XXX: implement
|
||||
None
|
||||
},
|
||||
|
@ -1011,7 +1015,9 @@ async fn run(settings: ApplicationSettings) -> IambResult<()> {
|
|||
// Set up the async worker thread and global store.
|
||||
let worker = ClientWorker::spawn(client.clone(), settings.clone()).await;
|
||||
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));
|
||||
worker.init(store.clone());
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ pub fn mock_tunables() -> TunableValues {
|
|||
open_command: None,
|
||||
external_edit_file_suffix: String::from(".md"),
|
||||
username_display: UserDisplayStyle::Username,
|
||||
username_display_regex: Some(String::from(".*")),
|
||||
message_user_color: false,
|
||||
mouse: Default::default(),
|
||||
notifications: Notifications {
|
||||
|
|
|
@ -864,16 +864,16 @@ impl PromptActions<ProgramContext, ProgramStore, IambInfo> for ChatState {
|
|||
|
||||
fn recall(
|
||||
&mut self,
|
||||
filter: &RecallFilter,
|
||||
dir: &MoveDir1D,
|
||||
count: &Count,
|
||||
prefixed: bool,
|
||||
ctx: &ProgramContext,
|
||||
_: &mut ProgramStore,
|
||||
) -> EditResult<Vec<(ProgramAction, ProgramContext)>, IambInfo> {
|
||||
let count = ctx.resolve(count);
|
||||
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 {
|
||||
self.tbox.set_text(text);
|
||||
|
@ -897,9 +897,7 @@ impl Promptable<ProgramContext, ProgramStore, IambInfo> for ChatState {
|
|||
match act {
|
||||
PromptAction::Submit => self.submit(ctx, store),
|
||||
PromptAction::Abort(empty) => self.abort(*empty, ctx, store),
|
||||
PromptAction::Recall(dir, count, prefixed) => {
|
||||
self.recall(dir, count, *prefixed, ctx, store)
|
||||
},
|
||||
PromptAction::Recall(filter, dir, count) => self.recall(filter, dir, count, ctx, store),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -840,8 +840,8 @@ impl EditorActions<ProgramContext, ProgramStore, IambInfo> for ScrollbackState {
|
|||
|
||||
fn complete(
|
||||
&mut self,
|
||||
_: &CompletionStyle,
|
||||
_: &CompletionType,
|
||||
_: &CompletionSelection,
|
||||
_: &CompletionDisplay,
|
||||
_: &ProgramContext,
|
||||
_: &mut ProgramStore,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue