Skip to content

Commit

Permalink
[sweep] pass window uid in Sweep(Select|Bind)
Browse files Browse the repository at this point in the history
  • Loading branch information
aslpavel committed Nov 10, 2024
1 parent 67f5e2b commit 050ec88
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 85 deletions.
2 changes: 1 addition & 1 deletion sweep-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ async fn main() -> Result<(), Error> {
});
};
while let Some(event) = sweep.next_event().await {
if let SweepEvent::Select(items) = event {
if let SweepEvent::Select { items, .. } = event {
if items.is_empty() && !args.no_match_use_input {
continue;
}
Expand Down
54 changes: 39 additions & 15 deletions sweep-lib/src/sweep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ where
loop {
tokio::select! {
event = sweep.next_event() => match event {
Some(SweepEvent::Select(entry)) => return Ok(entry),
Some(SweepEvent::Select { items, .. }) => return Ok(items),
None => return Ok(Vec::new()),
_ => continue,
},
Expand All @@ -151,7 +151,6 @@ enum SweepRequest<H> {
tag: String,
desc: String,
},
Terminate,
Current(oneshot::Sender<Option<H>>),
Marked(oneshot::Sender<Vec<H>>),
CursorSet {
Expand All @@ -168,16 +167,25 @@ enum SweepRequest<H> {
},
HaystackClear,
RankerKeepOrder(Option<bool>),
RenderSuppress(bool),

Terminate,
WindowSwitch(Either<Box<dyn Window>, WindowId>),
WindowPop,
RenderSuppress(bool),
}

/// Events returned to [Sweep] type
#[derive(Clone, Debug)]
pub enum SweepEvent<H> {
Select(Vec<H>),
Bind { tag: String, chord: KeyChord },
Select {
uid: WindowId,
items: Vec<H>,
},
Bind {
uid: WindowId,
tag: String,
chord: KeyChord,
},
Window(WindowEvent),
Resize(TerminalSize),
}
Expand Down Expand Up @@ -379,9 +387,9 @@ where
Arc::new({
let send = std::sync::Mutex::new(Some(send)); // one shot is moved on send
move |event| {
if let SweepEvent::Select(selected) = event {
if let SweepEvent::Select { items, .. } = event {
if let Some(send) = send.with_mut(|send| send.take()) {
_ = send.send(selected);
_ = send.send(items);
}
Ok(WindowAction::Close {
uid: Some(uid.clone()),
Expand Down Expand Up @@ -775,12 +783,16 @@ where

while let Some(event) = sweep.next_event().await {
match event {
SweepEvent::Bind { tag, chord } => {
peer.notify_with_value("bind", json!({"tag": tag, "key": chord}))?
}
SweepEvent::Select(items) => {
SweepEvent::Bind { uid, tag, chord } => peer.notify_with_value(
"bind",
json!({"uid": uid, "tag": tag, "key": chord}),
)?,
SweepEvent::Select { uid, items } => {
if !items.is_empty() {
peer.notify_with_value("select", json!({"items": items}))?
peer.notify_with_value(
"select",
json!({"uid": uid, "items": items}),
)?
}
}
SweepEvent::Window(window_event) => {
Expand Down Expand Up @@ -1236,6 +1248,7 @@ where
SweepAction::User { tag, chord, .. } => {
if !tag.is_empty() {
return (self.event_handler)(SweepEvent::Bind {
uid: self.window_uid.clone(),
tag: tag.clone(),
chord: chord.clone(),
});
Expand All @@ -1251,11 +1264,17 @@ where
.into_iter()
.collect()
};
return (self.event_handler)(SweepEvent::Select(selected));
return (self.event_handler)(SweepEvent::Select {
uid: self.window_uid.clone(),
items: selected,
});
}
SweepAction::SelectByIndex(index) => {
if let Some(item) = self.haystack.get(*index) {
return (self.event_handler)(SweepEvent::Select(vec![item.clone()]));
return (self.event_handler)(SweepEvent::Select {
uid: self.window_uid.clone(),
items: vec![item.clone()],
});
}
}
SweepAction::Mark => {
Expand Down Expand Up @@ -1364,7 +1383,10 @@ where
self.term_waker.clone(),
None,
Arc::new(move |event| {
if let SweepEvent::Select(selected) = event {
if let SweepEvent::Select {
items: selected, ..
} = event
{
let name = selected
.into_iter()
.next()
Expand Down Expand Up @@ -1525,6 +1547,7 @@ impl<H: Haystack> Window for SweepWindow<H> {
if is_first_key && key == backspace && self.input.get().count() == 0 {
if let Some(ref tag) = self.key_empty_backspace {
return (self.event_handler)(SweepEvent::Bind {
uid: self.window_uid.clone(),
tag: tag.clone(),
chord: KeyChord::from_iter([backspace]),
});
Expand Down Expand Up @@ -1560,6 +1583,7 @@ impl<H: Haystack> Window for SweepWindow<H> {
_ => {
let key = Key::new(mouse.name, mouse.mode);
(self.event_handler)(SweepEvent::Bind {
uid: self.window_uid.clone(),
tag: tag.to_owned(),
chord: KeyChord::from_iter([key]),
})
Expand Down
5 changes: 1 addition & 4 deletions sweep-py/sweep/apps/bash_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
BASH_HISTORY_FILE = "~/.bash_history"
DATE_RE = re.compile(r"^#(\d+)$")
TERM_ICON = Icon(
path="M20,19V7H4V19H20M20,3A2,2 0 0,1 22,5V19A2,2 0 0,1 20,21H4"
"A2,2 0 0,1 2,19V5C2,3.89 2.9,3 4,3H20M13,17V15H18V17H13M9.58,13"
"L5.57,9H8.4L11.7,12.3C12.09,12.69 12.09,13.33 11.7,13.72L8.42,17"
"H5.59L9.58,13Z",
path="M20,19V7H4V19H20M20,3A2,2 0 0,1 22,5V19A2,2 0 0,1 20,21H4A2,2 0 0,1 2,19V5C2,3.89 2.9,3 4,3H20M13,17V15H18V17H13M9.58,13L5.57,9H8.4L11.7,12.3C12.09,12.69 12.09,13.33 11.7,13.72L8.42,17H5.59L9.58,13Z",
view_box=(0, 0, 24, 24),
size=(1, 3),
fallback=" ",
Expand Down
50 changes: 6 additions & 44 deletions sweep-py/sweep/apps/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,57 +31,25 @@
from . import sweep_default_cmd

ICON_BEER = Icon(
path="M8.5 10A.75.75 0 0 0 7 10v7a.75.75 0 0 0 1.5 0v-7ZM11.5 10a.75.75 0 0 "
"0-1.5 0v7a.75.75 0 0 0 1.5 0v-7ZM14.5 10a.75.75 0 0 0-1.5 0v7a.75.75 0 0 0 "
"1.5 0v-7ZM4 5.25A3.25 3.25 0 0 1 7.25 2h7a3.25 3.25 0 0 1 3.25 3.25V6h1.25"
"A3.25 3.25 0 0 1 22 9.25v5.5A3.25 3.25 0 0 1 18.75 18H17.5v1.75A2.25 2.25 0"
" 0 1 15.25 22h-9A2.25 2.25 0 0 1 4 19.75V5.25ZM16 7.5H5.5v12.25c0 .414.336"
".75.75.75h9a.75.75 0 0 0 .75-.75V7.5Zm1.5 9h1.25a1.75 1.75 0 0 0 1.75-1.75"
"v-5.5a1.75 1.75 0 0 0-1.75-1.75H17.5v9ZM16 5.25a1.75 1.75 0 0 0-1.75-1.75"
"h-7A1.75 1.75 0 0 0 5.5 5.25V6H16v-.75Z",
path="M8.5 10A.75.75 0 0 0 7 10v7a.75.75 0 0 0 1.5 0v-7ZM11.5 10a.75.75 0 0 0-1.5 0v7a.75.75 0 0 0 1.5 0v-7ZM14.5 10a.75.75 0 0 0-1.5 0v7a.75.75 0 0 0 1.5 0v-7ZM4 5.25A3.25 3.25 0 0 1 7.25 2h7a3.25 3.25 0 0 1 3.25 3.25V6h1.25A3.25 3.25 0 0 1 22 9.25v5.5A3.25 3.25 0 0 1 18.75 18H17.5v1.75A2.25 2.25 0 0 1 15.25 22h-9A2.25 2.25 0 0 1 4 19.75V5.25ZM16 7.5H5.5v12.25c0 .414.336.75.75.75h9a.75.75 0 0 0 .75-.75V7.5Zm1.5 9h1.25a1.75 1.75 0 0 0 1.75-1.75v-5.5a1.75 1.75 0 0 0-1.75-1.75H17.5v9ZM16 5.25a1.75 1.75 0 0 0-1.75-1.75h-7A1.75 1.75 0 0 0 5.5 5.25V6H16v-.75Z",
view_box=(0, 0, 24, 24),
size=(1, 3),
fallback="[P]",
)
ICON_COCKTAIL = Icon(
path="M19.873 3.49a.75.75 0 1 0-.246-1.48l-6 1a.75.75 0 0 0-.613.593L12.736 "
"5H5.75a.75.75 0 0 0-.75.75v4a3.25 3.25 0 0 0 3 3.24v.51c0 1.953 1.4 3.579 "
"3.25 3.93v3.07h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-3.07A4.001"
" 4.001 0 0 0 16 13.5v-.51a3.25 3.25 0 0 0 3-3.24v-4a.75.75 0 0 0-.75-.75h-3.985"
"l.119-.595 5.49-.915ZM17.5 8h-3.835l.3-1.5H17.5V8Zm-4.135 1.5H17.5v.25a1.75"
" 1.75 0 0 1-1.75 1.75h-.5a.75.75 0 0 0-.75.75v1.25a2.5 2.5 0 0 1-5 0v-1.25"
"a.75.75 0 0 0-.75-.75h-.5A1.75 1.75 0 0 1 6.5 9.75V9.5h5.335l-.82 4.103a.75"
".75 0 1 0 1.47.294l.88-4.397ZM12.135 8H6.5V6.5h5.935l-.3 1.5Z",
path="M19.873 3.49a.75.75 0 1 0-.246-1.48l-6 1a.75.75 0 0 0-.613.593L12.736 5H5.75a.75.75 0 0 0-.75.75v4a3.25 3.25 0 0 0 3 3.24v.51c0 1.953 1.4 3.579 3.25 3.93v3.07h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-3.07A4.001 4.001 0 0 0 16 13.5v-.51a3.25 3.25 0 0 0 3-3.24v-4a.75.75 0 0 0-.75-.75h-3.985l.119-.595 5.49-.915ZM17.5 8h-3.835l.3-1.5H17.5V8Zm-4.135 1.5H17.5v.25a1.75 1.75 0 0 1-1.75 1.75h-.5a.75.75 0 0 0-.75.75v1.25a2.5 2.5 0 0 1-5 0v-1.25a.75.75 0 0 0-.75-.75h-.5A1.75 1.75 0 0 1 6.5 9.75V9.5h5.335l-.82 4.103a.75.75 0 1 0 1.47.294l.88-4.397ZM12.135 8H6.5V6.5h5.935l-.3 1.5Z",
view_box=(0, 0, 24, 24),
size=(1, 3),
fallback="[C] ",
)
ICON_BACKPACK = Icon(
path="M12 2a3.75 3.75 0 0 0-3.736 3.424A7.999 7.999 0 0 0 4 12.5v6.25A3.25 3.25"
" 0 0 0 7.25 22h5.56a6.518 6.518 0 0 1-1.078-1.5H7.25a1.75 1.75 0 0 1-1.75-1.75"
"v-3.036H8v1.536a.75.75 0 0 0 1.5 0v-1.536h1.748c.175-.613.438-1.19.774-1.714"
"H5.5v-1.5a6.5 6.5 0 0 1 12.838-1.446 6.455 6.455 0 0 1 1.596.417 8.006 8.006"
" 0 0 0-4.198-6.047A3.75 3.75 0 0 0 12 2Zm0 2.5c-.698 0-1.374.09-2.02.257a2.25"
" 2.25 0 0 1 4.04 0A8.013 8.013 0 0 0 12 4.5ZM14.034 12a6.465 6.465 0 0 1 1.74"
"-.768c.144-.239.226-.517.226-.815A2.417 2.417 0 0 0 13.583 8h-3.166A2.417 "
"2.417 0 0 0 8 10.417C8 11.29 8.709 12 9.583 12h4.451ZM9.5 10.417c0-.507.41-.917"
".917-.917h3.166c.507 0 .917.41.917.917a.083.083 0 0 1-.083.083H9.583a.083.083"
" 0 0 1-.083-.083ZM23 17.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Zm-5 .5.001 "
"2.503a.5.5 0 1 1-1 0V18h-2.505a.5.5 0 0 1 0-1H17v-2.5a.5.5 0 1 1 1 0V17h2.497"
"a.5.5 0 0 1 0 1H18Z",
path="M12 2a3.75 3.75 0 0 0-3.736 3.424A7.999 7.999 0 0 0 4 12.5v6.25A3.25 3.25 0 0 0 7.25 22h5.56a6.518 6.518 0 0 1-1.078-1.5H7.25a1.75 1.75 0 0 1-1.75-1.75v-3.036H8v1.536a.75.75 0 0 0 1.5 0v-1.536h1.748c.175-.613.438-1.19.774-1.714H5.5v-1.5a6.5 6.5 0 0 1 12.838-1.446 6.455 6.455 0 0 1 1.596.417 8.006 8.006 0 0 0-4.198-6.047A3.75 3.75 0 0 0 12 2Zm0 2.5c-.698 0-1.374.09-2.02.257a2.25 2.25 0 0 1 4.04 0A8.013 8.013 0 0 0 12 4.5ZM14.034 12a6.465 6.465 0 0 1 1.74-.768c.144-.239.226-.517.226-.815A2.417 2.417 0 0 0 13.583 8h-3.166A2.417 2.417 0 0 0 8 10.417C8 11.29 8.709 12 9.583 12h4.451ZM9.5 10.417c0-.507.41-.917.917-.917h3.166c.507 0 .917.41.917.917a.083.083 0 0 1-.083.083H9.583a.083.083 0 0 1-.083-.083ZM23 17.5a5.5 5.5 0 1 0-11 0 5.5 5.5 0 0 0 11 0Zm-5 .5.001 2.503a.5.5 0 1 1-1 0V18h-2.505a.5.5 0 0 1 0-1H17v-2.5a.5.5 0 1 1 1 0V17h2.497a.5.5 0 0 1 0 1H18Z",
view_box=(0, 0, 24, 24),
size=(1, 3),
fallback="[B]",
)
ICON_SOFA = Icon(
path="M21 9V7C21 5.35 19.65 4 18 4H14C13.23 4 12.53 4.3 12 4.78"
"C11.47 4.3 10.77 4 10 4H6C4.35 4 3 5.35 3 7V9C1.35 9 0 10.35 0 12V17"
"C0 18.65 1.35 20 3 20V22H5V20H19V22H21V20C22.65 20 24 18.65 24 17V12"
"C24 10.35 22.65 9 21 9M14 6H18C18.55 6 19 6.45 19 7V9.78"
"C18.39 10.33 18 11.12 18 12V14H13V7C13 6.45 13.45 6 14 6M5 7"
"C5 6.45 5.45 6 6 6H10C10.55 6 11 6.45 11 7V14H6V12C6 11.12 5.61 10.33 5 9.78"
"V7M22 17C22 17.55 21.55 18 21 18H3C2.45 18 2 17.55 2 17V12"
"C2 11.45 2.45 11 3 11S4 11.45 4 12V16H20V12C20 11.45 20.45 11 21 11S22 11.45 22 12V17Z",
path="M21 9V7C21 5.35 19.65 4 18 4H14C13.23 4 12.53 4.3 12 4.78C11.47 4.3 10.77 4 10 4H6C4.35 4 3 5.35 3 7V9C1.35 9 0 10.35 0 12V17C0 18.65 1.35 20 3 20V22H5V20H19V22H21V20C22.65 20 24 18.65 24 17V12C24 10.35 22.65 9 21 9M14 6H18C18.55 6 19 6.45 19 7V9.78C18.39 10.33 18 11.12 18 12V14H13V7C13 6.45 13.45 6 14 6M5 7C5 6.45 5.45 6 6 6H10C10.55 6 11 6.45 11 7V14H6V12C6 11.12 5.61 10.33 5 9.78V7M22 17C22 17.55 21.55 18 21 18H3C2.45 18 2 17.55 2 17V12C2 11.45 2.45 11 3 11S4 11.45 4 12V16H20V12C20 11.45 20.45 11 21 11S22 11.45 22 12V17Z",
size=(4, 10),
view_box=(0, 0, 24, 24),
fallback="[S]",
Expand All @@ -90,13 +58,7 @@
view_box=(0, 0, 128, 128),
size=(1, 3),
fallback="[P]",
path="M37.73 26.48L90.27 26.48Q96.79 26.48 101.41 31.11Q106.04 35.73 106.04 42.25"
"L106.04 42.25L106.04 79.03Q106.04 85.54 101.41 90.17Q96.79 94.79 90.27 94.79"
"L90.27 94.79L37.73 94.79Q31.21 94.79 26.59 90.17Q21.96 85.54 21.96 79.03"
"L21.96 79.03L21.96 42.25Q21.96 35.73 26.59 31.11Q31.21 26.48 37.73 26.48"
"L37.73 26.48ZM71.99 31.74L37.73 31.74Q33.31 31.74 30.27 34.78"
"Q27.22 37.83 27.22 42.25L27.22 42.25L27.22 79.03Q27.22 83.44 30.27 86.49"
"Q33.31 89.54 37.73 89.54L37.73 89.54L71.99 89.54L71.99 31.74Z",
path="M37.73 26.48L90.27 26.48Q96.79 26.48 101.41 31.11Q106.04 35.73 106.04 42.25L106.04 42.25L106.04 79.03Q106.04 85.54 101.41 90.17Q96.79 94.79 90.27 94.79L90.27 94.79L37.73 94.79Q31.21 94.79 26.59 90.17Q21.96 85.54 21.96 79.03L21.96 79.03L21.96 42.25Q21.96 35.73 26.59 31.11Q31.21 26.48 37.73 26.48L37.73 26.48ZM71.99 31.74L37.73 31.74Q33.31 31.74 30.27 34.78Q27.22 37.83 27.22 42.25L27.22 42.25L27.22 79.03Q27.22 83.44 30.27 86.49Q33.31 89.54 37.73 89.54L37.73 89.54L71.99 89.54L71.99 31.74Z",
)
ICON_FOOT = Icon(
view_box=(0, 0, 128, 128),
Expand Down Expand Up @@ -272,7 +234,7 @@ def candidate_clicked(clicked: int) -> Candidate:
match event:
case SweepSize() | SweepWindow():
continue
case SweepSelect(items) if len(items) == 1:
case SweepSelect(items=items) if len(items) == 1:
item = items[0]
if isinstance(item, Candidate) and item.extra:
match item.extra:
Expand Down
16 changes: 10 additions & 6 deletions sweep-py/sweep/apps/mpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from typing import Any, NamedTuple, cast
from typing import Any, NamedTuple, cast, final, override
from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence

from PIL import Image as PILImage
Expand Down Expand Up @@ -190,11 +190,13 @@ def __init__(self, file: str) -> None:
self.id = None
self.current = None

@override
def __eq__(self, other: Any) -> bool:
if not isinstance(other, Song):
return False
return self.file == other.file

@override
def __hash__(self) -> int:
return hash(self.file)

Expand Down Expand Up @@ -412,12 +414,14 @@ def get_bytes(self) -> bytes:
return cast(bytes, self.data)
return b""

@override
def __repr__(self) -> str:
if self.name == "binary":
return f"binary={len(self.data)}"
return f"{self.name}={self.data}"


@final
class MPD:
"""MPD Client implementation
Expand Down Expand Up @@ -725,10 +729,10 @@ class MPDSweepView(Enum):

class MPDSweep:
def __init__(self, mpd: MPD, sweep: Sweep[Song]) -> None:
self._mpd = mpd
self._sweep = sweep
self._view = MPDSweepView.MAX
self._events_queue = asyncio.Queue[MPDEvent]()
self._mpd: MPD = mpd
self._sweep: Sweep[Song] = sweep
self._view: MPDSweepView = MPDSweepView.MAX
self._events_queue: asyncio.Queue[MPDEvent] = asyncio.Queue()

async def run(self) -> None:
# fields
Expand Down Expand Up @@ -973,7 +977,7 @@ async def _playlist_song_move_down(self) -> None:
return
await self._mpd.move(song, 1)

async def _goto(self, sweep: Sweep[Song], tag: str) -> None:
async def _goto(self, sweep: Sweep[Song], _tag: str) -> None:
song = await self._sweep.items_current()
if song is None:
return None
Expand Down
32 changes: 17 additions & 15 deletions sweep-py/sweep/sweep.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,18 @@ def from_json(obj: Any) -> Size:
return Size(height, width)


@dataclass
class SweepSelect[I]:
"""Event generated on item(s) select"""

uid: WindowId
items: list[I]


class SweepBind(NamedTuple):
"""Event generated on bound key press"""

uid: WindowId
tag: str
key: str | None

Expand Down Expand Up @@ -135,16 +144,6 @@ def from_json(obj: Any) -> SweepSize:
return SweepSize(cells, pixels, pixels_per_cell)


@dataclass
class SweepSelect[I]:
"""Event generated on item(s) select"""

items: list[I]

def __init__(self, items: list[I]):
self.items = items


@dataclass
class SweepWindow:
"""Fired on window transition"""
Expand Down Expand Up @@ -671,23 +670,26 @@ async def event_iter() -> AsyncGenerator[SweepEvent[I], None]:
continue
if event.method == "select":
yield SweepSelect(
[
uid=event.params["uid"],
items=[
self.__item_get(item)
for item in event.params.get("items", [])
]
],
)
elif event.method == "bind":
uid = event.params["uid"]
tag = event.params.get("tag", "")
handler = self.__binds.get(tag)
if handler is None:
yield SweepBind(
event.params.get("tag", ""),
event.params.get("key", None),
uid=uid,
tag=tag,
key=event.params.get("key", None),
)
else:
item = await handler(self, tag)
if item is not None:
yield SweepSelect([item])
yield SweepSelect(uid, items=[item])
elif event.method == "resize":
size = SweepSize.from_json(event.params)
self.__size = size
Expand Down

0 comments on commit 050ec88

Please sign in to comment.