#+END_SRC
Let us make a helm function to insert a label link. This will help you enter unique labels.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el
(defun org-ref-helm-insert-label-link ()
- "Insert a label link. helm just shows you what labels already exist."
+ "Insert a label link. helm just shows you what labels already exist.
+If you are on a label link, replace it."
(interactive)
(let* ((labels (org-ref-get-labels))
(cb (current-buffer)))
(helm :sources `(((name . "Existing labels")
(candidates . ,labels)
+ ;; default action is to open to the label
(action . (lambda (label)
;; unfortunately I do not have markers here
- (org-open-link-from-string (format "ref:%s" label)))))
+ (org-open-link-from-string (format "ref:%s" label))))
+ ;; if you select a label, replace current one
+ (action . (lambda (label)
+ (switch-to-buffer ,cb)
+ (cond
+ ;; no prefix or on a link
+ ((equal helm-current-prefix-arg nil)
+ (let* ((object (org-element-context))
+ (last-char (save-excursion
+ (goto-char (org-element-property :end object))
+ (backward-char)
+ (if (looking-at " ")
+ " "
+ ""))))
+ (when (-contains? '("label")
+ (org-element-property :type object))
+ ;; we are on a link, so replace it.
+ (setf
+ (buffer-substring
+ (org-element-property :begin object)
+ (org-element-property :end object))
+ (concat
+ (replace-regexp-in-string
+ (org-element-property :path object)
+ label
+ (org-element-property :raw-link object))
+ last-char)))))
+ ;; no prefix options defined
+ ))))
+ ;; no matching selection creates a new label
((name . "Create new label")
(dummy)
+ ;; default action creates a new label, or replaces old one
(action . (lambda (label)
(switch-to-buffer ,cb)
- (insert
- (concat
- "label:"
- (or label
- helm-pattern))))))))))
+ (let* ((object (org-element-context))
+ (last-char (save-excursion
+ (goto-char (org-element-property :end object))
+ (backward-char)
+ (if (looking-at " ")
+ " "
+ ""))))
+ (if (-contains? '("label")
+ (org-element-property :type object))
+ ;; we are on a link, so replace it.
+ (setf
+ (buffer-substring
+ (org-element-property :begin object)
+ (org-element-property :end object))
+ (concat
+ (replace-regexp-in-string
+ (org-element-property :path object)
+ helm-pattern
+ (org-element-property :raw-link object))
+ last-char))
+ ;; new link
+ (insert
+ (concat
+ "label:"
+ (or label
+ helm-pattern))))))))))))
#+END_SRC
Now we create the completion function. This works from the org-machinery, e.g. if you type C-c C-l to insert a link, and use completion by pressing tab.
Another alternative ref insertion is to use helm.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el
(defun org-ref-helm-insert-ref-link ()
"Helm menu to insert ref links to labels in the document.
-Use C-u to insert a different kind of ref link."
+If you are on link, replace with newly selected label.
+Use C-u to insert a different kind of ref link.
+"
(interactive)
(let* ((labels (org-ref-get-labels))
(contexts (mapcar 'org-ref-get-label-context labels))
(cb (current-buffer)))
- (helm :sources `(((name . "Available labels to ref")
+ (helm :input (thing-at-point 'word)
+ :sources `(((name . "Available labels to ref")
(candidates . ,(loop for label in labels
for context in contexts
-;; we do some kludgy adding spaces and bars to make it "easier" to see in helm.
+ ;; we do some kludgy adding spaces
+ ;; and bars to make it "easier" to
+ ;; see in helm.
collect (cons (concat
label "\n"
(mapconcat
(split-string context "\n")
"\n"
) "\n\n") label)))
+ ;; default action to replace or insert ref link.
(action . (lambda (label)
(switch-to-buffer ,cb)
- (insert
- (concat
- (if helm-current-prefix-arg
- (helm :sources '((name . "Ref link types")
- (candidates . ("ref" "eqref" "pageref" "nameref"))
- (action . (lambda (x) x))))
- "ref")
- ":" label)))))))))
+
+ (cond
+ ;; no prefix or on a link
+ ((equal helm-current-prefix-arg nil)
+ (let* ((object (org-element-context))
+ (last-char (save-excursion
+ (goto-char (org-element-property :end object))
+ (backward-char)
+ (if (looking-at " ")
+ " "
+ ""))))
+ (if (-contains? '("ref" "eqref" "pageref" "nameref")
+ (org-element-property :type object))
+ ;; we are on a link, so replace it.
+ (setf
+ (buffer-substring
+ (org-element-property :begin object)
+ (org-element-property :end object))
+ (concat
+ (replace-regexp-in-string
+ (org-element-property :path object)
+ label
+ (org-element-property :raw-link object))
+ last-char))
+ ;; insert a new link
+ (insert
+ (concat
+ "ref:" label))
+ )))
+ ;; one prefix, alternate ref link
+ ((equal helm-current-prefix-arg '(4))
+ (insert
+ (concat
+ (helm :sources '((name . "Ref link types")
+ (candidates . ("ref" "eqref" "pageref" "nameref"))
+ (action . (lambda (x) x))))
+ ":" label)))
+ ))))))))
#+END_SRC
#+RESULTS:
(progn
(forward-line 4)
(point)))))
-
- ;; maybe we have a CUSTOM-ID
- (org-map-entries
- (lambda () (when (string=
- label
- (org-entry-get (point) "CUSTOM_ID"))
- (throw 'result (org-get-heading)))))
(beep)
(throw 'result "!!! NO CONTEXT FOUND !!!"))))
(link-string (org-element-property :path object))
(link-string-beginning)
(link-string-end))
-
(save-excursion
(goto-char (org-element-property :begin object))
(search-forward link-string nil nil 1)
(setq link-string-beginning (match-beginning 0))
(setq link-string-end (match-end 0)))
+ ;; make sure we are in link and not before the :
+ (when (> link-string-beginning (point))
+ (goto-char link-string-beginning))
+
;; now if we have comma separated bibliographies
;; we find the one clicked on. we want to
;; search forward to next comma from point
(save-excursion
- (goto-char link-string-beginning)
(if (search-forward "," link-string-end 1 1)
(setq key-end (- (match-end 0) 1)) ; we found a match
(setq key-end (point)))) ; no comma found so take the point
+
;; and backward to previous comma from point
(save-excursion
- (goto-char link-string-beginning)
(if (search-backward "," link-string-beginning 1 1)
(setq key-beginning (+ (match-beginning 0) 1)) ; we found a match
(setq key-beginning (point)))) ; no match found
C-u C-u will change the key at point to the selected keys.
"
- (let* ((object (org-element-context)))
+ (let* ((object (org-element-context))
+ (last-char (save-excursion
+ (goto-char (org-element-property :end object))
+ (backward-char)
+ (if (looking-at " ")
+ " "
+ ""))))
(cond
;; case where we are in a link
((and (equal (org-element-type object) 'link)
(insert (concat "," (mapconcat 'identity keys ","))))
;; double prefix, replace key at point
((equal helm-current-prefix-arg '(16))
- (message-box "Replacing %s with %s"
- (car (org-ref-get-bibtex-key-and-file))
- (mapconcat 'identity keys ","))
(setf (buffer-substring
(org-element-property :begin object)
(org-element-property :end object))
(org-element-property :raw-link object)
)
;; replace space at end to avoid collapsing into next word.
- " ")))
+ last-char)))
(t
- (message-box "Not found"))))
+ (message "Not found"))))
;; We are next to a link, and we want to append
;; next to a link means one character back is on a link.
(-contains?
org-ref-cite-types
(org-element-property :type (org-element-context)))))
- ;;(message-box "at end of a link")
- ;; (goto-char (org-element-property :end object))
(while (looking-back " ") (backward-char))
(insert (concat "," (mapconcat 'identity keys ","))))
(setq helm-bibtex-format-citation-functions
'((org-mode . helm-bibtex-format-org-ref)))
-(defun org-ref-helm-insert-cite-link ()
- "org-ref function to use helm on the bibliography defined in the org-file."
- (interactive)
- (let ((helm-bibtex-bibliography (org-ref-find-bibliography)))
- (helm-bibtex)))
+(defun org-ref-helm-insert-cite-link (arg)
+ "org-ref function to use helm-bibtex to insert a citation link.
+With one prefix arg, insert a ref link.
+With two prefix args, insert a label link."
+ (interactive "P")
+ (cond
+ ((equal arg nil)
+ (let ((helm-bibtex-bibliography (org-ref-find-bibliography)))
+ (helm-bibtex)))
+ ((equal arg '(4))
+ (org-ref-helm-insert-ref-link))
+ ((equal arg '(16))
+ (org-ref-helm-insert-label-link))))
(require 'helm-bibtex)