;**
;**		BRIEF -- Basic Reconfigurable Interactive Editing Facility
;**
;**		Written by Dave Nanian and Michael Strickman.
;**
;**		Revision history:
;**		-----------------
;**		6 October 1985			Removed "force" parameter from refreshes.
;**

;**
;**		i_search.m:
;**
;**		This macro implements a simple incremental search.  It does not
;**	allow regular expressions to be specified.  The Esc key terminates
;**	the search.
;**
;**		The backspace key moves you to the previously matched pattern.
;**

(macro i_search
	(
		(string		pattern
						character
						assignment
		)
		(int			char
						level
		)
		;**
		;**		We use the save_position/restore_position commands to keep
		;**	track of the previously matched location.  Searching back for
		;**	the identical pattern would not work, since it would match the
		;**	current occurrence.  In addition, prev_char then search_back
		;**	would not match if the current occurrence were the correct one.
		;**

		(save_position)

		(while (!= char 27)
			(
				;**
				;**		Since we want the cursor to remain on the screen in the
				;**	proper place, we create a "pseudo-cursor" with an IBM
				;**	graphics character.
				;**

				(message "I-search for: %sÜ" pattern)

				(while (== (= char (read_char)) -1))

				(sprintf character "%s#%d" character char)
				(= assignment (inq_assignment character))
				(%= char 256)

				(if (|| (&& (== char 27) (== character ""))
						(|| (== assignment "self_insert") (== assignment "nothing")))
					(
						(if (!= char 27)
							(if (== char 8)
								(
									(if (> (strlen pattern) 1)
								 		(= pattern (substr pattern 1 (- (strlen pattern) 1)))
									;else
								 		(= pattern "")
									)
									(restore_position)
		
									(if (! (-- level))
										(
											(save_position)
											(= level 1)
										)
									)
								)
							;else
								(
									;**
									;**		Now we have a character that we can search for.
									;**	We add it to the string of characters, and use
									;**	the search_fwd command to locate it.  While we're
									;**	searching, we place an ellipsis after the
									;**	string, so the user know's we're doing something.
									;**
		
									(sprintf character "%c" char)
									(+= pattern character)
									(save_position)
									(message "I-search for: %sÜ..." pattern)
		
									(if (! (search_fwd pattern 0))
										(
											(beep)
											(restore_position)
											(= pattern (substr pattern 1 (- (strlen pattern) 1)))
										)
									;else
										(++ level)
									)
								)
							)
						)
						(refresh)
						(= character "")
					)
				;else
					(if (!= assignment "ambiguous")
						(
							(= character "")

							(if (== assignment "search_again")
								(
									(message "I-search for: %sÜ..." pattern)
									(save_position)
									(next_char)

									(if (! (search_fwd pattern 0))
										(
											(beep)
											(restore_position)
										)
									;else
										(
											(refresh)
											(restore_position 0)
										)
									)
								)
							;else
								(beep)
							)
						)
					)
				)
			)
		)
		;**
		;**		When finished, we pop all of the saved positions off the
		;**	stack.  Note the use of the "pop, don't move" parameter with
		;**	restore_position.
		;**

		(while (>= (-- level) 0)
			(restore_position 0)
		)
		(message "I-search ended.")
	)
)
