ruby_jard 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/CHANGELOG.md +18 -0
  4. data/CNAME +1 -0
  5. data/README.md +206 -33
  6. data/_config.yml +1 -0
  7. data/docs/_config.yml +8 -0
  8. data/docs/demo.png +0 -0
  9. data/docs/index.md +238 -0
  10. data/docs/logo.jpg +0 -0
  11. data/docs/screen-backtrace.png +0 -0
  12. data/docs/screen-repl.png +0 -0
  13. data/docs/screen-source.png +0 -0
  14. data/docs/screen-threads.png +0 -0
  15. data/docs/screen-variables.png +0 -0
  16. data/images/bg_hr.png +0 -0
  17. data/images/blacktocat.png +0 -0
  18. data/images/body-bg.jpg +0 -0
  19. data/images/download-button.png +0 -0
  20. data/images/github-button.png +0 -0
  21. data/images/header-bg.jpg +0 -0
  22. data/images/highlight-bg.jpg +0 -0
  23. data/images/icon_download.png +0 -0
  24. data/images/sidebar-bg.jpg +0 -0
  25. data/images/sprite_download.png +0 -0
  26. data/javascripts/main.js +1 -0
  27. data/lib/ruby_jard.rb +3 -18
  28. data/lib/ruby_jard/box_drawer.rb +68 -22
  29. data/lib/ruby_jard/color_scheme.rb +28 -0
  30. data/lib/ruby_jard/color_schemes.rb +26 -0
  31. data/lib/ruby_jard/color_schemes/256_color_scheme.rb +64 -0
  32. data/lib/ruby_jard/color_schemes/deep_space_color_scheme.rb +63 -0
  33. data/lib/ruby_jard/column.rb +12 -6
  34. data/lib/ruby_jard/commands/continue_command.rb +1 -0
  35. data/lib/ruby_jard/commands/list_command.rb +29 -0
  36. data/lib/ruby_jard/commands/next_command.rb +1 -0
  37. data/lib/ruby_jard/commands/step_command.rb +1 -0
  38. data/lib/ruby_jard/commands/step_out_command.rb +1 -0
  39. data/lib/ruby_jard/console.rb +102 -18
  40. data/lib/ruby_jard/control_flow.rb +9 -8
  41. data/lib/ruby_jard/decorators/color_decorator.rb +46 -57
  42. data/lib/ruby_jard/decorators/inspection_decorator.rb +76 -0
  43. data/lib/ruby_jard/decorators/loc_decorator.rb +83 -107
  44. data/lib/ruby_jard/decorators/source_decorator.rb +1 -1
  45. data/lib/ruby_jard/keys.rb +1 -0
  46. data/lib/ruby_jard/layout.rb +9 -99
  47. data/lib/ruby_jard/layout_calculator.rb +151 -0
  48. data/lib/ruby_jard/layouts/narrow_layout.rb +41 -0
  49. data/lib/ruby_jard/layouts/wide_layout.rb +17 -103
  50. data/lib/ruby_jard/repl_processor.rb +5 -1
  51. data/lib/ruby_jard/repl_proxy.rb +2 -1
  52. data/lib/ruby_jard/row.rb +5 -5
  53. data/lib/ruby_jard/row_renderer.rb +108 -0
  54. data/lib/ruby_jard/screen.rb +20 -115
  55. data/lib/ruby_jard/screen_drawer.rb +8 -75
  56. data/lib/ruby_jard/screen_manager.rb +78 -55
  57. data/lib/ruby_jard/screen_renderer.rb +138 -0
  58. data/lib/ruby_jard/screens/backtrace_screen.rb +67 -69
  59. data/lib/ruby_jard/screens/menu_screen.rb +43 -38
  60. data/lib/ruby_jard/screens/source_screen.rb +43 -27
  61. data/lib/ruby_jard/screens/threads_screen.rb +91 -39
  62. data/lib/ruby_jard/screens/variables_screen.rb +72 -56
  63. data/lib/ruby_jard/session.rb +16 -0
  64. data/lib/ruby_jard/span.rb +8 -6
  65. data/lib/ruby_jard/version.rb +1 -1
  66. data/ruby_jard.gemspec +4 -4
  67. data/stylesheets/github-light.css +130 -0
  68. data/stylesheets/normalize.css +424 -0
  69. data/stylesheets/print.css +228 -0
  70. data/stylesheets/stylesheet.css +245 -0
  71. metadata +52 -21
  72. data/lib/ruby_jard/templates/column_template.rb +0 -17
  73. data/lib/ruby_jard/templates/row_template.rb +0 -22
  74. data/lib/ruby_jard/templates/space_template.rb +0 -15
  75. data/lib/ruby_jard/templates/span_template.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94dbda134fd22365f583f71fa2aaddffae206045cc8da4fd6ee51e2eeaebfca7
4
- data.tar.gz: af8c443ac2c40619cead142c3e77dd3b7f7ad59c19993966edcdd1eae8c31a3d
3
+ metadata.gz: 49f057d809cf1b9208df17537c1fb2f80b0380193d497351314d567a75e9ddc5
4
+ data.tar.gz: 74d8fa560a06dcc07579f1ccf8761c85c65c7110dfd6d0cbe93aeaab817934e4
5
5
  SHA512:
6
- metadata.gz: 6d18a6894bcb24bae3bf30244dfcf1f39412e9804df5897e7adac6b74cdb8929b3353a8a0999ec55b687bfa60e87890a5db637bfe7d046b30a470b0d5158c46e
7
- data.tar.gz: 7eaacc77cd4eaa4fdb7e183292872cef01217e5c92f75bea1882d454dad1ad1ae97ff3790ca129e76de4f893167d1b1b81b6deb7eb44b6931d67a23cca03f7f5
6
+ metadata.gz: d0da56029611ab8712f889b284c2e5a672e8b9609f76636b4cd354f08b65f3429c331324c31fa136572088eabdbf5a7aa1ebaedba526f517f4080145a73e2ff6
7
+ data.tar.gz: 3fb4581a4e913aa2fbe2985b8b842f76e78f8e1207a6ac0847ea52e898a1e1ac02178ff3ec46949e17b85e383a9fa3853428592ad3e4359aae1c71d008d83975
@@ -1,3 +1,5 @@
1
+ Lint/NonLocalExitFromIterator:
2
+ Enabled: false
1
3
  Naming/MethodParameterName:
2
4
  Enabled: false
3
5
  Style/SymbolArray:
@@ -18,6 +20,7 @@ Metrics/ParameterLists:
18
20
  Enabled: false
19
21
  Metrics/ClassLength:
20
22
  Enabled: false
23
+ Layout/HashAlignment:
24
+ Enabled: false
21
25
  AllCops:
22
26
  TargetRubyVersion: 2.5
23
-
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.1 - Alpha 3] - Render mechanism and theme system
4
+ ### UX/UI
5
+ - New color scheme: 256, as the default color scheme. It works well with all 256-color terminal emulators.
6
+ - New color scheme: deep-space. It's a 24-bit color scheme.
7
+ - UX change: swap positions of default panels:
8
+ ```
9
+ Source | Backtrace
10
+ Variables | Threads
11
+ ```
12
+ - New narrow layout, which consists of source and variables only. Useful when running tests.
13
+ - Add aliases to common commands
14
+ ### Bug fixes
15
+ - https://github.com/nguyenquangminh0711/ruby_jard/issues/2
16
+ - Fix display bug that some rows are out of screen if above rows have word wraps.
17
+ ### Internal Refactoring
18
+ - New rendering mechanism, that supports data windowing, selection locating, and cursor.
19
+ - Improve compatibility, and add fallbacks in case io/console, or tput are not available.
20
+
3
21
  ## [0.2.0 - Alpha 2] - UI completeness
4
22
 
5
23
  ### UX/UI
data/CNAME ADDED
@@ -0,0 +1 @@
1
+ rubyjard.org
data/README.md CHANGED
@@ -1,29 +1,20 @@
1
- # RubyJard
1
+ ![Ruby Jard](./docs/logo.jpg)
2
2
 
3
- Jard stands for Just Another Ruby Debugger. It implements a layer of UI wrapping around byebug, aims to provide a unified experience when debugging Ruby source code. Ruby Jard supports the following major features at the moment:
3
+ Jard stands for Just Another Ruby Debugger, aims to provide a better experience while debugging Ruby. Ruby Jard supports the following major features at the moment:
4
4
 
5
- - Default Terminal UI, in which the layout and display are responsive to support different screen sizes.
5
+ - Informative Terminal UI, reduce your mental effort for repeated stuff so that you can focus on killing bugs.
6
6
  - Highlighted source code screen.
7
- - Stacktrace visualization and navigation.
8
- - Auto explore and display variables in the current context.
7
+ - Backtrace visualization and navigation.
8
+ - Auto variable display in the current context.
9
9
  - Multi-thread exploration and debugging.
10
10
 
11
- In the roadmap:
12
- - Dynamic breakpoints.
13
- - Watch expressions.
14
- - Support different screen sizes.
15
- - Minimal layout configuration.
16
- - Fully layout configuration with Tmux.
17
- - Integrate with Vim.
18
- - Integrate with Visual Studio Code.
19
- - Encrypted remote debugging.
20
- - Some handful debug tools and data visualization.
11
+ Ruby Jard's core is [Byebug](https://github.com/deivid-rodriguez/byebug), an awesome de factor debugger for Ruby. Therefore, Ruby Jard supports most of Byebug's functionalities.
21
12
 
22
- Ruby Jard's core is Byebug, an awesome de factor debugger for Ruby. Therefore, Ruby Jard supports most of Byebug's functionalities.
13
+ If you still don't know what it is, let's watch this video.
23
14
 
24
- If you still don't know what it is, let's watch this video. This is a record of debugging Code Ray - A syntax highlighter for Ruby.
15
+ [![Ruby Jard Demo](./docs/demo.png)](https://asciinema.org/a/350233)
25
16
 
26
- [![asciicast](https://asciinema.org/a/ejWK3Px55QNQmhM4nbd1lSigW.svg)](https://asciinema.org/a/ejWK3Px55QNQmhM4nbd1lSigW)
17
+ *[(Click for demo video)](https://asciinema.org/a/350233)*
27
18
 
28
19
  ## Getting Started
29
20
 
@@ -46,24 +37,206 @@ def test_method
46
37
  end
47
38
  ```
48
39
 
49
- ## Guides
40
+ ## Screens
41
+
42
+ When Jard attaches at any line of code, the main tile-style UI shows up. By default, there are 5 areas on the UI that you'll be interested.
43
+
44
+ ### Source panel
45
+
46
+ <img src="./docs/screen-source.png" alt="Source screen" />
47
+
48
+ This panel shows the current line of code that your program is stopping, and surrounding related lines. The number of lines shown in this panel depends on your current terminal height, but never less than 5.
49
+
50
+ Ruby Jard supports any file extensions that your program runs into, especially `.rb`, `.erb`, `.haml` files. Other file types may encounter minor syntax highlighting issues.
51
+
52
+ Ruby Jard also supports inspecting gems and libraries, if you are interested.
53
+
54
+ ### Backtrace panel
55
+
56
+ <img src="./docs/screen-backtrace.png" alt="Screen backtrace"/>
57
+
58
+ This panel describes the current backtrace of the current thread your program is stopping. Each line of this panel describes the current Frame. What is frame and backtrace by the way? Let's step back a little bit at how Ruby executes your code. Internally, Ruby uses an interpreter to read and execute your code, line by line (technically, YARD instructions, but let's go with a simple version). When it meets a chunk of code that needs to open a new scope, like method calls or inline-block call, the interpreter creates a new structure to store the current context so that it can link to the next scope and go back later. This data structure is call Frame. The interpreter pushes frame into a stack, called backtrace (or stack trace, or call stack, whatever), and continues to execute your code. Each thread has a separate backtrace. To understand deeply, you may be interested in this wonderful slide: [Grow and Shrink - Dynamically Extending the Ruby VM Stack](https://www.slideshare.net/KeitaSugiyama1/grow-and-shrink-dynamically-extending-the-ruby-vm-stack).
59
+
60
+ Overall, the whole backtrace panel lets you know where you are stopping at, the trace of how your program is running. When combining with other tools and other panels, you will be surprised by how much information the bugger can help you when you encounter your bugs.
61
+
62
+ Each frame includes the following information:
63
+
64
+ - Frame ID: incremental, can be used to jump to an arbitrary frame with frame command.
65
+ - Current location label: a class name and method name of the method covers its frame. If there is a `[c]` prefix in front of a class name, it means that the method is provided by Ruby, implemented in C, and impossible to peek.
66
+ - Current physical location: exact file name and line number. If a frame is allocated in a gem, the physical location shows a gem name and version only. For example: `RSpec::Core::Hooks::HookCollections in run in rspec-core (3.9.2)`.
67
+
68
+ ### Variable panel
69
+
70
+ <img src="./docs/screen-variables.png" alt="Variables screen"/>
71
+
72
+ The variable panel lets you explore all the local variables, instance variables, and constants in the current display context. Each variable is described by:
73
+
74
+ - Inline indicator: the beginning dot (`•`) implies a variable that appears in the current line.
75
+ - Variable type: allow you to know the type of a variable at a single glance. Only built-in types, such as `int`, `flt`, `hash`, `bool`, `rng`, are supported. Instances of any classes will be noted as `var`.
76
+ - Size of variable: the size of collection-like variables. Current Jard version supports 3 types:
77
+ - Hash: this field shows the number of keys
78
+ - Array: this field shows the number of items
79
+ - String: this field shows the number of character (fetched from`String#size` method)
80
+ - Variable inspection: the content of the variable. The current Jard version generates this field by calling `#inspect`. **Known issue**: this accidentally triggers materializing method of objects, such as `ActiveRecord::Relation`. Future Jard version gonna fix this by a new safe generator.
81
+
82
+ This panel interacts well with backtrace panel and backtrace-exploring commands such as (`up`, `down`, `frame`, etc.) to inspect relative variables at each frame layer in the program. A common use case is to recall the parameter values you forgot when digging too deep into a method call.
83
+
84
+ By default, the variables are sorted by the following criteria:
85
+
86
+ - Pinned variables (coming soon)
87
+ - Current context (self)
88
+ - Local variables
89
+ - Instance variables
90
+ - Constants
91
+ - Global variables (coming soon)
92
+
93
+ ### Thread panel
94
+
95
+ <img src="./docs/screen-threads.png" alt="Screen threads" />
96
+
97
+ Show all the threads running at the moment. This panel is useful when you are working with a complicated multi-threaded environment like web server, or background jobs.
98
+
99
+ ### Repl panel
100
+
101
+ <img src="./docs/screen-repl.png" alt="Screen repl" />
102
+
103
+ An interactive Repl for you to interact with your program, inspect values, update values, or control the debug flow as you want. The heart of Jard's repl is [Pry](https://github.com/pry/pry), a masterpiece gem. When you type a command, Jard parses, and does corresponding actions if what you type matches supported command. Otherwise, they are evaluated as Ruby code.
104
+
105
+ ## Commands
106
+
107
+ ### List
108
+
109
+ **Repl command**: `list`
110
+
111
+ **Key binding:** F5
112
+
113
+ **Alias**: `l`
114
+
115
+ Refresh the whole terminal UI. This command doesn't move you to other steps, nor change any data in your session. It is useful (or the only way) to get back the beautiful UI if you type too much in the REPL console.
116
+
117
+ ### Step
118
+
119
+ **Repl command**: `step`
120
+
121
+ **Key binding**: F7
122
+
123
+ **Alias**: `s`
124
+
125
+ Detect and step into a method call or block in the current line. If there isn't anything to step in, the program continues to next line. In case there are multiple methods on the same line, Jard hornors Ruby's execution order.
126
+
127
+ ### Step out
128
+
129
+ **Repl command**: `step-out`
50
130
 
51
- ![Guide UI](./docs/guide-ui.png)
131
+ **Key binding**: Shift + F7
132
+
133
+ **Alias**: `so`
134
+
135
+ The opposite of step out. This command is used to finish the execution of current frame, and jump to the next line of upper frame. In other words, this command is equivalent to the sequence `up` and `next`. If the neighbor frame already finishes, it continues with even higher frame.
136
+
137
+ This command is useful when you loose your interest in frame, and want to quickly go up again. One example is that you accidentally step into a longgggg loop with nothing useful. Another example is that you step into the library source code and don't really care what it does underlying.
138
+
139
+ ### Next
140
+
141
+ **Repl command**: `next`
142
+
143
+ **Key binding**: F8
144
+
145
+ **Alias**: `n`
146
+
147
+ Continue to the next line in the current frame, by pass any steppable method call or blocks in the mid way unless they contains dynamic breakpoint or any `jard` attachment command. If the current frame already reaches the end, it continues to the next line of upper frame and so on.
148
+
149
+ ### Continue
150
+
151
+ **Repl command**: `continue`
152
+
153
+ **Key binding**: F9
154
+
155
+ **Alias**: `c`
156
+
157
+ Continue the execution of your program to the end, or stop at the first dynamic break point or `jard` attachment command. One common confusion is that long-running ruby processes, such as web server or background jobs, won't stop, and may be used to debug the next request without restarting. If you want to end everything and just exit the process, let's use `exit`.
158
+
159
+ ### Up
160
+
161
+ **Repl command**: `up`
162
+
163
+ **Key binding**: F6
164
+
165
+ Explore the upper frame. When you use this command, all associated displaying screens will be updated accordingly, but your program current position is still at the latest frame. This command is mostly used to explore, and view the trace, input parameters, or how your program stops at the current position. When use this command, you should have a glance at Variable panel, and Source panel to see the variables at destination frame.
166
+
167
+ You can combine with `next` or `step` to perform powerful execution redirection at the destination frame. Let's look at an example. You are debugging a chain of 10 rack middlewares, you go deep into the #9 middleware, found something, then want to go back to #5 middleware. It's pretty boring and frustrated to just use `next` or `step-out` and hope it eventually goes back. Now use `up` for some times (or `frame`, described below) to go to your desired frame, and use `next` there. Tada, it's magical, just like teleport.
168
+
169
+ One note is that you cannot explore a frame in c.
170
+
171
+ ### Down
172
+
173
+ **Repl command**: `down`
174
+
175
+ **Key binding**: Shift+F6
176
+
177
+ Explore the lower frame. See `up` command for more information.
178
+
179
+ ### Frame
180
+
181
+ **Repl command**: `frame <frame_id>`
182
+
183
+ **Key binding:** None
184
+
185
+ **Examples**:`frame 10`
186
+
187
+ Explore a particular frame with id `<frame_id>`. It's faster than `up` and `down`. See `up` command for more information.
188
+
189
+ ### [Done] Version 0.1.0: Proof of concept
190
+
191
+ This version is a bootstrap to see whether my idea works or not, in term of technical possibility and user usability. Luckily, everything works now, and I receive possible feedback from friends and peers.
192
+
193
+ ### [Done] Version 0.2.0: UI completeness
194
+
195
+ The bootstrap version is just a series of ugly prints on stdout. It's frustrated as many things can be broken, wrong drawing, text overlapping, etc. This version is to fix those issues, and provide a foundation for more complicated drawing.
196
+
197
+ ### Version 0.3.0: Complete the workflow
198
+
199
+ This version focuses on making Jard usable for daily activities of any developer. In other words, this version is to become a complete replacement for Byebug (sorry :pray:).
200
+
201
+ - Dynamic breakpoints.
202
+ - Watch expressions.
203
+ - Pin variables.
204
+ - Program's STDOUT panel.
205
+ - Post moterm.
206
+ - Trace variable changes.
207
+ - Multi-threaded debugging.
208
+ - Fulfill options for existing commands.
209
+ - Add more commands to control workflow.
210
+ - etc.
211
+
212
+ ### Version 0.4.0: User satisfaction
213
+
214
+ Ruby Jard now serves well for all debugging use case. But it becomes floated, hard to use, and maybe just not "click" for the user. This version focuses on improve userability, stability, bugs, tweak small details. So that, after this version, Ruby Jard is just pleasant to use.
215
+
216
+ - Support different screen sizes.
217
+ - Minimal layout configuration.
218
+ - Allow customizations (keyboard shortcut for example).
219
+ - Rebuild variable inspection to optimize for each data type, especially nested complicated structure.
220
+ - Collapsible and expandale variable inspection.
221
+ - Windows, viewport, scrolling, etc.
222
+ - Navigate between panels.
223
+ - Build a buffer system to reduce interaction with STDOUT, and eventually improve drawing latency.
224
+
225
+ ### Version 0.5.0: Integration
226
+
227
+ Accept or not, not everyone uses vim, or even terminal. Even in the terminal, I just want to provide minimal layout customizations, as I don't want to rebuild Tmux. Therefore, integration with other powerful systems to extend use cases, adapt different work flow and preferences is the focus on this version. I'm not sure about the ultimate solution, but at my limited knowledge now, [Debugger Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) looks promising.
228
+
229
+ - Prepare the infrastructure for DAP protocol.
230
+ - Separate and split the panels into possible isolated processes, connect them together with DAP.
231
+ - Fully layout configurations and integrate with Tmux.
232
+ - Integrate with Vim 8+/Neovim via Terminal mode.
233
+ - Integrate with Visual Studio Code via DAP.
234
+ - Integrate with Emacs via dap mode.
235
+ - Encrypted remote debugging.
52
236
 
53
- The main page of the debugging UI includes 4 screens:
54
- - Source: Show the current file, surrounding the source code of the executing line.
55
- - Stacktrace: Show the current thread's stack trace. You can use `up`, `down`, `frame` to navigate through the stack trace.
56
- - Variables: Show all the variables in the current context, including local variables, instance variables, and constants.
57
- - Threads: Show all the threads of the process. This screen is valuable in case you are debugging a multi-threaded program.
237
+ ### Further future
58
238
 
59
- At this alpha state, Ruby Jard support some basic commands:
60
- - `next`: continue the execution to the next line.
61
- - `step`: continue the execution, do deep into the implementation of methods in the current line.
62
- - `continue`: continue the execution. The program gonna stops at the next breakpoint.
63
- - `finish`: Finish the execution of the current frame, and go back.
64
- - `up`: explore the stack trace, jump to the upper frame of the current program
65
- - `down`: explore the stack trace, jump to the lower frame of the current program
66
- - `frame`: explore the stack trace, jump to a precise frame in the stack trace.
239
+ I won't stop until 0.5.0 version, even Jard doesn't have any users. However, as soon as it reaches 0.5.0, and serves my interest well, I don't have much things in mind now. The future is uncertain. Dreaming is good. Making dreams come true is hard, and time-consuming. Hope I can reach that future.
67
240
 
68
241
  ## Contributing
69
242
 
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-cayman
@@ -0,0 +1,8 @@
1
+ title: Ruby Jard
2
+ description: Just another ruby debugger. Provide a better experience while debugging Ruby
3
+ google_analytics:
4
+ show_downloads: true
5
+ theme: jekyll-theme-cayman
6
+
7
+ gems:
8
+ - jekyll-mentions
Binary file
@@ -0,0 +1,238 @@
1
+ ![Ruby Jard](./docs/logo.jpg)
2
+
3
+ Jard stands for Just Another Ruby Debugger, aims to provide a better experience while debugging Ruby. Ruby Jard supports the following major features at the moment:
4
+
5
+ - Informative Terminal UI, reduce your mental effort for repeated stuff so that you can focus on killing bugs.
6
+ - Highlighted source code screen.
7
+ - Backtrace visualization and navigation.
8
+ - Auto variable display in the current context.
9
+ - Multi-thread exploration and debugging.
10
+
11
+ Ruby Jard's core is [Byebug](https://github.com/deivid-rodriguez/byebug), an awesome de factor debugger for Ruby. Therefore, Ruby Jard supports most of Byebug's functionalities.
12
+
13
+ If you still don't know what it is, let's watch this video.
14
+
15
+ [![asciicast](https://asciinema.org/a/348526.svg)](https://asciinema.org/a/348526)
16
+
17
+ ## Getting Started
18
+
19
+ **Warning**: Ruby Jard is still under heavy development. Bugs and weird behaviors are expected. If you see one, please don't hesitate to open an issue. I'll try my best to fix.
20
+
21
+ Add `ruby_jard` to your Gemfile, recommend to put it in test or development environment.
22
+
23
+ ``` ruby
24
+ gem 'ruby_jard'
25
+ ```
26
+
27
+ Add magic method `jard` before the line you want to debug, just like `byebug`
28
+
29
+ ```ruby
30
+ def test_method
31
+ a = 1
32
+ b = 2
33
+ jard # Debugger will stop here
34
+ c = a + b
35
+ end
36
+ ```
37
+
38
+ ## Screens
39
+
40
+ When Jard attaches at any line of code, the main tile-style UI shows up. By default, there are 5 areas on the UI that you'll be interested.
41
+
42
+ ### Source panel
43
+
44
+ <img src="./docs/screen-source.png" alt="Source screen" style="max-width: 500px;" />
45
+
46
+ This panel shows the current line of code that your program is stopping, and surrounding related lines. The number of lines shown in this panel depends on your current terminal height, but never less than 5.
47
+
48
+ Ruby Jard supports any file extensions that your program runs into, especially `.rb`, `.erb`, `.haml` files. Other file types may encounter minor syntax highlighting issues.
49
+
50
+ Ruby Jard also supports inspecting gems and libraries, if you are interested.
51
+
52
+ ### Backtrace panel
53
+
54
+ <img src="./docs/screen-backtrace.png" alt="Screen backtrace" style="max-width: 500px;" />
55
+
56
+ This panel describes the current backtrace of the current thread your program is stopping. Each line of this panel describes the current Frame. What is frame and backtrace by the way? Let's step back a little bit at how Ruby executes your code. Internally, Ruby uses an interpreter to read and execute your code, line by line (technically, YARD instructions, but let's go with a simple version). When it meets a chunk of code that needs to open a new scope, like method calls or inline-block call, the interpreter creates a new structure to store the current context so that it can link to the next scope and go back later. This data structure is call Frame. The interpreter pushes frame into a stack, called backtrace (or stack trace, or call stack, whatever), and continues to execute your code. Each thread has a separate backtrace. To understand deeply, you may be interested in this wonderful slide: [Grow and Shrink - Dynamically Extending the Ruby VM Stack](https://www.slideshare.net/KeitaSugiyama1/grow-and-shrink-dynamically-extending-the-ruby-vm-stack).
57
+
58
+ Overall, the whole backtrace panel lets you know where you are stopping at, the trace of how your program is running. When combining with other tools and other panels, you will be surprised by how much information the bugger can help you when you encounter your bugs.
59
+
60
+ Each frame includes the following information:
61
+
62
+ - Frame ID: incremental, can be used to jump to an arbitrary frame with frame command.
63
+ - Current location label: a class name and method name of the method covers its frame. If there is a `[c]` prefix in front of a class name, it means that the method is provided by Ruby, implemented in C, and impossible to peek.
64
+ - Current physical location: exact file name and line number. If a frame is allocated in a gem, the physical location shows a gem name and version only. For example: `RSpec::Core::Hooks::HookCollections in run in rspec-core (3.9.2)`.
65
+
66
+ ### Variable panel
67
+
68
+ <img src="./docs/screen-variables.png" alt="Variables screen" style="max-width: 500px;" />
69
+
70
+ The variable panel lets you explore all the local variables, instance variables, and constants in the current display context. Each variable is described by:
71
+
72
+ - Inline indicator: the beginning dot (`•`) implies a variable that appears in the current line.
73
+ - Variable type: allow you to know the type of a variable at a single glance. Only built-in types, such as `int`, `flt`, `hash`, `bool`, `rng`, are supported. Instances of any classes will be noted as `var`.
74
+ - Size of variable: the size of collection-like variables. Current Jard version supports 3 types:
75
+ - Hash: this field shows the number of keys
76
+ - Array: this field shows the number of items
77
+ - String: this field shows the number of character (fetched from`String#size` method)
78
+ - Variable inspection: the content of the variable. The current Jard version generates this field by calling `#inspect`. **Known issue**: this accidentally triggers materializing method of objects, such as `ActiveRecord::Relation`. Future Jard version gonna fix this by a new safe generator.
79
+
80
+ This panel interacts well with backtrace panel and backtrace-exploring commands such as (`up`, `down`, `frame`, etc.) to inspect relative variables at each frame layer in the program. A common use case is to recall the parameter values you forgot when digging too deep into a method call.
81
+
82
+ By default, the variables are sorted by the following criteria:
83
+
84
+ - Pinned variables (coming soon)
85
+ - Current context (self)
86
+ - Local variables
87
+ - Instance variables
88
+ - Constants
89
+ - Global variables (coming soon)
90
+
91
+ ### Thread panel
92
+
93
+ <img src="./docs/screen-threads.png" alt="Screen threads" style="max-width: 500px;" />
94
+
95
+ Show all the threads running at the moment. This panel is useful when you are working with a complicated multi-threaded environment like web server, or background jobs.
96
+
97
+ ### Repl panel
98
+
99
+ <img src="./docs/screen-repl.png" alt="Screen repl" />
100
+
101
+ An interactive Repl for you to interact with your program, inspect values, update values, or control the debug flow as you want. The heart of Jard's repl is [Pry](https://github.com/pry/pry), a masterpiece gem. When you type a command, Jard parses, and does corresponding actions if what you type matches supported command. Otherwise, they are evaluated as Ruby code.
102
+
103
+ ## Commands
104
+
105
+ ### Step
106
+
107
+ **Repl command**: `step`
108
+
109
+ **Key binding**: F7
110
+
111
+ Detect and step into a method call or block in the current line. If there isn't anything to step in, the program continues to next line. In case there are multiple methods on the same line, Jard hornors Ruby's execution order.
112
+
113
+ ### Step out
114
+
115
+ **Repl command**: `step-out`
116
+
117
+ **Key binding**: Shift + F7
118
+
119
+ The opposite of step out. This command is used to finish the execution of current frame, and jump to the next line of upper frame. In other words, this command is equivalent to the sequence `up` and `next`. If the neighbor frame already finishes, it continues with even higher frame.
120
+
121
+ This command is useful when you loose your interest in frame, and want to quickly go up again. One example is that you accidentally step into a longgggg loop with nothing useful. Another example is that you step into the library source code and don't really care what it does underlying.
122
+
123
+ ### Next
124
+
125
+ **Repl command**: `next`
126
+
127
+ **Key binding**: F8
128
+
129
+ Continue to the next line in the current frame, by pass any steppable method call or blocks in the mid way unless they contains dynamic breakpoint or any `jard` attachment command. If the current frame already reaches the end, it continues to the next line of upper frame and so on.
130
+
131
+ ### Continue
132
+
133
+ **Repl command**: `continue`
134
+
135
+ **Key binding**: F9
136
+
137
+ Continue the execution of your program to the end, or stop at the first dynamic break point or `jard` attachment command. One common confusion is that long-running ruby processes, such as web server or background jobs, won't stop, and may be used to debug the next request without restarting. If you want to end everything and just exit the process, let's use `exit`.
138
+
139
+ ### Up
140
+
141
+ **Repl command**: `up`
142
+
143
+ **Key binding**: F6
144
+
145
+ Explore the upper frame. When you use this command, all associated displaying screens will be updated accordingly, but your program current position is still at the latest frame. This command is mostly used to explore, and view the trace, input parameters, or how your program stops at the current position. When use this command, you should have a glance at Variable panel, and Source panel to see the variables at destination frame.
146
+
147
+ You can combine with `next` or `step` to perform powerful execution redirection at the destination frame. Let's look at an example. You are debugging a chain of 10 rack middlewares, you go deep into the #9 middleware, found something, then want to go back to #5 middleware. It's pretty boring and frustrated to just use `next` or `step-out` and hope it eventually goes back. Now use `up` for some times (or `frame`, described below) to go to your desired frame, and use `next` there. Tada, it's magical, just like teleport.
148
+
149
+ One note is that you cannot explore a frame in c.
150
+
151
+ ### Down
152
+
153
+ **Repl command**: `down`
154
+
155
+ **Key binding**: Shift+F6
156
+
157
+ Explore the lower frame. See `up` command for more information.
158
+
159
+ ### Frame
160
+
161
+ **Repl command**: `frame <frame_id>`
162
+
163
+ **Key binding:** None
164
+
165
+ **Examples**:`frame 10`
166
+
167
+ Explore a particular frame with id `<frame_id>`. It's faster than `up` and `down`. See `up` command for more information.
168
+
169
+
170
+
171
+ ## Roadmap
172
+
173
+ The ultimate goal of Ruby Jard is to provide a better experience while debugging Ruby. All the items in the roadmap are supposed to serve that. However, I have a life. There won't be any promises on when those items will be finished. In fact, this roadmap may be changed at anytime, depends on the current direction, focus and circumstances.
174
+
175
+ ### [Done] Version 0.1.0: Proof of concept
176
+
177
+ This version is a bootstrap to see whether my idea works or not, in term of technical possibility and user usability. Luckily, everything works now, and I receive possible feedback from friends and peers.
178
+
179
+ ### [Done] Version 0.2.0: UI completeness
180
+
181
+ The bootstrap version is just a series of ugly prints on stdout. It's frustrated as many things can be broken, wrong drawing, text overlapping, etc. This version is to fix those issues, and provide a foundation for more complicated drawing.
182
+
183
+ ### Version 0.3.0: Complete the workflow
184
+
185
+ This version focuses on making Jard usable for daily activities of any developer. In other words, this version is to become a complete replacement for Byebug (sorry :pray:).
186
+
187
+ - Dynamic breakpoints.
188
+ - Watch expressions.
189
+ - Pin variables.
190
+ - Program's STDOUT panel.
191
+ - Post moterm.
192
+ - Trace variable changes.
193
+ - Multi-threaded debugging.
194
+ - Fulfill options for existing commands.
195
+ - Add more commands to control workflow.
196
+ - etc.
197
+
198
+ ### Version 0.4.0: User satisfaction
199
+
200
+ Ruby Jard now serves well for all debugging use case. But it becomes floated, hard to use, and maybe just not "click" for the user. This version focuses on improve userability, stability, bugs, tweak small details. So that, after this version, Ruby Jard is just pleasant to use.
201
+
202
+ - Support different screen sizes.
203
+ - Minimal layout configuration.
204
+ - Allow customizations (keyboard shortcut for example).
205
+ - Rebuild variable inspection to optimize for each data type, especially nested complicated structure.
206
+ - Collapsible and expandale variable inspection.
207
+ - Windows, viewport, scrolling, etc.
208
+ - Navigate between panels.
209
+ - Build a buffer system to reduce interaction with STDOUT, and eventually improve drawing latency.
210
+
211
+ ### Version 0.5.0: Integration
212
+
213
+ Accept or not, not everyone uses vim, or even terminal. Even in the terminal, I just want to provide minimal layout customizations, as I don't want to rebuild Tmux. Therefore, integration with other powerful systems to extend use cases, adapt different work flow and preferences is the focus on this version. I'm not sure about the ultimate solution, but at my limited knowledge now, [Debugger Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) looks promising.
214
+
215
+ - Prepare the infrastructure for DAP protocol.
216
+ - Separate and split the panels into possible isolated processes, connect them together with DAP.
217
+ - Fully layout configurations and integrate with Tmux.
218
+ - Integrate with Vim 8+/Neovim via Terminal mode.
219
+ - Integrate with Visual Studio Code via DAP.
220
+ - Integrate with Emacs via dap mode.
221
+ - Encrypted remote debugging.
222
+
223
+ ### Further future
224
+
225
+ I won't stop until 0.5.0 version, even Jard doesn't have any users. However, as soon as it reaches 0.5.0, and serves my interest well, I don't have much things in mind now. The future is uncertain. Dreaming is good. Making dreams come true is hard, and time-consuming. Hope I can reach that future.
226
+
227
+ ## Contributing
228
+
229
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nguyenquangminh0711/ruby_jard. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/nguyenquangminh0711/ruby_jard/blob/master/CODE_OF_CONDUCT.md).
230
+
231
+
232
+ ## License
233
+
234
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
235
+
236
+ ## Code of Conduct
237
+
238
+ Everyone interacting in the RubyJard project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ruby_jard/blob/master/CODE_OF_CONDUCT.md).