Hi Marcelo. Thanks for the thumbs up, its nice when that happens.
So, to your questions - The answers are a bit long, and I'm cc'ing to the list so that others wanting org-action-verb like stuff can understand what it does, and hack it for their needs. * Debugging. I've been coding elisp on and off for years, but I'm no elisp expert. I put org-action-verb together after allot of RTFM, and looking at other code. I debugged it using these methods: + (message). To get an idea about what is going on without having to use the debugger, the message function is handy. It will print whatever to the *messages* buffer. Primitive, but worked for me at the time. + (regexp-builder). For regular expression work there is the built in regular expression builder (M-x regexp-builder) or John Wiegley's excellent (M-x regex-tool), which i only just remembered I have. + (eval-region). I have it mapped to a key, but (M-x eval-region) is great for changing small parts of the compiled elisp, variables or whatever. + (info-lookup-symbol). When poking about in the innards of (X)Emacs, it is always a good idea to have info-lookup-symbol mapped to a key somewhere. I have it mapped to f1. (define-key global-map [f1] 'info-lookup-symbol) It will bring up a buffer showing what the symbol under the cursor does and what file it is defined in (if the symbol is documented). * RTFM - Read the Fine Manual. Other things to read up on to understand org-action-verb: + What brackets do in a regular expression http://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp-Backslash.html#Regexp-Backslash It is also kind of confusing to see "\\" in the code and "\" in the documentation. Some more RTFM may be required :) + What this line of elisp does: (make-overlay (match-beginning 1) (match-end 1) nil t nil) http://www.gnu.org/software/emacs/manual/html_node/elisp/Managing-Overlays.html#Managing-Overlays http://www.gnu.org/software/emacs/manual/html_node/elisp/Simple-Match-Data.html#index-match_002dbeginning-3021 * org-action-verb - what it does. Essentially, all org-action-verb does, is build a bunch of regular expressions to find headlines between 'point' and 'limit' with the correct TODO type. Once it has found a headline that matches, it uses other regular expressions to add or remove the overlay *to the first sub-element* of those regular expressions. The meat of the code from the original org-action-verb with some better comments, will probably provide a better explanation ----------------------- starting at line 189 ;; ;; match the whole headline and remove any previous overlay without ;; moving point. Where point should be at the start of a headline. ;; (if (looking-at "\\(.*\\)$") (remove-overlays (match-beginning 1) (match-end 1) 'org-action-overlay t)) ;; ;; check for the presence of a valid action-verb ;; (if (looking-at todo-action-verbs-regexp) ;; ;; do nothing if the action verb matches ;; nil ;; ;; It is not an action verb, apply the overlay to the first word ;; in the line. ;; ;; The regular expression matches the first word after a space or ;; tab on a matching headline, and applies the org-action-incorrect ;; overlay to it. ;; So: ;; "[ ]+\\(\\<\\w+\\>\\)" ;; ;; in english becomes: ;; ;; - "[ ]+" - Match one or more space or tab (should use :space:). ;; - "\\(" - Open sub expression 1 ;; - "\\<" - Match the empty string, but only at the beginning of a word ;; - "\\w" - Match one or more word-constituent characters ;; - "\\>" - Match the empty string, but only at the end of a word ;; - "\\)" - Close sub expression 1 ;; (if (looking-at "[ ]+\\(\\<\\w+\\>\\)") ;; apply new overlay to 1st matching sub-expression (let ((overlay (make-overlay (match-beginning 1) (match-end 1) nil t nil))) (overlay-put overlay 'org-action-overlay t) (overlay-put overlay 'face 'org-action-incorrect) (overlay-put overlay 'evaporate t) overlay)))) ----------------------- ending at line 202 * What you need to do to fix your problem? I suspect all you need to do is change the matching expression to something like: (let ((tag-keywords-regexp (concat "^\\*+[:space:]+[\\w:space:]+[:space:]+:\\(" tag "\\):$") )) Also you probably want to first match the whole line to remove the overlay, before applying a new one. Hope that helps, Tim. 2009/11/16 Marcelo de Moraes Serpa <celose...@gmail.com>: > Ok, I'm sorry, I actually had to research a little bit more before posting > :) > > Well, what I need to know now is how to make the overlay work. The code to > match is working, but I'm receiving the following error: > > Error during redisplay: (wrong-number-of-arguments match-beginning 0) > > Here's the full code: http://pastie.org/701448 > > (Thanks to Tim O'Calaghan for the original contribution) > > Marcelo. > > Also, how can I debug it? I tried debug-on-entry but it is not working :S > > > On Mon, Nov 16, 2009 at 12:10 PM, Marcelo de Moraes Serpa > <celose...@gmail.com> wrote: >> >> Hello, >> >> I started writing an extension to org that actually applies a custom face >> to an item tagges as CATEGORY or PROJECT. The thing is I'm really having a >> hard time understanding the regexp. The code is adapted from the >> org-action-verb.el by Tim O'Calaghan, basically using the same structure >> since my elisp knowledge is very basic. I have managed to get it to work to >> a basic level, but it is applying the face to the whole tree instead of >> applying to only one item. >> >> (defface org-gtd-default-category-face >> '((((class color) (background light)) (:foreground "purple" :bold t >> :underline t)) >> (((class color) (background dark)) (:foreground "purple" :bold t >> :underline t)) >> (t (:bold t :underline t))) >> "Used by org-color-by-tag for items tagged with :CATEGORY:") >> >> (defface org-gtd-default-project-face >> '((((class color) (background light)) (:foreground "purple" :bold t >> :underline t)) >> (((class color) (background dark)) (:foreground "purple" :bold t >> :underline t)) >> (t (:bold t :underline t))) >> "Used by org-color-by-tag for items tagged with :PROJECT:") >> >> (defvar org-gtd-tags '("PROJECT" "CATEGORY")) >> >> (defun org-font-lock-add-tag-faces (limit) >> "Add the faces to corresponding items depending on the TAG." >> (let (rtn a) >> ;; check variable is set, and buffer left to search >> (when (and (not rtn) org-gtd-tags) >> ;; for each todo/action verb set >> (dolist (tag org-gtd-tags) >> ;; build regexps >> (let ((tag-keywords-regexp >> >> (regexp-opt (cdr tag) 'word))) >> >> ;; while we can find a todo keyword >> (while (re-search-forward ":PROJECT:" limit t) >> ;; check for action verb >> >> >> ;; apply new overlay >> (let ((overlay (make-overlay (match-beginning 1) >> (match-end 1) nil t nil))) >> (overlay-put overlay 'face >> 'org-gtd-default-project-face) >> ;;(overlay-put overlay 'mouse-face mouse-face) >> (overlay-put overlay 'org-action-overlay t) >> (overlay-put overlay 'evaporate t) >> (overlay-put overlay 'help-echo "mouse-2: correct word >> at point") >> overlay) >> >> >> ;; reset search point? >> (backward-char 1))))) >> rtn)) >> >> (org-font-lock-add-tag-faces 10) >> >> (defun org-mode-color-by-tag-hook () >> "Initalise org-color-by-tag." >> (interactive) >> (font-lock-add-keywords nil '((org-font-lock-add-tag-faces))) >> ) >> >> ;; Turn on action verb font locking. >> (add-hook 'org-mode-hook 'org-mode-color-by-tag-hook) >> >> As you can see, I'm in the debug phase, and I'm not even using the list of >> strings (PROJECT CATEGORY) I've created. I'm just trying to search for >> occurrences of the PROJECT tag and trying to apply the face. I've removed >> the regexp string that Tim used, which were: >> >> "^\\*+[ ]+" >> >> Was used here: >> (let ((todo-keywords-regexp >> (concat "^\\*+[ ]+" >> (regexp-opt (car todo) 'words))) >> (todo-action-verbs-regexp >> (concat "[ ]+" (regexp-opt (cdr todo) 'words)))) >> >> >> And: "[ ]+\\(\\<\\w\\w+\\>\\)" >> >> Used in: (looking-at "[ ]+\\(\\<\\w\\w+\\>\\)") >> >> What I want to do is: Search for items tagged as PROJECT or CATEGORY and >> apply the corresponding face to them. >> >> If someone could explain me the role of "[ ]", and w, I would be >> grateful :) >> >> Thanks, >> >> Marcelo. >> > > > _______________________________________________ > Emacs-orgmode mailing list > Remember: use `Reply All' to send replies to the list. > Emacs-orgmode@gnu.org > http://lists.gnu.org/mailman/listinfo/emacs-orgmode > > _______________________________________________ Emacs-orgmode mailing list Remember: use `Reply All' to send replies to the list. Emacs-orgmode@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-orgmode