diff --git a/org-link-minor-mode.el b/org-link-minor-mode.el new file mode 100644 index 0000000..0aa951e --- /dev/null +++ b/org-link-minor-mode.el @@ -0,0 +1,57 @@ +;;; org-link-minor-mode.el -- Enable org-mode bracket links in non-org modes +;; +;; Copyright (C) 2012 +;; Author: Sean O'Halpin +;; +;; Enables org-mode bracket links of the form: +;; +;; [[http://www.bbc.co.uk][BBC]] +;; [[org-link-minor-mode]] +;; +;; Note that =org-toggle-link-display= will also work when this mode +;; is enabled. +;; + +(require 'org) + +(define-minor-mode org-link-minor-mode + "Toggle display of org-mode style bracket links in non-org-mode buffers." + :lighter " org-link" + + (save-excursion + (save-match-data + (let ((org-link-minor-mode-keywords + (list '(org-activate-bracket-links (0 'org-link t))))) + (goto-char (point-min)) + (if org-link-minor-mode + (if (derived-mode-p 'org-mode) + (progn + (message "org-mode doesn't need org-link-minor-mode") + (org-link-minor-mode -1) + ) + (font-lock-add-keywords nil org-link-minor-mode-keywords t) + (org-set-local 'org-descriptive-links 'org-descriptive-links) + (if org-descriptive-links (add-to-invisibility-spec '(org-link))) + (org-set-local 'font-lock-unfontify-region-function + 'org-unfontify-region) + (org-restart-font-lock) + ) + (unless (derived-mode-p 'org-mode) + (progn + (font-lock-remove-keywords nil org-link-minor-mode-keywords) + (org-remove-from-invisibility-spec '(org-link)) + (while (re-search-forward org-bracket-link-regexp nil t) + (with-silent-modifications + (org-unfontify-region (match-beginning 0) (match-end 0)) + ) + ) + (org-restart-font-lock) + ) + ) + ) + ) + ) + ) + ) + +(provide 'org-link-minor-mode) diff --git a/org-link-minor-mode.org b/org-link-minor-mode.org new file mode 100644 index 0000000..b27da5c --- /dev/null +++ b/org-link-minor-mode.org @@ -0,0 +1,198 @@ +#+TITLE: org-link-minor-mode +#+SETUPFILE: ~/org/setup2.org +#+PROPERTY: eval never +#+COMMENT: comments noweb +#+LINK: elisp http://www.gnu.org/software/emacs/manual/html_node/elisp/%s.html + +* Header +:PROPERTIES: +:ID: 14f6023b-6e29-4266-82f2-d227902d4cf7 +:END: + +#+name: header-comments +#+begin_src emacs-lisp +;;; org-link-minor-mode.el -- Enable org-mode bracket links in non-org modes +;; +;; Copyright (C) 2012 +;; Author: Sean O'Halpin +;; +;; Enables org-mode bracket links of the form: +;; +;; [[http://www.bbc.co.uk][BBC]] +;; [[org-link-minor-mode]] +;; +;; Note that =org-toggle-link-display= will also work when this mode +;; is enabled. +;; +#+end_src + +* Require org-mode +:PROPERTIES: +:ID: 0e3b4960-cc9f-4ebe-9acf-c6632b3c68f2 +:END: + +As we rely on many =org-mode= functions, to avoid warnings, we +load =org-mode=: + +#+name: requires +#+begin_src emacs-lisp +(require 'org) +#+end_src + +* Using the =define-minor-mode= macro +:PROPERTIES: +:ID: 2e643e2a-acb4-43dd-92b3-d8048f66f854 +:END: + +The simplest way to define a new minor mode is to use +the [[elisp:Defining-Minor-Modes][=define-minor-mode=]] macro: + +#+name: define-minor-mode +#+begin_src emacs-lisp :noweb tangle + (define-minor-mode org-link-minor-mode + "Toggle display of org-mode style bracket links in non-org-mode buffers." + :lighter " org-link" + + «body» + ) +#+end_src + +To save the current buffer's state and the current match state, we +wrap the body of the function in =save-excursion= and =save-match-data=: + +#+name: body +#+begin_src emacs-lisp :noweb tangle + (save-excursion + (save-match-data + «inner-body» + ) + ) +#+end_src + +* The body +:PROPERTIES: +:ID: 4e5b0abe-bc41-43f6-9271-b6365a7b5bce +:END: + +#+name: inner-body +#+begin_src emacs-lisp :noweb tangle + (let ((org-link-minor-mode-keywords + (list '(org-activate-bracket-links (0 'org-link t))))) + (goto-char (point-min)) + (if org-link-minor-mode + «enter-minor-mode» + «exit-minor-mode» + ) + ) +#+end_src + +* Entering the minor mode +:PROPERTIES: +:ID: a1b76a00-4444-4b5c-bbfa-54c88dac769f +:END: + +We first test if we're already in org-mode and if so display an +informational message and switch =org-link-minor-mode= off. We need to +do it this way as by this point we've already entered the mode. + +#+name: enter-minor-mode +#+begin_src emacs-lisp :noweb tangle + (if (derived-mode-p 'org-mode) + (progn + (message "org-mode doesn't need org-link-minor-mode") + (org-link-minor-mode -1) + ) + «enter-minor-mode-body» + ) +#+end_src + +* Turning on org-link highlighting +:PROPERTIES: +:noweb-ref: enter-minor-mode-body +:ID: 8d3990a4-ee3b-4276-9a6b-53665c095133 +:END: + +Add the font-lock specification +#+begin_src emacs-lisp + (font-lock-add-keywords nil org-link-minor-mode-keywords t) +#+end_src + +Enable =org-toggle-link-display= for this buffer only (by +making =org-descriptive-links= buffer local). This is the variable used +by =org-toggle-link-display=. +#+begin_src emacs-lisp + (org-set-local 'org-descriptive-links 'org-descriptive-links) + (if org-descriptive-links (add-to-invisibility-spec '(org-link))) +#+end_src + +This is the magic that makes the link body appear if you backspace +into it (or use replace to make it no longer a link): +#+begin_src emacs-lisp + (org-set-local 'font-lock-unfontify-region-function + 'org-unfontify-region) +#+end_src + +Finally, we refontify the buffer using org's own method: +#+begin_src emacs-lisp + (org-restart-font-lock) +#+end_src + +* Exiting the minor mode +:PROPERTIES: +:ID: 95c5162b-ec40-4bb7-849c-f10d12185b29 +:END: + +Again, we don't run this code if we're already in org-mode. +#+name: exit-minor-mode +#+begin_src emacs-lisp :noweb tangle + (unless (derived-mode-p 'org-mode) + (progn + «exit-minor-mode-body» + ) + ) +#+end_src + +* Exit minor mode body +:PROPERTIES: +:noweb-ref: exit-minor-mode-body +:ID: a555c274-844a-4913-91e0-6be72a1911e1 +:END: + +Remove all org-link properties (without setting buffer-modified-p): +#+begin_src emacs-lisp + (font-lock-remove-keywords nil org-link-minor-mode-keywords) + (org-remove-from-invisibility-spec '(org-link)) + (while (re-search-forward org-bracket-link-regexp nil t) + (with-silent-modifications + (org-unfontify-region (match-beginning 0) (match-end 0)) + ) + ) +#+end_src + +Restore existing font lock highlighting +#+begin_src emacs-lisp + (org-restart-font-lock) +#+end_src + +* Provide +:PROPERTIES: +:ID: 317688ba-da16-4a42-9e4f-20b06a8d86cf +:END: + +#+name: provide +#+begin_src emacs-lisp +(provide 'org-link-minor-mode) +#+end_src + +* Complete source + +#+name: source +#+begin_src emacs-lisp :tangle org-link-minor-mode.el :noweb yes :padline no +«header-comments» + +«requires» + +«define-minor-mode» + +«provide» +#+end_src