Skip to content

Commit 73f76ae

Browse files
author
José Valim
committed
Allow __FILE__ and __LINE__ customization in EDITOR
1 parent ae8262a commit 73f76ae

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

lib/iex/lib/iex/helpers.ex

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,20 +222,33 @@ defmodule IEx.Helpers do
222222
end
223223

224224
@doc """
225-
Opens the given module, module/function/arity or file.
225+
Opens the given module, module/function/arity or `{file, line}`.
226226
227227
This function uses the `ELIXIR_EDITOR` environment variable
228-
and falls back to EDITOR if the former is not available.
228+
and falls back to `EDITOR` if the former is not available.
229229
230-
Since this function prints the result returned by the
231-
editor, `ELIXIR_EDITOR` can be set "echo" if you prefer
232-
to display the location rather than opening it.
230+
By default, it attempts to open the file and line using the
231+
`file:line` notation. For example, if your editor is called
232+
`subl`, it will open the file as:
233+
234+
subl path/to/file:line
235+
236+
Custom editors are supported by using the __FILE__ and __LINE__
237+
notations. For example, vi/vim users can set `ELIXIR_EDITOR` to:
238+
239+
ELIXIR_EDITOR="vi +__LINE__ __FILE__"
240+
241+
and Elixir will properly interpolate values.
242+
243+
Since this function prints the result returned by the editor,
244+
`ELIXIR_EDITOR` can be set "echo" if you prefer to display the
245+
location rather than opening it.
233246
234247
## Examples
235248
236249
iex> open MyApp
237250
iex> open MyApp.fun/2
238-
iex> open "path/to/file"
251+
iex> open {"path/to/file", 1}
239252
240253
"""
241254
defmacro open(term) do

lib/iex/lib/iex/introspection.ex

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,25 @@ defmodule IEx.Introspection do
8484
end
8585

8686
def open({file, line}) when is_binary(file) and is_integer(line) do
87-
if File.regular?(file) do
88-
open("#{file}:#{line}")
89-
else
90-
puts_error("Could not open: #{inspect file}. File is not available.")
87+
cond do
88+
not File.regular?(file) ->
89+
puts_error("Could not open: #{inspect file}. File is not available.")
90+
editor = System.get_env("ELIXIR_EDITOR") || System.get_env("EDITOR") ->
91+
command =
92+
if editor =~ "__FILE__" or editor =~ "__LINE__" do
93+
editor
94+
|> String.replace("__FILE__", inspect(file))
95+
|> String.replace("__LINE__", Integer.to_string(line))
96+
else
97+
"#{editor} #{inspect file}:#{line}"
98+
end
99+
IO.write IEx.color(:eval_info, :os.cmd(String.to_charlist(command)))
100+
true ->
101+
puts_error("Could not open: #{inspect file}. " <>
102+
"Please set the ELIXIR_EDITOR or EDITOR environment variables with the " <>
103+
"command line invocation of your favorite EDITOR.")
91104
end
92-
dont_display_result()
93-
end
94105

95-
def open(path) when is_binary(path) do
96-
if editor = System.get_env("ELIXIR_EDITOR") || System.get_env("EDITOR") do
97-
IO.write IEx.color(:eval_info, :os.cmd('#{editor} #{inspect path}'))
98-
else
99-
puts_error("Could not open: #{inspect path}. " <>
100-
"Please set the ELIXIR_EDITOR or EDITOR environment variables with the " <>
101-
"command line invocation of your favorite EDITOR.")
102-
end
103106
dont_display_result()
104107
end
105108

lib/iex/test/iex/helpers_test.exs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ defmodule IEx.HelpersTest do
125125
describe "open" do
126126
@iex_helpers Path.expand("../../lib/iex/helpers.ex", __DIR__)
127127
@elixir_erl Path.expand("../../../elixir/src/elixir.erl", __DIR__)
128+
@editor System.get_env("ELIXIR_EDITOR")
129+
130+
test "opens __FILE__ and __LINE__" do
131+
System.put_env("ELIXIR_EDITOR", "echo __LINE__:__FILE__")
132+
assert capture_iex("open({#{inspect __ENV__.file}, 3})") |> maybe_trim_quotes() ==
133+
"3:#{__ENV__.file}"
134+
after
135+
System.put_env("ELIXIR_EDITOR", @editor)
136+
end
128137

129138
test "opens Elixir module" do
130139
assert capture_iex("open(IEx.Helpers)") |> maybe_trim_quotes() =~
@@ -210,11 +219,6 @@ defmodule IEx.HelpersTest do
210219
"Could not open: \"foo\". File is not available."
211220
end
212221

213-
test "opens given path" do
214-
assert capture_iex("open(#{inspect __ENV__.file})") |> maybe_trim_quotes() ==
215-
__ENV__.file
216-
end
217-
218222
defp maybe_trim_quotes(string) do
219223
case :os.type do
220224
{:win32, _} -> String.trim(string, "\"")

0 commit comments

Comments
 (0)