blueFast
blueFast

Reputation: 44461

Emacs org-mode: textual reference to a file:line

I am using org-mode in Emacs to document my development activities. One of the tasks which I must continuously do by hand is to describe areas of code. Emacs has a very nice Bookmark List: create a bookmark with CTRL-x r m, list them with CTRL-x r l. This is very useful, but is not quite what I need.

Org-mode has the concept of link, and the command org-store-link will record a link to the current position in any file, which can be pasted to the org-file. The problem with this is two-fold:

I need to have the bookmark in textual form, so that I can copy paste it into org-mode, end edit it if needed, with a simple format like this:

absolute-file-path:line

And this must be obtained from the current point position. The workflow would be as simple as:

Unfortunately my lisp is non-existent, so I do not know how to do this. Is there a simple solution to my problem?

Upvotes: 10

Views: 2791

Answers (5)

wenjianhn
wenjianhn

Reputation: 448

;; Insert a org link to the function in the next window
(defun insert-org-link-to-func ()
  (interactive)
  (insert (with-current-buffer (window-buffer (next-window))
        (org-make-link-string
         (concat "file:" (buffer-file-name)
             "::" (number-to-string (line-number-at-pos)))
         (which-function)
         ))))

This func generates link with the function name as the description. Open two windows, one is the org file and the other is src code. Then M-x insert-org-link-to-func RET

Upvotes: 0

phils
phils

Reputation: 73344

(defun position-to-kill-ring ()
  "Copy to the kill ring a string in the format \"file-name:line-number\"
for the current buffer's file name, and the line number at point."
  (interactive)
  (kill-new
   (format "%s:%d" (buffer-file-name) (save-restriction
                                        (widen) (line-number-at-pos)))))

Upvotes: 14

Stefan
Stefan

Reputation: 28571

BTW, if you want something better than FILE:LINE, you can try to use add-log-current-defun (in add-log.el) which should return the name of the current function.

Upvotes: 0

bzg
bzg

Reputation: 2605

You want to use the org-create-file-search-functions and org-execute-file-search-functions hooks.

For example, if you need the search you describe for text-mode files, use this:

(add-hook 'org-create-file-search-functions
      '(lambda ()
         (when (eq major-mode 'text-mode)
           (number-to-string (line-number-at-pos)))))

(add-hook 'org-execute-file-search-functions
      '(lambda (search-string)
         (when (eq major-mode 'text-mode)
           (goto-line (string-to-number search-string)))))

Then M-x org-store-link RET will do the right thing (store a line number as the search string) and C-c C-o (i.e. M-x org-open-at-point RET) will open the file and go to this line number.

You can of course check for other modes and/or conditions.

Upvotes: 7

elemakil
elemakil

Reputation: 3811

An elisp beginner myself I though of it as a good exercise et voila:

Edit: Rewrote it using the format methode, but I still think not storing it to the kill-ring is less intrusive in my workflow (don't know about you). Also I have added the capability to add column position.

(defvar current-file-reference ""  "Global variable to store the current file reference")

(defun store-file-line-and-col ()
  "Stores the current file, line and column point is at in a string in format \"file-name:line-number-column-number\". Insert the string using \"insert-file-reference\"."
  (interactive)
  (setq current-file-reference (format "%s:%d:%d" (buffer-file-name) (line-number-at-pos) (current-column))))
(defun store-file-and-line ()
  "Stores the current file and line oint is at in a string in format \"file-name:line-number\". Insert the string using \"insert-file-reference\"."
  (interactive)
 (setq current-file-reference (format "%s:%d" (buffer-file-name) (line-number-at-pos))))

(defun insert-file-reference ()
  "Inserts the value stored for current-file-reference at point."
  (interactive)
  (if (string= "" current-file-reference)
      (message "No current file/line/column set!")
    (insert current-file-reference)))

Not tested extensively but working for me. Just hit store-file-and-line or store-file-line-and-col to store current location and insert-file-reference to insert the stored value at point.

Upvotes: 0

Related Questions