Skip to main content

Overview

The EditorContext provides centralized state management for the Code Editor Thing application. It manages file operations, UI state, theme selection, and terminal integration.

Components

EditorProvider

Context provider component that wraps the application and provides editor state to all child components.
children
ReactNode
required
Child components that will have access to the editor context
import { EditorProvider } from './lib/editor-context';

function App() {
  return (
    <EditorProvider>
      <YourAppComponents />
    </EditorProvider>
  );
}

useEditor Hook

Custom React hook that provides access to the editor context. Must be used within an EditorProvider.
return
EditorContextType
Object containing all editor state and methods
import { useEditor } from './lib/editor-context';

function MyComponent() {
  const editor = useEditor();
  // Access editor state and methods
}
useEditor() will throw an error if used outside of an EditorProvider. Always ensure your component tree is wrapped with the provider.

EditorContextType Interface

The complete interface for values returned by useEditor().

UI State

sidebarVisible
boolean
Whether the file explorer sidebar is currently visible
setSidebarVisible
(v: boolean) => void
Function to show/hide the sidebar
terminalVisible
boolean
Whether the integrated terminal is currently visible
setTerminalVisible
(v: boolean) => void
Function to show/hide the terminal

File Management

fileTree
FileItem[]
Array of files and directories in the current workspace
setFileTree
(v: FileItem[]) => void
Function to update the file tree
openFiles
OpenFile[]
Array of currently open file tabs
setOpenFiles
(v: OpenFile[]) => void
Function to update the open files array
activeFilePath
string | null
Path of the currently focused file, or null if no file is active
setActiveFilePath
(v: string | null) => void
Function to set the active file
currentFolder
string | null
Path of the currently open workspace folder, or null if none
setCurrentFolder
(v: string | null) => void
Function to set the current workspace folder

Theme Management

selectedTheme
string
ID of the currently selected theme (e.g., "vs-dark", "dracula")
setSelectedTheme
(v: string) => void
Function to change the active theme
currentTheme
ThemeConfig
Complete theme configuration object for the selected theme. See Theme System for details.

Environment

isElectron
boolean
Whether the app is running in Electron environment (vs web browser)

Event Handlers

handleFileSelect
(item: FileItem) => Promise<void>
Opens a file for editing. If the file is already open, switches to that tab. Ignores directories.
handleContentChange
(content: string) => void
Updates the content of the currently active file and marks it as modified.
handleSave
() => Promise<void>
Saves the currently active file to disk and marks it as unmodified.
handleCloseTab
(path: string) => void
Closes a file tab. If it’s the active file, clears the active file selection.
handleRefreshTree
(folderPath: string) => Promise<void>
Refreshes the file tree for a given folder path.

Usage Examples

Basic File Operations

import { useEditor } from './lib/editor-context';

function FileExplorer() {
  const { fileTree, handleFileSelect } = useEditor();
  
  return (
    <ul>
      {fileTree.map(item => (
        <li key={item.path} onClick={() => handleFileSelect(item)}>
          {item.isDirectory ? '📁' : '📄'} {item.name}
        </li>
      ))}
    </ul>
  );
}

Saving Files

import { useEditor } from './lib/editor-context';

function SaveButton() {
  const { handleSave, activeFilePath, openFiles } = useEditor();
  
  const activeFile = openFiles.find(f => f.path === activeFilePath);
  const hasUnsavedChanges = activeFile?.modified;
  
  return (
    <button 
      onClick={handleSave}
      disabled={!hasUnsavedChanges}
    >
      Save {hasUnsavedChanges && '*'}
    </button>
  );
}

Managing Open Files

import { useEditor } from './lib/editor-context';

function OpenFilesTabs() {
  const { 
    openFiles, 
    activeFilePath, 
    setActiveFilePath,
    handleCloseTab 
  } = useEditor();
  
  return (
    <div>
      {openFiles.map(file => (
        <div 
          key={file.path}
          className={file.path === activeFilePath ? 'active' : ''}
        >
          <span onClick={() => setActiveFilePath(file.path)}>
            {file.name} {file.modified && '*'}
          </span>
          <button onClick={() => handleCloseTab(file.path)}>×</button>
        </div>
      ))}
    </div>
  );
}

Toggling UI Elements

import { useEditor } from './lib/editor-context';

function ViewControls() {
  const { 
    sidebarVisible, 
    setSidebarVisible,
    terminalVisible,
    setTerminalVisible 
  } = useEditor();
  
  return (
    <div>
      <button onClick={() => setSidebarVisible(!sidebarVisible)}>
        {sidebarVisible ? 'Hide' : 'Show'} Sidebar
      </button>
      <button onClick={() => setTerminalVisible(!terminalVisible)}>
        {terminalVisible ? 'Hide' : 'Show'} Terminal
      </button>
    </div>
  );
}

Theme Switching

import { useEditor } from './lib/editor-context';
import { THEMES } from './lib/themes';

function ThemeSelector() {
  const { selectedTheme, setSelectedTheme, currentTheme } = useEditor();
  
  return (
    <select 
      value={selectedTheme} 
      onChange={(e) => setSelectedTheme(e.target.value)}
      style={{
        backgroundColor: currentTheme.editor.bg,
        color: currentTheme.editor.fg
      }}
    >
      {THEMES.map(theme => (
        <option key={theme.id} value={theme.id}>
          {theme.name}
        </option>
      ))}
    </select>
  );
}

Refreshing File Tree

import { useEditor } from './lib/editor-context';

function RefreshButton() {
  const { currentFolder, handleRefreshTree } = useEditor();
  
  const handleRefresh = async () => {
    if (currentFolder) {
      await handleRefreshTree(currentFolder);
    }
  };
  
  return (
    <button onClick={handleRefresh} disabled={!currentFolder}>
      Refresh Files
    </button>
  );
}

State Management Patterns

The EditorContext uses React’s built-in state management with useState and useContext. State updates are batched for performance.

Automatic State Updates

The provider automatically listens for Electron IPC events:
  • folder-opened - Updates currentFolder and fileTree
  • toggle-sidebar - Toggles sidebarVisible
  • toggle-terminal - Toggles terminalVisible

Manual State Updates

All state setters are exposed for manual control when needed:
const { setOpenFiles, setActiveFilePath } = useEditor();

// Manually manage open files
setOpenFiles(prev => [...prev, newFile]);
setActiveFilePath(newFile.path);

Build docs developers (and LLMs) love