!* -*-TECO-*- *! !~Filename~:! !EMACS support for Scribe.! SCRIBE !& Setup SCRIBE Library:! !C Create variables etc.! m(m.mKill Variable)MM Scribe Mode !* kill patch file version, sigh.! m(m.mKill Variable)Scribe ..D !* kill bad ..D! m.m^R Backward Paragraphm.vMM ^R Backward Paragraph !* Mode function!  !Scribe Mode:! !C Set up for editing Scribe source text. Comments are defined, and suitable parenthesis matching is enabled. The following keys are redefined: Tab ^R Tab to Tab Stop C-M-A Move up to beginning of containing environment. C-M-D Move inside first environment after point. C-M-E Move after end of containing environment. C-M-G Change name of containing environment. C-M-H Put point and mark around containing environment. C-M-N Move after end of next environment. C-M-P Move before start of previous environment. C-M-Q Change short form environment to long or vice versa.! m(m.m& Init Buffer Locals) !* back to Fundamental mode! m.q..D !* make Syntax table local to buffer! 0fo..qScribe ..Df"n u..D' !* if already an exiting Scribe table,! !* use it! "#w :g..Du..D !* otherwise copy current one! q..Dm.vScribe ..D !* save for reuse! 5*.:f..D  !* period is break! !"! 5*':f..DAA !* apostrophe is alphabetic! 1m(m.m& Alter ..D)(())[(]){(})<(>)"|'| !* Define <>, (), [], and {} as! !* parenthesis. " and ' are defined! !* to be string quote characters.! 2m(m.m& Alter ..D)<>()[]{}""'' !* add proper pairing! !* used in ^R Forward! !* Environment! ' 1,(m.m^R Tab to Tab Stop)m.qI !* Tab is Tab to Tab Stop! :i*@Comment{m.lComment Start 1m.lComment Multi Line !* don't put in Comment End on auto fill! :i*}m.lComment End 0m.lComment Column !* Comments go in first column if possible.! :i*f"n/8+1*8'm.lComment Rounding !* otherwise one tab over from text.! 1,(m.m^R Backward Scribe Paragraph)f(m.lMM ^R Backward Paragraphw)m.q..[ 1,(m.m^R Forward Environment)m.q...N 1,(m.m^R Backward Environment)m.q...P 1,(m.m^R Down Environment)m.q...D 1,(m.m^R Backward Up Environment)m.q...U 1,(m.m^R End of Environment)m.q...E 1,(m.m^R Change Environment Name)m.q...G 1,(m.m^R Mark Environment)m.q...H 1,(m.m^R Backward Up Environment)m.q...A 1,(m.m^R Change Form)m.q...Q 1,(@:i*|f6ERRfsDFN2 e?"n @ft(No errors) 0fsEchoActive ' m(m.mSelect Buffer)*Errors* m(m.mVisit File) m(m.mNext Scribe Error)|) m.lAfter Compilation Hook 1m(m.m& Set Mode Line)Scribe !* put Scribe in mode line!  !^R Forward Environment:! !^R Move after end of next environment. Find start of first environment after point, and move past end of it. An argument serves as a repeat count.! !* If pre-comma argument is specified, it is a string to stop at.! !* Returns 0 if close delimiter found, 1 if moved over environment.! "l -(f):m(m.m^R Backward Environment)' !* negative argument for! !* backward! [1[2[3 !* save regs! "n u1 :i11@'"# :i1@' !* 1: if pre-comma argument, use that! !* as a delimiter to search for in! !* addition to @! < .u3 !Search! !* 3: place to return on failure! :s1f"ew q3j fg 1'+1"e 0' !* find next @ or close delimiter! !* return 0 to indicate close found! @f@f(c)&1"n oSearch' !* go find another if @@, @@@@, etc.! 0,1af+-:"l c oAfter name' !* @+ and @- are environments,! !* unfortunately! 0,1a"b oSearch' !* if @; or the likes, ignore it! fwf~BEGIN"e 6c :i2@END !* if @BEGIN, then close delimiter is! !* @END! < q2,1m(m.m^R Forward Environment)@; > !* move forward over nested! !* environments until the! !* specified close delimiter! !* is found! fll' !* now move over the (NAME) after the! !* @END! "# fwl !After name! @f l !* @FOO and not @BEGIN! 1af<([{"'!>!:"l !* if @FOO not followed by a! !* Scribe open delimiter,! !* ignore this command! c 0a*5+2:g..d:i*u2 !* get corresponding close delimiter! < q2,1m(m.m^R Forward Environment)@; > !* move forward over nested! '' !* environments until the! !* specified close delimiter! !* is found! > !* iterate argument times! 1 !* return 1 to indicate moved over! !* environment! !^R Backward Environment:! !^R Move before start of previous environment. An argument serves as a repeat count.! "l -(f):m(m.m^R Forward Environment)' !* negative argument is forward! [1[2[3[4[5 !* save regs! < .u1 -u2 !* 1: point to restore on error! !* 2: current guess as to previous! !* environment! !)]}"'l .u3 !* 3: starting place for backward! !* movement! < -:s@"e q1j fg 1' !* find previous @, feep if none! -@f@&1"e fwf~@END"n !* if even number of @s, and not @END! .u5 1m(m.m^R Forward Environment) .-q3"e q5j 0;' !* if comes exactly to where we! !* started from, then this is it! .-q3"g q2"l q1j fg 1' q4j 0;' !* if past starting place, then we7ve! !* reached a containing environment,! !* so no need to look further. use! !* best previous environment, or feep! !* if none! .-q2:"l .u2 q5u4' !* if closer than previous, remember! q5j'' !* it, then back to environment start! -@f@l > !* back over extra @s! > 1 !^R Down Environment:! !^R Move inside first environment after point. An argument serves as a repeat count.! !* Feeps and returns -1 on failure.! "l -(f):m(m.m^R Backward Up Environment)' !* negative argument is upward! .[1 !* 1: where to go on failure! < :s@"e q1j fg -1' !* find next @! @f@f(c)&1"n !' !* go find another if @@, @@@@, etc.! 0,1a"b !' !* if @; or the likes, ignore it! fwl @f l c 0af<([{"'!>!"l !' !* if @FOO not followed by! !* open delimiter, ignore it! .u1 > !* 1: where to go on failure! 1 !^R Backward Up Environment:! !^R Move before start of containing environment. An argument specifies the Nth containing environment.! !* Feeps and returns -1 on failure.! !* This code has a bug: @; etc. will confuse it.! "l -(f):m(m.m^R Down Environment)' !* negative argument is downard! [1[2 !* save regs! <.u1 !* 1: where we started from. used to! !* restore point on errors and for! !* completion test! < -:s@"e q1j fg -1' !* find previous @, feep if none! .u2 -@f@&1"e 0,2a"c !* 2: before @. if not @@, @@@@, etc.! !* and not @; etc.! 1m(m.m^R Forward Environment) !* then find end of this environment! q1-.:; q2j'' !* if end is past starting position,! !* we7re done! -@f@l > !* otherwise skip over the extra @s! !* (probably none) and try again! q2j > !* back to before @, do ARG times! 1 !^R End of Environment:! !^R Move after end of containing environment. An arugment specifies the Nth containing environment.! f@m(m.m^R Backward Up Environment) 1:m(m.m^R Forward Environment) !^R Mark Environment:! !^R Put point and mark around containing environment. An argument specifies the Nth containing environment.! f@m(m.m^R Backward Up Environment) .( 1m(m.m^R Forward Environment)w .:w )j 1 !^R Change Environment Name:! !^R Change name of containing environment. Prompts for new environment name. An argument specifies Nth containing environment.! [1[2 .[3 !* 3: where we started from! f@m(m.m^R Backward Up Environment)"l 1' !* find containing! !* environment! .u2 !* 2: start of containing environment! q3j 1,f Environment: u1 !* 1: new environment name! q2j fwf~@BEGIN"e !* if @BEGIN form! 1m(m.m^R Forward Environment) !* find end! r -fwk !* delete name inside @END()! ,f1f"lw g1'"# ,0:g1' !* if new name contains a comma then! !* insert up to the comma, otherwise! !* insert whole thing! q2j 6c @f l !* goto to beginning again, and move! !* to close delimiter! z-q3( fl(c)-2d g1 ),zj ' !* delete inside delimiters, and! !* restore point to starting place! "# z-q3(c .(fwk g1),.f ),zj 1' !* @FOO form. delete the FOO, insert! !* new name, and restore point to! !* starting place! !^R Change Form:! !^R Change @FOO to @BEGIN(FOO) or vice versa. Change containing environment from long to short form or vice versa. An argument specifies the Nth containing environment.! [1[2 .[3 [4 !* 3: where we started from! f@m(m.m^R Backward Up Environment)"l 1' .u2 !* 2: start of environment! fwf~@BEGIN"e !* @BEGIN form! 6c @f l .u1 fll .u4 !* 1: before open delimiter after! !* @BEGIN! !* 4: after matching close delimiter! q1,.:fb,"l q3j fg 1' !* if comma inside @BEGIN, then cant! !* convert to short form! q2j 1m(m.m^R Forward Environment) !* find end of environment! .(-fll -@f l 4r),.:k i] !* delete the @END(name), insert ]! q4j z-q3( -di[ q2+1,q1+1k ),zj !* goto close delimiter of @BEGIN,! !* replace with [, and delete BEGIN! !* and its open delimiter, and! !* finally restore point! ' !* whew, were done! !* @FOO form! 1m(m.m^R Forward Environment) !* find end of environment! z-.u4 !* 4: distance from end of! !* environment to end of buffer! q2j c z-q3( !* goto environment start, skip @! ibegin[ fwf(l)x1 i] d !* put in @BEGIN[, move over and pick! !* up next word, put in ], and delete! !* old open delimiter! ),zu3 !* 3: where we started from updated! !* after inserting/deleting! z-q4j -d i@end[1] q3j !* back to end of environment, delete! !* old close delimiter, insert! !* @END(name), and restore point!  !^R Backward SCRIBE Paragraph:! !^R Move backward to start of paragraph. Paragraphs are delimited by blank lines. Lines composed of one SCRIBE command which fills the whole line, and lines which start with @; or a page delimiter, count as blank. Also, lines starting with space or tab start a paragraph.! qPage Delimiter[1 0s 1  !* Search for page delim or nothing.! "l 0@l' !* Move in reverse to line-beginning if not at one.! "# 0@f"n @l'' !* Note: we won't stop before line we start at, because Q3 is initially 1.! [3 [4 [5 < !* As many times as wanted, find next P. is ABS! 1u3 0u5 < q3u4 !* Q4 is 1 if previous line was "blank".! 0u3 :@f"e 1u3' !* Q3 gets 1 if this line is blank! "# .-(s.(0@l))"l 1u3' !* Stop on line starting with page delimiter.! "# 1a-@"e c 0,1a-;"e 1u3' !* @; starts a "blank" line.! 1a:"b fwl !* Move over command name.! 1af<([{ !>!"l 1u3' !* No delimiter after => line is "blank"! "# :f-( fl)"e 1u3''' !* Expression is entire line => "blank"! 0@l''' q3"n q4"e q5-1"g 0;' :;'' !* Stop at first "blank" line we see, if we've gone > 1! !* or are going forward.! %5 "g :rw 0@l b-.;' !* Advance one line.! "l @l .-z; q3"n !'' !* Don't stop, going fwd, on line after "blank" line.! 0,1af  ; !* Stop on line starting with space or tab.! > > "g q3"n q4"e @L'' !* If we stopped moving backwards under a line that! -@F-2"E -@L'' !* is really empty, include it as well.! 0 !Next Scribe Error:! !C Put next error in window 1, with source in window 2.! f~Buffer Name*Errors*"n !* if not already in *Errors*! m(m.mSelect Buffer)*Errors*' !* then get in it! [0[1[2[3 !* save regs! .u0 !* 0: current point! !* Find next , p.n/L.m: in error file! < :s, p."e q0j fg 1' .u1 !* 1: just after filename! \u2 q2"n !* 2: page number! 3f=/L."e !* insure line number follows! 3c \u3 q3"n 1a-:@;'' !* 3: line number! > .(q1-4j 0x0 et0 0fsDVersionw fsDFileu0)j !* 0: filename! fsMSnamefsDSnamew et0 fsDFileu0 !* default to connected directory,! !* parse filename! f 1@:f !* tell TECO to put . on line 1 of! !* window! 2u1 .(4< l :f@; %1w >)j !* 1: number of lines in error! !* message! qBuffer Namem.vWindow 1 Buffer q..om.vOther Window Buffer fsWindowm.vWindow 1 Window .m.vWindow 1 Pointer q1m.vWindow 1 Size m(m.mFind File)0 !* read in file! j q2-1s  q3-1l !* goto page Q2, line Q3! 1f[NoQuit 0fo..qWindow 2 Size"e !* ! fsLinesm.vDefault Size fsLinesf"ew fsHeight-(fsEchoLines)-1'm.vTotal Size fsRefreshm.vWindow 1 Refreshw' qTotal Size-1-q1m.vWindow 2 Size qBuffer Namem.vWindow 2 Buffer m.vWindow 2 Pointer m.vWindow 2 Window m.m& Multi-window RefreshfsRefresh qWindow 1 Size+1fsTopLine qWindow 2 SizefsLines m(fsRefresh)  !* * Local Modes: * Comment Column:40 * End: *!