emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Small patch to restrict syntactic context where [[links]] are active
@ 2010-07-24 23:39 Paul Sexton
  2010-07-26  6:08 ` Paul Sexton
  0 siblings, 1 reply; 2+ messages in thread
From: Paul Sexton @ 2010-07-24 23:39 UTC (permalink / raw)
  To: emacs-orgmode

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)

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Small patch to restrict syntactic context where [[links]] are active
  2010-07-24 23:39 Small patch to restrict syntactic context where [[links]] are active Paul Sexton
@ 2010-07-26  6:08 ` Paul Sexton
  0 siblings, 0 replies; 2+ messages in thread
From: Paul Sexton @ 2010-07-26  6:08 UTC (permalink / raw)
  To: emacs-orgmode

Paul Sexton <psexton <at> xnet.co.nz> writes:


Unfortunately this doesn't seem to work as well as I thought. For some reason 
when org-bracket-link-context-ok is called, (point) is not at the end of the
link, despite the fact that the docs for re-search-forward state that is where
the point should be. Without a way to get the position at the end of the match,
the context stuff does not work correctly.

(the stuff activating org links outside org mode still works however.)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-07-26  6:09 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-24 23:39 Small patch to restrict syntactic context where [[links]] are active Paul Sexton
2010-07-26  6:08 ` Paul Sexton

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).