IconHacks.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Mike Spreitzer March 5, 1987 10:30:27 am PST
Last tweaked by Mike Spreitzer on October 6, 1989 2:37:26 pm PDT
Eduardo Pelegri-Llopart January 5, 1989 1:15:48 pm PST
Willie-s, February 14, 1992 6:04 pm PST
Doug Wyatt, September 25, 1992 2:42 pm PDT
DIRECTORY Atom, BackStop, Commander, FS, IconRegistry, IO, List, MessageWindow, Rope, SystemNames, TextReplace, UserProfile, ViewerClasses, ViewerEvents, ViewerLocks, ViewerOps;
IconHacks: CEDAR PROGRAM
IMPORTS Atom, BackStop, Commander, FS, IconRegistry, IO, List, MessageWindow, Rope, SystemNames, TextReplace, UserProfile, ViewerEvents, ViewerLocks, ViewerOps
=
BEGIN
ROPE: TYPE ~ Rope.ROPE;
LOR: TYPE ~ LIST OF ROPE;
myKey: REF ¬ Atom.MakeAtom["the label created by IconHacks"];
hackLabels, hackIcons: BOOL ¬ FALSE;
subst: TextReplace.RopeMap ¬ NIL;
pairs: TextReplace.PairList ¬ NIL;
Hackit: PROC [viewer: ViewerClasses.Viewer, event: ViewerEvents.ViewerEvent, before: BOOL] RETURNS [abort: BOOL ¬ FALSE] --ViewerEvents.EventProc-- ~ {
HackLabel: PROC ~ {
name: ROPE ~ viewer.name;
label: ROPE ¬ name;
IF event # close OR List.Assoc[myKey, viewer.props] # viewer.label THEN RETURN;
IF NOT hackLabels THEN {viewer.label ¬ NIL; RETURN};
{cache: LOR ¬ WITH List.Assoc[key: subst, aList: viewer.props] SELECT FROM
x: LOR => x,
ENDCASE => NIL;
IF cache # NIL AND cache.rest # NIL AND cache.rest.rest = NIL AND cache.first = viewer.name THEN {viewer.label ¬ cache.rest.first; RETURN};
label ¬ subst.Apply[label];
cache ¬ LIST[name, label];
viewer.props ¬
List.PutAssoc[subst, cache,
List.PutAssoc[myKey, label,
viewer.props]];
viewer.label ¬ label;
}};
HackIcon: PROC ~ {
IF hackIcons AND viewer.parent=NIL AND viewer.file#NIL THEN {
Icon: PROC [r1, r2: ROPE ¬ NIL] RETURNS [found: BOOL] ~ {
iconName ¬ UserProfile.Token[key: Rope.Cat["IconHacks.", r1, r2]];
RETURN [iconName#NIL]
};
cp: FS.ComponentPositions;
fullFName, extension, iconName: ROPE;
[cp: cp, fullFName: fullFName] ¬ FS.ExpandName[name: viewer.file];
extension ¬ Rope.Substr[base: fullFName, start: cp.ext.start, len: cp.ext.length];
SELECT TRUE FROM
viewer.newVersion AND Icon["DirtyIcon.", extension] => {};
Icon["Icon.", extension] => {};
viewer.newVersion AND (iconName ¬ IconRegistry.IsRegistered[Rope.Concat["Dirty", extension]].name)#NIL => {};
(iconName ¬ IconRegistry.IsRegistered[extension].name)#NIL => {};
viewer.newVersion AND Icon["DefaultDirtyIcon"] => {};
Icon["DefaultIcon"] => {};
ENDCASE => iconName ¬ iconName;
IF iconName#NIL THEN {
viewer.icon ¬ IconRegistry.GetIcon[iconName: iconName, default: viewer.icon];
IF event#close THEN ViewerOps.PaintViewer[viewer, caption] ELSE viewer ¬ viewer;
}
ELSE hackIcons ¬ hackIcons;
}
ELSE viewer ¬ viewer;
};
BackStopped: PROC ~ {
HackLabel[];
HackIcon[];
RETURN};
WithLock: PROC ~ {
IF lastMsg.Length[] > 0 THEN lastErr ¬ lastMsg;
lastMsg ¬ BackStop.Call[inner: BackStopped];
RETURN};
IF event=close OR viewer.iconic
THEN ViewerLocks.CallUnderWriteLock[WithLock, viewer]
ELSE event ¬ event;
RETURN};
lastErr, lastMsg: ROPE ¬ NIL;
NoteProfile: PROC [reason: UserProfile.ProfileChangeReason] --UserProfile.ProfileChangedProc-- ~ {
user: ROPE ~ SystemNames.UserName[];
asRope: ROPE ~ UserProfile.Line["IconHacks.LabelSubstitutions", "defaults"];
in: IO.STREAM ~ IO.RIS[asRope];
head, tail: TextReplace.PairList ¬ NIL;
DO
ENABLE IO.EndOfStream => {
MessageWindow.Append["Syntax error in IconHacks.LabelSubstitutions profile entry", TRUE];
EXIT};
[] ¬ in.SkipWhitespace[];
IF in.EndOf[] THEN EXIT;
{find: ROPE ~ GetToken[in];
this: TextReplace.PairList;
IF find.Equal["defaults", FALSE] THEN {
this ¬ LIST[
["/Cedar/", "c/", TRUE],
["/Cedar10.1/", "c/", TRUE],
["/PCedar2.0/", "pc/", TRUE],
[SystemNames.SimpleHomeDirectory[], "~/", TRUE, FALSE, TRUE],
[".mesa", ".m", TRUE, FALSE, TRUE],
[".config", ".c", TRUE, FALSE, TRUE] ]
this ¬ LIST[
["<mn:~$~$> ('$&) :", "<mn>:"],
["<mn:~$~$> ('$&) WD = ~$~$ :", "<mn>:"],
["[Cedar7.0]", "dc]", TRUE],
["[CedarChest7.0]", "dcc]", TRUE],
["/pseudo/cedarchest7.0/", "dcc/", TRUE],
["/pseudo/cedar7.0/", "dc/", TRUE],
["[PCedar2.0]", "pc]", TRUE],
["/pseudo/pcedar2.0/", "pc/", TRUE],
[Rope.Cat["/pseudo/", SystemNames.ReleaseDir["cedar", current], "/"], "c/", TRUE],
[Rope.Cat["/", SystemNames.ReleaseDir["Cedar", current], "/"], "c/", TRUE],
[SystemNames.SimpleHomeDirectory[], "~/", TRUE, FALSE, TRUE],
["Telephone Directory:", "TD", TRUE],
[".mesa", ".m", TRUE, FALSE, TRUE],
[".config", ".c", TRUE, FALSE, TRUE] ]
}
ELSE {
literal, ignoreCase: BOOL ¬ TRUE;
word: BOOL ¬ FALSE;
sense: BOOL ¬ TRUE;
UNTIL MyBreak[in.PeekChar[]]=sepr DO
switch: CHAR ~ in.GetChar[];
SELECT switch FROM
'- => sense ¬ FALSE;
'+ => sense ¬ TRUE;
'l => literal ¬ sense;
'p => literal ¬ NOT sense;
'w => word ¬ sense;
'c => ignoreCase ¬ NOT sense;
'b => addBounds ¬ sense;
ENDCASE => MessageWindow.Append[IO.PutFR["Invalid IconsHacks switch %c after %g", [character[switch]], [rope[find]] ], TRUE];
ENDLOOP;
this ¬ LIST[[find, GetToken[in], literal, word, ignoreCase]];
};
IF tail = NIL THEN head ¬ this ELSE tail.rest ¬ this;
FOR tail ¬ this, tail.rest WHILE tail.rest # NIL DO NULL ENDLOOP;
tail ¬ tail}ENDLOOP;
subst ¬ TextReplace.RopeMapFromPairs[pairs ¬ head];
hackLabels ¬ UserProfile.Boolean[key: "IconHacks.HackLabels", default: FALSE];
hackIcons ¬ UserProfile.Boolean[key: "IconHacks.HackIcons", default: FALSE];
};
GetToken: PROC [in: IO.STREAM] RETURNS [token: ROPE] ~ {
[] ¬ in.SkipWhitespace[];
token ¬ SELECT in.PeekChar[] FROM
'" => in.GetRopeLiteral[],
ENDCASE => in.GetTokenRope[MyBreak].token;
};
MyBreak: PROC [char: CHAR] RETURNS [IO.CharClass] --IO.BreakProc-- ~ {
RETURN [SELECT char FROM
IN [0C .. ' ] => sepr,
ENDCASE => other];
};
ListHacksCmd: PROC [cmd: Commander.Handle] RETURNS [result: REF ¬ NIL, msg: ROPE ¬ NIL] --Commander.CommandProc-- ~ {
FOR pl: TextReplace.PairList ¬ pairs, pl.rest WHILE pl#NIL DO
cmd.out.PutFL["\"%q\" => \"%q\" %g %g %g %g\n", LIST[ [rope[pl.first.match]], [rope[pl.first.replace]], [boolean[pl.first.literal]], [boolean[pl.first.word]], [boolean[pl.first.ignoreCase]] ]];
ENDLOOP;
RETURN};
hreg: ViewerEvents.EventRegistration ¬ ViewerEvents.RegisterEventProc[Hackit, close];
regs: LIST OF ViewerEvents.EventRegistration ¬ LIST[
ViewerEvents.RegisterEventProc[proc: Hackit, event: close, before: TRUE],
ViewerEvents.RegisterEventProc[proc: Hackit, event: save, before: FALSE],
ViewerEvents.RegisterEventProc[proc: Hackit, event: edit, before: FALSE]];
UserProfile.CallWhenProfileChanges[NoteProfile];
Commander.Register["IconHacksList", ListHacksCmd, "lists the icon label substitutions"];
END.