Welcome back! In the previous chapter, Dynamic Command Loading, we set up our command so that the heavy code is only loaded when the user asks for it.
Now that the file is loaded, we need to write the actual "brain" of the command. This chapter covers the logic that decides how the editor behaves.
Imagine a modern sports car. It has a button to switch between "Drive" (for comfortable, normal driving) and "Sport" (for high-performance driving).
The Problem: Our CLI tool handles text input. By default, it works like a standard notepad ("Normal"). But power users want it to behave like the famous Vim editor ("Vim"). We need a way to switch between these two sets of rules.
The Use Case: A user types vim in the terminal.
normal mode, switch them to vim.vim mode, switch them to normal.emacs), reset them to normal safely.To handle this, we need to implement Editor Mode Logic. This involves three specific steps:
Let's write the code inside vim.ts. We will break this down into small, manageable pieces.
First, we need to find out the current state. We also need to handle "legacy" data. Suppose an older version of our app supported an emacs mode, but we removed it. We need to ensure we don't break if a user still has that setting.
// Inside vim.ts
const config = getGlobalConfig()
// 1. Get current mode (default to 'normal' if undefined)
let currentMode = config.editorMode || 'normal'
// 2. Normalize: Treat 'emacs' as 'normal' (Backward Compatibility)
if (currentMode === 'emacs') {
currentMode = 'normal'
}
Explanation:
getGlobalConfig(): Fetches the user's settings. (We will build this in Global Configuration Management).|| 'normal': This is a safety net. If no mode is set, assume 'normal'.if statement ensures that if we encounter the obsolete 'emacs' mode, we treat it just like 'normal' mode.
Now that we have a clean currentMode, we decide what the new mode should be.
// 3. Logic to swap modes
const newMode = currentMode === 'normal' ? 'vim' : 'normal'
Explanation:
newMode to 'vim'.newMode to 'normal'.Changing a variable in memory isn't enough; we need to save it so the app remembers next time.
// 4. Save the new preference
saveGlobalConfig(current => ({
...current, // Keep other settings (like theme, colors)
editorMode: newMode, // Update only the editor mode
}))
Explanation:
saveGlobalConfig: This function updates the permanent configuration file....current: This is the "spread" operator. It ensures we don't accidentally delete other settings the user might have.Finally, we need to tell the user what happened.
// 5. Return a text response to the CLI
return {
type: 'text',
value: `Editor mode set to ${newMode}. ${
newMode === 'vim'
? 'Use Escape key to toggle between INSERT and NORMAL modes.'
: 'Using standard (readline) keyboard bindings.'
}`,
}
Explanation:
vim, we remind them how to use the Escape key.What happens internally when this logic runs? Let's visualize the data flow.
Here is how the pieces fit together in the actual vim.ts file. Note that we also include a line for logEvent.
// File: vim.ts
export const call: LocalCommandCall = async () => {
// ... (Retrieval and Toggle Logic we wrote above) ...
const newMode = currentMode === 'normal' ? 'vim' : 'normal'
// ... (Save Logic) ...
// Analytics: Record that the user changed modes
logEvent('tengu_editor_mode_changed', {
mode: newMode,
source: 'command',
})
// ... (Return Logic) ...
}
Explanation:
logEvent: It is helpful to know how many users actually use the Vim mode. We track this data using telemetry. We will learn exactly how this works in Event Analytics & Telemetry.In this chapter, we built the "brain" of our command. You learned:
However, we treated getGlobalConfig and saveGlobalConfig as magic functions. How does the application actually store these settings? Does it use a database? A text file?
To understand how we persist user preferences, proceed to the next chapter: Global Configuration Management.
Generated by Code IQ