!* -*-TECO-*-!

!^R Incremental Search:! !^R Search for character string as you type it.
C-Q quotes special characters.  Rubout cancels last character.
C-S repeats the search, forward, and C-R repeats it backward.
C-R or C-S with search string empty changes the direction of search
or brings back search string from previous search.
Altmode exits the search; with search string empty
it switches to non-incremental ^R String Search.
Other Control and Meta chars exit the search and then are executed.
If not all the input string can be found, the rest is not discarded.
You can rub it out, discard it all with C-G, exit,
or use C-R or C-S to search the other way.
Quitting a successful search aborts the search and moves point back;
quitting a failing search just discards whatever input wasn't found.
On printing terminals, C-L types line found but doesn't exit the search.!

    [D			    !* QD is direction and # times to search.!
    0[L				    !* QL > 0 iff failed to find current search string,!
    10.[R			    !* QR is state register: !
				    !* 40. => ^R or ^S repeating search or gobbling default.!
				    !* 10. => just starting.!
				    !* 4 => printing char just read.!
				    !* 2 => rubout just done wants full redisplay.!
				    !* 1 => rubout just done.!

    [Q @:iQ`			    !* MQ pushes current info:  ., qL, q2, q0, qD.!
      q4+1*5-fq3"e		    !* We are going to push in q3, so make sure space exists.!
	q3[..o zj
	200,0i ]..o'
      .u:3(%4)			    !* Push point, search string,!
      qLu:3(%4)
      q2u:3(%4)
      q0u:3(%4)			    !* this character, and current direction of search.!
      qDu:3(%4)
      `

    [T
    fs tyi sourc"e
     @:iT`			    !* MT updates the echo area.!
      Q9-Q.9"N 2[R' Q9U.9	    !* Q9 holds prompt for echo area.  Redisplay if changed.!
      fs rgetty"n 2&qR"n	    !* If we need to redisplay the whole thing,!
	qc fs echo dis		    !* home up and clear line first,!
	@ft 9:_ q2u8''	    !* then type the prompt and decide to retype whole string.!
      @ft 8 :i8 	    !* Update displayed search string.!
      ` '
     "# :iT'			    !* Don't display if inside a macro.!

    [C :IC TL		    !* QC has string to home up in echo area and clear line.!
    [0				    !* Q0 holds type-in character being processed.!
    [2 :i2			    !* Q2 holds accumulated search string.!
    [8 :i8			    !* Q8 has accumulated stuff to type in echo area.!
    [9				    !* Q9 has [Failing ][Reverse ]Search for echo area.!
    0[.9			    !* Q.9 has last value of Q9 actually displayed.!
    1fo..qSearch_Exit_Option[E	    !* QE nonzero => random control chars exit.!
    200fs q vector [3		    !* Q3 holds stack for partial search strings.!
    -1[4			    !* Q4 is stack pointer.!
    [5				    !* Q5 is random temp.!
    .[P				    !* QP has old point (to maybe push at end).!
    [S :IS M.M&_Isearch_RuboutUS :MS    !* QS has & Isearch Rubout (autoloading)!
    :I* M(M.M&_Isearch_Help) F[Help Mac
    1f[noquit
    [6 [7			    !* Q6 and Q7 are the success and failure echo strings.!
    qD"g :i6I-Search :i7Failing_I-Search'
    qD"l :i6Reverse_I-Search :i7Failing_Reverse_I-Search'
    q6u9			    !* Search starts out successful.!

    0[I				    !* QI is nonzero when we are reading input.!

    fs rgetty"e
       fs tyi sourc"e @ft _S:_'   !* On printing tty, start typing out.!
       1fstypeo''

  !Restart!

    1:< 1uI -2f[noquit		    !* Set up an errset to catch quits.!
     < qL"e q6' "# q7'u9 q9-q.9"n mt'	    !* Display direction and status in echo area.!
      0@V 1uI :fiu0 0uI @fiu5
      q5fs^r indir-qSearch_Exit_Char"e fq2:@;
         !<! 0;> 0fsnoquitw qD:m(m.m ^R_String_Search)'
      q5-8"e  o Funny'
      q5-176."g  o Funny'
      q5-"e  o Control'	    !* If Altmode isn't the exit char, it's like a ctl char!
      q5-î"e 
FS REREAD'

   !Normal!

      4uR			    !* Handle printing char.!
      mQ			    !* Push ., qL, q2, q0 and qD into q3, for rubbing out.!
      :i2 2 0	    !* stick this char at end of search string,!
      fs tyi source"e		    !* If not inside a keyboard macro,!
        fq8"n mt'		    !* Update the display.!
        @ft 0
	"#

   !Try!  !* Note if fall through we are inside a failing conditional.!

          mt			    !* Update the displayed search string.!
   	  ''
      qL"n !<!>'		    !* No point in searching if know it would fail.!

      .u5
      40.&qR"e			    !* For ^S, ^R suppress the moving back so don't no-op.!
	qD"g fq2-1r'		    !* Move back, so that from FO/\O we find the FOO.!
	  "# fsz-qP f[ vz
	     fq2-1"g fq2:c"e zj''
	     f]vz''		    !* After finding FO backwd, move fwd 3 so can find FOO.!
      qD:s2"l !<!>'
      q5j 1uL fg !<!>		    !* But if search fails, undo that motion back.!

   !Funny!

      q5-177."e  o Rubout'
  !* Only control characters and backspace get past here.!
      q5&537.-S"e  o Forward'    !* Check for C-S and C-s (ignore case bit).!
      q5&537.-R"e  o Backward'   !* Note: mustn't change q5 since Control rereads it.!
      q5&537.-Q"e  o Quote'
      q5&537.-L"e  fs rgetty"e o Reprint' o Control'
      qE"e  o normal'
      o Control

   !Reprint!	!* ^L on printing tty prints current line.!
      0t ft..a t
      ft _S:_2		    !* Then re-prompt.!
      !<!>

   !Quote!	!* ^Q quotes the next character.!

      1f[noquit
      fs osteco"n -1f[helpch'
      fiu0
      fs osteco"n f]helpch'
      0fs quitw f]noquit
      o normal

   !Forward!      !* ^S means search again forward.!

      qD"l :i6I-Search :i7Failing_I-Search'
      q4"L qD"g  o Default'	    !* ^S as 1st char going fwd => gobble default string.!
	     "# 1uD !<!>''	    !* ^S as 1st char, going backward, changed to fwd.!
      mQ			    !* Push ., qL, q2, q0 and qD into q3.!
      qD"L 0uL'			    !* If reversing direction, don't assume search will fail.!
      1uD			    !* String not null:  make sure going fwd,!
      40.uR			    !* Mark us as a ^S so don't change search string,!
      o try			    !* just search for it a second time.!

   !Backward!      !* ^R means search again backward.!

      qD"g :i6Reverse_I-Search :i7Failing_Reverse_I-Search'
      q4"L qD"l  o Default'	    !* ^R as 1st char going backwd => gobble default string.!
	     "# -1uD !<!>''	    !* ^R as 1st char, going forward, changed to backwd.!
      mQ			    !* Push ., qL, q2, q0 and qD into q3.!
      qD"g 0uL'			    !* If reversing direction, don't assume search will fail.!
      -1uD			    !* String not null:  make sure going backwd,!
      40.uR			    !* Mark us as a ^R so don't change search string,!
      o try

   !Default!	!* Come here to use default search string.!

      mQ			    !* Push current state so can rub the default out.!
      qSearch_Default_Ring[..o    !* Find the default!
      .fs word u2  ]..o	    !* and gobble it.!
      fq2"l :i2'
      q2u8
      40.uR			    !* Inhibit moving back before starting to search.!
      o try

   !Rubout!
 
      q4"l fg !<!>'		    !* Rubout when string is empty does nothing.!
      ms			    !* Call & Isearch Rubout.!
      qL"e q6' "# q7'u9		    !* Fix displayed direction and status for echo area.!
      mt !<!>			    !* Redisplay and loop back.!

   !Control!

      q5 fs reread
      0;

      >
     f]noquit
     >u0 @feqit-q0"e @fg	    !* If we quit, record in journal file.!
				    !* Record Rubout if quit while searching,!
				    !* record :^G if failing or waiting for input.!
	     qL"'gqI"N :i*:' "# :i*_›' fsjrn wr
	     QL"g <ms -ql;>  mt	    !* If failing, rub out the unfound chars and restart.!
	          o Restart'
	     qI"e ms mt o Restart' !* If quit while actually searching, restart.!
	     QPJ 0fsnoquit
	        -1fsquit'	    !* If succeeding, restore starting point and quit.!
	q0f"n fs err'		    !* Error not a quit => pass it on.!

    fq2"g
      qSearch_Default_Ring [..o   !* New search char, save prev default.!
      fq(.fsword)-1"G 5c .-z"e j'' !* If previous default is worth saving, push it!
      q2,.fsword		    !* Store current (new) default!
      ]..o'

    fs tyi source"e @ft  '	    !* Echo an altmode to show we have exited.!
    qP mMM_&_Maybe_Push_Point	    !* Maybe leave mark at place search started.!
    0

!^R Reverse Search:! !^R Incremental Search Backwards.
Like ^R Incremental Search but in reverse.!
    -@:M( M.M ^R_Incremental_Search)

!& Isearch Rubout:! !S Rubout-handling subroutine for incremental search.!
!* Kept in QS during incremental search.!
!* Assumes that there is something to rub out (so check first).!

      qD(
	q:3(q4)uD		    !* Else pop last set of pushed info!
	)-qD"N			    !* If popping a ^R or ^S that reversed direction,!
	  qD"g :i6I-Search :i7Failing_I-Search'	    !* fix up displayed mode.!
	  qD"l :i6Reverse_I-Search :i7Failing_Reverse_I-Search''
      q:3(q4-1)u0
      q:3(q4-2)u2
      q:3(q4-3)uL
      q:3(q4-4)j		    !* restore point saved by popped char.!
      q4-5u4
      3uR
      fs tyi source"e		    !* No display inside keyboard macros.!
        fs rgetty"e q0:i8'	    !* On printing tty, rub out char by typing it.!
        "# Q0-_:"L Q0-¢L	    !* On display, redisplay whole search string!
	     1uR :I*X FS ECHO DISP''''  !* unless we can fix it up!
      q0-12."e q4"g q:3(q4-1)-15."e !* If we just rubbed a LF that has a CR before it,!
	:ms'''			    !* Rub out that CR too.!

!& Isearch Help:! !S FS Help Mac calls this, inside I-search.!

    m(m.m Describe)^R_Incremental_Search
    0u..h f
