emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] Small patch to restrict syntactic context where [[links]] are


From: Paul Sexton
Subject: [Orgmode] Small patch to restrict syntactic context where [[links]] are active
Date: Sat, 24 Jul 2010 23:39:16 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Hi,
I posted a bit of code here a while back which allows org [[links]] and
<<targets>> to be fontified and active in any major mode.

I have been using this with great success in elisp and common lisp source code
files, where it actually works much more smoothly than "linkd mode" (see
emacswiki) which I used previously.

I have become interested in a very cool dialect of lisp called Clojure. Clojure
uses square brackets [ ] for syntax a lot more than other lisps. This sometimes
leads to eg argument lists of functions being fontified as org [[links]].

Fixing this requires a tiny change to 'org-activate-bracket-links' (2 lines),
one helper function and one variable which the user can set per-buffer.

With this, if I have the following code in my .emacs:

(add-hook 'clojure-mode-hook
          (lambda ()
            (setq org-bracket-link-context '(string comment))))

Then org [[links]] will only be recognised when they occur inside a string or
comment (as defined by Clojure mode), rather than messing up function
arglists.


The patch follows (org.el):

 
 (defun org-activate-bracket-links (limit)
   "Run through the buffer and add overlays to bracketed links."
-  (if (re-search-forward org-bracket-link-regexp limit t)
+  (if (and (re-search-forward org-bracket-link-regexp limit t)
+           (org-bracket-link-context-ok))
       (let* ((help (concat "LINK: "
                           (org-match-string-no-properties 1)))
             ;; FIXME: above we should remove the escapes.



The helper function and variable:


(defvar org-bracket-link-context nil
  "Buffer-local Variable that defines the syntactic contexts
where org-style bracketed links should be recognised as such,
provided that they match the regular expression for bracketed
links.
Possible values:
nil     - Any context is acceptable (default).
STRING  - The point is within a 'string'.
COMMENT - The point is within a comment.
OTHER   - The point is outside a string or comment.
A list  - One of the contexts in the list is satisfied. The list must
only contain some combination of the symbols STRING, COMMENT, or OTHER. ")
(make-variable-buffer-local 'org-bracket-link-context)


(defun org-bracket-link-context-ok ()
  "Helper function, called by ORG-ACTIVATE-BRACKET-LINKS. Returns
true if the syntactic context at the point is an acceptable place
to fontify an org bracketed link.  This is decided by checking
the syntactic context against the value of the variable
ORG-BRACKET-LINK-CONTEXT."
  (or (null org-bracket-link-context)
      (let ((context (syntax-ppss-context (syntax-ppss))))
        (cond
         ((eql context org-bracket-link-context)
          t)
         ((eql 'other org-bracket-link-context)
          (null context))
         ((listp org-bracket-link-context)
          (find (or context 'other) org-bracket-link-context))))))


Below I have copied the code that activates org-style links in arbitrary
buffers, in case anyone is interested and missed it.


;; Put all this in your .emacs:

(defface orgl-target-face 
 '((t (:foreground "cyan" :background "royalblue4" :weight normal)))
;;  '((t (:weight bold :box (:line-width 1 :color "red"))))
  "The face used to emphasise org-mode <<targets>>.")
(make-face 'orgl-target-face)
(setq orgl-target-face 'orgl-target-face)


(defvar *orgl-link-abbrevs*
  '((lisp-mode ("defun" . "(defun %s (")
               ("class" . "(defclass %s (")
               ("wwdoc" . "file:../TODO::%s")))
  "Define link abbreviations for each major mode.
The variable contains a list, each element of which has the
form (MAJOR-MODE (ABBREV . EXPANSION) .....)
ABBREV is a short string. Links of the form '[[ABBREV:TEXT]]' will
be expanded into EXPANSION. See the documentation for
org-link-abbrev-alist for more details.")


(defun orgl-do-font-lock (add-or-remove)
  "Add or remove font-lock rules for org hyperlinks."
  (funcall add-or-remove nil '((org-activate-bracket-links (0 'org-link t))))
  (funcall add-or-remove nil `((,org-target-regexp (0 'orgl-target-face t)))))


(defun orgl-enable ()
  "Enable fontification of org-style hyperlinks in the current buffer."
  (interactive)
  ;; The following variable has to be bound to a string, or following links
  ;; will not work.
  ;; There is probably a more elegant solution.
  (unless org-todo-line-tags-regexp
    (set (make-local-variable 'org-todo-line-tags-regexp)
         "DSFSFSFSF_UTTER_NONSENSE_TAG_SDSDFSFDF"))
  (orgl-do-font-lock 'font-lock-add-keywords)
  (font-lock-fontify-buffer)
  ;; Add special link abbreviations.
  (unless org-link-abbrev-alist-local
    (make-local-variable 'org-link-abbrev-alist-local))
  (dolist (pair (cdr (assoc major-mode *orgl-link-abbrevs*)))
    (pushnew pair org-link-abbrev-alist-local)))


(defun orgl-disable ()
  "Disable fontification of org-style hyperlinks in the current buffer."
  (interactive)
  (remove-text-properties
     (point-min) (point-max)
       '(mouse-face t keymap t org-linked-text t
                    invisible t intangible t
                    org-no-flyspell t))
  (orgl-do-font-lock 'font-lock-remove-keywords)
  (font-lock-fontify-buffer)
  ;; Remove special link abbreviations
  (dolist (pair (cdr (assoc major-mode *orgl-link-abbrevs*)))
    (setq org-link-abbrev-alist-local
          (delete pair org-link-abbrev-alist-local))))

;; Example code in .emacs to activate this facility in Python mode:
(add-hook 'python-mode-hook 'orgl-enable)







reply via email to

[Prev in Thread] Current Thread [Next in Thread]