%M \logo [CTAGS] {CTAGS}

%D \module
%D   [       file=t-ctags,
%D        version=2007-02-26,
%D          title=\CONTEXT\ tags(\CTAGS),
%D       subtitle=\CTAGS\ support in \CONTEXT,
%D         author={Aditya Mahajan},
%D           date=\currentdate]
%D

%M \setuphead [section] [page=]
%M \useURL[ctags][http://ctags.sourceforge.net/]
%M \useURL[vim]  [http://www.vim.org]
%M \logo  [VIM] {VIM}
%M \logo  [EMACS] {EMACS}


%D \section Introduction
%D 
%D \CTAGS\ is a program that generates an index of language objects
%D found in a file that allows these objects to be easily located by a
%D text editor. They are tightly integrated with \VIM\ and \EMACS. For
%D large \TEX\ files, \CTAGS\ is very useful to find reference labels.
%D Suppose you are writing a long book or paper, and you want to add
%D reference to an equation. Also suppose all your equation labels start
%D with \type{eq:}. Then in \VIM\ you can type \type{eq:} and press
%D \type{^X^]} and \VIM\ will present you with a pop-up menu showing the
%D different labels that start with \type{eq:}. For long files this can
%D save you a lot of time.
%D
%D Traditionally tags are generated from an external program. However,
%D \CONTEXT's syntax is almost impossible to parse from an external
%D program. Consider the following two cases
%D \starttyping
%D \defineenumeration[problem]
%D \startproblem[tag]
%D blah blah
%D \stopproblem
%D \stoptyping
%D and
%D \starttyping
%D \defineitemgroup[problem]
%D \startproblem[intro]
%D \item blah blah
%D \stopproblem
%D \stoptyping
%D
%D For an external program to correctly parse this, it must be able to
%D understand \TEX. The only program that can understand \TEX\ is \TEX.
%D So, I decided to write \CTAGS\ support for \CONTEXT\ in \CONTEXT. It
%D turned out to be much simpler than expected. So now, one can read
%D \CTAGS\ as \CONTEXT\ tags \mono{:-)}.
%D
%D \section User Guide
%D
%D To use the module simply add 
%D \starttyping
%D \usemodule[ctags]
%D \stoptyping
%D on the top of the file\footnote{This must be done before
%D \type{\everystarttext} is executed. That is either in the environment
%D file or before \type{\starttext} in a file.}. Unfortunately, right
%D now (that is with \PDFTEX), it is not possible to create a file
%D without extension. So, the tags are written to a file
%D \filename{context.tags}. To use this in \VIM, you have to add
%D \starttyping
%D set tags=./tags,tags,context.tags
%D \stoptyping
%D in your \filename{.vimrc} (\filename{_vimrc} on Windows). I do not
%D know how to do something similar in \EMACS. If someone knows, please
%D let me know.
%D
%D This file modifies a core \CONTEXT\ macro, so be careful while using
%D it. It may (although it should not) break in some cases. You have
%D been warned.
%D
%D The rest of the file is self explanatory.


\writestatus  {loading}   {Context CTAGS support Module}

\startmodule[vim]

\unprotect

\newwrite\ctagsfile

\newtoks\everyopenctags
\newtoks\everyclosectags

%D TODO: Find out if we are running \LUATEX, and if we are write to
%D \filename{tags}.

\appendtoks
  \immediate\openout\ctagsfile context.tags
  \immediate\write\ctagsfile{!_TAG_FILE_FORMAT\rawcharacter{9}1}
  \immediate\write\ctagsfile{!_TAG_FILE_SORTED\rawcharacter{9}1}%using sort now
  \immediate\write\ctagsfile{!_TAG_PROGRAM_AUTHOR\rawcharacter{9}Aditya Mahajan}
  \immediate\write\ctagsfile{!_TAG_PROGRAM_NAME\rawcharacter{9}ConTeXt t-ctags module}
\to \everyopenctags

\appendtoks
  \immediate\closeout\ctagsfile
  \executesystemcommand{texmfstart bin:sort -o context.tags context.tags}
\to \everyclosectags

\let\normalwriterefernce\writereference

%D TODO: Make sure that \BIBTEX\ references are not written to the tags file.

\def\ctagswritereference#1% #2#3#4
  {\doifsomething{#1}
    {\doifnot{#1}{+}%We do not want to write + references
      {\immediate\write\ctagsfile{#1\rawcharacter{9}\currentctagsfile \rawcharacter{9}\the\inputlineno}}}%
   \normalwriterefernce{#1}}% #2#3#4

%D \type{\everystarttext} is executed at \type{\startcomponent}. If we
%D have a typical structure
%D \starttyping
%D \startcomponent file
%D \product  file
%D \enviromnent file
%D \stoptyping
%D then \type{\everystarttext} is executed before ctags module is
%D loaded. So, no tags file is generated when executing a module. This
%D is desirable behaviour, since we want the tag file to be rewritten
%D only when compiling product file.

\def\openctags{\the\everyopenctags}

\let\closectags\donothing

\def\doclosectags{\the\everyclosectags}

\startmode[*first]
\appendtoks 
  \openctags
  \let\writereference\ctagswritereference
  \let\closectags\doclosectags
  \to \everystarttext

\appendtoks \closectags \to \everygoodbye
\stopmode

%D It does not seem possible to get the name of the current file being
%D processed. I tried \type{\inputfilename} and \type{\currentfilename}
%D but \type{\inputfilename} always gives the name of the product file,
%D while \type{\currentfilename} always get the name of the environment
%D file. So, I redefine \type{\registerfileinfo} to keep track of the
%D current file. This will only work if you have a proper project
%D structure, and not work with \type{\input}

\let\normalregisterfileinfo=\registerfileinfo

\def\registerfileinfo[#1#2]#3%
  {\doif{#1#2}{begin}
    {\splitctagsfilename{#3}
     \edef\currentctagsfile{\ctagsfilename.\ctagsfilesuffix}}
   \normalregisterfileinfo[#1#2]{#3}}

\def\splitctagsfilename#1
  {\edef\ascii{#1}\convertcommand\ascii\to\ascii%
   \splitstring\ascii\at.\to\ctagsfilename\and\ctagsfilesuffix%
   \lowercasestring\ctagsfilesuffix\to\ctafsfilesuffix%
   \doifnothing\ctagsfilename  {\let\ctagsfilename  \currentctagsfile}%
   \doifnothing\ctagsfilesuffix{\let\ctagsfilesuffix\c!tex}}
 
\def\currentctagsfile{\jobfullname}

\stopmodule
\protect
