Welcome to Chapter 4! In the previous chapter, Dynamic Lazy Loading, we learned how to keep our application fast by loading code only when we need it.
We now have a command that registers itself and loads efficiently. But we have a new problem: The command is blind.
When the diff command wakes up, it has the logic to show changes, but it doesn't know what the changes are. It doesn't know which files you edited or what text you deleted.
In this chapter, we explore Context Injection. This is how the main application gathers all the necessary information and hands it to your command.
Imagine you are a specialist doctor (the Command). You are called into a room to treat a patient.
If you walk in with zero information, you have to waste time asking:
It is much more efficient if the nurse hands you a Clipboard (the Context) before you even enter the room. The clipboard has the patient's name, vitals, and notes. You can immediately get to work.
In our software:
diff command.context object.Without the context, every command would have to manually scan the hard drive to find files. That is slow and repetitive.
context Object
The application solves this by doing the heavy lifting for you. Before it calls your command, it gathers data about the environment and packs it into a neat object called context.
Let's look at our diff.tsx file again. You might remember the second argument in our function:
// --- File: diff.tsx ---
// Notice the second argument: 'context'
export const call: LocalJSXCommandCall = async (onDone, context) => {
// The 'context' object holds the data we need!
const data = context.messages;
// ...
};
Explanation:
onDone: The remote control to close the app (discussed in Chapter 2).context: The "Clipboard." It contains everything the application knows about the current situation.
For a tool like diff, the context usually contains:
We don't need to create this data; we just need to pass it along.
Our goal is to get this data into our visual component so the user can see it.
Inside our call function, we access context.messages. This array contains the actual lines of code or text that have changed.
// --- File: diff.tsx ---
export const call: LocalJSXCommandCall = async (onDone, context) => {
// 1. We have the data here
const recentChanges = context.messages;
// ... continued below
We pass this data as a "prop" (property) to our React component.
// ... continued from above
const { DiffDialog } = await import('../../components/diff/DiffDialog.js');
// 2. We inject it into the UI here
return <DiffDialog
messages={recentChanges}
onDone={onDone}
/>;
};
Explanation:
messages={recentChanges}: This is the injection. We are taking the data from the "Clipboard" (Context) and handing it to the "Surgeon" (The Dialog Component).You might be wondering: Who creates this clipboard?
The main application core acts as a Data Gatherer. When the user presses "Enter" on a command, the core pauses to collect information before running your code.
diff..git folder to see what changed.call function and passes the object as an argument.Let's look at a simplified version of the code that runs inside the framework (not your command code) to see how it constructs this object.
// --- Framework Code (Simplified) ---
async function runCommand(commandName) {
// 1. Gather Data (The hard work)
const history = await git.getUncommittedChanges();
// 2. Create the Clipboard
const context = {
messages: history,
timestamp: Date.now()
};
// 3. Find the registered command
const command = registry.get(commandName);
// 4. INJECT the context
await command.call(sys.exit, context);
}
Explanation:
call is triggered, the context variable is already full of fresh data.context with fake messages. You don't need a real Git repository to run tests.In this chapter, you learned about Context Injection.
context.messages in our handler and pass it to our component.We have now successfully:
The final piece of the puzzle is the visual part. We have passed the messages to <DiffDialog />, but we haven't looked at how that component is built.
How do we build a React component that interacts with the terminal? Let's find out in the final chapter: React Component Bridge.
Generated by Code IQ