Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ show_trayicon = true
# hotkey for opening clipboard history
clipboard_hotkey = "SUPER+SHIFT+2"

# number of recent actions to show when search is empty
recent_actions_limit = 5

# Create a presentation.sh file and you can make it do pretty much anything
# Example usage:
# - turn on / off your WM in different "modes"
Expand Down Expand Up @@ -66,4 +69,3 @@ command = "echo "
# icon_path is optional
alias = "Variables 1" # the name that will be displayed in the results
alias_lc = "var test" # the name used to search for it

1 change: 1 addition & 0 deletions docs/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ haptic_feedback = false
show_trayicon = true
shells = []
clipboard_hotkey = "SUPER+SHIFT+C"
recent_actions_limit = 5

[buffer_rules]
clear_on_hide = true
Expand Down
1 change: 1 addition & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub enum Message {
UpdateAvailable,
ResizeWindow(Id, f32),
OpenWindow,
OpenResult(u32),
OpenToSettings,
SearchQueryChanged(String, Id),
KeyPressed(u32),
Expand Down
5 changes: 3 additions & 2 deletions src/app/apps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ impl App {
theme: crate::config::Theme,
id_num: u32,
focussed_id: u32,
on_press: Option<Message>,
) -> iced::Element<'static, Message> {
let focused = focussed_id == id_num;

Expand Down Expand Up @@ -202,11 +203,11 @@ impl App {
}
row = row.push(container(text_block).width(Fill));

let msg = match self.open_command.clone() {
let msg = on_press.or(match self.open_command.clone() {
AppCommand::Function(func) => Some(Message::RunFunction(func)),
AppCommand::Message(msg) => Some(msg),
AppCommand::Display => None,
};
});

let theme_clone = theme.clone();

Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn clipboard_view(
Column::from_iter(clipboard_content.iter().enumerate().map(|(i, content)| {
content
.to_app()
.render(theme.clone(), i as u32, focussed_id)
.render(theme.clone(), i as u32, focussed_id, None)
}))
.width(WINDOW_WIDTH / 3.),
)
Expand Down
38 changes: 38 additions & 0 deletions src/app/tile.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! This module handles the logic for the tile, AKA rustcast's main window
pub mod elm;
mod recent_actions;
pub mod update;

use crate::app::apps::App;
Expand Down Expand Up @@ -34,6 +35,8 @@ use std::fmt::Debug;
use std::str::FromStr;
use std::time::Duration;

use self::recent_actions::RecentActions;

/// This is a wrapper around the sender to disable dropping
#[derive(Clone, Debug)]
pub struct ExtSender(pub Sender<Message>);
Expand Down Expand Up @@ -70,6 +73,14 @@ impl AppIndex {
app.ranking += 1;
}

fn contains_key(&self, name: &str) -> bool {
self.by_name.contains_key(name)
}

fn get(&self, name: &str) -> Option<&App> {
self.by_name.get(name)
}

fn empty() -> AppIndex {
AppIndex {
by_name: HashMap::new(),
Expand Down Expand Up @@ -123,6 +134,7 @@ pub struct Tile {
frontmost: Option<Retained<NSRunningApplication>>,
pub config: Config,
hotkeys: Hotkeys,
recent_actions: RecentActions,
clipboard_content: Vec<ClipBoardContentType>,
tray_icon: Option<TrayIcon>,
sender: Option<ExtSender>,
Expand Down Expand Up @@ -259,6 +271,32 @@ impl Tile {
self.results = results;
}

pub fn recent_results(&self) -> Vec<App> {
self.recent_actions.resolve(|key| self.options.get(key))
}

pub fn record_recent_action(&mut self, key: &str) {
self.recent_actions.record(key);
}

pub fn action_exists(&self, key: &str) -> bool {
self.options.contains_key(key)
}

pub fn refresh_recent_actions(&mut self) {
let mut changed = self
.recent_actions
.set_limit(self.config.recent_actions_limit);
changed = self
.recent_actions
.prune_by(|key| self.options.contains_key(key))
|| changed;

if changed {
self.recent_actions.persist_async();
}
}

/// Gets the frontmost application to focus later.
pub fn capture_frontmost(&mut self) {
use objc2_app_kit::NSWorkspace;
Expand Down
31 changes: 22 additions & 9 deletions src/app/tile/elm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ pub fn new(hotkey: HotKey, config: &Config) -> (Tile, Task<Message>) {
info!("Loaded basic apps / default apps");
options.par_sort_by_key(|x| x.display_name.len());
let options = AppIndex::from_apps(options);
let mut recent_actions =
crate::app::tile::recent_actions::RecentActions::load(config.recent_actions_limit);

if recent_actions.prune_by(|key| options.contains_key(key)) {
recent_actions.persist_async();
}

let hotkeys = Hotkeys {
toggle: hotkey,
Expand All @@ -79,6 +85,7 @@ pub fn new(hotkey: HotKey, config: &Config) -> (Tile, Task<Message>) {
focused: false,
config: config.clone(),
theme: config.theme.to_owned().clone().into(),
recent_actions,
clipboard_content: vec![],
tray_icon: None,
sender: None,
Expand Down Expand Up @@ -131,12 +138,16 @@ pub fn view(tile: &Tile, wid: window::Id) -> Element<'_, Message> {
tile.focus_id,
),
Page::Settings => settings_page(tile.config.clone()),
Page::FileSearch | Page::Main => container(Column::from_iter(
tile.results.iter().enumerate().map(|(i, app)| {
app.clone()
.render(tile.config.theme.clone(), i as u32, tile.focus_id)
}),
))
Page::FileSearch | Page::Main => container(Column::from_iter(tile.results.iter().enumerate().map(
|(i, app)| {
app.clone().render(
tile.config.theme.clone(),
i as u32,
tile.focus_id,
Some(Message::OpenResult(i as u32)),
)
},
)))
.into(),
};

Expand All @@ -155,16 +166,18 @@ pub fn view(tile: &Tile, wid: window::Id) -> Element<'_, Message> {
.id("results")
.height(height as u32);

let text = if tile.query_lc.is_empty() {
tile.page.to_string()
} else {
let text = if !tile.query_lc.is_empty() {
match results_count {
1 => "1 result found".to_string(),
0 => "No results found".to_string(),
count => {
format!("{count} results found")
}
}
} else if tile.page == Page::Main {
"Recent actions".to_string()
} else {
tile.page.to_string()
};

let contents = container(
Expand Down
Loading
Loading