Re: who_calls rewrite

Bill Clementson <[email protected]> Mon, 17 Sep 2007 17:39:58 -0700
Newsgroups gmane.comp.lang.erlang.distel.devel
Message-ID <[email protected]>
--=-=-=

Hi Matthias,

Matthias Radestock <[email protected]> writes:
> Bill Clementson wrote:
>>> There is a comment in the code saying "FIXME: Use line number for a
>>> hyperlink.". I reckon one way to implement something sensible along
>>> these lines is to construct an, in Emacs-lingo, "overlay" for the
>>> displayed m:f/a with the line number information. 
>> 
>> I thought that "overlays" were more for display properties and that
>> "text-properties" would be what you would want to use for storing the
>> line# and source file of any matches.
>
> If you say so. I am not an emacs hacker.
>
>> Are you suggesting that "M-." be used to go to the "call"? Normally,
>> "M-." is used to go to the definition, not a reference. Why not just
>> use "RET"? You could have a separate RET key binding for the who-calls
>> results buffer.
>
> That would be better indeed. It still has to do much of the same work as 
> "M-.", so I was just trying to cut some corners.
>
> Any chance you could have a go at implementing this?

I had a bit of free time today, so I implemented this (patch
attached). The who-calls buffer will now let you press RET on a line
and it will open the source member of the module containing the caller
and jump to the line number of the function definition of the caller
(which is what is returned by your "(Lin)(domain (E || ~p))" who-calls
xref query. I think it would be preferable to jump to the place in the
function where the call was made; however, I don't know what the
correct xref string should be. It looks like changing the "(Lin)" to
something like "(LLin + XLin)" is what is needed (so that xref returns
the line numbers for both local and external calls). However, I played
around with some variations and couldn't figure out the right
one. And, the xref documentation didn't provide any enlightenment. Do
you know what the xref query should be changed to?

- Bill


--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=patch

Index: elisp/erl-service.el
===================================================================
--- elisp/erl-service.el	(revision 38)
+++ elisp/erl-service.el	(working copy)
@@ -1182,17 +1182,54 @@
     (erl-receive ()
         ((['rex calls]
           (with-current-buffer (get-buffer-create "*Erlang Calls*")
+	    (erl-who-calls-mode)
             (setq buffer-read-only t)
             (let ((inhibit-read-only t))
-              (erlang-mode)
               (erase-buffer)
               (dolist (call calls)
-                (mlet [m f a _line] call
-                  ;; FIXME: Use line number for a hyperlink.
-                  (insert (format "%s:%s/%S\n" m f a)))))
+                (mlet [m f a line] call
+		  (erl-propertize-insert (list 'module m
+					       'function f
+					       'arity a
+					       'line line
+					       'face 'bold)
+					 (format "%s:%s/%S\n" m f a))))
+	      ;; Remove the final newline to ensure all lines contain xref's
+	      (backward-char 1)
+	      (delete-char 1))
             (goto-char (point-min))
             (message "")
             (pop-to-buffer (current-buffer))))))))
 
+(define-derived-mode erl-who-calls-mode fundamental-mode
+  "who-calls"
+  "Distel Who-Calls Mode. Goto caller by pressing RET.
+
+\\{erl-who-calls-mode-map}")
+
+(define-key erl-who-calls-mode-map (kbd "RET") 'erl-goto-caller)
+
+(defun erl-goto-caller ()
+  "Goto the caller that is at point."
+  (interactive)
+  (let ((line (get-text-property (line-beginning-position) 'line))
+	(module (get-text-property (line-beginning-position) 'module))
+	(node (or erl-nodename-cache (erl-target-node))))
+    (erl-spawn
+      (erl-send-rpc node 'distel 'find_source (list (intern module)))
+      (erl-receive (line)
+	  ((['rex ['ok path]]
+	    (find-file path)
+	    (goto-line line))
+	   (['rex ['error reason]]
+	    (message "Error: %s" reason)))))))
+
+(defmacro erl-propertize-insert (props &rest body)
+  "Execute and insert BODY and add PROPS to all the text that is inserted."
+  (let ((start (gensym)))
+    `(let ((,start (point)))
+       (prog1 (progn (insert ,@body))
+	 (add-text-properties ,start (point) ,props)))))
+
 (provide 'erl-service)
 

--=-=-=
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
--=-=-=
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Distel-hackers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/distel-hackers

--=-=-=--