From mboxrd@z Thu Jan 1 00:00:00 1970 From: Carsten Dominik Subject: Re: Integrating ctags & org mode (patch) Date: Tue, 15 Dec 2009 15:29:07 +0100 Message-ID: References: <2AC5C31A-0ABA-4163-9F4F-9F0D26A6F538@gmail.com> Mime-Version: 1.0 (Apple Message framework v936) Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NKYOw-0001W2-To for emacs-orgmode@gnu.org; Tue, 15 Dec 2009 09:29:23 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NKYOr-0001Tj-1Y for emacs-orgmode@gnu.org; Tue, 15 Dec 2009 09:29:21 -0500 Received: from [199.232.76.173] (port=44027 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NKYOq-0001TR-8W for emacs-orgmode@gnu.org; Tue, 15 Dec 2009 09:29:16 -0500 Received: from postduif.ic.uva.nl ([145.18.40.180]:50471) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NKYOp-0001Bo-S6 for emacs-orgmode@gnu.org; Tue, 15 Dec 2009 09:29:16 -0500 In-Reply-To: <2AC5C31A-0ABA-4163-9F4F-9F0D26A6F538@gmail.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Carsten Dominik Cc: emacs-orgmode@gnu.org, Paul Sexton Another issue is the following: How should we handle export of such links? Maybe we need another function that does not *jump* to the link location, but just returns the file in which the target is, so that the exporters can make use of this? - Carsten On Dec 15, 2009, at 8:20 AM, Carsten Dominik wrote: > Hi Paul, > > I like this very much. But I would like to change the > implementation so that > there will be a hook. Then people can do different things, > including matching tags in source code files etc. > > Would you be interested to turn your way of doing things into a > little add-on > that people could load? I realize that it would be a very small > file because the heavy lifting is done by the tags creating file and > Emacs ctags searches. But it would keep the way open for other ideas. > > If you agree I will make a new hook and interface for this. > > I would be very interested to include the new module (if you write it) > at least as a contributed package, or, if you are willing > to sign the papers with the FSF, in the core. > > - Carsten > > On Dec 15, 2009, at 4:02 AM, Paul Sexton wrote: > >> Hi, >> >> I have managed to get exuberant ctags working with org mode. This >> means that >> plain links [[like this]], instead of defaulting to plain text >> search when no >> match is found in the current file, now look for a matching tag >> <> in >> all your *.org files, and jumps there. >> >> This means your org files all now "seamlessly" talk to each other >> and interlink. >> You can split that monolithic file up into smaller files and the >> plain links >> still work. You can throw a plain link to a topic you know exists >> in another >> file, without having to worry about the format of special inter- >> file links, >> whether you got the directory right, and so on. >> >> Steps: >> >> 1. First you need a small patch to org.el. This is necessary >> because AFAIK there >> is no easy way to customise or advise org's behaviour when opening >> a plain link. >> The patch is at the end of this post. >> >> 2. Next you need to get exuberant ctags from http://ctags.sourceforge.net/ >> There is a windows executable there (a zip file). Many linux >> distributions have >> 'ctags-exuberant' as an installable package in their repositories. >> >> If you are using windows, extract the ctags.zip file into a >> directory somewhere, >> eg C:\emacs23\ctags >> >> 3. Now make a new file called .ctags in your HOME directory. If you >> are not sure >> where this is, evaluate (getenv "HOME") in the emacs scratch buffer. >> >> Put the following 3 lines into this file, then save it: >> >> --langdef=orgmode >> --langmap=orgmode:.org >> --regex-orgmode=/<<([^>]+)>>/\1/d,definition/ >> >> The last line is a regular expression that defines what a tag is in >> orgmode. If >> you don't like my definition based on angle brackets, or you want >> to add other >> destinations as tags, just alter the bit between the first >> two /...slashes.../ >> >> 4. Paste the following into your .emacs file: >> >> (defvar home-dir "/home/paul/") ; replace with your home dir >> >> (defun operating-system () >> (case system-type >> ((windows-nt cygwin) 'windows) >> (darwin 'macos) >> (otherwise 'unix))) >> >> (defvar path-to-ctags >> (case (operating-system) >> (windows "c:/emacs/ctags/ctags.exe") ; or whereever you >> extracted it >> (unix "/usr/bin/ctags-exuberant")) ; wherever it went >> "Path to the CTAGS executable.") >> >> (defun create-tags (dir-name) >> "Create tags file." >> (interactive "DBase directory: ") >> (shell-command >> (format "%s --options=%s/.ctags -f %s/TAGS -e -R %s/*" >> path-to-ctags home-dir dir-name dir-name))) >> >> (global-set-key (kbd "") 'pop-tag-mark) >> >> (defadvice find-tag (before set-org-mark-before-finding-tag >> activate compile) >> "Before trying to find a tag, save our current position on org mark >> ring." >> (save-excursion >> (if (org-mode-p) >> (org-mark-ring-push)))) >> >> 5. Now run create-tags: >> >> M-x create-tags ENTER "/path/to/org/files/" ENTER >> >> create-tags searches all subdirectories as well, and will also >> create tags for >> all source code files that if finds (*.c, *.lisp, *.el, etc). All >> these tags >> will go in one big TAGS file, located in the "base" directory that >> you specify >> as an argument to create-tags. Thus, if you have any large source >> trees in >> subdirectories, create-tags may pause for a few seconds. >> >> 6. Check that the file 'TAGS' is in the right place and is not an >> empty file. >> >> Tags is now ready to use. See below for usage. The first time you >> try and find >> a tag, you will be asked which tags file to use. The right answer >> is the file >> named TAGS which you created with create-tags. >> To avoid being asked this every time you restart emacs, try putting >> this in your >> .emacs: >> >> (add-hook 'org-mode-hook >> (lambda () (visit-tags-table "/path/to/TAGSfile") >> >> Tags are defined in the .ctags file as any text in <> brackets>>. >> (triple angle brackets work too) >> >> When you click on a link "[[foo]]" and org cannot find a matching >> "<>" in >> the current buffer, the tags facility will take over. The file TAGS >> is examined >> to see if the tags facility knows about "<>" in any other >> files. If it >> does, the matching file will be opened and the cursor will jump to >> the position >> of "<>" in that file. >> >> Important commands: >> * M-. >> Press to enter a tag name (default is a string extracted from the >> current cursor position) and then try & jump there. No >> autocompletion yet. >> * C-M-. >> as above, but search term is a regular expression >> * M-x tags-search >> Also searches for a regexp, but searches through the *entire text* of >> all the files that the tags facility knows about. Jumps to the >> first match. >> Then, press M-, to jump to each successive match. >> * M-* "go back" from a tag jump. (note: if you jumped from an org- >> mode buffer, >> your previous position will also have been saved on the org mark >> ring). >> >> Tags mode has no way of knowing when you create new tags. So, any >> new <> targets>> you make after running create-tags will not be in the >> 'TAGS' file & so >> will be unknown to the tags facility. For new tags to make it into >> the TAGS >> file, you need to re-run (create-tags "path") to refresh the file. >> >> You also might want to put (create-tags "/path/to/org/files") in >> your .emacs or >> even "ctags-exuberant -e -R /path/to/org/ &" in your .bashrc or >> equivalent. >> >> There is probably a clever way to re-run create-tags at sensible >> times eg when >> saving an org file, but I haven't looked into it. >> >> Also if someone clever wants to enable tabbed completion when >> prompted for a tag >> name with find-tag: please feel free. >> >> There are other tags programs that interface with emacs, for >> example GNU Global. >> However I believe that to write parsers for new languages like >> orgmode, you have >> to write them in C for most of the other tags programs. With >> exuberant ctags >> it's just a matter of writing a regular expression. >> >> Hope some people find this helpful. >> >> Here is the patch. Sadly the dumb gmane web interface thingy forced >> me to change >> all '<' to '{' and '>' to '}' before I could post this, as it >> accused me of top >> posting. You will therefore need to change them all back. >> >> ----BEGIN PATCH for org.el (delete this line)---- >> 8349,8369c8349,8350 >> { (condition-case nil (eval cmd) >> { ;; ORG-TAGS >> { (error >> { (progn >> { (widen) >> { (condition-case nil (eval cmd) >> { (error >> { ;; No matching link found anywhere in this file >> { ;; See if we can find a tag >> { ;; If so, jump to it >> { (condition-case nil (find-tag path) >> { (error >> { (cond >> { (org-make-new-topics-for-missing-links-p >> { (if (y-or-n-p >> { (format "Topic `%S' not found; >> append to current >> buffer?" >> { path))) >> { (org-append-new-topic path nil)) >> { (t >> { (error "No match found")))))))))))) >> { >> --- >> } (condition-case nil (eval cmd) >> } (error (progn (widen) (eval cmd)))))) >> 8592,8595d8572 >> { ;; ORG-TAGS >> { ((not org-open-link-defaults-to-normal-string-search-p) >> { ;; We don't want to search for a plain text match. >> { (error "No match.")) >> 8651,8682d8627 >> { >> { >> { ;; ORG-TAGS >> { >> { (defvar org-open-link-defaults-to-normal-string-search-p nil >> { "Behaviour when attempting to open a 'thisfile' hyperlink for >> which no >> { EXACT match can be found (i.e. no match in angled brackets, etc). >> { If true (default), exhibit normal org behaviour of doing a search >> for a string >> { matching the link name. >> { If nil, abort the attempt to open the link.") >> { >> { >> { (defvar org-make-new-topics-for-missing-links-p nil >> { "If true, when attempting to follow a 'plain' hyperlink for >> which no precise >> { match is found, offer to append a top-level heading with the same >> name as the >> { hyperlink, to the end of the buffer.") >> { >> { >> { (defun org-append-new-topic (word) >> { (interactive "s") >> { (widen) >> { (end-of-buffer) >> { (newline 2) >> { (insert (format "* <<%s>>" word)) ; <<<>>> to make radio word >> { (backward-char 4) >> { ;;(org-update-radio-target-regexp) >> { (end-of-line) >> { (newline 2) >> { (next-line 2)) >> { >> { >> { >> ----END PATCH (delete this line)---- >> >> >> >> >> _______________________________________________ >> Emacs-orgmode mailing list >> Please use `Reply All' to send replies to the list. >> Emacs-orgmode@gnu.org >> http://lists.gnu.org/mailman/listinfo/emacs-orgmode > > - Carsten > > > - Carsten