/**********************************************************************/
/*                                                                    */
/*	CRISP - Programmable editor                                   */
/*	===========================                                   */
/*                                                                    */
/*  File:          x.cr                                               */
/*  Author:        P. D. Fox                                          */
/*  Created:       9 Mar 1991                      		      */
/*                                                                    */
/*  Copyright (c) 1990, 1991 Paul Fox                                 */
/*                All Rights Reserved.                                */
/*                                                                    */
/*                                                                    */
/*--------------------------------------------------------------------*/
/*  Description:  Features menu.                                      */
/*                                                                    */
/**********************************************************************/

/* SCCS ID: %Z% %M% %R%.%L% */
# include	"crisp.h"

/**********************************************************************/
/*   Following  list  defines  the entries to appear in the features  */
/*   menu.  First  item is the window title, and the remaining items  */
/*   are  grouped  in  pairs -- the label and the macro/keystroke to  */
/*   call.							      */
/**********************************************************************/
list feature_list = {
	"CRISP Features",
	"ASCII Chart", "ascii",
	"Ansi mode toggle", "ansi",
	"Auto indent",	"autoindent",
	"Auto wrap", "autowrap",
	"Buffer List", "buffer_list 1",
	"C Hierarchy chart", "hier",
	"CRISP Demonstration",	"demo",
	"Calculator (infix)", "calc",
	"Center text",	"center",
	"Change Log", "change",
	"Color mappings",	"setcolor",
	"Define abbreviation",	"abbrev",
	"Delete blank lines",	"delete_blank_lines",
	"Delete trailing space",	"delete_trailing_spaces",
	"Document options",	"options",
	"Edit file again",	"edit_again",
	"Explain CRISP macro", "explain",
	"Find function", "tag",
	"Find manual entry", "apropos",
	"Format Region", "objects format_block",
	"GREP",	"grep",
	"Game of Tetris",	"tetris",
	"HP Calculator (RPN)", "hpcalc",
	"Help", "help",
	"Indent region", "shiftr",
	"Interactive Search",	"i_search",
	"Join next line", "<Ctrl-A><Ctrl-J>",
	"Keyboard Summary", "kbd_summary",
	"Keystroke Library",	"keylib",
	"Lint", "lint",
	"List functions/sections", "objects routines",
	"Literal display mode",	"literal",
	"Lower case region", "block_lower_case",
	"Mail", "mail",
	"Make buffer writeable", "make_writeable",
	"Make", "make",
	"Manual page", "man",
	"Match brackets", "find_matching_brace",
	"Outdent region", "shiftl",
	"Pipe region", "<Ctrl-A><Ctrl-P>",
	"Print buffer", "print_buffer",
	"Save window layout", "save_state",
	"Scroll lock window", "scroll",
	"Set right hand margin", "margin",
	"Shell buffer", "csh",
	"Spell", "spell",
	"Sub-shell", "shell",
	"Sum column of numbers", "sum",
	"Texinfo", "texinfo",
	"Tower of Hanoi", "hanoi",
	"Upper case region", "block_upper_case",
	"Use tabs or spaces", "use_tab_char",
	"Word count", "wc",
	"Zoom/unzoom window", "zoom"
	};
void
feature()
{
	message("Generating features menu...");	
	select_feature(feature_list, 30);
}
void
select_feature(list lst, int width)
{	int	i, j, ret;
	int	llen;
	int	win;
	int	curbuf = inq_buffer();
	int	curwin = inq_window();
	int	buf;
	int	width;
	string	title;
	string	s;
	declare	t;
	extern int top_line;
	
	title = lst[0];
	buf = create_buffer(title, title, TRUE);
	set_buffer(buf);
	llen = length_of_list(lst);
	
	/***********************************************/
	/*   First  insert  the left hand side of the  */
	/*   buffer,  because  we  dont know how wide  */
	/*   to  pad  the  screen until we've scanned  */
	/*   all entries.			       */
	/***********************************************/
	for (i = 1; i < llen; ) {
		s = lst[i++];
		t = lst[i++];
		j = strlen(s) + 6;
		/***********************************************/
		/*   Check  to  see whats on the right of the  */
		/*   line.				       */
		/***********************************************/
		if (is_string(t)) {
			/***********************************************/
			/*   We  may  have a pure macro name or a key  */
			/*   binding   so  look  for  a  key  binding  */
			/*   first  because  thats  more  helpful for  */
			/*   the user.				       */
			/***********************************************/
			s = inq_assignment(t, 1);
			if (s == "nothing")
				j += strlen(t);
			else
				j += strlen(s);
			}
		else {
			/***********************************************/
			/*   We  have  a  list  so  we  only  need to  */
			/*   indicate there is another popup.	       */
			/***********************************************/
			j += 2;
			}
		/***********************************************/
		/*   Keep track of longest line length.	       */
		/***********************************************/
		if (j > width)
			width = j;
		}
		
	/***********************************************/
	/*   Now  we  know  the  width of the longest  */
	/*   line,  we  can  go  and  insert the data  */
	/*   into the buffer.			       */
	/***********************************************/
	for (i = 1; i < llen; ) {
		s = lst[i++];
		t = lst[i++];
		insert(s + " ");
		/***********************************************/
		/*   Check  to  see whats on the right of the  */
		/*   line.				       */
		/***********************************************/
		if (is_string(t)) {
			/***********************************************/
			/*   We  may  have a pure macro name or a key  */
			/*   binding   so  look  for  a  key  binding  */
			/*   first  because  thats  more  helpful for  */
			/*   the user.				       */
			/***********************************************/
			j = width - strlen(s);
			s = inq_assignment(t, 1);
			if (s != "nothing")
				t = s;
			insert(" ", j - strlen(t));
			insert(t + "\n");
			}
		else {
			/***********************************************/
			/*   We  have  a  list  so  we  only  need to  */
			/*   indicate there is another popup.	       */
			/***********************************************/
			insert(" ", width - strlen(s) - 2);
			insert("=>\n");
			}
		}
	win = sized_window(inq_lines(), inq_line_length() + 1);
	message(int_to_key(ALT_H) + " help; <Enter> select " +
		int_to_key(ALT_S) + " search");
	top_of_buffer();
	top_line++;
	ret = select_buffer(buf, win, SEL_NORMAL);
	top_line--;

	delete_buffer(buf);
	set_buffer(curbuf);
	set_window(curwin);
	attach_buffer(curbuf);
	
	/***********************************************/
	/*   Erase  any  info  messages  at bottom of  */
	/*   screen.				       */
	/***********************************************/
	refresh();
	message("");
	/***********************************************/
	/*   If   selection   aborted,   then  return  */
	/*   without executing the action.	       */
	/***********************************************/
	if (ret < 0)
		return;
		
	/***********************************************/
	/*   If  macro  started  with  a  '<' then it  */
	/*   must  be  a literal keystroke so we need  */
	/*   to  force  it  into  the  keyboard input  */
	/*   buffer.				       */
	/***********************************************/
	s = lst[ret * 2];
	if (substr(s, 1, 1) == "<")
		force_input(s);
	else
		execute_macro(s);
}
	
