Skip to content

Commit 8d75486

Browse files
committed
Add hover documentation for 'break'
1 parent 4f440e7 commit 8d75486

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

lib/ruby_lsp/listeners/hover.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class Hover
77
include Requests::Support::Common
88

99
ALLOWED_TARGETS = [
10+
Prism::BreakNode,
1011
Prism::CallNode,
1112
Prism::ConstantReadNode,
1213
Prism::ConstantWriteNode,
@@ -55,6 +56,7 @@ def initialize(response_builder, global_state, uri, node_context, dispatcher, so
5556

5657
dispatcher.register(
5758
self,
59+
:on_break_node_enter,
5860
:on_constant_read_node_enter,
5961
:on_constant_write_node_enter,
6062
:on_constant_path_node_enter,
@@ -251,6 +253,11 @@ def on_class_variable_write_node_enter(node)
251253
handle_class_variable_hover(node.name.to_s)
252254
end
253255

256+
#: (Prism::BreakNode node) -> void
257+
def on_break_node_enter(node)
258+
handle_keyword_documentation(node.keyword)
259+
end
260+
254261
private
255262

256263
#: ((Prism::InterpolatedStringNode | Prism::StringNode) node) -> void

lib/ruby_lsp/static_docs.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ module RubyLsp
1616
KEYWORD_DOCS = {
1717
"yield" => "Invokes the passed block with the given arguments",
1818
"case" => "Starts a case expression for pattern matching or multiple condition checking",
19+
"break" => "Terminates the execution of a block, loop, or method",
1920
}.freeze #: Hash[String, String]
2021
end

static_docs/break.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Break
2+
3+
In Ruby, the `break` keyword is used to exit a loop or block prematurely. Unlike `next` which skips to the next iteration, `break` terminates the loop entirely and continues with the code after the loop.
4+
5+
```ruby
6+
# Basic break usage in a loop
7+
5.times do |i|
8+
break if i == 3
9+
10+
puts i
11+
end
12+
# Output:
13+
# 0
14+
# 1
15+
# 2
16+
```
17+
18+
The `break` statement can be used with any of Ruby's iteration methods or loops.
19+
20+
```ruby
21+
# Using break with different types of loops
22+
array = [1, 2, 3, 4, 5]
23+
24+
# With each
25+
array.each do |num|
26+
break if num > 3
27+
28+
puts "Number: #{num}"
29+
end
30+
# Output:
31+
# Number: 1
32+
# Number: 2
33+
# Number: 3
34+
35+
# With infinite loop
36+
i = 0
37+
loop do
38+
i += 1
39+
break if i >= 5
40+
41+
puts "Count: #{i}"
42+
end
43+
```
44+
45+
## Break with a Value
46+
47+
When used inside a block, `break` can return a value that becomes the result of the method call.
48+
49+
```ruby
50+
# Using break with a return value
51+
result = [1, 2, 3, 4, 5].map do |num|
52+
break "Too large!" if num > 3
53+
54+
num * 2
55+
end
56+
puts result # Output: "Too large!"
57+
58+
# Break in find method
59+
number = (1..100).find do |n|
60+
break n if n > 50 && n.even?
61+
end
62+
puts number # Output: 52
63+
```
64+
65+
## Break in Nested Loops
66+
67+
When using `break` in nested loops, it only exits the innermost loop unless explicitly used with a label (not commonly used in Ruby).
68+
69+
```ruby
70+
# Break in nested iteration
71+
result = (1..3).each do |i|
72+
puts "Outer loop: #{i}"
73+
74+
(1..3).each do |j|
75+
break if j == 2
76+
77+
puts " Inner loop: #{j}"
78+
end
79+
end
80+
# Output:
81+
# Outer loop: 1
82+
# Inner loop: 1
83+
# Outer loop: 2
84+
# Inner loop: 1
85+
# Outer loop: 3
86+
# Inner loop: 1
87+
88+
# Breaking from nested loops using a flag
89+
found = false
90+
(1..3).each do |i|
91+
(1..3).each do |j|
92+
if i * j == 4
93+
found = true
94+
break
95+
end
96+
end
97+
break if found
98+
end
99+
```
100+
101+
The `break` keyword is essential for controlling loop execution and implementing early exit conditions. It's particularly useful when you've found what you're looking for and don't need to continue iterating.

0 commit comments

Comments
 (0)