mirror of
https://github.com/lotabout/skim.git
synced 2026-09-10 07:16:23 -04:00
remove the usage of ItemWrapper to reduce memory
This commit is contained in:
parent
a1f17d533c
commit
1d72fcac57
|
|
@ -10,7 +10,6 @@ use std::env;
|
|||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, BufWriter, Write};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::sync::atomic::AtomicU32;
|
||||
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
use nix::unistd::isatty;
|
||||
|
|
@ -454,7 +453,6 @@ pub fn filter(options: &SkimOptions, source: Option<SkimItemReceiver>) -> Result
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
// start
|
||||
let item_index = AtomicU32::new(0);
|
||||
let components_to_stop = Arc::new(AtomicUsize::new(0));
|
||||
let collector_option = CollectorOption::with_options(&options);
|
||||
|
||||
|
|
@ -467,8 +465,7 @@ pub fn filter(options: &SkimOptions, source: Option<SkimItemReceiver>) -> Result
|
|||
let mut num_matched = 0;
|
||||
stream_of_item
|
||||
.into_iter()
|
||||
.map(|item| ItemWrapper::new(item, (0, item_index.fetch_add(0, Ordering::SeqCst))))
|
||||
.filter_map(|wrapped| engine.match_item(Arc::new(wrapped)))
|
||||
.filter_map(|item| engine.match_item(item))
|
||||
.try_for_each(|matched| {
|
||||
num_matched += 1;
|
||||
if options.print_score {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::fmt::{Display, Error, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::item::{ItemWrapper, MatchedItem, MatchedRange, Rank};
|
||||
use crate::MatchEngine;
|
||||
use crate::item::{MatchedItem, MatchedRange, Rank};
|
||||
use crate::{MatchEngine, SkimItem};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#[derive(Debug)]
|
||||
|
|
@ -19,7 +19,7 @@ impl MatchAllEngine {
|
|||
}
|
||||
|
||||
impl MatchEngine for MatchAllEngine {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem> {
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem> {
|
||||
let rank = Rank {
|
||||
score: 0,
|
||||
begin: 0,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::fmt::{Display, Error, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::item::{ItemWrapper, MatchedItem, MatchedRange};
|
||||
use crate::MatchEngine;
|
||||
use crate::item::{MatchedItem, MatchedRange};
|
||||
use crate::{MatchEngine, SkimItem};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// OrEngine, a combinator
|
||||
|
|
@ -26,7 +26,7 @@ impl OrEngine {
|
|||
}
|
||||
|
||||
impl MatchEngine for OrEngine {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem> {
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem> {
|
||||
for engine in &self.engines {
|
||||
let result = engine.match_item(Arc::clone(&item));
|
||||
if result.is_some() {
|
||||
|
|
@ -98,7 +98,7 @@ impl AndEngine {
|
|||
}
|
||||
|
||||
impl MatchEngine for AndEngine {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem> {
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem> {
|
||||
// mock
|
||||
let mut results = vec![];
|
||||
for engine in &self.engines {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use crate::engine::util::{contains_upper, regex_match};
|
||||
use crate::item::{ItemWrapper, MatchedItem, MatchedRange, Rank};
|
||||
use crate::SkimItem;
|
||||
use crate::{CaseMatching, MatchEngine};
|
||||
use crate::item::{MatchedItem, MatchedRange, Rank};
|
||||
use crate::{CaseMatching, MatchEngine, SkimItem};
|
||||
use regex::{escape, Regex};
|
||||
use std::fmt::{Display, Error, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
|
@ -66,7 +65,7 @@ impl ExactEngine {
|
|||
}
|
||||
|
||||
impl MatchEngine for ExactEngine {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem> {
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem> {
|
||||
let mut matched_result = None;
|
||||
for &(start, end) in item.get_matching_ranges().as_ref() {
|
||||
if self.query_regex.is_none() {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use fuzzy_matcher::clangd::ClangdMatcher;
|
|||
use fuzzy_matcher::skim::{SkimMatcher, SkimMatcherV2};
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
|
||||
use crate::item::{ItemWrapper, MatchedItem, MatchedRange, Rank};
|
||||
use crate::item::{MatchedItem, MatchedRange, Rank};
|
||||
use crate::SkimItem;
|
||||
use crate::{CaseMatching, MatchEngine};
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ impl FuzzyEngine {
|
|||
}
|
||||
|
||||
impl MatchEngine for FuzzyEngine {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem> {
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem> {
|
||||
// iterate over all matching fields:
|
||||
let mut matched_result = None;
|
||||
for &(start, end) in item.get_matching_ranges().as_ref() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||
use regex::Regex;
|
||||
|
||||
use crate::engine::util::regex_match;
|
||||
use crate::item::{ItemWrapper, MatchedItem, MatchedRange, Rank};
|
||||
use crate::item::{MatchedItem, MatchedRange, Rank};
|
||||
use crate::SkimItem;
|
||||
use crate::{CaseMatching, MatchEngine};
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ impl RegexEngine {
|
|||
}
|
||||
|
||||
impl MatchEngine for RegexEngine {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem> {
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem> {
|
||||
let mut matched_result = None;
|
||||
for &(start, end) in item.get_matching_ranges().as_ref() {
|
||||
if self.query_regex.is_none() {
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ impl Draw for Header {
|
|||
.text_width(screen_width - 2)
|
||||
.hscroll_offset(self.hscroll_offset)
|
||||
.build();
|
||||
print_item(canvas, &mut printer, &item, self.theme.header());
|
||||
print_item(canvas, &mut printer, item, self.theme.header());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
63
src/item.rs
63
src/item.rs
|
|
@ -12,7 +12,7 @@ use regex::Regex;
|
|||
use crate::ansi::{ANSIParser, AnsiString};
|
||||
use crate::field::{parse_matching_fields, parse_transform_fields, FieldRange};
|
||||
use crate::spinlock::{SpinLock, SpinLockGuard};
|
||||
use crate::{ItemPreview, SkimItem};
|
||||
use crate::SkimItem;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// An item will store everything that one line input will need to be operated and displayed.
|
||||
|
|
@ -123,53 +123,6 @@ impl SkimItem for DefaultSkimItem {
|
|||
//------------------------------------------------------------------------------
|
||||
pub type ItemIndex = (u32, u32);
|
||||
|
||||
pub struct ItemWrapper {
|
||||
inner: Arc<dyn SkimItem>,
|
||||
// (num of run, number of index)
|
||||
id: ItemIndex,
|
||||
}
|
||||
|
||||
impl ItemWrapper {
|
||||
pub fn new(item: Arc<dyn SkimItem>, index: ItemIndex) -> Self {
|
||||
Self { id: index, inner: item }
|
||||
}
|
||||
|
||||
pub fn get_id(&self) -> ItemIndex {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn get_index(&self) -> usize {
|
||||
self.id.1 as usize
|
||||
}
|
||||
|
||||
pub fn get_inner(&self) -> Arc<dyn SkimItem> {
|
||||
self.inner.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// delegate to inner
|
||||
impl SkimItem for ItemWrapper {
|
||||
fn display(&self) -> Cow<AnsiString> {
|
||||
self.inner.display()
|
||||
}
|
||||
|
||||
fn text(&self) -> Cow<str> {
|
||||
self.inner.text()
|
||||
}
|
||||
|
||||
fn preview(&self) -> ItemPreview {
|
||||
self.inner.preview()
|
||||
}
|
||||
|
||||
fn output(&self) -> Cow<str> {
|
||||
self.inner.output()
|
||||
}
|
||||
|
||||
fn get_matching_ranges(&self) -> Cow<[(usize, usize)]> {
|
||||
self.inner.get_matching_ranges()
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Default)]
|
||||
pub struct Rank {
|
||||
|
|
@ -188,13 +141,13 @@ pub enum MatchedRange {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct MatchedItem {
|
||||
pub item: Arc<ItemWrapper>,
|
||||
pub item: Arc<dyn SkimItem>,
|
||||
pub rank: Rank,
|
||||
pub matched_range: Option<MatchedRange>, // range of chars that matched the pattern
|
||||
}
|
||||
|
||||
impl MatchedItem {
|
||||
pub fn builder(item: Arc<ItemWrapper>) -> Self {
|
||||
pub fn builder(item: Arc<dyn SkimItem>) -> Self {
|
||||
MatchedItem {
|
||||
item,
|
||||
rank: Rank::default(),
|
||||
|
|
@ -233,12 +186,12 @@ const ITEM_POOL_CAPACITY: usize = 1024;
|
|||
|
||||
pub struct ItemPool {
|
||||
length: AtomicUsize,
|
||||
pool: SpinLock<Vec<Arc<ItemWrapper>>>,
|
||||
pool: SpinLock<Vec<Arc<dyn SkimItem>>>,
|
||||
/// number of items that was `take`n
|
||||
taken: AtomicUsize,
|
||||
|
||||
/// reverse first N lines as header
|
||||
reserved_items: SpinLock<Vec<Arc<ItemWrapper>>>,
|
||||
reserved_items: SpinLock<Vec<Arc<dyn SkimItem>>>,
|
||||
lines_to_reserve: usize,
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +234,7 @@ impl ItemPool {
|
|||
self.taken.store(0, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
pub fn append(&self, mut items: Vec<Arc<ItemWrapper>>) {
|
||||
pub fn append(&self, mut items: Vec<Arc<dyn SkimItem>>) {
|
||||
let mut pool = self.pool.lock();
|
||||
let mut header_items = self.reserved_items.lock();
|
||||
|
||||
|
|
@ -296,13 +249,13 @@ impl ItemPool {
|
|||
self.length.store(pool.len(), Ordering::SeqCst);
|
||||
}
|
||||
|
||||
pub fn take(&self) -> ItemPoolGuard<Arc<ItemWrapper>> {
|
||||
pub fn take(&self) -> ItemPoolGuard<Arc<dyn SkimItem>> {
|
||||
let guard = self.pool.lock();
|
||||
let taken = self.taken.swap(guard.len(), Ordering::SeqCst);
|
||||
ItemPoolGuard { guard, start: taken }
|
||||
}
|
||||
|
||||
pub fn reserved(&self) -> ItemPoolGuard<Arc<ItemWrapper>> {
|
||||
pub fn reserved(&self) -> ItemPoolGuard<Arc<dyn SkimItem>> {
|
||||
let guard = self.reserved_items.lock();
|
||||
ItemPoolGuard { guard, start: 0 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use tuikit::prelude::{Event as TermEvent, *};
|
|||
pub use crate::ansi::AnsiString;
|
||||
pub use crate::engine::fuzzy::FuzzyAlgorithm;
|
||||
use crate::event::{EventReceiver, EventSender};
|
||||
pub use crate::item::{ItemWrapper, MatchedItem};
|
||||
pub use crate::item::MatchedItem;
|
||||
use crate::model::Model;
|
||||
pub use crate::options::SkimOptions;
|
||||
pub use crate::output::SkimOutput;
|
||||
|
|
@ -174,7 +174,7 @@ impl Default for CaseMatching {
|
|||
}
|
||||
|
||||
pub trait MatchEngine: Sync + Send + Display {
|
||||
fn match_item(&self, item: Arc<ItemWrapper>) -> Option<MatchedItem>;
|
||||
fn match_item(&self, item: Arc<dyn SkimItem>) -> Option<MatchedItem>;
|
||||
}
|
||||
|
||||
pub trait MatchEngineFactory {
|
||||
|
|
|
|||
25
src/model.rs
25
src/model.rs
|
|
@ -15,7 +15,7 @@ use crate::engine::factory::{AndOrEngineFactory, ExactOrFuzzyEngineFactory, Rege
|
|||
use crate::event::{Event, EventHandler, EventReceiver, EventSender};
|
||||
use crate::header::Header;
|
||||
use crate::input::parse_action_arg;
|
||||
use crate::item::{ItemPool, ItemWrapper};
|
||||
use crate::item::ItemPool;
|
||||
use crate::matcher::{Matcher, MatcherControl};
|
||||
use crate::options::SkimOptions;
|
||||
use crate::output::SkimOutput;
|
||||
|
|
@ -352,27 +352,27 @@ impl Model {
|
|||
}
|
||||
|
||||
fn act_execute_silent(&mut self, cmd: &str) {
|
||||
let item = self.selection.get_current_item();
|
||||
if depends_on_items(cmd) && item.is_none() {
|
||||
let current_index = self.selection.get_current_item_idx();
|
||||
let current_item = self.selection.get_current_item();
|
||||
if depends_on_items(cmd) && current_item.is_none() {
|
||||
debug!("act_execute_silent: command refers to items and there is no item for now");
|
||||
debug!("command to execute: [{}]", cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
let current_selection = item
|
||||
let current_selection = current_item
|
||||
.as_ref()
|
||||
.map(|item| item.output())
|
||||
.unwrap_or_else(|| Cow::Borrowed(""));
|
||||
let query = self.query.get_fz_query();
|
||||
let cmd_query = self.query.get_cmd_query();
|
||||
|
||||
let selections = self.selection.get_selected_wrapped_items();
|
||||
let (indices, selections) = self.selection.get_selected_indices_and_items();
|
||||
let tmp: Vec<Cow<str>> = selections.iter().map(|item| item.text()).collect();
|
||||
let selected_texts: Vec<&str> = tmp.iter().map(|cow| cow.as_ref()).collect();
|
||||
let indices: Vec<usize> = selections.iter().map(|x| x.get_index()).collect();
|
||||
|
||||
let context = InjectContext {
|
||||
current_index: item.as_ref().map(|x| x.get_index()).unwrap_or(0),
|
||||
current_index,
|
||||
delimiter: &self.delimiter,
|
||||
current_selection: ¤t_selection,
|
||||
selections: &selected_texts,
|
||||
|
|
@ -395,10 +395,7 @@ impl Model {
|
|||
|
||||
let item_index = (std::u32::MAX, self.next_idx_to_append);
|
||||
|
||||
let item: Arc<ItemWrapper> = Arc::new(ItemWrapper::new(
|
||||
Arc::new(query),
|
||||
(std::u32::MAX, self.next_idx_to_append),
|
||||
));
|
||||
let item: Arc<dyn SkimItem> = Arc::new(query);
|
||||
|
||||
self.next_idx_to_append += 1;
|
||||
|
||||
|
|
@ -475,7 +472,7 @@ impl Model {
|
|||
accept_key,
|
||||
query: self.query.get_fz_query(),
|
||||
cmd: self.query.get_cmd_query(),
|
||||
selected_items: self.selection.get_selected_items(),
|
||||
selected_items: self.selection.get_selected_indices_and_items().1,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -555,11 +552,13 @@ impl Model {
|
|||
|
||||
// re-draw
|
||||
if !self.preview_hidden {
|
||||
let item_index = self.selection.get_current_item_idx();
|
||||
let item = self.selection.get_current_item();
|
||||
if let Some(previewer) = self.previewer.as_mut() {
|
||||
let selections = &self.selection;
|
||||
let get_selected_items = || selections.get_selected_wrapped_items();
|
||||
let get_selected_items = || selections.get_selected_indices_and_items();
|
||||
previewer.on_item_change(
|
||||
item_index,
|
||||
item,
|
||||
env.query.to_string(),
|
||||
env.cmd_query.to_string(),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,3 @@
|
|||
use crate::ansi::{ANSIParser, AnsiString};
|
||||
use crate::event::{Event, EventHandler, UpdateScreen};
|
||||
use crate::item::ItemWrapper;
|
||||
use crate::spinlock::SpinLock;
|
||||
use crate::util::{depends_on_items, inject_command, InjectContext};
|
||||
use crate::{ItemPreview, SkimItem};
|
||||
use derive_builder::Builder;
|
||||
use nix::libc;
|
||||
use regex::Regex;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::{max, min};
|
||||
use std::env;
|
||||
|
|
@ -16,8 +7,18 @@ use std::sync::mpsc::{channel, Receiver, Sender};
|
|||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use derive_builder::Builder;
|
||||
use nix::libc;
|
||||
use regex::Regex;
|
||||
use tuikit::prelude::{Event as TermEvent, *};
|
||||
|
||||
use crate::ansi::{ANSIParser, AnsiString};
|
||||
use crate::event::{Event, EventHandler, UpdateScreen};
|
||||
use crate::spinlock::SpinLock;
|
||||
use crate::util::{depends_on_items, inject_command, InjectContext};
|
||||
use crate::{ItemPreview, SkimItem};
|
||||
|
||||
const TAB_STOP: usize = 8;
|
||||
const DELIMITER_STR: &str = r"[\t\n ]+";
|
||||
|
||||
|
|
@ -31,7 +32,8 @@ pub struct Previewer {
|
|||
vscroll_offset: usize,
|
||||
wrap: bool,
|
||||
|
||||
prev_item: Option<Arc<ItemWrapper>>,
|
||||
prev_item: Option<Arc<dyn SkimItem>>,
|
||||
prev_item_index: Option<usize>,
|
||||
prev_query: Option<String>,
|
||||
prev_cmd_query: Option<String>,
|
||||
prev_num_selected: usize,
|
||||
|
|
@ -67,6 +69,7 @@ impl Previewer {
|
|||
wrap: false,
|
||||
|
||||
prev_item: None,
|
||||
prev_item_index: None,
|
||||
prev_query: None,
|
||||
prev_cmd_query: None,
|
||||
prev_num_selected: 0,
|
||||
|
|
@ -89,21 +92,22 @@ impl Previewer {
|
|||
|
||||
pub fn on_item_change(
|
||||
&mut self,
|
||||
new_item: impl Into<Option<Arc<ItemWrapper>>>,
|
||||
new_item_index: usize,
|
||||
new_item: impl Into<Option<Arc<dyn SkimItem>>>,
|
||||
new_query: impl Into<Option<String>>,
|
||||
new_cmd_query: impl Into<Option<String>>,
|
||||
num_selected: usize,
|
||||
get_selected_items: impl Fn() -> Vec<Arc<ItemWrapper>>, // lazy get
|
||||
get_selected_items: impl Fn() -> (Vec<usize>, Vec<Arc<dyn SkimItem>>), // lazy get
|
||||
) {
|
||||
let new_item = new_item.into();
|
||||
let new_query = new_query.into();
|
||||
let new_cmd_query = new_cmd_query.into();
|
||||
|
||||
let item_changed = match (self.prev_item.as_ref(), new_item.as_ref()) {
|
||||
let item_changed = match (self.prev_item_index.as_ref(), new_item.as_ref()) {
|
||||
(None, None) => false,
|
||||
(None, Some(_)) => true,
|
||||
(Some(_), None) => true,
|
||||
(Some(prev), Some(cur)) => prev.get_id() != cur.get_id(),
|
||||
(Some(&prev_index), Some(_)) => prev_index == new_item_index,
|
||||
};
|
||||
|
||||
let query_changed = match (self.prev_query.as_ref(), new_query.as_ref()) {
|
||||
|
|
@ -127,6 +131,7 @@ impl Previewer {
|
|||
}
|
||||
|
||||
self.prev_item = new_item.clone();
|
||||
self.prev_item_index = Some(new_item_index);
|
||||
self.prev_query = new_query;
|
||||
self.prev_cmd_query = new_cmd_query;
|
||||
self.prev_num_selected = num_selected;
|
||||
|
|
@ -156,13 +161,12 @@ impl Previewer {
|
|||
let query = self.prev_query.as_ref().map(|s| &**s).unwrap_or("");
|
||||
let cmd_query = self.prev_cmd_query.as_ref().map(|s| &**s).unwrap_or("");
|
||||
|
||||
let selections = get_selected_items();
|
||||
let (indices, selections) = get_selected_items();
|
||||
let tmp: Vec<Cow<str>> = selections.iter().map(|item| item.text()).collect();
|
||||
let selected_texts: Vec<&str> = tmp.iter().map(|cow| cow.as_ref()).collect();
|
||||
let indices: Vec<usize> = selections.iter().map(|x| x.get_index()).collect();
|
||||
|
||||
let context = InjectContext {
|
||||
current_index: item.get_index(),
|
||||
current_index: new_item_index,
|
||||
delimiter: &self.delimiter,
|
||||
current_selection: ¤t_selection,
|
||||
selections: &selected_texts,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
use crate::global::{current_run_num, mark_new_run};
|
||||
use crate::global::mark_new_run;
|
||||
///! Reader is used for reading items from datasource (e.g. stdin or command output)
|
||||
///!
|
||||
///! After reading in a line, reader will save an item into the pool(items)
|
||||
use crate::item::ItemWrapper;
|
||||
use crate::item_collector::{read_and_collect_from_command, CollectorInput, CollectorOption};
|
||||
use crate::options::SkimOptions;
|
||||
use crate::spinlock::SpinLock;
|
||||
use crate::SkimItemReceiver;
|
||||
use crate::{SkimItem, SkimItemReceiver};
|
||||
use crossbeam::channel::{bounded, select, Sender};
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
|
@ -18,7 +17,7 @@ pub struct ReaderControl {
|
|||
tx_interrupt: Sender<i32>,
|
||||
tx_interrupt_cmd: Option<Sender<i32>>,
|
||||
components_to_stop: Arc<AtomicUsize>,
|
||||
items: Arc<SpinLock<Vec<Arc<ItemWrapper>>>>,
|
||||
items: Arc<SpinLock<Vec<Arc<dyn SkimItem>>>>,
|
||||
}
|
||||
|
||||
impl ReaderControl {
|
||||
|
|
@ -33,7 +32,7 @@ impl ReaderControl {
|
|||
while self.components_to_stop.load(Ordering::SeqCst) != 0 {}
|
||||
}
|
||||
|
||||
pub fn take(&self) -> Vec<Arc<ItemWrapper>> {
|
||||
pub fn take(&self) -> Vec<Arc<dyn SkimItem>> {
|
||||
let mut items = self.items.lock();
|
||||
let mut ret = Vec::with_capacity(items.len());
|
||||
ret.append(&mut items);
|
||||
|
|
@ -66,7 +65,6 @@ impl Reader {
|
|||
|
||||
pub fn run(&mut self, cmd: &str) -> ReaderControl {
|
||||
mark_new_run(cmd);
|
||||
let run_num = current_run_num();
|
||||
|
||||
let components_to_stop: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0));
|
||||
let items = Arc::new(SpinLock::new(Vec::new()));
|
||||
|
|
@ -82,7 +80,7 @@ impl Reader {
|
|||
});
|
||||
|
||||
let components_to_stop_clone = components_to_stop.clone();
|
||||
let tx_interrupt = collect_item(components_to_stop_clone, rx_item, run_num, items_clone);
|
||||
let tx_interrupt = collect_item(components_to_stop_clone, rx_item, items_clone);
|
||||
|
||||
ReaderControl {
|
||||
tx_interrupt,
|
||||
|
|
@ -96,8 +94,7 @@ impl Reader {
|
|||
fn collect_item(
|
||||
components_to_stop: Arc<AtomicUsize>,
|
||||
rx_item: SkimItemReceiver,
|
||||
run_num: u32,
|
||||
items: Arc<SpinLock<Vec<Arc<ItemWrapper>>>>,
|
||||
items: Arc<SpinLock<Vec<Arc<dyn SkimItem>>>>,
|
||||
) -> Sender<i32> {
|
||||
let (tx_interrupt, rx_interrupt) = bounded(CHANNEL_SIZE);
|
||||
|
||||
|
|
@ -108,15 +105,12 @@ fn collect_item(
|
|||
components_to_stop.fetch_add(1, Ordering::SeqCst);
|
||||
started_clone.store(true, Ordering::SeqCst); // notify parent that it is started
|
||||
|
||||
let mut index = 0;
|
||||
loop {
|
||||
select! {
|
||||
recv(rx_item) -> new_item => match new_item {
|
||||
Ok(item) => {
|
||||
let item_wrapped = ItemWrapper::new(item, (run_num, index));
|
||||
let mut vec = items.lock();
|
||||
vec.push(Arc::new(item_wrapped));
|
||||
index += 1;
|
||||
vec.push(item);
|
||||
}
|
||||
Err(_) => break,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use tuikit::prelude::{Event as TermEvent, *};
|
|||
use crate::event::{Event, EventHandler, UpdateScreen};
|
||||
use crate::global::current_run_num;
|
||||
use crate::item::{parse_criteria, ItemIndex, RankCriteria};
|
||||
use crate::item::{ItemWrapper, MatchedItem, MatchedRange};
|
||||
use crate::item::{MatchedItem, MatchedRange};
|
||||
use crate::orderedvec::CompareFunction;
|
||||
use crate::orderedvec::OrderedVec;
|
||||
use crate::spinlock::SpinLock;
|
||||
|
|
@ -29,7 +29,7 @@ lazy_static! {
|
|||
pub struct Selection {
|
||||
// all items
|
||||
items: OrderedVec<MatchedItem>,
|
||||
selected: BTreeMap<ItemIndex, Arc<ItemWrapper>>,
|
||||
selected: BTreeMap<ItemIndex, Arc<dyn SkimItem>>,
|
||||
|
||||
//
|
||||
// |>------ items[items.len()-1]
|
||||
|
|
@ -219,7 +219,7 @@ impl Selection {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn act_select_item(&mut self, item_index: ItemIndex, item: Arc<ItemWrapper>) {
|
||||
pub fn act_select_item(&mut self, item_index: ItemIndex, item: Arc<dyn SkimItem>) {
|
||||
if !self.multi_selection {
|
||||
return;
|
||||
}
|
||||
|
|
@ -250,10 +250,11 @@ impl Selection {
|
|||
self.hscroll_offset = hscroll_offset as usize;
|
||||
}
|
||||
|
||||
pub fn get_selected_wrapped_items(&self) -> Vec<Arc<ItemWrapper>> {
|
||||
pub fn get_selected_indices_and_items(&self) -> (Vec<usize>, Vec<Arc<dyn SkimItem>>) {
|
||||
// select the current one
|
||||
let select_cursor = !self.multi_selection || self.selected.is_empty();
|
||||
let mut selected: Vec<Arc<ItemWrapper>> = self.selected.values().cloned().collect();
|
||||
let mut selected: Vec<Arc<dyn SkimItem>> = self.selected.values().cloned().collect();
|
||||
let mut item_indices: Vec<usize> = self.selected.keys().map(|(_run, idx)| *idx as usize).collect();
|
||||
|
||||
if select_cursor && !self.items.is_empty() {
|
||||
let cursor = self.item_cursor + self.line_cursor;
|
||||
|
|
@ -262,18 +263,11 @@ impl Selection {
|
|||
.get(cursor)
|
||||
.unwrap_or_else(|| panic!("model:act_output: failed to get item {}", cursor));
|
||||
let item = current_item.item.clone();
|
||||
item_indices.push(cursor);
|
||||
selected.push(item);
|
||||
}
|
||||
|
||||
selected.sort_by_key(|item| item.get_id());
|
||||
selected
|
||||
}
|
||||
|
||||
pub fn get_selected_items(&self) -> Vec<Arc<dyn SkimItem>> {
|
||||
self.get_selected_wrapped_items()
|
||||
.into_iter()
|
||||
.map(|wrapped| wrapped.get_inner())
|
||||
.collect()
|
||||
(item_indices, selected)
|
||||
}
|
||||
|
||||
pub fn get_num_of_selected_exclude_current(&self) -> usize {
|
||||
|
|
@ -292,7 +286,7 @@ impl Selection {
|
|||
self.multi_selection
|
||||
}
|
||||
|
||||
pub fn get_current_item(&self) -> Option<Arc<ItemWrapper>> {
|
||||
pub fn get_current_item(&self) -> Option<Arc<dyn SkimItem>> {
|
||||
let item_idx = self.get_current_item_idx();
|
||||
self.items.get(item_idx).map(|item| item.item.clone())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use tuikit::prelude::*;
|
|||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
use crate::field::get_string_by_range;
|
||||
use crate::item::ItemWrapper;
|
||||
use crate::SkimItem;
|
||||
use std::sync::Arc;
|
||||
|
||||
lazy_static! {
|
||||
static ref RE_ESCAPE: Regex = Regex::new(r"['\U{00}]").unwrap();
|
||||
|
|
@ -179,7 +179,7 @@ impl LinePrinter {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn print_item(canvas: &mut dyn Canvas, printer: &mut LinePrinter, item: &ItemWrapper, default_attr: Attr) {
|
||||
pub fn print_item(canvas: &mut dyn Canvas, printer: &mut LinePrinter, item: &Arc<dyn SkimItem>, default_attr: Attr) {
|
||||
for (ch, attr) in item.display().iter() {
|
||||
printer.print_char(canvas, ch, default_attr.extend(attr), false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue