DIRECTORY Basics, BasicTime, DFOperations, DFUtilities, FS, IO, List, ProcessProps, RedBlackTree, Rope, TEditOps, UserProfile, ViewerClasses, ViewerTools; GetDWIM: CEDAR PROGRAM IMPORTS DFUtilities, FS, IO, RedBlackTree, Rope, TEditOps, UserProfile, ViewerTools = BEGIN ROPE: TYPE = Rope.ROPE; ROPEList: TYPE = LIST OF ROPE; Viewer: TYPE = ViewerClasses.Viewer; inPlace, processDF, assocExts, followAttachments, tryRenaming: BOOLEAN _ FALSE; OldFNP: PROC [ROPE, Viewer] RETURNS [fileName: ROPE, search: ROPE] _ NIL; log: IO.STREAM _ NIL; Debug: PROC = {log _ IO.ROS[]}; DontDebug: PROC = {log _ NIL}; GetLog: PROC RETURNS [r: ROPE] = {r _ log.RopeFromROS[]}; sourceFileExtensions, implFileExtensions: ROPEList _ NIL; DWIMit: PROC [orgName: ROPE, viewer: Viewer] RETURNS [fileName: ROPE, search: ROPE] = BEGIN Try: PROC [dir, short: ROPE, BaseMatch, FullMatch: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL]] RETURNS [stop: BOOL] = { cp: FS.ComponentPositions; expanded, dirPart: ROPE; stop _ FALSE; [expanded, cp, ] _ FS.ExpandName[dir.Concat[short], NIL]; dirPart _ expanded.Substr[start: 0, len: cp.base.start]; IF goalVersioned THEN { IF expanded.Substr[start: cp.base.start, len: cp.ver.start+cp.ver.length - cp.base.start].Equal[s2: goalFull, case: FALSE] THEN stop _ FullMatch[dirPart, goalFull, NIL]; } ELSE { testBase: ROPE _ expanded.Substr[start: cp.base.start, len: cp.base.length]; testExt: ROPE _ expanded.Substr[start: cp.ext.start, len: cp.ext.length]; IF testBase.Equal[goalBase, FALSE] THEN { stop _ IF testExt.Equal[goalExt, FALSE] THEN FullMatch[dirPart, goalFull, NIL] ELSE BaseMatch[dirPart, testBase, testExt] }; }; stop _ stop; }; FullMatch: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL] = { IF Exists[fileName _ dir.Cat[file]] THEN { search _ ext; RETURN [found _ TRUE]}; stop _ stop; }; BaseMatch: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL] = { allButExt: ROPE _ dir.Cat[file]; stop _ FALSE; IF goalExtended THEN { IF assocExts AND Exists[fileName _ allButExt.Cat[".", goalExt]] THEN { search _ NIL; RETURN [found _ TRUE]}; IF Member[ext, implFileExtensions] AND Exists[fileName _ allButExt.Cat[".", ext]] THEN { search _ goalExt; RETURN [found _ TRUE]}; IF assocExts AND NOT allButExt.Equal[lastImplAssoced, FALSE] THEN { lastImplAssoced _ allButExt; FOR ifel: ROPEList _ implFileExtensions, ifel.rest WHILE ifel # NIL DO IF Exists[fileName _ allButExt.Cat[".", ifel.first]] THEN { search _ goalExt; RETURN [found _ TRUE]}; ENDLOOP; }; }; IF NOT goalExtended THEN { IF Member[ext, sourceFileExtensions] AND Exists[fileName _ allButExt.Cat[".", ext]] THEN { search _ NIL; RETURN [found _ TRUE]}; IF assocExts AND NOT allButExt.Equal[lastSourceAssoced, FALSE] THEN { lastSourceAssoced _ allButExt; FOR ifel: ROPEList _ sourceFileExtensions, ifel.rest WHILE ifel # NIL DO IF Exists[fileName _ allButExt.Cat[".", ifel.first]] THEN { search _ goalExt; RETURN [found _ TRUE]}; ENDLOOP; }; }; stop _ stop; }; found: BOOL _ FALSE; goalFull, goalExpanded, goalBase, goalExt: ROPE; goalCP: FS.ComponentPositions; goalExtended, goalVersioned: BOOL; wDir: ROPE _ IF viewer # NIL THEN TEditOps.WorkingDirectoryFromViewer[viewer] ELSE NIL; lastSourceAssoced, lastImplAssoced: ROPE _ NIL; dotPos: INT; mesaNote: MesaNote; IF tryRenaming AND (dotPos _ orgName.Find["."]) >= 0 AND (mesaNote _ GetMesaNote[viewer]) # NIL THEN { short: ROPE _ orgName.Substr[len: dotPos]; rest: ROPE _ orgName.Substr[start: dotPos]; found: BOOL _ FALSE; FOR ml: MapList _ mesaNote.maps, ml.rest WHILE ml # NIL AND NOT found DO IF ml.first.short.Equal[short] THEN { found _ TRUE; orgName _ ml.first.long.Concat[rest]; }; ENDLOOP; }; goalFull _ orgName; [goalExpanded, goalCP, ] _ FS.ExpandName[orgName]; goalBase _ goalExpanded.Substr[start: goalCP.base.start, len: goalCP.base.length]; goalExt _ goalExpanded.Substr[start: goalCP.ext.start, len: goalCP.ext.length]; goalExtended _ goalCP.ext.length # 0; goalVersioned _ goalCP.ver.length # 0; { Consume: PROC [fullFName, attachedTo: ROPE, created: BasicTime.GMT, bytes: INT, keep: CARDINAL] RETURNS [continue: BOOLEAN] --FS.InfoProc-- = { IF Try[NIL, fullFName, BaseMatch, FullMatch] THEN RETURN [FALSE]; IF followAttachments AND attachedTo # NIL AND Try[NIL, attachedTo, BaseMatch, FullMatch] THEN RETURN [FALSE]; }; IF assocExts AND followAttachments THEN { FS.EnumerateForInfo[pattern: goalBase.Cat["!H"], proc: Consume, wDir: wDir !FS.Error => CONTINUE]; IF found THEN RETURN; FS.EnumerateForInfo[pattern: goalBase.Cat[".*!H"], proc: Consume, wDir: wDir !FS.Error => CONTINUE]; IF found THEN RETURN; } ELSE { EnumerateForInfo[base: goalBase, exts: sourceFileExtensions, proc: Consume, wDir: wDir]; IF found THEN RETURN; }; }; IF viewer # NIL THEN BEGIN IF processDF AND IsADFFileName[viewer.file] THEN BEGIN [] _ Find[viewer.file, Try, BaseMatch, FullMatch]; IF found THEN RETURN; END; END; IF OldFNP # NIL THEN [fileName, search] _ OldFNP[orgName, viewer] ELSE {fileName _ search _ NIL}; END; EnumerateForInfo: PROC [base: ROPE, exts: ROPEList, proc: FS.InfoProc, wDir: ROPE _ NIL] = { FOR exts _ exts, exts.rest WHILE exts # NIL DO fullFName, attachedTo: ROPE; keep: CARDINAL; bytes: INT; created: BasicTime.GMT; [fullFName:fullFName, attachedTo:attachedTo, keep:keep, bytes:bytes, created:created] _ FS.FileInfo[name: base.Cat[".", exts.first], remoteCheck: FALSE, wDir: wDir !FS.Error => LOOP]; IF NOT proc[fullFName:fullFName, attachedTo:attachedTo, keep:keep, bytes:bytes, created:created] THEN EXIT; ENDLOOP; wDir _ wDir; }; Find: PROC [ dfFileName: ROPE, Try: PROC [ dir, short: ROPE, BaseMatch, FullMatch: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL]] RETURNS [stop: BOOL], BaseMatch, FullMatch: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL]] RETURNS [stopped: BOOL] = BEGIN PerItem: PROC [item: REF ANY] RETURNS [stop: BOOL _ FALSE] --DFUtilities.ProcessItemProc-- = BEGIN WITH item SELECT FROM di: REF DFUtilities.DirectoryItem => dir _ di.path1; fi: REF DFUtilities.FileItem => IF Try[dir, fi.name, BaseMatch, FullMatch] THEN stop _ TRUE; ii: REF DFUtilities.ImportsItem => { IF Try[NIL, ii.path1, BaseMatch, FullMatch] THEN stop _ TRUE ELSE { tryThis: BOOL _ ii.list = NIL; RightOn: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL] = { tryThis _ stop _ TRUE; }; Almost: PROC [dir, file, ext: ROPE] RETURNS [stop: BOOL] = { IF stop _ assocExts THEN tryThis _ TRUE; }; IF NOT tryThis THEN FOR i: NAT IN [0 .. ii.list.nEntries) WHILE NOT tryThis DO [] _ Try["[]<>", ii.list[i].name, Almost, RightOn]; ENDLOOP; IF tryThis THEN stop _ Find[ii.path1, Try, BaseMatch, FullMatch]; }; }; ii: REF DFUtilities.IncludeItem => stop _ Find[ii.path1, Try, BaseMatch, FullMatch]; c: REF DFUtilities.CommentItem => NULL; w: REF DFUtilities.WhiteSpaceItem => NULL; ENDCASE => ERROR; stopped _ stop; END; from: IO.STREAM _ NIL; dir: ROPE _ NIL; stopped _ FALSE; from _ FS.StreamOpen[dfFileName !FS.Error => CONTINUE]; IF from = NIL THEN RETURN; DFUtilities.ParseFromStream[in: from, proc: PerItem]; from.Close[]; END; Member: PROC [r: ROPE, in: ROPEList] RETURNS [m: BOOL] = { FOR in _ in, in.rest WHILE in # NIL DO IF in.first.Equal[r, FALSE] THEN RETURN [TRUE]; ENDLOOP; m _ FALSE}; IsADFFileName: PROC [name: ROPE] RETURNS [isa: BOOLEAN] = {isa _ name.Find[s2: ".DF!", case: FALSE] >= 0}; Exists: PROC [fileName: ROPE] RETURNS [exists: BOOLEAN] = BEGIN exists _ TRUE; [] _ FS.FileInfo[name: fileName, remoteCheck: FALSE ! FS.Error => {exists _ FALSE; CONTINUE}]; exists _ exists; --wouldn't it be nice if we could really break on exit? END; MesaNote: TYPE = REF MesaNoteRep; MesaNoteRep: TYPE = RECORD [ name: ROPE, maps: MapList ]; MapList: TYPE = LIST OF Map; Map: TYPE = RECORD [short, long: ROPE]; mesaNotes: RedBlackTree.Table _ RedBlackTree.Create[GetMNKey, CompareMNs]; FlushMesaCache: PROC = { mesaNotes _ RedBlackTree.Create[GetMNKey, CompareMNs]; }; GetMesaNote: PROC [v: Viewer] RETURNS [mn: MesaNote] = { vFull: ROPE _ NIL; vcp: FS.ComponentPositions; ext, name: ROPE; IF v = NIL THEN RETURN [NIL]; [vFull, vcp] _ FS.ExpandName[v.name !FS.Error => CONTINUE]; IF vFull = NIL THEN RETURN [NIL]; ext _ vFull.Substr[start: vcp.ext.start, len: vcp.ext.length]; IF NOT (ext.Equal["mesa", FALSE] OR ext.Equal["cedar", FALSE]) THEN RETURN [NIL]; name _ vFull.Substr[len: vcp.ext.start + vcp.ext.length]; mn _ NARROW[mesaNotes.Lookup[name]]; IF mn # NIL THEN RETURN; mn _ NEW [MesaNoteRep _ [ name: name, maps: AnalyzeMesa[ViewerTools.GetContents[v]] ]]; mesaNotes.Insert[mn, mn.name]; }; AnalyzeMesa: PROC [module: ROPE] RETURNS [maps: MapList] = { ENABLE IO.Error => CONTINUE; Work: PROC [intro: ROPE] = { start: INT = module.Find[intro]; in: IO.STREAM; toke: ROPE; IF start < 0 THEN RETURN; in _ IO.RIS[module.Substr[start: start]]; toke _ in.GetCedarTokenRope[].token; IF toke.Equal[intro] THEN { FOR toke _ in.GetCedarTokenRope[].token, in.GetCedarTokenRope[].token DO short, long: ROPE; IF toke.Equal[";"] OR toke.Equal["}"] OR toke.Equal["END"] OR toke.Equal["="] OR toke.Equal["EXPORTS"] OR toke.Equal["SHARES"] THEN EXIT; short _ toke; toke _ in.GetCedarTokenRope[].token; IF toke.Equal[","] THEN LOOP; IF NOT toke.Equal[":"] THEN EXIT; long _ in.GetCedarTokenRope[].token; maps _ CONS[[short, long], maps]; toke _ in.GetCedarTokenRope[].token; IF NOT toke.Equal[","] THEN EXIT; ENDLOOP; }; in.Close[]; }; maps _ NIL; Work["IMPORTS"]; Work["OPEN"]; }; GetMNKey: PROC [data: REF ANY] RETURNS [key: ROPE] = { mn: MesaNote = NARROW[data]; RETURN [mn.name]; }; CompareMNs: PROC [k, data: REF ANY] RETURNS [Basics.Comparison] = { k1: ROPE = NARROW[k]; k2: ROPE = GetMNKey[data]; RETURN [k1.Compare[k2]]; }; NoticeProfileChanges: PROC [reason: UserProfile.ProfileChangeReason] --UserProfile.ProfileChangedProc-- = BEGIN tryRenaming _ UserProfile.Boolean["GetDWIM.TryRenaming", TRUE]; processDF _ UserProfile.Boolean["GetDWIM.ProcessDF", TRUE]; assocExts _ UserProfile.Boolean["GetDWIM.AssociateExtensions", TRUE]; followAttachments _ UserProfile.Boolean["GetDWIM.FollowAttachments", TRUE]; sourceFileExtensions _ UserProfile.ListOfTokens["SourceFileExtensions", LIST["mesa", "tioga", "df", "cm", "config", "style"]]; implFileExtensions _ UserProfile.ListOfTokens["ImplFileExtensions", LIST["mesa", "cedar"]]; IF (processDF OR assocExts) AND NOT inPlace THEN BEGIN inPlace _ TRUE; OldFNP _ TEditOps.ReplaceFileNameProc[DWIMit]; END; END; UserProfile.CallWhenProfileChanges[NoticeProfileChanges]; END. ΞGetDWIM.Mesa Last Edited by: Spreitzer, October 2, 1985 9:19:42 pm PDT First, see if it's from a renaming OPEN. Next, look around locally. Next, try DF-file smarts. Lastly, try whatever we replaced. Κΐ– "cedar" style˜šœ ™ J™9—J˜IcodešΟk œ/œœ\˜šK˜šΠbxœœ˜Kšœœœ:˜U—K˜Kš˜K˜Kšœœœ˜Kš œ œœœœ˜Kšœœ˜$K˜Kšœ?œœ˜OK˜KšΟnœœœ œ œ œœ˜IK˜Kšœœœœ˜K˜KšŸœœ œœ˜K˜KšŸ œœ œ˜K˜KšŸœœœœ˜9K˜Kšœ5œ˜9K˜š Ÿœœ œœ œ œ˜UKš˜šŸœœœ Ÿ œœœœœœœ˜}Kšœœ˜Kšœœ˜Kšœœ˜ Kšœœœ˜9K˜8šœœ˜Kšœrœœ%œ˜©K˜—šœ˜Kšœ œ>˜LKšœ œ<˜Išœœœ˜)Kš œœœœœœ&˜yK˜—K˜—K˜ K˜—š Ÿ œœœœœ˜?šœ"œ˜*K˜ Kšœ œ˜—K˜ K˜—š Ÿ œœœœœ˜?Kšœ œ˜ Kšœœ˜ šœœ˜šœ œ0œ˜FKšœ œ˜ Kšœ œ˜—šœ!œ,œ˜XKšœ˜Kšœ œ˜—š œ œœ"œœ˜CKšœ˜šœ0œœ˜Fšœ3œ˜;Kšœ˜Kšœ œ˜—Kšœ˜—K˜—K˜—šœœœ˜šœ#œ,œ˜ZKšœ œ˜ Kšœ œ˜—š œ œœ$œœ˜EKšœ˜šœ2œœ˜Hšœ3œ˜;Kšœ˜Kšœ œ˜—Kšœ˜—K˜—K˜—K˜ K˜—Kšœœœ˜Kšœ+œ˜0Kšœœ˜Kšœœ˜"Kš œœœ œœ-œœ˜WKšœ$œœ˜/Kšœœ˜ Kšœ˜K™(š œ œ#œ$œœ˜fKšœœ˜*Kšœœ!˜+Kšœœœ˜š œ&œœœœ˜Hšœœ˜%Kšœœ˜ K˜%K˜—Kšœ˜—K˜—K˜Kšœœ˜2KšœR˜RKšœO˜OKšœ%˜%Kšœ&˜&™Kšœ˜šŸœœœœ œœœ œΟcœ˜Kš œœ#œœœ˜AKšœœœœœ$œœœ˜mK˜—šœ œœ˜)KšœJœ œ˜bKšœœœ˜KšœLœ œ˜dKšœœœ˜K˜—šœ˜KšœX˜XKšœœœ˜K˜—K˜—K™šœ œ˜Kš˜šœ œ˜0Kš˜K˜2Kšœœœ˜Kšœ˜—Kšœ˜—K™!Kšœ œœ-˜AKšœœ˜Kšœ˜—K˜š Ÿœœœœœœ˜\šœœœ˜.Kšœœ˜Kšœœ˜Kšœœ˜ Kšœœ˜Kš œXœ8œœ œ˜·Kšœœ[œœ˜kKšœ˜—K˜ K˜—K˜šŸœ˜ šœ˜Kšœ œ˜šŸœ˜ šœ˜Kšœ œ˜Kš œ Ÿ œœœœœ˜G—Kšœœ˜—Kš œ Ÿ œœœœœ˜G—Kšœ œ˜Kš˜šŸœœœœœœœ œ˜\Kš˜šœœ˜Kšœœ-˜4Kš œœœ)œœ˜\šœœ˜$Kšœœ"œ˜<šœ˜Kšœ œ œ˜š Ÿœœœœœ˜=Kšœœ˜K˜—š Ÿœœœœœ˜Kšœœœœœœœœ˜QK˜9Kšœœ˜$Kšœœœœ˜šœœ˜K˜ Kšœ-˜-K˜—K˜K˜—K˜šŸ œœ œœ˜