Frequently Asked Questions

Last updated: May 2015

This page is a set of Frequently Asked Questions (FAQ) which our support department gets regularly asked. These questions (and answers) include useful tips on getting the best out of CRiSP.

Most of this information can be found in the on-line guides, but the information here is condensed to highlight the tips and tricks which you may have missed in using the product.

If you have a question or request then send a mail message to Foxtrot Systems Ltd

General issues

Q U1. Files which can be removed to reduce disk space usage
Q U2. What are these .FTS files in the help directory ?
Q U3. Improving performance
Q U4. Viewing the Contents window
Q U5. Can I move the config to the C:\ drive

Macro Programming

Q M1. How do I create custom menus?
Q M2. How do I create a bookmark stack?


Q U1. I have a notebook and want to install CRiSP on to it. Unfortunately I do not have a lot of free disk space, and are there any components I can safely remove without reducing functionality ?

A. Yes. There are quite a few things which can trim down the installation size. The biggest components which are mostly unused are the Dictionaries - especially for languages you do not speak, the macro source files, and additional support files such as help.

The dictionaries are stored in the dict/ sub-directory. These amount to over 5MB of disk. You can delete all of them, or all those for the languages you do not need.

If you do not do any macro programming and are not interested in the macros which make CRiSP what it is, delete the directory tree src/crunch. This can save approximately 6MB.

Binaries you can delete include:

Help files for Windows users you can delete:

There are many other files you can delete, but these are significantly smaller than the above list and unless you are really tight on space, the above is probably sufficient.

Q U2. What are these .FTS files in the help directory ?

Files with an extension of .FTS are files used by the help system and are created when you do an indexed search of a help file. The system creates these automatically. You can quite happily remove them - the system will just recreate them the next time you need them.

Under Windows, these files are located in the same directory as the .HLP file. Under Unix, if the directory where the .hlp file resides is not writable by you, then a directory $HOME/.h2h will be created and the .FTS files will be stored there.

Q U3. How can I increase performance when searching large files?

There are a number of aspects to the way CRiSP is used which can affect performance. CRiSP generally automatically handles performance issues for you and there is little need for any fine tuning or manual intervention. For typical files, e.g. less than 1MB, there is little you can do to affect the performance. CPU's are getting faster, memory is cheaper and CRiSP just works out of the box.

There are some circumstances where getting the last grain of performance out of the system can be helpful. The following are some hints.

Firstly, when editing a large file, by default the file is not loaded into memory until it is needed. This improves response but eventually you have to wait whilst the file is loaded. For example, immediately jumping to the end of the file or searching for something a long way into the file will cause the file to be loaded and searched. Worse still, a failed search will cause the whole file to be searched - eventually failing.

If the file is not too large, then this is not too bad - subsequent searches will be speedier because the file has already been 'parsed', e.g. to find line endings, and the file will be sitting in the systems cache.

When searching there are generally things you can do to help things a bit. Firstly, searches at the start of a line (using ^) are signficantly faster than plain searches since only the characters at the start of the line need to be scanned - reducing the amount of work required by a large amount.

If this is not possible, then searching for a fixed string or a regular expression which starts with a fixed string is faster than a complex very dynamic regular expression. For example:

	xyz.*abc

is much better than:

	x+.*abc

In the first case, the scanner can look for the string xyz and then try to establish if an abc is on the same line. In the second case, we need to look for one or more x's before doing the search for the abc.

Q U4. How do I view the Contents window in CRiSP ?

The Contents window is a tabbed window to the left of the editing area which contains various useful selections when editing, including:

The Contents window is a tabbed window to the left of the editing area which

Browser, based on the builtin tags facility and helps you to navigate around the project

File selector, allowing fast access to directories and files

Sections - automated version of the routines facility for quick access to sections/routines/procedures in the current or other loaded buffers.

Language templates (v6.0.14 and above). Allows fast pasting of language templates into the current buffer without obscuring the current window or having to remember what abbreviations are available.

You can enable or disable from view the contents window by using the View->Contents Window menu option.

Support has been added for multiple Contents Windows so you can have different views at the same time - either as a dialog or an MDI window side by side with your code.

Q U5. Can I move the config to the C:\ drive?

By default, on Windows, CRiSP will store the user settings in the home directory (%HOME%). If this is a network drive, this can cause problems when detached from the network.

Older releases of CRiSP would store the config in the config\ directory next to the bin.win32 folder - wherever CRiSP was installed.

On Unix, $HOME/.Crisp is the location of the users settings.

In all cases, you can set the environment variable CRCONFIG to be the name of a folder or directory and CRiSP will store the settings there.


Q M1. How do I create custom menus?

CRiSP supports the creation of custom menu items for user written macros. This mechanism allows you to create menus and sub-menus. The mechanism relies on callbacks which are executed at the time the menu is popped up.

CRiSP v5 relied on modifying the menu data structures before the menu was created. CRiSP v6 provides faster startup by delaying menu creation until the point at which the user invokes the menu.

The following example shows a simple macro which is used to add 3 new menu items to the end of the File menu. If you want a copy of this file, click here. This is a plain text copy of the example.


/**********************************************************************/
/*   Example illustrating how to append items to one of the standard  */
/*   menus.							      */
/**********************************************************************/

# include <crisp.h>

extern list menu_bar_hook;

void
main()
{
	/***********************************************/
	/*   Ensure  we  get  called  when  menus are  */
	/*   being created.			       */
	/***********************************************/
	menu_bar_hook += "my_menu_hook";
}
/**********************************************************************/
/*   Hook functions gets called with three arguments: a reason code,  */
/*   a  name  associated  with a menu about to be popped up, and the  */
/*   screen dialog object id.					      */
/**********************************************************************/
int
my_menu_hook(int reason, string name_id, int obj_id)
{
	if (reason != MENU_CALLBACK_INITED) {
		/***********************************************/
		/*   We  may  get  called  because  a menu is  */
		/*   about to be popped up.		       */
		/***********************************************/
		return 0;
		}
	/***********************************************/
	/*   MENU_CALLBACK_INITED   means   we   just  */
	/*   created  the  popup  menu.  Now  we have  */
	/*   something to insert our entries onto.     */
	/*   					       */
	/*   Detect  which  menu just got created and  */
	/*   add our entries to this menu.	       */
	/***********************************************/
	switch (name_id) {
	  case "file_menu_button":
		/***********************************************/
		/*   Add custom menu items here.	       */
		/***********************************************/
		insert_object(obj_id, name_id, 0, name_id,
			DBOX_MENU_ITEM," My menu item &1", 
				DBOX_CALLBACK, "my_callback1",
				DBOX_HELP_STRING, "Do something #1.",
			DBOX_MENU_ITEM," My menu item &2", 
				DBOX_CALLBACK, "my_callback2",
				DBOX_HELP_STRING, "Do something #2.",

			DBOX_MENU_ITEM," My menu item &3", 
				DBOX_CALLBACK, "my_callback3",
				DBOX_HELP_STRING, "Do something #3."
			);
	  	return 0;

	  /***********************************************/
	  /*   Other  possible  menus  are (see xwin.cr	 */
	  /*   for details).				 */
	  /***********************************************/
		// File		"file_menu_button"
		// Edit		"edit_menu_button"
		// View		"view_menu_button"
		// Find		"find_menu_button"
		// Options	"options_menu_button"
		// Tools	"tools_menu_button"
		// Window	"window_menu_button"
		// Help		"help_menu_button"

	  }
	return 0;
}

Q M2. How do I create a bookmark stack?

I'm still trying to get the hang of bookmarks, I hope you can clear up some points.

As I understand it the drop_bookmark command stores buffer,line, col & the name of the bookmark in a list. Is this the list accessed by bookmark_list() ? If so do you need to initialise the list before using it ?

bookmark_list() returns the internal info recorded when dropping bookmarks. Without it theres no way of querying the bookmarks. The internal list is restored on startup by reading the crstate.dat file and for each line that starts "bookmark=", calling drop_bookmark to set the bookmark.

Why can't I use a variable for the name of the bookmark as follows:

	int mark=0;
	drop_bookmark("mark","Y"); // saves location in bookmark(0)
	++mark;                    // ready for next bookmark                               
	.....                              

then goto bookmarks in reverse order

	goto_bookmark(mark -1, buf, line, col);

You are confusing something here. Originally that 1st argument was a number and CRiSP supported dropping 10 bookmarks, 0..9. Later on CRiSP evolved to support named bookmarks. So your

	drop_bookmark("mark", "Y");

is fine. drop_bookmark() does not return an id to access the bookmark. Thats what the name ("mark") is for.

You are thinking about this all incorrectly. Heres how to do it:

	int mark = 0;

	drop_bookmark("mark" + mark, "Y");
	mark++;
	....
	mark--;
	goto_bookmark("mark" + mark, ....);
(Note the predecrement).

Does a bookmark store the path & file with the buffer info or just the buffer name, and the file name is handled some other way?

It stores the buffer id, not the name. If you delete the buffer, the bookmarks get destroyed. To handle this situation (you seem to be creating a bookmark stack), implement it yourself like this:

	list stack;
	int	ln, col;
	string filename;

	inq_position(ln, col);
	inq_names(filename);
	stack = make_list(make_list(filename, ln, col)) + stack;
	// doubled make_list is necessary to avoid a flat list.
	....
	// pop it:
	edit__file(stack[0][0]);
	move_abs(stack[0][1], stack[0][2]);
	stack = delete_nth(stack, 0);