@@ -135,9 +135,29 @@ defmodule IEx.Introspection do
135135 end
136136
137137 def open ( { file , line } ) when is_binary ( file ) and is_integer ( line ) do
138+ case open_location ( file , line ) do
139+ { :ok , result } -> IO . write ( IEx . color ( :eval_info , result ) )
140+ { :error , message } -> puts_error ( message )
141+ end
142+
143+ dont_display_result ( )
144+ end
145+
146+ def open ( invalid ) do
147+ puts_error ( "Invalid arguments for open helper: #{ inspect ( invalid ) } " )
148+ dont_display_result ( )
149+ end
150+
151+ @ doc """
152+ Opens the given file at the given line using the ELIXIR_EDITOR or EDITOR
153+ environment variable.
154+
155+ Returns `{:ok, result}` on success or `{:error, message}` on failure.
156+ """
157+ def open_location ( file , line ) when is_binary ( file ) and is_integer ( line ) do
138158 cond do
139159 not File . regular? ( file ) ->
140- puts_error ( "Could not open #{ inspect ( file ) } , file is not available." )
160+ { :error , "Could not open #{ inspect ( file ) } , file is not available." }
141161
142162 editor = System . get_env ( "ELIXIR_EDITOR" ) || System . get_env ( "EDITOR" ) ->
143163 command =
@@ -149,31 +169,23 @@ defmodule IEx.Introspection do
149169 "#{ editor } #{ inspect ( file ) } :#{ line } "
150170 end
151171
152- IO . write ( IEx . color ( :eval_info , :os . cmd ( String . to_charlist ( command ) ) ) )
172+ { :ok , :os . cmd ( String . to_charlist ( command ) ) }
153173
154174 true ->
155- puts_error (
156- "Could not open: #{ inspect ( file ) } . " <>
157- "Please set the ELIXIR_EDITOR or EDITOR environment variables with the " <>
158- "command line invocation of your favorite EDITOR."
159- )
175+ { :error ,
176+ "Could not open: #{ inspect ( file ) } . " <>
177+ "Please set the ELIXIR_EDITOR or EDITOR environment variables with the " <>
178+ "command line invocation of your favorite EDITOR." }
160179 end
161-
162- dont_display_result ( )
163- end
164-
165- def open ( invalid ) do
166- puts_error ( "Invalid arguments for open helper: #{ inspect ( invalid ) } " )
167- dont_display_result ( )
168180 end
169181
170182 @ doc """
171183 Prints source code.
172184 """
173185 def source ( module ) when is_atom ( module ) do
174186 case source_location ( module ) do
175- { :ok , { file , _line } } ->
176- IO . puts ( File . read! ( file ) )
187+ { :ok , { file , line } } ->
188+ print_source ( file , line )
177189
178190 { :error , reason } ->
179191 puts_error ( "Could not show source for #{ inspect ( module ) } , #{ reason } " )
@@ -184,8 +196,8 @@ defmodule IEx.Introspection do
184196
185197 def source ( { module , function } ) when is_atom ( module ) and is_atom ( function ) do
186198 case source_location ( { module , function } ) do
187- { :ok , { file , _line } } ->
188- IO . puts ( File . read! ( file ) )
199+ { :ok , { file , line } } ->
200+ print_source ( file , line )
189201
190202 { :error , reason } ->
191203 puts_error ( "Could not show source for #{ inspect ( module ) } .#{ function } , #{ reason } " )
@@ -197,8 +209,8 @@ defmodule IEx.Introspection do
197209 def source ( { module , function , arity } )
198210 when is_atom ( module ) and is_atom ( function ) and is_integer ( arity ) do
199211 case source_location ( { module , function , arity } ) do
200- { :ok , { file , _line } } ->
201- IO . puts ( File . read! ( file ) )
212+ { :ok , { file , line } } ->
213+ print_source ( file , line )
202214
203215 { :error , reason } ->
204216 puts_error ( "Could not show source for #{ inspect ( module ) } .#{ function } /#{ arity } , #{ reason } " )
@@ -212,24 +224,34 @@ defmodule IEx.Introspection do
212224 dont_display_result ( )
213225 end
214226
215- defp source_location ( module ) when is_atom ( module ) do
227+ defp print_source ( file , line ) do
228+ IO . puts ( Path . relative_to_cwd ( file ) <> ":" <> Integer . to_string ( line ) )
229+ end
230+
231+ @ doc """
232+ Returns the source location for the given module, {module, function},
233+ or {module, function, arity}.
234+
235+ Returns `{:ok, {file, line}}` or `{:error, reason}`.
236+ """
237+ def source_location ( module ) when is_atom ( module ) do
216238 case source_mfa ( module , :__info__ , 1 ) do
217239 { source , nil , _ } -> { :ok , { source , 1 } }
218240 { _ , tuple , _ } -> { :ok , tuple }
219241 { :error , reason } -> { :error , reason }
220242 end
221243 end
222244
223- defp source_location ( { module , function } ) when is_atom ( module ) and is_atom ( function ) do
245+ def source_location ( { module , function } ) when is_atom ( module ) and is_atom ( function ) do
224246 case source_mfa ( module , function , :* ) do
225247 { _ , _ , nil } -> { :error , "function/macro is not available" }
226248 { _ , _ , tuple } -> { :ok , tuple }
227249 { :error , reason } -> { :error , reason }
228250 end
229251 end
230252
231- defp source_location ( { module , function , arity } )
232- when is_atom ( module ) and is_atom ( function ) and is_integer ( arity ) do
253+ def source_location ( { module , function , arity } )
254+ when is_atom ( module ) and is_atom ( function ) and is_integer ( arity ) do
233255 case source_mfa ( module , function , arity ) do
234256 { _ , _ , nil } -> { :error , "function/macro is not available" }
235257 { _ , _ , tuple } -> { :ok , tuple }
0 commit comments