Skip to content

Commit df94927

Browse files
committed
Add :history_size option to IEx
1 parent 336b9cf commit df94927

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

lib/iex/lib/iex/helpers.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ defmodule IEx.Helpers do
8181
their results.
8282
"""
8383
def v do
84-
history = Enum.reverse(Process.get(:iex_history))
84+
history = Enum.reverse(:queue.to_list(Process.get(:iex_history)))
8585
Enum.each(history, print_history(&1))
8686
end
8787

lib/iex/lib/iex/options.ex

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ defmodule IEx.Options do
6464
opts
6565
end
6666

67+
def get(:history_size) do
68+
{ :ok, size } = :application.get_env(:iex, :history_size)
69+
size
70+
end
71+
6772
def get(name) do
6873
raise_option(name)
6974
end
@@ -97,7 +102,7 @@ defmodule IEx.Options do
97102
end
98103

99104
def set(:colors, _) do
100-
raise_value
105+
raise_value("a keyword list")
101106
end
102107

103108
def set(:inspect, opts) when is_list(opts) do
@@ -108,7 +113,17 @@ defmodule IEx.Options do
108113
end
109114

110115
def set(:inspect, _) do
111-
raise_value
116+
raise_value("a keyword list")
117+
end
118+
119+
def set(:history_size, size) when is_integer(size) do
120+
old_size = get(:history_size)
121+
:application.set_env(:iex, :history_size, size)
122+
old_size
123+
end
124+
125+
def set(:history_size, _) do
126+
raise_value("an integer")
112127
end
113128

114129
def set(name, _) do
@@ -191,8 +206,8 @@ defmodule IEx.Options do
191206
raise ArgumentError, message: "Unknown IEx option #{inspect name}"
192207
end
193208

194-
defp raise_value do
195-
raise ArgumentError, message: "Expected the value to be a keyword list"
209+
defp raise_value(type) do
210+
raise ArgumentError, message: "Expected the value to be #{type}"
196211
end
197212

198213
defp filtered_kw(reference_kw, user_kw) do

lib/iex/lib/iex/server.ex

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ defmodule IEx.Server do
44
@doc """
55
Eval loop for an IEx session. Its responsibilities include:
66
7+
* loading of .iex files
78
* reading input
89
* trapping exceptions in the code being evaluated
9-
* keeping input history
10+
* keeping expression history
1011
1112
"""
1213
def start(config) do
13-
Process.put :iex_history, []
14+
Process.put :iex_history, :queue.new
1415

1516
{ _, _, scope } = :elixir.eval('require IEx.Helpers', [], 0, config.scope)
1617
config = config.scope(scope)
@@ -135,8 +136,29 @@ defmodule IEx.Server do
135136
end
136137

137138
defp update_history(config) do
138-
current = Process.get :iex_history
139-
Process.put :iex_history, [config|current]
139+
limit = IEx.Options.get(:history_size)
140+
history = Process.get(:iex_history)
141+
len = :queue.len(history)
142+
new_history =
143+
:queue.in(config, history)
144+
|> limit_history(len + 1, limit)
145+
Process.put(:iex_history, new_history)
146+
end
147+
148+
defp limit_history(_, _, 0) do
149+
:queue.new
150+
end
151+
152+
defp limit_history(queue, _, limit) when limit < 0 do
153+
queue
154+
end
155+
156+
defp limit_history(queue, len, limit) when len > limit do
157+
limit_history(:queue.drop(queue), len-1, limit)
158+
end
159+
160+
defp limit_history(queue, _, _) do
161+
queue
140162
end
141163

142164
defp io_get(config) do

lib/iex/mix.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ defmodule IEx.Mixfile do
1717
directory: "blue",
1818
device: "green"
1919
],
20+
history_size: 20,
2021
started: true
2122
]]
2223
end

0 commit comments

Comments
 (0)