It would be nice to simply click on a debug message and have it open Emacs to the correct location in the corresponding file. There are a variety of ways to accomplish this, I chose to use terminal hyperlinks along with adding an Emacs URI protocol to my system.
emacs://open/?url=file://{_filename}&line=#{line_num}&column={col_num}
To appear as a link in the terminal, the URI string must appear inside a terminal hyperlink escape sequence (shown below).
'\e]8;;http://example.com\e\\This is a link\e]8;;\e\\'
I created a simple Elixir macro to add links to Logger messages. Since Elixir macros are expanded at compile time there is no run-time overhead to this approach. I made the Logger calls lazy in the macro, which means the caller can use a non lazy call and it will be optimized in this macro.
ElixirApp.PMLogger
defmodule ElixirApp.PMLogger do
@moduledoc false
defmacro __using__(_opts) do
quote do
require Logger
alias ElixirApp.PMLogger
end
end
defmacro log(message \\ "") do
quote do: Logger.log fn -> " \e]8;;emacs://open/?url=file://#{__ENV__.file}&line=#{__ENV__.line}&column=0\e\\#{__MODULE__}\e]8;;\e\\ : #{unquote(message)} " end
end
defmacro info(message \\ "") do
quote do: Logger.info fn -> " \e]8;;emacs://open/?url=file://#{__ENV__.file}&line=#{__ENV__.line}&column=0\e\\#{__MODULE__}\e]8;;\e\\ : #{unquote(message)} " end
end
defmacro debug(message \\ "") do
quote do: Logger.debug fn -> " \e]8;;emacs://open/?url=file://#{__ENV__.file}&line=#{__ENV__.line}&column=0\e\\#{__MODULE__}\e]8;;\e\\ : #{unquote(message)} " end
end
defmacro error(message \\ "") do
quote do: Logger.error fn -> " \e]8;;emacs://open/?url=file://#{__ENV__.file}&line=#{__ENV__.line}&column=0\e\\#{__MODULE__}\e]8;;\e\\ : #{unquote(message)} " end
end
end
With this macro, hyperlinks will be shown in the Logger output. I chose to use the module name as the hyperlink text because the links themselves can be very long. You can see the link in action in the image above. In iTerm2 you hold the command
key down then hover over links to see the target URI in the status bar.
To add the Emacs protocol on macOS you can try my uri-handler solution.