Implementation:TobikoData Sqlmesh Editor Hooks
| Knowledge Sources | |
|---|---|
| Domains | Web_UI, Code_Editor, React_Hooks |
| Last Updated | 2026-02-07 20:00 GMT |
Overview
React hooks that provide keyboard shortcuts and CodeMirror extensions for SQLMesh model interactions in the editor.
Description
Editor_Hooks provides two custom React hooks that enhance the editor with keyboard shortcuts and interactive model features. The useDefaultKeymapsEditorTab hook registers keyboard shortcuts for creating and closing editor tabs (Shift+Cmd+. and Shift+Cmd+,), with confirmation dialogs for unsaved changes. The useSQLMeshModelExtensions hook creates a collection of CodeMirror extensions that enable interactive model and column navigation, hover tooltips, and visual highlighting with support for action mode (activated by holding the meta/cmd key).
The hooks integrate with multiple context stores (editor, project, context) and manage complex state including action mode toggling, lineage filtering, and model click handling. The extensions system provides Cmd+Click functionality for navigating to model definitions and column references, making the editor highly interactive and navigation-friendly for exploring SQLMesh projects.
Usage
Use these hooks in editor components to add keyboard shortcuts and interactive SQLMesh features. The keymaps hook should be used in the main editor component, while the model extensions hook should be used when configuring CodeMirror extensions.
Code Reference
Source Location
- Repository: TobikoData_Sqlmesh
- File: web/client/src/library/components/editor/hooks.ts
Signature
export function useDefaultKeymapsEditorTab(): KeyBinding[]
export function useSQLMeshModelExtensions(
path?: string,
handleModelClick?: (model: ModelSQLMeshModel) => void,
handleModelColumn?: (model: ModelSQLMeshModel, column: Column) => void,
): Extension[]
Import
import { useDefaultKeymapsEditorTab, useSQLMeshModelExtensions } from '@components/editor/hooks'
I/O Contract
useDefaultKeymapsEditorTab Hook
| Name | Type | Required | Description |
|---|---|---|---|
| N/A | N/A | N/A | Hook reads state from editor context |
Returns: KeyBinding[] - Array of CodeMirror key bindings
useSQLMeshModelExtensions Hook
| Name | Type | Required | Description |
|---|---|---|---|
| path | string | No | Path to the current file being edited |
| handleModelClick | (model) => void | No | Callback when a model is Cmd+Clicked |
| handleModelColumn | (model, column) => void | No | Callback when a column is Cmd+Clicked |
Returns: Extension[] - Array of CodeMirror extensions
useDefaultKeymapsEditorTab Hook
Keyboard Shortcuts
The hook provides two keyboard shortcuts:
| Shortcut | Action | Description |
|---|---|---|
| Shift+Cmd+. | Create Tab | Creates a new custom SQL tab and selects it |
| Shift+Cmd+, | Close Tab | Closes the current tab with confirmation for unsaved changes |
Implementation
const keymaps = useMemo(() => {
return isNil(file) ? [] : [
{
key: 'Shift-Mod-.',
preventDefault: true,
run() {
const newTab = createTab()
addTab(newTab)
selectTab(newTab)
return true
},
},
{
key: 'Shift-Mod-,',
preventDefault: true,
run() {
closeEditorTabWithConfirmation()
return true
},
},
]
}, [file, selectTab, closeTab, createTab, addTab])
Close Confirmation
function closeEditorTabWithConfirmation(): void {
if (isNil(file)) return
if (isTrue(file.isChanged)) {
addConfirmation({
headline: 'Closing Tab',
description: 'All unsaved changes will be lost. Do you want to close the tab anyway?',
yesText: 'Yes, Close Tab',
noText: 'No, Cancel',
action: () => {
closeTab(file)
},
})
} else {
closeTab(file)
}
}
useSQLMeshModelExtensions Hook
Extension Collection
The hook returns an array of extensions:
- HoverTooltip: Shows model information on hover (when in action mode)
- Keyboard event handlers: Manage action mode toggling
- Model click handler: Handles Cmd+Click on model names
- Column click handler: Handles Cmd+Click on column names
- SQLMeshModel extension: Provides visual highlighting
Action Mode
Action mode is activated by holding the meta/cmd key:
events({
keydown: e => {
if (e.metaKey) {
setIsActionMode(true)
}
},
keyup: e => {
if (isFalse(e.metaKey)) {
setIsActionMode(false)
}
},
})
When action mode is active:
- Hover tooltips are enabled
- Model and column names are styled as clickable
- Cursor changes to pointer over models/columns
Column Collection
The hook intelligently selects which columns to highlight:
const columns = new Set(
isNil(lineage) || isObjectEmpty(lineage)
? // All columns from all models
Array.from(new Set(models.values())).flatMap(m =>
m.columns.map(c => c.name),
)
: // Only columns from models in current lineage
(Object.keys(lineage)
.flatMap(modelName =>
models.get(modelName)?.columns.map(c => c.name),
)
.filter(Boolean) as string[]),
)
This optimizes performance by only highlighting relevant columns when lineage data is available.
Click Handlers
function handleEventModelClick(event: MouseEvent): void {
if (event.metaKey) {
const model = findModel(event, models)
if (isNil(model)) return
handleModelClick?.(model)
}
}
function handleEventlColumnClick(event: MouseEvent): void {
if (event.metaKey) {
if (isNil(model)) return
const column = findColumn(event, model)
if (isNil(column)) return
handleModelColumn?.(model, column)
}
}
Click handlers only trigger when meta/cmd key is held down.
Extension Composition
return [
models.size > 0 && isActionMode && HoverTooltip(models),
events({ keydown, keyup }),
isNotNil(handleModelClick) && events({ click: handleEventModelClick }),
isNotNil(handleModelColumn) && events({ click: handleEventlColumnClick }),
SQLMeshModel(models, columns, isActionMode, model),
].filter(Boolean) as Extension[]
Extensions are conditionally included based on available data and callbacks.
Usage Example
import { useDefaultKeymapsEditorTab, useSQLMeshModelExtensions } from '@components/editor/hooks'
import { useNavigate } from 'react-router'
function MyEditor({ file }) {
const navigate = useNavigate()
// Add keyboard shortcuts
const keymaps = useDefaultKeymapsEditorTab()
// Add model interaction extensions
const modelExtensions = useSQLMeshModelExtensions(
file.path,
(model) => {
// Navigate to model page on Cmd+Click
navigate(`/models/${model.name}`)
},
(model, column) => {
// Handle column click
console.log(`Clicked column ${column.name} in model ${model.name}`)
}
)
const extensions = [
...keymaps,
...modelExtensions,
// other extensions
]
return <CodeMirror extensions={extensions} />
}