Skip to content

Commit

Permalink
Implement a navigation undo/redo system
Browse files Browse the repository at this point in the history
Closes #108
  • Loading branch information
jpmonettas committed Nov 30, 2023
1 parent 5b84a05 commit 63a713e
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 22 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
### New Features

- Add a bookmarking system
- Add navigation undo/redo system

### Changes

### Bugs fixed
Expand Down
13 changes: 7 additions & 6 deletions docs/user_guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -714,12 +714,6 @@ You can use it to step over each expression, visualize values, locals and more.

image::user_guide_images/controls.png[]

The numbers at the center show `current_step_index / total_steps`. This means that a total of `total_steps` has been recorded
for this thread so far. The buttons right next to it control the <<#_bookmarks, bookmarking system>>

Write any number (less than total_steps) on the text box to jump into that position in time. When jumping around you can write down any interesting
positions you find and then use this text box to jump back to it if you need.

The code tool allows you to step and "travel thought time" in two ways:

- You can use the controls at the top to step over your code in different ways.
Expand All @@ -739,6 +733,11 @@ From left to right this are the controls you have available :
- Step over forward, will make one step forwards always staying on the same frame.
- Jump to the last step of the recording.

The numbers at the center show `current_step_index / total_steps`. This means that a total of `total_steps` has been recorded
for this thread so far. The buttons right next to it control undo/redo of the navigation system and the <<#_bookmarks, bookmarking system>>.

Write any number (less than total_steps) on the text box to jump into that position in time.

==== Power stepping

The controls at the right are power stepping controls. They provide more powerfull ways of stepping through the code.
Expand Down Expand Up @@ -1530,6 +1529,8 @@ You can overwrite all the styles defined here https://github.com/flow-storm/flow
- `>` Step last
- `Ctrl-f` Copy current function symbol
- `Ctrl-Shift-f` Copy current function call form
- `Ctrl-z` Undo navigation
- `Ctrl-r` Redo navigation

== Debugging react native applications

Expand Down
23 changes: 14 additions & 9 deletions docs/user_guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -1892,14 +1892,6 @@ <h5 id="_code_stepping"><a class="anchor" href="#_code_stepping"></a><a class="l
</div>
</div>
<div class="paragraph">
<p>The numbers at the center show <code>current_step_index / total_steps</code>. This means that a total of <code>total_steps</code> has been recorded
for this thread so far. The buttons right next to it control the <a href="#_bookmarks">bookmarking system</a></p>
</div>
<div class="paragraph">
<p>Write any number (less than total_steps) on the text box to jump into that position in time. When jumping around you can write down any interesting
positions you find and then use this text box to jump back to it if you need.</p>
</div>
<div class="paragraph">
<p>The code tool allows you to step and "travel thought time" in two ways:</p>
</div>
<div class="ulist">
Expand Down Expand Up @@ -1946,6 +1938,13 @@ <h5 id="_code_stepping"><a class="anchor" href="#_code_stepping"></a><a class="l
</li>
</ul>
</div>
<div class="paragraph">
<p>The numbers at the center show <code>current_step_index / total_steps</code>. This means that a total of <code>total_steps</code> has been recorded
for this thread so far. The buttons right next to it control undo/redo of the navigation system and the <a href="#_bookmarks">bookmarking system</a>.</p>
</div>
<div class="paragraph">
<p>Write any number (less than total_steps) on the text box to jump into that position in time.</p>
</div>
</div>
<div class="sect4">
<h5 id="_power_stepping"><a class="anchor" href="#_power_stepping"></a><a class="link" href="#_power_stepping">Power stepping</a></h5>
Expand Down Expand Up @@ -3186,6 +3185,12 @@ <h4 id="_flows"><a class="anchor" href="#_flows"></a><a class="link" href="#_flo
<li>
<p><code>Ctrl-Shift-f</code> Copy current function call form</p>
</li>
<li>
<p><code>Ctrl-z</code> Undo navigation</p>
</li>
<li>
<p><code>Ctrl-r</code> Redo navigation</p>
</li>
</ul>
</div>
</div>
Expand Down Expand Up @@ -3428,7 +3433,7 @@ <h3 id="_internals_diagrams_and_documentation"><a class="anchor" href="#_interna
</div>
<div id="footer">
<div id="footer-text">
Last updated 2023-11-30 10:20:49 -0300
Last updated 2023-11-30 14:50:05 -0300
</div>
</div>
</body>
Expand Down
Binary file modified docs/user_guide_images/bookmarks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user_guide_images/bookmarks_controls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user_guide_images/controls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 68 additions & 2 deletions src-dbg/flow_storm/debugger/state.clj
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@
:flow-storm/fn-ns]))
(s/def :thread.ui/callstack-tree-hidden-fns (s/coll-of :thread.ui.callstack-tree-hidden-fns/ref))
(s/def :thread/bookmarks (s/map-of int? string?))

(s/def :navigation-history/history (s/coll-of :flow-storm/timeline-entry))
(s/def :thread/navigation-history (s/keys :req-un [:navigation-history/head-pos
:navigation-history/history]))

(s/def :flow/thread (s/keys :req [:thread/id
:thread/curr-timeline-entry]
:thread/curr-timeline-entry
:thread/navigation-history]
:opt [:thread/curr-frame
:thread.ui/callstack-tree-hidden-fns
:thread/bookmarks]))
Expand Down Expand Up @@ -259,7 +265,10 @@
(swap! state assoc-in [:flows flow-id :flow/threads thread-id]
{:thread/id thread-id
:thread/curr-timeline-entry nil
:thread/callstack-tree-hidden-fns #{}}))
:thread/callstack-tree-hidden-fns #{}
:thread/navigation-history {:head-pos 0
:history [{:fn-call-idx -1 ;; dummy entry
:idx -1}]}}))

(defn get-thread [flow-id thread-id]
(get-in @state [:flows flow-id :flow/threads thread-id]))
Expand Down Expand Up @@ -436,6 +445,63 @@
(when-let [cb (get-in @state [:pending-tasks-subscriptions [event-key task-id]])]
(cb data)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Navigation undo system ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def ^:dynamic *undo-redo-jump* false)

(defn update-nav-history

"Add to nav history if we are jumping to a different frame,
else update the head idx. If the head is not at the end, redo history
will be discarded."

[flow-id thread-id {:keys [fn-call-idx idx] :as tentry}]
(swap! state update-in [:flows flow-id :flow/threads thread-id :thread/navigation-history]
(fn [nav-hist]
(let [{:keys [history head-pos] :as nav-hist} (if (and (not *undo-redo-jump*)
(< (:head-pos nav-hist) (dec (count (:history nav-hist)))))
(-> nav-hist
(update :history subvec 0 (:head-pos nav-hist))
(update :head-pos dec))
nav-hist)
changing-frames? (not= fn-call-idx (get-in history [head-pos :fn-call-idx]))]
(if changing-frames?
(-> nav-hist
(update :history conj tentry)
(update :head-pos inc))

(assoc-in nav-hist [:history head-pos] tentry))))))

(defn current-nav-history-entry [flow-id thread-id]
(let [{:keys [history head-pos]} (get-in @state [:flows flow-id :flow/threads thread-id :thread/navigation-history])]
(get history head-pos)))

(defn undo-nav-history

"Move the nav history head back and return it's idx."

[flow-id thread-id]
(swap! state update-in [:flows flow-id :flow/threads thread-id :thread/navigation-history :head-pos]
(fn [p]
(if (> p 1)
(dec p)
p)))
(current-nav-history-entry flow-id thread-id))

(defn redo-nav-history

"Move the nav history head forward and return it's idx."

[flow-id thread-id]
(swap! state update-in [:flows flow-id :flow/threads thread-id :thread/navigation-history]
(fn [{:keys [history head-pos] :as h}]
(assoc h :head-pos (if (< (inc head-pos) (count history))
(inc head-pos)
head-pos))))
(current-nav-history-entry flow-id thread-id))

;;;;;;;;;;;
;; Other ;;
;;;;;;;;;;;
Expand Down
23 changes: 20 additions & 3 deletions src-dbg/flow_storm/debugger/ui/flows/code.clj
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@
(when changing-frame?
(dbg-state/set-current-frame flow-id thread-id next-frame))

(dbg-state/set-current-timeline-entry flow-id thread-id next-tentry))
(dbg-state/set-current-timeline-entry flow-id thread-id next-tentry)
(dbg-state/update-nav-history flow-id thread-id next-tentry))
(catch Throwable e
(utils/log-error (str "Error jumping into " flow-id " " thread-id " " next-tentry) e))))

Expand Down Expand Up @@ -509,6 +510,14 @@
(.setSpacing 3))]
power-stepping-pane))

(defn undo-jump [flow-id thread-id]
(binding [dbg-state/*undo-redo-jump* true]
(jump-to-coord flow-id thread-id (dbg-state/undo-nav-history flow-id thread-id))))

(defn redo-jump [flow-id thread-id]
(binding [dbg-state/*undo-redo-jump* true]
(jump-to-coord flow-id thread-id (dbg-state/redo-nav-history flow-id thread-id))))

(defn- trace-pos-pane [flow-id thread-id]
(let [curr-trace-text-field (doto (text-field {:initial-text "1"
:on-return-key (fn [idx-str]
Expand All @@ -529,14 +538,22 @@
flow-id
thread-id
(dbg-state/current-idx flow-id thread-id)))
:tooltip "Bookmark the current position")]
:tooltip "Bookmark the current position")
undo-nav-btn (ui-utils/icon-button :icon-name "mdi-undo"
:on-click (fn [] (undo-jump flow-id thread-id))
:tooltip "Undo navigation")
redo-nav-btn (ui-utils/icon-button :icon-name "mdi-redo"
:on-click (fn [] (redo-jump flow-id thread-id))
:tooltip "Redo navigation")]


(store-obj flow-id thread-id "thread_curr_trace_tf" curr-trace-text-field)
(store-obj flow-id thread-id "thread_trace_count_lbl" thread-trace-count-lbl)

(doto (h-box [curr-trace-text-field separator-lbl thread-trace-count-lbl
bookmark-btn open-book-btn] "trace-position-box")
undo-nav-btn redo-nav-btn
bookmark-btn open-book-btn]
"trace-position-box")
(.setSpacing 2.0))))

(defn- create-thread-controls-pane [flow-id thread-id]
Expand Down
6 changes: 5 additions & 1 deletion src-dbg/flow_storm/debugger/ui/flows/screen.clj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
(= key-txt "t") (ui-general/select-thread-tool-tab flow-id thread-id :call-tree)
(= key-txt "c") (ui-general/select-thread-tool-tab flow-id thread-id :code)
(= key-txt "f") (ui-general/select-thread-tool-tab flow-id thread-id :functions)

(= key-txt "P") (flow-code/step-prev-over flow-id thread-id)
(= key-txt "p") (flow-code/step-prev flow-id thread-id)
(= key-txt "n") (flow-code/step-next flow-id thread-id)
Expand All @@ -73,7 +74,10 @@
(= key-txt ">") (flow-code/step-last flow-id thread-id)

(and shift? ctrl? (= key-name "F")) (copy-current-frame-symbol flow-id thread-id true)
(and ctrl? (= key-name "F")) (copy-current-frame-symbol flow-id thread-id false))))))
(and ctrl? (= key-name "F")) (copy-current-frame-symbol flow-id thread-id false)

(and ctrl? (= key-name "Z")) (flow-code/undo-jump flow-id thread-id)
(and ctrl? (= key-name "R")) (flow-code/redo-jump flow-id thread-id))))))

(defn open-thread [thread-info]
(let [flow-id (:flow/id thread-info)
Expand Down

0 comments on commit 63a713e

Please sign in to comment.