CDCommandOpsImpl.mesa
by Christian Jacobi July 12, 1984 3:49:16 pm PDT
last edited Christian Jacobi July 12, 1984 3:49:19 pm PDT
DIRECTORY
Atom,
CD,
CDApplications,
CDCallSpecific,
CDCommandOps,
CDOps,
CDProperties,
CDSequencer,
CDValue,
Rope,
SymTab,
TerminalIO;
CDCommandOpsImpl: CEDAR PROGRAM
IMPORTS Atom, CDApplications, CDCallSpecific, CDOps, CDProperties, CDSequencer, CDValue, Rope, SymTab, TerminalIO
EXPORTS CDCommandOps =
BEGIN
-- -- -- -- -- --
--generic
ProbablyLastChar: PROC [r: Rope.ROPE] RETURNS [CHAR] =
BEGIN
l: INT = r.Length[];
IF l<=0 THEN RETURN ['@];
RETURN [r.Fetch[l-1]]
END;
-- -- -- -- -- --
--ImplementSpecificCommand
Entry: TYPE = RECORD [key: ATOM, text: Rope.ROPENIL, x: REF];
tableKey: REF = NEW[ATOM←$tableKey]; -- indirect to make inaccessible
gTable: SymTab.Ref = SymTab.Create[];
GetTTable: PROC [t: CD.Technology] RETURNS [table: SymTab.Ref] =
BEGIN
IF t=NIL THEN table←gTable
ELSE {
x: REF ← CDValue.Fetch[boundTo: t, key: tableKey, propagation: technology];
IF x=NIL THEN {
x ← SymTab.Create[7];
CDValue.Store[boundTo: t, key: tableKey, value: x]
};
TRUSTED {table ← LOOPHOLE[x]}
}
END;
GetEntry: PROC [tipKey: Rope.ROPE, tech: CD.Technology] RETURNS [entry: REF Entry←NIL] =
BEGIN
IF tipKey.Length[]>=2 THEN {
x: REF;
found: BOOL ← FALSE;
tipKey ← tipKey.Substr[len: tipKey.Length[]];
IF tech#NIL THEN [found, x] ← SymTab.Fetch[GetTTable[tech], tipKey];
IF NOT found THEN [found, x] ← SymTab.Fetch[gTable, tipKey];
IF found THEN
WITH x SELECT FROM e: REF Entry => entry𡤎 ENDCASE => NULL
}
END;
GeneralCommand: PROC [comm: CDSequencer.Command] =
BEGIN
n: NAT𡤀
t: Rope.ROPE = Atom.GetPName[comm.a];
entry: REF Entry = GetEntry[t, comm.design.technology];
IF entry=NIL THEN {
TerminalIO.WriteRope["unknown command: "];
TerminalIO.WriteRope[t];
}
ELSE {
TerminalIO.WriteRope[entry.text];
TerminalIO.WriteRope[" "];
SELECT ProbablyLastChar[t] FROM
'S => {
TerminalIO.WriteRope["selected "];
n ← CDCallSpecific.CallForSelected[design: comm.design, objectSpecific: entry.key, x: entry.x];
};
'P => {
TerminalIO.WriteRope["pointed "];
n ← CDCallSpecific.CallForPointed[design: comm.design, point: comm.pos, objectSpecific: entry.key, x: entry.x];
};
'A => {
TerminalIO.WriteRope["all "];
n ← CDCallSpecific.CallForAll[design: comm.design, objectSpecific: entry.key, x: entry.x];
};
'X => {
TerminalIO.WriteRope["(if 1 selected) "];
n ← CDCallSpecific.CallIfOneSelected[design: comm.design, objectSpecific: entry.key, x: entry.x];
};
'F => {
TerminalIO.WriteRope["(first selected) "];
n ← CDCallSpecific.CallForOneSelected[design: comm.design, objectSpecific: entry.key, x: entry.x];
};
ENDCASE => TerminalIO.WriteRope["bad modifier"];
};
TerminalIO.WriteRope["\n "];
TerminalIO.WriteInt[n]; TerminalIO.WriteRope[" objects handled\n"];
END;
ImplementSpecificCommand: PUBLIC PROC [specificAtom: ATOM, text: Rope.ROPENIL, tipBase: Rope.ROPENIL, useFor: Rope.ROPENIL, x: REFNIL, technology: CD.Technology←NIL] =
--Implements a command which is executed by using CDCallSpecific
--specificAtom: handled through to select CDCallSpecific command
--text: logged; defaults to tipBase
--tipBase: How command is called in tiptable; defaults to specificAtom
--useFor: Suffix letters appended to tipBase getting the tip table entry
--x: handled through to CDCallSpecific
--technology: NIL => all technologies
BEGIN
t: SymTab.Ref = GetTTable[technology];
entry: REF Entry;
EachKey: Rope.ActionType -- PROC [c: CHAR] RETURNS [quit: BOOL ← FALSE] -- =
BEGIN
SELECT c FROM
'P, 'S, 'A, 'F, 'X => {
fiddledTip: Rope.ROPE ← Rope.Concat[tipBase, Rope.FromChar[c]];
[] ← SymTab.Store[t, fiddledTip, entry];
CDSequencer.ImplementCommand[Atom.MakeAtom[fiddledTip], GeneralCommand, technology];
}
ENDCASE => NULL
END;
--set up defaults
IF useFor=NIL THEN useFor ← "PS";
IF tipBase=NIL THEN tipBase ← Atom.GetPName[specificAtom];
IF text=NIL THEN text ← tipBase;
SELECT ProbablyLastChar[text] FROM
'\n, ' => text ← text.Substr[len: text.Length[]-1];
ENDCASE => NULL;
--do it
entry ← NEW[Entry ← [key: specificAtom, text: text, x: x]];
[] ← Rope.Map[base: useFor, action: EachKey];
END;
-- -- -- -- -- --
--TheApplication
TheApplication: PUBLIC PROC[comm: CDSequencer.Command, text: Rope.ROPENIL] RETURNS [aptr: CD.ApplicationPtr←NIL] =
--extracts the application given a command
--if returned application is nil, all the messages are made and caller should return quiet;
--if returned application is not nil; text line is written and object is there
BEGIN
multiple: BOOL;
key: Rope.ROPE ← Atom.GetPName[comm.a];
IF text=NIL THEN text ← key;
SELECT ProbablyLastChar[text] FROM
'\n, ' => text ← text.Substr[len: text.Length[]-1];
ENDCASE => NULL;
TerminalIO.WriteRope[text];
TerminalIO.WriteRope[" "];
SELECT ProbablyLastChar[key] FROM
'S => {
TerminalIO.WriteRope["selected\n"];
[aptr, multiple] ← CDOps.SelectedApplication[comm.design];
IF multiple THEN {TerminalIO.WriteRope[" multiple selection\n"]; RETURN [NIL]};
IF aptr=NIL THEN TerminalIO.WriteRope[" no selection\n"];
};
'P => {
TerminalIO.WriteRope["pointed\n"];
aptr ← CDApplications.AplicationAt[CDOps.AppList[comm.design], comm.pos];
IF aptr=NIL THEN TerminalIO.WriteRope[" no pointed application\n"];
};
'X => {
TerminalIO.WriteRope["(if 1 selected)\n"];
[aptr, multiple] ← CDOps.SelectedApplication[comm.design];
IF multiple THEN {TerminalIO.WriteRope[" multiple selection\n"]; RETURN [NIL]};
IF aptr=NIL THEN TerminalIO.WriteRope[" no selection\n"];
};
ENDCASE => { -- and specially 'F
TerminalIO.WriteRope["(first selected)\n"];
[aptr, multiple] ← CDOps.SelectedApplication[comm.design];
IF aptr=NIL THEN TerminalIO.WriteRope[" no selection\n"];
};
IF aptr#NIL THEN {
IF aptr.ob=NIL THEN {aptr←NIL; TerminalIO.WriteRope[" bad object\n"]};
};
END;
-- -- -- -- -- --
--WriteInfo
WriteInfo: PUBLIC PROC[aptr: CD.ApplicationPtr, verbosity: INT𡤀] =
BEGIN
TerminalIO.WriteRope[" ("];
IF aptr=NIL THEN TerminalIO.WriteRope["no object"]
ELSE {
TerminalIO.WriteRope[CDOps.Info[aptr.ob]];
IF verbosity>0 THEN {
x: REF ~ CDProperties.GetPropFromApplication[aptr, $SignalName];
IF x#NIL THEN
WITH x SELECT FROM
r: Rope.ROPE => TerminalIO.WriteRope[Rope.Concat[" ", r]];
a: ATOM => TerminalIO.WriteRope[Rope.Concat[" ", Atom.GetPName[a]]];
ENDCASE => NULL;
};
};
TerminalIO.WriteRope[")"];
END;
END.