DIRECTORY Char, CharOps, Rope, SimpleFeedback, TEditDocument, TEditInput, TEditInputBackdoor, TEditInputExtras, TEditProfile, TEditSelection, TEditSelectionPrivate, TEditSelectionPrivateExtras, TextEdit, TextEditExtras, TextNode, TIPUser, ViewerClasses; SchemeSelectImpl: CEDAR PROGRAM IMPORTS CharOps, Rope, SimpleFeedback, TEditInput, TEditInputBackdoor, TEditInputExtras, TEditProfile, TEditSelection, TEditSelectionPrivate, TEditSelectionPrivateExtras, TextEdit, TextEditExtras, TextNode = BEGIN ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; SetNot0: ERROR [node: TextNode.Ref] ~ CODE; Loc: TYPE ~ RECORD [node, parent: TextNode.Ref, rope: ROPE, size, where, idx: INT]; Span: TYPE ~ RECORD [start, end: Loc]; Cmd: TYPE ~ REF CmdPrivate; CmdPrivate: TYPE ~ RECORD [extend, track: BOOL, upLevels: INT]; nullLoc: Loc ~ [NIL, NIL, NIL, 0, 0, 0]; theSS: Span _ [nullLoc, nullLoc]; theTDD: TEditDocument.TEditDocumentData _ NIL; lockless: BOOL _ FALSE; testIdx: BOOL _ FALSE; SelectCmd: PROC [data: REF ANY, viewer: Viewer, param: REF ANY _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE] --TEditInputExtras.CommandClosureProc-- ~ {--cloned from TEditInputImpl's handling of SelWord on May 22, 1990 tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; z: REF TIPUser.TIPScreenCoordsRec ~ IF param#NIL THEN WITH param SELECT FROM x: REF TIPUser.TIPScreenCoordsRec => x, ENDCASE => NIL ELSE NIL; cmd: Cmd ~ NARROW[data]; IF tdd = NIL THEN RETURN; IF z=NIL THEN { SimpleFeedback.Append[$SchemeSelect, oneLiner, $Bug, "SchemeSelectImpl: my PARAM isn't a Coords - are typescripts bogus?"]; SimpleFeedback.Blink[$SchemeSelect, $Bug]; RETURN [FALSE, TRUE]}; TEditInput.interpreterNesting _ 0; IF TEditInput.editState=abort THEN RETURN; IF TEditInputBackdoor.sel=secondary AND TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; SelectForm[viewer, tdd, z.mouseX, viewer.ch-z.mouseY, TEditInputBackdoor.sel, TEditInputBackdoor.pDel, cmd]; IF TEditInputBackdoor.sel=primary THEN TEditInput.CloseEvent[]; RETURN [FALSE, TRUE]}; SelectForm: PROC [viewer: Viewer, tdd: TEditDocument.TEditDocumentData, x, y: INTEGER, sel: TEditDocument.SelectionId, pDel: BOOL, cmd: Cmd] ~ { Finish: PROC ~ { IF testIdx THEN SimpleFeedback.PutFL[$SchemeSelect, oneLiner, $Debug, "%g..%g vs. %g..%g", LIST[ [integer[theSS.start.idx]], [integer[theSS.end.idx]], [integer[TextNode.LocOffset[[tdd.text, 0], Export[theSS.start]] ]], [integer[TextNode.LocOffset[[tdd.text, 0], Export[theSS.end]] ]] ]]}; DoSelectForm: PROC [tSel, refSel: TEditDocument.Selection, rightOfLine: BOOL] = {--cloned from TEditMouseImpl.SelectWord on May 22, 1990 punc: TEditDocument.PunctuationPosition _ none; newInsertion: TEditDocument.BeforeAfter; newGrain: TEditDocument.SelectionGrain ~ word; startValid, endValid: BOOLEAN _ TRUE; hitLine: INTEGER _ tSel.start.line; given: Loc ~ Import[tSel.start.pos, tdd.text]; cont: BOOL ~ (cmd.track OR cmd.extend) AND tdd=theTDD AND refSel.start.pos=Export[theSS.start] AND refSel.end.pos=Export[theSS.end]; IF cmd.track AND cont AND given.idx IN [theSS.start.idx .. theSS.end.idx] THEN NULL ELSE IF cmd.extend AND cont THEN { idx: INT ~ given.idx; railed, tamed: BOOL _ FALSE; type: TokeType; SELECT idx FROM { WHILE idx NULL; openList, openVector => theSS.end _ FindGroupEnd[theSS.end].end; closeList => [theSS.start, railed] _ FindGroupBegin[theSS.start]; ENDCASE => NULL}; ENDLOOP; Finish[]; IF railed AND idxtheSS.end.idx => { WHILE idx>theSS.end.idx AND NOT railed DO oldSS: Span ~ theSS; [railed, theSS.end] _ FwdLoc[theSS.end]; IF NOT railed THEN { [theSS.end, type] _ ParseWholeToken[theSS.end]; SELECT type FROM blank, leaf => NULL; quote => theSS.end _ FindQuoteEnd[theSS.end]; openList, openVector => [theSS.end, railed] _ FindGroupEnd[theSS.end]; closeList => theSS.start _ FindGroupBegin[theSS.start].start; ENDCASE => ERROR}; ENDLOOP; Finish[]; IF railed AND idx>theSS.end.idx THEN ERROR}; ENDCASE => NULL; } ELSE {railed: BOOL _ FALSE; [theSS.start, theSS.end] _ ExpandToForm[given]; FOR i: INT IN [1 .. cmd.upLevels] WHILE NOT railed DO [theSS.start, theSS.end, railed] _ ExpandForm[theSS.start, theSS.end]; ENDLOOP; theTDD _ tdd; Finish[]}; tSel.viewer _ viewer; tSel.data _ tdd; tSel.start.pos _ Export[theSS.start]; tSel.end.pos _ Export[theSS.end]; TEditSelection.FixupSelection[tSel, viewer]; newInsertion _ SetInsertion[tSel, x, hitLine, rightOfLine, tdd]; IF refSel.viewer#tSel.viewer OR refSel.granularity#newGrain OR tSel.start.pos#refSel.start.pos OR tSel.end.pos#refSel.end.pos OR newInsertion#refSel.insertion OR refSel.pendingDelete#pDel THEN { tSel.granularity _ newGrain; tSel.punctuation _ punc; tSel.insertion _ newInsertion; tSel.pendingDelete _ pDel; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[tSel, sel, startValid, endValid, FALSE]; }; }; (IF lockless THEN LocklessDoSelect ELSE TEditSelectionPrivateExtras.DoSelect)[DoSelectForm, viewer, tdd, x, y, sel]; RETURN}; ExpandForm: PROC [oStart, oEnd: Loc] RETURNS [nStart, nEnd: Loc, railed: BOOL _ FALSE] ~ { type: TokeType; [nStart, type, railed] _ PrevNonBlank[oStart]; SELECT type FROM quote => nEnd _ oEnd; blank => [nEnd, railed] _ FindGroupEnd[oEnd]; openList, openVector => nEnd _ FindGroupEnd[oEnd].end; closeList => {r1: BOOL; [nStart, r1] _ FindGroupBegin[nStart]; IF NOT r1 THEN [nStart, r1] _ FindGroupBegin[nStart]; [nEnd, railed] _ FindGroupEnd[oEnd]; railed _ r1 AND railed}; ENDCASE => {r1: BOOL; [nStart, r1] _ FindGroupBegin[nStart]; [nEnd, railed] _ FindGroupEnd[oEnd]; railed _ r1 AND railed}}; ExpandToForm: PROC [pos: Loc] RETURNS [start, end: Loc] ~ { type: TokeType; [start, type] _ ToTokenStart[pos, FALSE]; SELECT type FROM closeList => {end _ start; start _ FindGroupBegin[end].start}; openList => end _ FindGroupEnd[start].end; openVector => end _ FindGroupEnd[DLoc[start, 1]].end; leaf, blank, quote => { [end, type] _ ParseWholeToken[start]; IF type=quote THEN end _ FindQuoteEnd[end]}; ENDCASE => ERROR; RETURN}; TokeType: TYPE ~ {leaf, blank, quote, openList, openVector, closeList}; ParseWholeToken: PROC [start: Loc] RETURNS [end: Loc, type: TokeType _ blank] ~ { rope: ROPE ~ start.rope; size: INT ~ start.size; GetOrSpace: PROC [i: INT] RETURNS [CHAR] ~ INLINE {RETURN [IF i<0 OR i>=size THEN ' ELSE rope.Fetch[i]]}; FwdOverId: PROC [start: Loc] RETURNS [end: Loc] ~ { end _ start; DO next: INT ~ end.where.SUCC; IF next>=size THEN RETURN [SetWhere[end, size-1]]; SELECT rope.Fetch[next] FROM <=' , ';, '(, '), '", '\', '`, ',, '\\, '# => RETURN [end]; ENDCASE => end _ DLoc[end, 1]; ENDLOOP}; FwdOverString: PROC [start: Loc] RETURNS [end: Loc] ~ { end _ start; DO end _ DLoc[end, 1]; IF end.where >= size THEN RETURN [SetWhere[end, size-1]]; SELECT rope.Fetch[end.where] FROM '" => RETURN [end]; '\l, '\r => RETURN [DLoc[end, -1]]; '\\ => SELECT GetOrSpace[end.where.SUCC] FROM '\l, '\r => RETURN [end]; ENDCASE => end _ DLoc[end, 1]; ENDCASE => NULL; ENDLOOP}; end _ start; IF end.node.comment THEN RETURN [SetWhere[end, MAX[0, size-1]], blank]; IF end.where=size THEN RETURN [end, blank]; SELECT rope.Fetch[end.where] FROM '\l, '\r => RETURN [end, blank]; <=' => {DO next: INT ~ end.where.SUCC; nc: CHAR ~ IF next=size THEN 'x ELSE rope.Fetch[next]; SELECT nc FROM '\l, '\r, >' => RETURN [end, blank]; ENDCASE => end _ DLoc[end, 1]; ENDLOOP}; '; => RETURN [SetWhere[end, rope.SkipTo[end.where.SUCC, "\l\r"].PRED], blank]; '( => RETURN [end, openList]; ') => RETURN [end, closeList]; '\', '` => RETURN [end, quote]; ', => RETURN [DLoc[end, IF GetOrSpace[end.where.SUCC]='@ THEN 1 ELSE 0], quote]; '" => RETURN [FwdOverString[end], leaf]; '# => SELECT GetOrSpace[end.where.SUCC] FROM '" => RETURN [FwdOverString[DLoc[end, 1]], leaf]; '( => RETURN [DLoc[end, 1], openVector]; '\\ => RETURN [FwdOverId[DLoc[end, 2]], leaf]; ENDCASE => RETURN [FwdOverId[end], leaf]; '\\ => RETURN [end, leaf]; ENDCASE => RETURN [FwdOverId[end], leaf]; }; ToTokenStart: PROC [loc: Loc, tamed: BOOL] RETURNS [start: Loc, type: TokeType] ~ { rope: ROPE ~ loc.rope; size: INT ~ loc.size; GetOrSpace: PROC [i: INT] RETURNS [CHAR] ~ INLINE {RETURN [IF i<0 OR i>=size THEN ' ELSE rope.Fetch[i]]}; start _ loc; IF start.node.comment THEN RETURN [SetWhere[start, 0], blank]; IF start.where >= size THEN RETURN [start, blank]; IF NOT tamed THEN { WHILE start.where>0 DO prev: INT ~ start.where.PRED; SELECT rope.Fetch[prev] FROM '\r, '\l => EXIT; ENDCASE => start _ DLoc[start, -1]; ENDLOOP; DO end: Loc; [end, type] _ ParseWholeToken[start]; IF end.where >= loc.where THEN RETURN [start, type]; start _ DLoc[end, 1]; ENDLOOP; }; {c: CHAR _ rope.Fetch[loc.where]; IF loc.where>0 AND c<=' AND c#'\l AND c#'\r THEN WHILE loc.where>0 DO prev: INT ~ loc.where.PRED; pc: CHAR ~ rope.Fetch[prev]; IF pc>' OR pc='\l OR pc='\r THEN EXIT; loc _ DLoc[loc, -1]; ENDLOOP; IF CcAt[rope, size, loc.where] THEN RETURN [DLoc[loc, -2], leaf]; {pc: CHAR ~ GetOrSpace[loc.where.PRED]; SELECT c FROM <=' => RETURN [loc, blank]; '\\ => RETURN [IF CcAt[rope, size, loc.where.SUCC] THEN DLoc[loc, -1] ELSE loc, leaf]; ') => RETURN [loc, closeList]; '( => SELECT TRUE FROM pc#'# => RETURN [loc, openList]; CcAt[rope, size, loc.where.PRED] => RETURN [loc, openList]; ENDCASE => RETURN [DLoc[loc, -1], openVector]; '# => RETURN [loc, IF GetOrSpace[loc.where.SUCC]='( THEN openVector ELSE leaf]; '" => {ss: Loc ~ BackOverString[loc]; SELECT TRUE FROM GetOrSpace[ss.where.PRED]#'# => RETURN [ss, leaf]; CcAt[rope, size, ss.where.PRED] => RETURN [ss, leaf]; ENDCASE => RETURN [DLoc[ss, -1], leaf]}; '\', '`, ', => RETURN [loc, quote]; '@ => IF pc=', AND NOT CcAt[rope, size, loc.where.PRED] THEN RETURN [DLoc[loc, -1], quote] ELSE RETURN BackOverId[loc]; '; => ERROR; ENDCASE => RETURN BackOverId[loc]}}}; CcAt: PROC [rope: ROPE, size, ccl: INT] RETURNS [BOOL] ~ { ifMism: BOOL _ FALSE; IF ccl >= size THEN RETURN [FALSE]; DO IF ccl < 2 THEN RETURN [ifMism]; IF rope.Fetch[ccl-1]#'\\ OR rope.Fetch[ccl-2]#'# THEN RETURN [ifMism]; ifMism _ NOT ifMism; ccl _ ccl - 2; ENDLOOP}; BackOverId: PROC [end: Loc] RETURNS [start: Loc, type: TokeType] ~ { rope: ROPE ~ end.rope; size: INT ~ end.size; start _ end; DO prev: INT ~ start.where.PRED; IF prev<0 THEN RETURN [SetWhere[start, 0], leaf]; IF CcAt[rope, size, prev] THEN RETURN [SetWhere[start, prev-2], leaf]; SELECT rope.Fetch[prev] FROM <=' , '(, '), '\', '`, ',, '\\ => RETURN [start, leaf]; '# => RETURN [SetWhere[start, prev], leaf]; '@ => IF prev=0 OR rope.Fetch[prev-1]#', THEN start _ DLoc[start, -1] ELSE IF CcAt[rope, size, prev-1] THEN RETURN [SetWhere[start, prev], leaf] ELSE RETURN [SetWhere[start, prev-1], quote]; '; => ERROR; ENDCASE => start _ DLoc[start, -1]; ENDLOOP}; BackOverString: PROC [end: Loc] RETURNS [start: Loc] ~ { rope: ROPE ~ end.rope; size: INT ~ end.size; start _ DLoc[end, -1]; WHILE start.where > 0 DO c: CHAR ~ rope.Fetch[start.where]; SELECT c FROM '\\, '" => {next: Loc; odd: BOOL; [next, odd] _ BackOverSlashes[start]; IF odd OR c#'" THEN start _ next ELSE RETURN}; ENDCASE => start _ DLoc[start, -1]; ENDLOOP; RETURN [SetWhere[end, 0]]}; BackOverSlashes: PROC [end: Loc] RETURNS [start: Loc, odd: BOOL _ FALSE] ~ { DO end _ DLoc[end, -1]; IF end.where<0 OR end.rope.Fetch[end.where] # '\\ THEN RETURN [end, odd]; odd _ NOT odd; ENDLOOP}; FindGroupBegin: PROC [end: Loc] RETURNS [start: Loc, railed: BOOL] ~ { depth: INT _ 1; start _ end; DO tamed: BOOL; type: TokeType; [railed, tamed, start] _ BwdLoc[start]; IF railed THEN RETURN; [start, type] _ ToTokenStart[start, tamed]; SELECT type FROM openList, openVector => IF (depth _ depth.PRED) = 0 THEN RETURN; closeList => depth _ depth.SUCC; leaf, blank, quote => NULL; ENDCASE => ERROR; ENDLOOP}; PrevNonBlank: PROC [end: Loc] RETURNS [start: Loc, type: TokeType _ blank, railed: BOOL] ~ { start _ end; DO tamed: BOOL; [railed, tamed, start] _ BwdLoc[start]; IF railed THEN RETURN; [start, type] _ ToTokenStart[start, tamed]; SELECT type FROM blank => NULL; ENDCASE => RETURN; ENDLOOP}; FindGroupEnd: PROC [start: Loc] RETURNS [end: Loc, railed: BOOL] ~ { depth: INT _ 1; end _ start; DO type: TokeType; [railed, end] _ FwdLoc[end]; IF railed THEN RETURN; [end, type] _ ParseWholeToken[end]; SELECT type FROM closeList => IF (depth _ depth.PRED) = 0 THEN RETURN; openList, openVector => depth _ depth.SUCC; leaf, blank => NULL; quote => end _ FindQuoteEnd[end]; ENDCASE => ERROR; ENDLOOP}; FindQuoteEnd: PROC [start: Loc] RETURNS [end: Loc] ~ { railed: BOOL; type: TokeType; [railed, end] _ FwdLoc[start]; IF railed THEN RETURN [end]; [end, type] _ ParseWholeToken[end]; SELECT type FROM leaf => RETURN [end]; blank, quote => RETURN FindQuoteEnd[end]; openList, openVector => RETURN [FindGroupEnd[end].end]; closeList => RETURN [start]; ENDCASE => ERROR}; FwdLoc: PROC [loc: Loc] RETURNS [railed: BOOL, nl: Loc] ~ { nw: INT ~ loc.where.SUCC; IF nw < loc.size THEN { loc.where _ nw; loc.idx _ loc.idx.SUCC; RETURN [FALSE, loc]}; IF nw # (IF loc.size#0 THEN loc.size ELSE 1) THEN ERROR; nl.node _ TextNode.StepForward[loc.node]; IF nl.node=NIL THEN RETURN [TRUE, loc]; IF TextEditExtras.HasCharSets[nl.node] THEN SetNot0[nl.node]; nl.rope _ TextEditExtras.GetString[nl.node]; nl _ [nl.node, NIL, nl.rope, nl.rope.Length, 0, loc.idx+2]; IF loc.size=0 THEN nl.idx _ nl.idx.PRED; railed _ FALSE}; BwdLoc: PROC [loc: Loc] RETURNS [railed, tamed: BOOL, nl: Loc] ~ { IF loc.where > 0 THEN { c: CHAR ~ loc.rope.Fetch[loc.where]; loc.where _ loc.where.PRED; loc.idx _ loc.idx.PRED; RETURN [FALSE, c#'\l AND c#'\r, loc]}; IF loc.where < 0 THEN ERROR; [nl.node, nl.parent] _ TextNode.Backward[loc.node, loc.parent]; IF nl.node=NIL THEN RETURN [TRUE, TRUE, loc]; IF TextEditExtras.HasCharSets[nl.node] THEN SetNot0[nl.node]; nl.rope _ TextEditExtras.GetString[nl.node]; nl.size _ nl.rope.Length[]; nl.where _ nl.size-1; nl.idx _ loc.idx-2; IF nl.where=-1 THEN {nl.where _ 0; nl.idx _ nl.idx.SUCC}; railed _ tamed _ FALSE}; NImport: PROC [tnl: TextNode.Location, root: TextNode.Ref] RETURNS [Loc] ~ {RETURN Import[tnl, root]}; Import: PROC [tnl: TextNode.Location, root: TextNode.Ref] RETURNS [Loc] ~ INLINE { r: ROPE ~ TextEditExtras.GetString[tnl.node]; s: INT ~ r.Length[]; IF TextEditExtras.HasCharSets[tnl.node] THEN SetNot0[tnl.node]; tnl.where _ MAX[0, MIN[tnl.where, s-1]]; RETURN [[tnl.node, NIL, r, s, tnl.where, TextNode.LocOffset[[root, 0], tnl] ]]}; Export: PROC [loc: Loc] RETURNS [TextNode.Location] ~ INLINE {RETURN [[loc.node, loc.where]]}; LocOffset: PROC [loc1, loc2: Loc] RETURNS [INT] ~ {RETURN [TextNode.LocOffset[Export[loc1], Export[loc2]]]}; DLoc: PROC [loc: Loc, d: INT] RETURNS [Loc] ~ INLINE {RETURN [[loc.node, loc.parent, loc.rope, loc.size, loc.where+d, loc.idx+d]]}; SetWhere: PROC [loc: Loc, w: INT] RETURNS [Loc] ~ INLINE {RETURN [[loc.node, loc.parent, loc.rope, loc.size, w, loc.idx+w-loc.where]]}; SetInsertion: PROC [sel: TEditDocument.Selection, x, line: INTEGER, rightOfLine: BOOLEAN, tdd: TEditDocument.TEditDocumentData] RETURNS [TEditDocument.BeforeAfter] = {--copied from TEditMouseImpl, 'cause not exported node: TextNode.RefTextNode _ sel.start.pos.node; size: TextNode.Offset _ TextEdit.Size[node]; IF sel.start.line=sel.end.line AND sel.start.pos.where>=size THEN RETURN [before]; SELECT TEditProfile.selectionCaret FROM before => RETURN[ IF sel.start.pos=sel.end.pos AND sel.granularity=char AND rightOfLine AND tdd.lineTable.lines[line].end=eon THEN after ELSE before]; after => RETURN[ IF sel.start.pos.where=0 AND sel.start.pos=sel.end.pos AND sel.granularity=char AND x-sel.start.x <= sel.end.x+sel.end.w-x THEN before ELSE after]; ENDCASE; IF sel.start.line=line THEN { IF sel.end.line#line THEN RETURN [before]; IF sel.start.pos.where>=size THEN RETURN [before]; IF rightOfLine THEN { BlankAt: PROC [offset: INT] RETURNS [BOOL] ~ INLINE --gfi saver-- { char: Char.XCHAR; char _ TextEdit.FetchChar[node, offset]; RETURN CharOps.XBlank[char]}; RETURN [IF sel.start.pos=sel.end.pos -- single char selection AND sel.start.pos.where+1 < size -- not last char in node AND BlankAt[sel.start.pos.where] THEN before ELSE after]; }; RETURN[IF x-sel.start.x <= sel.end.x+sel.end.w-x THEN before ELSE after]; } ELSE IF sel.end.line=line THEN RETURN[after]; RETURN[IF line-sel.start.line <= sel.end.line-line THEN before ELSE after]; }; AbortSecondary: PROC = {--copied from TEditInputImpl, 'cause not exported SimpleFeedback.Append[$SchemeSelect, oneLiner, $Error, "Make a primary selection first."]; SimpleFeedback.Blink[$SchemeSelect, $Error]; TEditInput.editState _ abort; TEditInputBackdoor.mouseColor _ dead }; LocklessDoSelect: PROC [proc: PROC [tSel, refSel: TEditDocument.Selection, rightOfLine: BOOL], viewer: Viewer, tdd: TEditDocument.TEditDocumentData, x, y: INTEGER, sel: TEditDocument.SelectionId] = {--cloned from TEditMouseImpl.DoSelect on May 25, 1990 refSel: TEditDocument.Selection = SELECT sel FROM primary => TEditSelection.pSel, secondary => TEditSelection.sSel, feedback => TEditSelection.fSel, ENDCASE => ERROR; tSel: TEditDocument.Selection; rightOfLine: BOOL _ FALSE; tSel _ TEditSelection.Alloc[]; rightOfLine _ TEditSelectionPrivate.ResolveToChar[tSel, viewer, tdd, x, y]; proc[tSel, refSel, rightOfLine]; TEditSelection.Free[tSel] }; Register: PROC [name: ATOM, cmd: CmdPrivate] ~ { TEditInputExtras.RegisterClosure[[name, SelectCmd, NEW [CmdPrivate _ cmd] ]]; RETURN}; Register[$SchemeSelect0, [FALSE, FALSE, 0]]; Register[$SchemeSelect1, [FALSE, FALSE, 1]]; Register[$SchemeSelect2, [FALSE, FALSE, 2]]; Register[$SchemeSelect3, [FALSE, FALSE, 3]]; Register[$TrackSchemeSelect0, [FALSE, TRUE, 0]]; Register[$TrackSchemeSelect1, [FALSE, TRUE, 1]]; Register[$ExtendSchemeSelect, [TRUE, FALSE, 0]]; END. ς SchemeSelectImpl.Mesa Copyright Σ 1990 by Xerox Corporation. All rights reserved. Last tweaked by Mike Spreitzer on July 3, 1992 2:00 pm PDT Assume no token crosses lines; find beginning of line. Parse forward, returning the token that contains loc. This ensures caret before in empty nodes. caret goes before unless making single character selection to right of last character in node caret goes after unless making single character selection to left of middle of first character in node Κl– "cedar" style•NewlineDelimiter ™codešœ™K™œ(œ˜šžœœ˜šœ œ6˜EKšœœ˜K˜5K˜CK˜E——šž œœ6œŸ7˜ˆK˜/K˜(K˜.Kšœœœ˜%Kšœ œ˜#K˜.Kš œœœ œ œ&œ"˜„Kš œ œœ œ$œ˜Sšœœ œœ˜"Kšœœ ˜Kšœœœ˜K˜šœ˜˜šœœœ˜+K˜K˜3šœœœ˜K˜7šœ˜Kšœœ˜Kšœ@˜@K˜AKšœœ˜——Kšœ˜—K˜ Kšœœœœ˜.—˜šœœœ˜)K˜K˜(šœœœ˜Kšœ/˜/šœ˜Kšœœ˜K˜-KšœF˜FK˜=Kšœœ˜——Kšœ˜—K˜ Kšœœœœ˜,—Kšœœ˜—Kšœ˜—šœ œœ˜K˜/š œœœœœ˜5KšœF˜FKšœ˜—Kšœ ˜ Kšœ ˜ —K˜K˜K˜%K˜!K˜,K˜@šœœœ!œœœœ˜ΒKšœ˜K˜K˜K˜Kšœ!˜!Kšœ>œ˜EK˜—K˜—Kšœœ œœM˜tKšœ˜—K˜š ž œœœœœ˜ZK˜K˜.šœ˜Kšœ˜Kšœ-˜-Kšœ6˜6šœœ˜Kšœ&˜&Kšœœœ'˜5Kšœ$˜$Kšœ œ ˜—šœ œ˜Kšœ&˜&Kšœ$˜$Kšœ œ ˜———K˜šž œœ œ˜;Kšœ˜Kšœ"œ˜)šœ˜Kšœ>˜>Kšœ*˜*Kšœ!Οgœ˜5šœ˜Kšœ%˜%Kšœ œ˜,—Kšœœ˜—Kšœ˜—K˜Kšœ œ9˜GK˜šžœœœ'˜QKšœœ˜Kšœœ˜š ž œœœœœ˜(Kš œœœœœ œœ˜A—šž œœœ˜3šœ œœ œ˜+Kšœ œœ˜2šœ˜Kšœ.œ˜;Kšœ  œ ˜—Kšœ˜ ——šž œœœ˜7šœ ˜Kšœ œ ˜Kšœœœ˜9šœ˜!Kšœœ˜Kšœ œ œ˜#šœœœ˜-Kšœ œ˜Kšœ  œ ˜—Kšœœ˜—Kšœ˜ ——K˜ Kšœœœœ˜GKšœœœ˜+šœ˜!Kšœ œ˜ šœ ˜ Kšœœ œ˜Kš œœœ œœ˜6šœ˜Kšœœ˜%Kšœ  œ ˜—Kšœ˜ —Kšœœ&œ œ ˜NKšœœ˜Kšœœ˜Kšœ œ˜Kš œœ œ œœœœ ˜PKšœœ˜(šœœœ˜,Kšœœ œ˜1Kšœœ œ˜(Kšœœ  œ˜.Kšœœ˜)—Kšœœ ˜Kšœœ˜)—Kšœ˜—K˜šž œœœœ!˜SKšœœ ˜Kšœœ ˜š ž œœœœœ˜(Kš œœœœœ œœ˜A—K˜ Kšœœœ˜>Kšœœœ˜2šœœœ˜K™6šœ˜Kšœœœ˜šœ˜Kšœ œ˜Kšœ  œ˜#—Kšœ˜—Kšœ5™5š˜K˜ K˜%Kšœœœ˜4Kšœ œ ˜Kšœ˜—K˜—Kšœœ˜!š œ œœœœœ ˜FKšœœ œ˜Kšœœ˜Kš œœœœœ˜'Kšœ œœ˜—Kšœœœ œ˜AKšœœœ˜'šœ˜ Kšœœ˜Kš œœœœœ œ œ ˜VKšœœ˜šœœœ˜Kšœ œ˜ Kšœœœ˜;Kšœœ œ˜.—Kš œœœœœ œ˜Ošœ%˜%šœœ˜Kšœœœ ˜2Kšœœœ ˜5Kšœœ œ˜(——Kšœœ˜#š œœœœœ˜7Kšœœ œ˜"Kšœœ˜—Kšœœ˜ Kšœœ˜%——K˜š žœœœ œœœ˜:Kšœœœ˜Kšœ œœœ˜#šœœ œœ ˜#Kšœœœœ ˜FKšœ œ˜#Kšœ˜ ——K˜šž œœ œ!˜DKšœœœ ˜,Kšœ ˜ šœœœ˜ Kšœœœ˜1Kšœœœ!˜Fšœ˜Kšœœœ˜7Kšœœ˜+š œœœœ  œ˜EKšœœœœ˜JKšœœ"˜-—Kšœœ˜ Kšœ  œ˜#—Kšœ˜ ——K˜šžœœ œ˜8Kšœœœ ˜,Kšœ œ ˜šœ˜Kšœœ˜"šœ˜ šœœ˜!Kšœ%˜%Kš œœœœœ˜.—Kšœ  œ˜#—Kšœ˜—Kšœ˜—K˜š žœœ œœœ˜Lš˜Kšœ œ ˜Kšœ œ!œœ ˜IKšœœ˜Kšœ˜ ——K˜šžœœ œœ˜FKšœœ˜K˜ š˜Kšœœ˜ K˜K˜'Kšœœœ˜Kšœ+˜+šœ˜Kš œœœœœ˜@Kšœœ˜ Kšœœ˜Kšœœ˜—Kšœ˜ ——K˜šž œœ œ.œ˜\K˜ š˜Kšœœ˜ K˜'Kšœœœ˜Kšœ+˜+šœ˜Kšœ œ˜Kšœœ˜—Kšœ˜ ——K˜šž œœœœ˜DKšœœ˜K˜ š˜K˜K˜Kšœœœ˜Kšœ#˜#šœ˜Kš œ œœœœ˜5Kšœ&œ˜+Kšœœ˜K˜!Kšœœ˜—Kšœ˜ ——K˜šž œœœ˜6Kšœœ˜ K˜Kšœ˜Kšœœœ˜Kšœ#˜#šœ˜Kšœœ˜Kšœœ˜)Kšœœ˜7Kšœ œ ˜Kšœœ˜——K˜šžœœ œ œ˜;Kšœœ œ˜šœœ˜Kšœ˜Kšœœ˜Kšœœ˜—Kš œœ œ œœœ˜8Kšœ)˜)Kš œ œœœœ˜'Kšœ%œ˜=K˜,Kšœœ)˜;Kšœ œœ˜(Kšœ œ˜—K˜šžœœ œœ˜Bšœœ˜Kšœœ˜$Kšœœ˜Kšœœ˜Kšœœœ˜&—Kšœœœ˜Kšœ?˜?Kš œ œœœœœ˜-Kšœ%œ˜=K˜,K˜K˜K˜Kšœ œ œ˜9Kšœœ˜—K˜šžœœ.œ˜HKšœœ˜—K˜šžœœ.œ œ˜RKšœœ&˜-Kšœœ˜Kšœ&œ˜?Kšœ œœ˜(Kšœ œ:˜P—K˜šžœœ œ˜3Kšœœœ˜*—K˜šž œœœœ˜/Kšœœ3˜<—K˜š Πgnžœœœœ˜+KšœœœG˜W—K˜šžœœœœ˜/KšœœœG˜W—K˜š ž œœ)œœ(œ Ÿ1˜ΨK˜0K˜,Kšœœœœ ˜RKšœ)™)šœ˜'šœ œ˜Kšœ]™]Kš œœœ œ#œœ ˜„—šœ œ˜Kšœf™fKš œœœœ(œœ˜“—Kšœ˜—šœœ˜Kšœœœ ˜*Kšœœœ ˜2šœ œ˜šžœœ œœœœŸ œ˜CKšœ œ˜K˜(Kšœ˜—šœœŸ˜=KšœŸ˜9Kšœ˜ Kšœœ˜—Kšœ˜—Kšœœ(œœ˜IK˜—Kšœœœœ˜-Kšœœ*œœ˜KK˜—K˜šžœœŸ1˜IK˜ZK˜,KšœC˜CK˜—K˜š žœœœ6œ?œ%Ÿ5˜όšœ"˜"šœ˜Kšœ˜Kšœ!˜!Kšœ ˜ Kšœœ˜——K˜Kšœ œœ˜K˜K˜KK˜ K˜K˜—K˜šžœœœ˜0Kšœ3œ˜MKšœ˜—K˜Kšœœœ˜,Kšœœœ˜,Kšœœœ˜,Kšœœœ˜,Kšœœœ˜0Kšœœœ˜0Kšœœœ˜0K˜Kšœ˜—…—F^t