diff --git a/src/main.rs b/src/main.rs
index 019c7e1..b95a762 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,7 +12,7 @@ use crate::event_sender::MostrMessage;
 use crate::helpers::*;
 use crate::kinds::{format_tag_basic, match_event_tag, Prio, BASIC_KINDS, PROPERTY_COLUMNS, PROP_KINDS};
 use crate::task::{State, Task, TaskState, MARKER_PROPERTY};
-use crate::tasks::{PropertyCollection, StateFilter, TasksRelay};
+use crate::tasks::{referenced_event, PropertyCollection, StateFilter, TasksRelay};
 use chrono::Local;
 use colored::Colorize;
 use directories::ProjectDirs;
@@ -438,14 +438,36 @@ async fn main() -> Result<()> {
                     Some('&') => {
                         match arg {
                             None => tasks.undo(),
-                            Some(text) => match text.parse::<u8>() {
-                                Ok(int) => {
-                                    tasks.move_back_by(int as usize);
+                            Some(text) => {
+                                if text == "&" {
+                                    println!(
+                                        "My History:\n{}",
+                                        tasks.history_before_now()
+                                            .take(9)
+                                            .enumerate()
+                                            .dropping(1)
+                                            .map(|(c, e)| {
+                                                format!("({}) {}",
+                                                        c,
+                                                        match referenced_event(e) {
+                                                            Some(target) => tasks.get_task_path(Some(target)),
+                                                            None => "---".to_string(),
+                                                        },
+                                                )
+                                            })
+                                            .join("\n")
+                                    );
+                                    continue 'repl;
                                 }
-                                _ => {
-                                    if !tasks.move_back_to(text) {
-                                        warn!("Did not find a match in history for \"{text}\"");
-                                        continue 'repl;
+                                match text.parse::<u8>() {
+                                    Ok(int) => {
+                                        tasks.move_back_by(int as usize);
+                                    }
+                                    _ => {
+                                        if !tasks.move_back_to(text) {
+                                            warn!("Did not find a match in history for \"{text}\"");
+                                            continue 'repl;
+                                        }
                                     }
                                 }
                             }
diff --git a/src/tasks.rs b/src/tasks.rs
index 7cfe7b1..21551bd 100644
--- a/src/tasks.rs
+++ b/src/tasks.rs
@@ -256,51 +256,60 @@ impl TasksRelay {
     }
 
     /// Dynamic time tracking overview for current task or current user.
-    pub(crate) fn times_tracked(&self) -> (String, Box<dyn DoubleEndedIterator<Item=String>>) {
+    pub(crate) fn times_tracked(&self) -> (String, Box<dyn DoubleEndedIterator<Item=String> + '_>) {
         self.times_tracked_for(&self.sender.pubkey())
     }
 
+    pub(crate) fn history_for(
+        &self,
+        key: &PublicKey,
+    ) -> Option<impl DoubleEndedIterator<Item=String> + '_> {
+        self.history.get(key).map(|hist| {
+            let mut last = None;
+            // TODO limit history to active tags
+            hist.values().filter_map(move |event| {
+                let new = some_non_empty(&event.tags.iter()
+                    .filter_map(|t| t.content())
+                    .map(|str| EventId::from_str(str).ok().map_or(str.to_string(), |id| self.get_task_path(Some(id))))
+                    .join(" "));
+                if new != last {
+                    // TODO omit intervals <2min - but I think I need threeway variable tracking for that
+                    // TODO alternate color with grey between days
+                    last = new;
+                    return Some(format!(
+                        "{} {}",
+                        format_timestamp_local(&event.created_at),
+                        last.as_ref().unwrap_or(&"---".to_string())
+                    ));
+                }
+                None
+            })
+        })
+    }
+
     pub(crate) fn times_tracked_for(
         &self,
         key: &PublicKey,
-    ) -> (String, Box<dyn DoubleEndedIterator<Item=String>>) {
+    ) -> (String, Box<dyn DoubleEndedIterator<Item=String> + '_>) {
         match self.get_position() {
             None => {
-                if let Some(hist) = self.history.get(key) {
-                    let mut last = None;
-                    let mut full = Vec::with_capacity(hist.len());
-                    for event in hist.values() {
-                        let new = some_non_empty(&event.tags.iter()
-                            .filter_map(|t| t.content())
-                            .map(|str| EventId::from_str(str).ok().map_or(str.to_string(), |id| self.get_task_path(Some(id))))
-                            .join(" "));
-                        if new != last {
-                            // TODO omit intervals <2min - but I think I need threeway for that
-                            // TODO alternate color with grey between days
-                            full.push(format!(
-                                "{} {}",
-                                format_timestamp_local(&event.created_at),
-                                new.as_ref().unwrap_or(&"---".to_string())
-                            ));
-                            last = new;
-                        }
-                    }
-                    // TODO show history for active tags
-                    (
-                        format!("Time-Tracking History for {}:", self.users.get_displayname(&key)),
-                        Box::from(full.into_iter()),
-                    )
-                } else {
-                    (
-                        "Nothing time-tracked yet".to_string(),
-                        Box::from(empty()),
-                    )
+                match self.history_for(key) {
+                    Some(hist) =>
+                        (
+                            format!("Time-Tracking History for {}:", self.users.get_displayname(&key)),
+                            Box::from(hist),
+                        ),
+                    None =>
+                        (
+                            "Nothing time-tracked yet".to_string(),
+                            Box::from(empty()),
+                        )
                 }
             }
             Some(id) => {
                 // TODO show current recursive with pubkey
                 let ids = [id];
-                let history =
+                let mut history =
                     self.history.iter().flat_map(|(key, set)| {
                         let mut vec = Vec::with_capacity(set.len() / 2);
                         let mut iter = timestamps(set.values(), &ids).tuples();
@@ -323,10 +332,13 @@ impl TasksRelay {
                             ))
                         });
                         vec
-                    }).sorted_unstable(); // TODO sorting depends on timestamp format - needed to interleave different people
+                    })
+                    .collect_vec();
+                // TODO sorting depends on timestamp format - needed to interleave different people
+                history.sort_unstable();
                 (
                     format!("Times Tracked on {:?}", self.get_task_title(&id)),
-                    Box::from(history),
+                    Box::from(history.into_iter()),
                 )
             }
         }
@@ -1200,25 +1212,29 @@ impl TasksRelay {
     }
 
     fn get_own_events_history(&self) -> impl DoubleEndedIterator<Item=&Event> + '_ {
-        self.history.get(&self.sender.pubkey())
+        self.get_own_history()
             .into_iter()
             .flat_map(|t| t.values())
     }
 
-    fn history_before_now(&self) -> impl Iterator<Item=&Event> {
+    pub(super) fn history_before_now(&self) -> impl Iterator<Item=&Event> {
         self.get_own_history().into_iter().flat_map(|hist| {
             let now = now();
-            hist.values().rev().skip_while(move |e| e.created_at > now)
+            hist.values().rev()
+                .skip_while(move |e| e.created_at > now)
+                .dedup_by(|e1, e2| e1.id == e2.id)
         })
     }
 
     pub(crate) fn move_back_to(&mut self, str: &str) -> bool {
         let lower = str.to_ascii_lowercase();
-        let found = self.history_before_now().find(|e| {
-            referenced_event(e)
-                .and_then(|id| self.get_by_id(&id))
-                .is_some_and(|t| t.event.content.to_ascii_lowercase().contains(&lower))
-        });
+        let found =
+            self.history_before_now()
+                .find(|e| {
+                    referenced_event(e)
+                        .and_then(|id| self.get_by_id(&id))
+                        .is_some_and(|t| t.event.content.to_ascii_lowercase().contains(&lower))
+                });
         if let Some(event) = found {
             self.move_to(referenced_event(event));
             return true;
@@ -1506,7 +1522,7 @@ fn referenced_events(event: &Event) -> impl Iterator<Item=EventId> + '_ {
     event.tags.iter().filter_map(|tag| match_event_tag(tag).map(|t| t.id))
 }
 
-fn referenced_event(event: &Event) -> Option<EventId> {
+pub fn referenced_event(event: &Event) -> Option<EventId> {
     referenced_events(event).next()
 }