Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

(editor-independent) function list, find function definition


  • Please log in to reply
6 replies to this topic
urlwolf
  • Members
  • 150 posts
  • Last active: Feb 26 2012 07:56 PM
  • Joined: 16 Mar 2006
This is my plea for ctags supporting ahk.
I have posted about it before, but I have reworded it here and make it evident why we may need it.

Let's face it, ahk is no longer used to do short scripts and little hacks. Many people here are plowning through 1000's of lines of code.

examples:
BBcode editor has this structure:
main.ahk
functions.ahk
hotkeys.ahk
BBCodeEditor.ahk
BBCodePreview.ahk

Would you like to 'teleport' just doubleclicking on a funciton in the file 'main' to where it's defined in 'functions'?
Me too.

Sometimes all functions you care for are on a single file, but it's a pain to move back and forth between them. An example of this is Isense.

There are many libraries out there, and the use of #include is more and more common.

So finding where a function is defined quickly and coming back to where you were is really important.

Let's recap:

Scripts are getting longer
People started sharing libraries and most scripts have #includes
People spend more time reading code written by others

These situations make the use of tags a very wise decision.

NOTE: there's a pure ahk implementation of this idea for notepad++ without using tags by Xander. It is still only for Notepad++, and not very sophisticated: it won't work for variables for example. It's a quick and dirty "open declaration" script, ctags would be the real thing.

Now, this won't be any good if your editor doesn't understand ctags.
But there are many editors that support ctags.

Notepad++,Crimson Editor, EditPlus or UltraEdit:
<!-- m -->http://openctags.sourceforge.net/<!-- m -->

OpenCTags will help you when you write code in big projects and you need a quick reference to keywords (classes, variables, structures, #define) in your project. It may be used as an autocomplete feature or to navigate throw your sources to reach the definition of your keyword. It keeps navigation history so you can easily go back and forth throw your code


PSPad seems not interested in implementing them.

Of course all the big ones, slickEdit, mutiEdit2006, vim, emacs, etc support ctags.

Jedit does it too.

What to do next


Someone needs to write a parser for ahk. I'm not sure I'm the best for the job, since last time I used C was 10 years ago, plus there are people in this community who have written parsers/lexers for ahk (savage, PhilLho) and may have an easy time doing this job while I may struggle.

Here's a very interesting post on how the actionscript community got support for its unsupported language.

looks like it's just a matter of adding a few regexps to a parser in c, an recompile;

/*
*   INCLUDE FILES
*/
#include "general.h"	/* must always come first */
#include "parse.h"

/*
*   FUNCTION DEFINITIONS
*
*/

static void installActionScriptRegex (const langType language)
{
	// Functions
    addTagRegex (language, "^[ \t]*[(private|public|static|protected|internal|final|override)( \t)]*function[ \t]+([A-Za-z0-9_]+)[ \t]*\\(([^\\{]*)",
	    "\\1 (\\2", "f,function,functions,methods", NULL);

	// Getters and setters
	addTagRegex (language, "^[ \t]*[(public|static|internal|final|override)( \t)]*function[ \t]+(set|get)[ \t]+([A-Za-z0-9_]+)[ \t]*\\(",
		"\\1 \\2", "p,property,properties", NULL);

	// Variables
	addTagRegex (language, "^[ \t]*[(private|public|static|protected|internal)( \t)]*var[ \t]+([A-Za-z0-9_]+)([ \t]*\\:[ \t]*([A-Za-z0-9_]+))*[ \t]*",
		"\\1 : \\3", "v,variable,variables", NULL);

	// Constants
	addTagRegex (language, "^[ \t]*[(private|public|static|protected|internal)( \t)]*const[ \t]+([A-Za-z0-9_]+)([ \t]*\\:[ \t]*([A-Za-z0-9_]+))*[ \t]*",
		"\\1 : \\3", "v,variable,variables", NULL);

	// Classes
	addTagRegex (language, "^[ \t]*[(private|public|static|dynamic|final|internal)( \t)]*class[ \t]+([A-Za-z0-9_]+)[ \t]*([^\\{]*)",
		"\\1 (\\2)", "c,class,classes", NULL);

	// Interfaces
	addTagRegex (language, "^[ \t]*[(private|public|static|dynamic|final|internal)( \t)]*interface[ \t]+([A-Za-z0-9_]+)[ \t]*([^\\{]*)",
		"\\1 (\\2)", "i,interface,interfaces", NULL);

	// Packages
	addTagRegex (language, "^[ \t]*[(private|public|static)( \t)]*package[ \t]+([A-Za-z0-9_.]+)[ \t]*",
		"\\1", "p,package", NULL);

	// Notes
	addTagRegex (language, "\\/\\/[ \t]*(NOTE|note|Note)[ \t]*\\:*(.*)",
		"\\2", "i,{Notes}", NULL);

	// Todos
	addTagRegex (language, "\\/\\/[ \t]*(TODO|todo|ToDo|Todo)[ \t]*\\:*(.*)",
		"\\2", "i,{To do}", NULL);

	// Prototypes (Put this in for AS1 compatibility...)
    addTagRegex (language, ".*\\.prototype\\.([A-Za-z0-9 ]+)[ \t]*\\=([ \t]*)function( [ \t]?)*\\(",
	    "\\1", "p,prototype", NULL);

}

/* Create parser definition stucture */


extern parserDefinition* ActionScriptParser (void)

{
    static const char *const extensions [] = { "as", NULL };
    parserDefinition *const def = parserNew ("ActionScript");
    def->extensions = extensions;
    def->initialize = installActionScriptRegex;
    def->regex      = TRUE;
    return def;
}

That is... I we have the regexps for ahk, it's just trivial to recompile ctags and make it work with ahk!
The only thing that worries me is that it seems that ahk is a hard to parse language. For example:
AHK can use comma as a parameter delimiter, as expression delimeter and as command delimiter.
This might be trouble, but nothing the people doing lexers haven't faced before.

What do you think?

Tuncay
  • Members
  • 1945 posts
  • Last active: Feb 08 2015 03:49 PM
  • Joined: 07 Nov 2006
Would this work with the stdlib without any #Include directive?

urlwolf
  • Members
  • 150 posts
  • Last active: Feb 26 2012 07:56 PM
  • Joined: 16 Mar 2006

Would this work with the stdlib without any #Include directive?


You have all the source in the site. What'd be the point of removing includes?

Update: there's a way to make ctags work for ahk without recompile. You just add the regex in a config file!

I'm working on this, I'll have my first crappy version soon, then we can refine them.

Tuncay
  • Members
  • 1945 posts
  • Last active: Feb 08 2015 03:49 PM
  • Joined: 07 Nov 2006

What'd be the point of removing includes?

I´ve did not mean to remove any #Include directive. May be you aren´t familiar with the standard library feature where #include directives are not needed? http://www.autohotke...nctions.htm#lib

urlwolf
  • Members
  • 150 posts
  • Last active: Feb 26 2012 07:56 PM
  • Joined: 16 Mar 2006
oh I see. These are not ahk #includes, but c #includes. it was a chunck of c code.

The c code is not vinculates to ahk in any way: it's ctags' code. Ctags is a command line utility that generates the tags.

Still, it looks like you can avoid recompile by adding the ahk-specific regular expressions in the config file ctags.cnf.

Example:

--langdef=autohotkey
--langmap=autohotkey:.ahk
--regex-autohotkey=/^def[ \t]*([a-zA-Z0-9_]+)/\1/d,definition/
--regex-autohotkey=/(^[a-zA-Z0-9_]+\\:\s*$)/\1/l,label/

I just added a very simple construct (def) to test that the regex works. Of course def is not part of the autohotkey language, but it's easy to parse.

So I have a def foo at the beginning of the ahk file just to make sure at least that is parsed, then I play with the actual ahk constructs.

Note, the function regex doesn't work. I'm playing with these right now. If anyone knows a good regex to detect functions, please let me know.

  • Guests
  • Last active:
  • Joined: --
Ok, getting there:

--langdef=autohotkey
--langmap=autohotkey:.ahk
--regex-autohotkey=/(^[ \t]*[a-zA-Z0-9_]+)\:\s*$/\1/l,label/
--regex-autohotkey=/(^[ \t]*[a-zA-Z0-9_]+)[:space:]*\:\=/\1/v,variable/
--regex-autohotkey=/^[ \t]*(NOTE|note|Note)[ \t]*\\:*(.*)/n,note/
--regex-autohotkey=/^[ \t]*([a-zA-Z0-9_]+)[ \t]*\(\)[:space:]*\\{/\1/s,function/

This one gets labels, and vars only when using the := operator to assign them.

The problem is that the comparison operator used in conditionals is the same as the assignment operator (=),so there's ambiguity.

I need to work on the function regex so it matches any number of paramters - currently only () is matched.

I'm sure I'm reinventing the wheel here... these regex must be here in the forums somewhere.

I have looked at Toralf/rajat actove goto. the problem is that in this ctags.cfg we need to get it right with a single line. It's also POSIX regex, a different flavor.

I'm getting there.[/code]

urlwolf
  • Members
  • 150 posts
  • Last active: Feb 26 2012 07:56 PM
  • Joined: 16 Mar 2006
NOTE:
The final thread for this is:
<!-- m -->http://www.autohotke...ic.php?p=169833<!-- m -->

fully working implementation, an example using vim, etc.