README for Tools

Tool classes can be added in this directory.  One file per Tool.  The
file name must match with the class name!

For examples see the existing files.

Some Tools are meta-tools, they can start a whole bunch of different programs.
E.g., ActionViewer uses the ":do view" actions defined in recipes.

When the Tool runs an external program, it is possible that the user exits the
program.  Then next time a file is referred to (e.g., with an open() call) the
external program should be restarted.  It's the responsibility of the Tool to
notice the program has exited.


Class interface
---------------

These are functions you can call to check out properties of the tool class,
start a tool, list of running tools, etc.  This is not related to one specific
tool instance.

getProperties()		Returns a dictionary with properties that the Tool
			normally supports.
			See PROPERTIES below for the possible properties.
			An instantiated tool may have slightly different
			properties.

canDoActions(item, type)
			Returns a dictionary with one entry for each action
			that the tool could perform.  The value of the entry
			is a percentage that indicates how well this tool
			will be able to handle the action on ActyItem "item"
			of filetype "type".
			Useful info is item.node.  If it is None the item is
			not a kind of file.  Otherwise the file name is
			item.node.name.

			percentages:
				0	I can't
				10	If nobody else can...
				50	OK
				80	I'm good at this
				100	Nobody else can do it better
			Note: the user may overrule the percentages by setting
			his preferences.

			actions:
				edit		editing
				view		viewing (read-only)
				build		building
				debug		debugging a program
				execute		run the item (in a window)
				analyze		return tree of items and types
				search_one	search for specific items in a
						file
				search_list	search for specific items in a
						list of files

openItem(item, topmodel, lnum = None, off = None)
			Instantiate a tool and open ActyItem "item" in it.
			Optionally position cursor at line "lnum" or "off"
			characters into the file.


Object interface
----------------

These are functions that apply to a specific tool instance.

Note that a tool instance may exist even though the external program that it
started has exited already.  It's also possible that the external program
keeps on running while the tool has been deleted.

getProperties(self)	Returns a dictionary with properties that the Tool
			supports.  Just like getProperties() of the class, but
			specifically for the running Tool.

			See PROPERTIES below for the possible properties.

close(self, shutdown)
			Close this tool.
			If "shutdown" is non-zero the IDE is about to exit.
			Although this may be aborted and we continue anyway.
			Must return a non-zero value if closing is OK, zero
			otherwise.

foreground(self, item, node = None)
			Bring the tool to the foreground.
			If "item" isn't None open this ActyItem.
			Otherwise, if "node" isn't None open this node.
			If both "item" and "node" are None bring the tool to
			the foreground without changing the current item.

openItem(self, item, lnum = None, col = None, off = None)
			Open ActyItem "item" in this Tool.  Only to be used
			to edit an item in an already running tool.
			Optionally position cursor at line "lnum" and column
			"col" or offset "off" characters into the file.
			Actually showing "item" may be postponed until the
			foreground() function is invoked for this item.
			Only used when the tool has the "mdi" property.

reload(self, item, node = NOne)
			Reload the item/node, it was changed outside of this
			Tool.
			Only when the tool has the "start_send" or
			"start_talk" property.

goto(self, item, node = None, lnum = None, col = None, off = None)
			If "item" isn't None open this ActyItem.
			Otherwise, if "node" isn't None open this node.
			Move the cursor to line "lnum" column "col" or
			character offset "off".
			Only when the tool has the "set_position" property.

showPC(self, item, node = None, lnum = None, col = None, off = None, show = 1)
			Place a PC marker at the specified position.  When
			"show" is zero remove the marker.
			If "item" isn't None use this ActyItem.
			Otherwise, if "node" isn't None use this node.
			Put/remove the marker at line "lnum" column "col" or
			character offset "off".
			Only when the tool has the "show_pc" property.

showBalloon(self, text)
			Show "text" in a balloon at the mouse pointer
			position.  The balloon is to be removed as soon as the
			mouse moves (more than a few pixels).
			See BALLOON EVAL below.
			Only when the tool has the "show_balloon" property.

evalText(self, func, text)
			Evaluate "text".  If the result is valid, call func
			with the resulting text as argument.  Both "text"
			and the result are strings.
			See BALLOON EVAL below.
			Only when the tool has the "eval_text" property.

displayBreakpoint(self, what, breakpoint)
			Update a breakpoint.  "what" can be one of these:
			   "new"	display a new breakpoint
			   "upd"	update an existing breakpoint
			   "del"	delete an existing breakpoint
			"breakpoint" is an instance of the Tool.Breakpoint
			class, see BREAKPOINTS below.
			Only when the tool has the "update_breakpoint"
			property.

getBreakpoints(self, node)
			Returns a list of breakpoints for Node "node".  Used
			for a debugger tool.
			Each item in the list is a Tool.Breakpoint object,
			such as passed to displayBreakpoint().
			Only when the tool has the "get_breakpoints" property.

enableEval(self)
			Enable debugger evaluation callbacks.
			Only when the tool has the "eval_callback" property.

evaluate(self, expr)	Evaluate "expr" and return the result.
			Only when the tool has the "debug_eval" property.


Generic Tools
-------------

Two generic tools are provided for start_async and start_sync kind of tools.
These use the actions defined in A-A-P recipes.  The user can add programs by
defining actions in his startup recipes.


Communication
-------------

The tools can use any form of communication with external programs.  The idea
is that the IDE communicates with all tools, but tools don't communicate
between each other directly.

When a new form of communication is needed, using the generic communication
layers provided is recommended:

	CommMesg.py	Message passing support.  A message is a byte string,
			it is easy to use in all programming languages.

	CommConn.py	Connection layer.  Methods for sending messages over
			various channels (pipes, sockets, windows message,
			etc.)

Callbacks
---------

A Tool may want to report back activities carried out in the tool.

Tool.savedFile(topmodel, node)
			The Tool saved file "node".
			When the file was a temp copy (URL editing) it will be
			transported.

Tool.evaluate(expr, node)
			Request evaluation of "expr" for "node".  Used by an
			editor that

Tool.gotoItem(topmodel, item, lnum = None, col = None, off = None)
			View "item" and position the cursor at the specified
			lnum/col or off.
			"topmodel" must be the AIDE instance.

Tool.gotoFile(topmodel, acty, fname, lnum = None, col = None, off = None)
			View file "fname", otherwise like Tool.gotoItem().
			"acty" is the activity to which a newly created item
			is added.

Tool.showPCItem(topmodel, item, lnum = None, col = None, off = None, show = 1)
			Like gotoItem(), but instead of positioning the cursor
			mark the line as the position of the PC (Program
			Counter).
			If "show" is zero the PC remove the mark.
			Used for a debugger.

Tool.showPCFile(topmodel, acty, fname, lnum = None, col = None, off = None,
								     show = 1)
			Like gotoIFile(), but instead of positioning the
			cursor mark the line as the position of the PC
			(Program Counter).
			If "show" is zero the PC remove the mark.
			Used for a debugger.

Tool.debugEvalText(tool, text)
			Finds a debugger with the "eval_text" property and
			calls its evalText() function.  If the result is not
			empty tool.showBalloon() is called for it.
			When several debuggers are running the result might be
			unpredictable...
			See BALLOON EVAL below.

Tool.toolOpenedFile(tool, name)
			Register that "tool" is editing file "name".  If there
			already is a node for the file it is returned.
			Otherwise a node is created (not associated to any
			Activity) and this is returned.

Tool.getBreakpoints(node)
			Return all breakpoints in "node" from tools that
			have the "get_breakpoints" property.

Tool.updateBreakpoints(tool, node)
			Find out what breakpoints are defined for "node" by
			calling getBreakpoints() for all tools that have the
			"get_breakpoints" property.  It then invokes
			tool.display_breakpoint("new", bp) to notify the
			editor of breakpoint "bp".  Called by an editor that
			just opened "node".

Tool.setBreakpoint(what, node, enable, lnum = None, col = None, off = None)
			Set a breakpoint for "node".
			"what" can be:
				"new"	create new breakpoint
				"del"   remove existing breakpoint
				"upd"	enable/disable existing breakpoint
			All tools that have the "set_breakpoint" property will
			be found and their setBreakpoint() function called.

PROPERTIES
----------

Unless otherwise noted, the presence of an entry indicates the feature is
supported.  The value is "1" then.

start_async		Program is started and that's it.  No communication
			possible or even checking that it still runs.
start_sync		Program starts, runs and exits.  The tool waits for it
			to finish.
start_send		Can check if the program is still running and send
			commands to the running program.  Minimally supported
			is telling the program to exit.
start_talk		Bidirectional communication with the program.  It will
			also send messages back asynchronously (e.g.,.

mdi			Can edit several files in one tool instance.  Without
			this property a new tool is started for every file.
one_instance		Can only instantiate one of this Tool.

open_url		List of URL types that the tool can open file by
			itself (if not, a temporary file copy will be passed)
			Possible types: http, ftp, scp, cvs.

set_position		Can position the cursor at a position in the file.
			Requires the goto() function.
set_view		Can position the view at a position in the file.
get_position		Can obtain the cursor position in the file.
get_view		Can obtain the view position in the file.

show_pc			Can show a marker at the PC position (Program
			Counter).  Used for a debugger.  Requires the
			showPC() function.

show_balloon		Can show a balloon text at the mouse pointer position.
			Requires the showBalloon() function.

eval_text		Can evaluate text and return the value.  Requires
			the evalText() function.

display_breakpoint	Can show a marker at a breakpoint position.  Used for
			an editor of viewer.  Requires the displayBreakpoint()
			function.

get_breakpoints		Can return a list of breakpoints.  Used for a
			debugger.  Requires the getBreakpoints() function.

set_breakpoint		Can place a breakpoint.  Used for a debugger.
			Requires the setBreakpoint() function.

edit_text		Can insert/delete text in the edited file.
edit_report		Can report text changes.
edit_block		Can block editing areas of the text.

mark_set		Can set and display markers in the text (for edit and
			view).

debug_eval		Debugger: Can evaluate expressions and return the
			result.
eval_callback		Editor/Viewer: can request expression evaluation.



BREAKPOINTS
-----------

The usual setup for debugging is to have one tool run the debugger and another
tool edit or view the source code.  This makes it possible to use various
debuggers with various editors and viewers.

Below we will refer to editors only, viewers may be used in the same way.

For flexibility, it is possible to debug several programs at the same time.
E.g., two programs that communicate through a socket.
And it is possible to use several editors, e.g., one for a Python file and
another for C code.

This is how all these tools work together to set and display breakpoints:

- The debugger tool maintains a list of breakpoints in that debugger.  It
  supports the "get_breakpoints" property and defines the getBreakpoints()
  function.
 
- The editor displays breakpoints in edited files.  It supports the
  "display_breakpoint" property and defines the displayBreakpoint() function.

- When a debugger notices a change in the breakpoints it calls
  item.displayBreakpoint().  "item" is the ActyItem for the breakpoint.
  This function will pass the change on to every editor that is displaying the
  item by calling its displayBreakpoint() function.

- When an editor opens another file, it first invokes Tool.toolOpenedFile() to
  register it is editing the item.  Then it invokes Tool.updateBreakpoints().
  This function will find out what breakpoints are defined for the file and
  call back the displayBreakpoint() function of the editor.

- When an editor gets a command from the user to add/remove/enable/disable a
  breakpoint, it calls Tool.setBreakpoint().  This function will find all
  tools that support the "set_breakpoint" property and invoke their
  setBreakpoint() function.

The Tool.Breakpoint class is used to store information about a breakpoint:

   bp.fname	File name of the file (absolute path).
   bp.item	ActyItem of the file.  Can be None when the file is unknown
		(which means the breakpoint will never be displayed in an
		editor).
   bp.lnum	Line number in the file (starting with one) or None.
   bp.col	Column in "lnum" (starting with zero) or None.
   bp.off	Character offset in the file (starting with zero) or None.
   		Line breaks also count as characters
   bp.enable	True or false; when false the breakpoint is set but not
   		active.
   bp.debugger	The debugger tool where this breakpoint is defined.
   bp.ID	Unique ID of the breakpoint within bp.debugger.  Type is
   		undefined but "bp1.ID == bp2.ID" can be used to compare it.

   "lnum" or "off" is always present.


BALLOON EVAL

This feature allows the user to point the mouse at a word and get the value of
that word displayed in a balloon.  This works for a file that is being
debugged.

The editor waits for the mouse pointer to rest on a word and grabs the this
word.  The editor may also use text that the user selected.  This text is
passed to Tool.debugEvalText(), which will find a debugger that can evaluate
the text.  The debugger is then told to call the showBalloon() function of the
editor to display the result.
