Packages

Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.

Current section

Files

Jump to
raxol examples apps file_browser key_handler.ex
Raw

examples/apps/file_browser/key_handler.ex

defmodule Examples.FileBrowser.KeyHandler do
@moduledoc """
Key handling logic for the file browser explorer.
Handles all keyboard input including navigation, file operations,
and mode switching.
"""
alias Examples.FileBrowser.{State, FileOperations}
def handle_key(state, :up) do
new_index = max(0, state.selected_index - 1)
%{state | selected_index: new_index}
|> FileOperations.load_preview()
end
def handle_key(state, :down) do
max_index = length(state.entries) - 1
new_index = min(max_index, state.selected_index + 1)
%{state | selected_index: new_index}
|> FileOperations.load_preview()
end
def handle_key(state, :enter) do
case FileOperations.get_selected_entry(state) do
%{type: :directory, path: path} ->
FileOperations.enter_directory(state, path)
%{path: path} ->
FileOperations.open_file(state, path)
_ ->
state
end
end
def handle_key(state, :backspace) do
parent = Path.dirname(state.current_path)
if parent != state.current_path do
FileOperations.enter_directory(state, parent)
else
state
end
end
def handle_key(state, {:char, ?h}) do
%{state | show_hidden: not state.show_hidden}
|> FileOperations.refresh_directory()
end
def handle_key(state, {:char, ?/}) do
%{state | mode: :search, search_query: ""}
end
def handle_key(%{mode: :search} = state, {:char, char}) do
query = state.search_query <> <<char>>
%{state | search_query: query}
|> FileOperations.filter_entries()
end
def handle_key(%{mode: :search} = state, :escape) do
%{state | mode: :browse, search_query: ""}
|> FileOperations.refresh_directory()
end
def handle_key(state, {:char, ?c}) when state.mode == :browse do
case FileOperations.get_selected_entry(state) do
%{path: path} = entry ->
%{
state
| clipboard: entry,
clipboard_operation: :copy,
status_message: "Copied: #{entry.name}"
}
_ ->
state
end
end
def handle_key(state, {:char, ?x}) when state.mode == :browse do
case FileOperations.get_selected_entry(state) do
%{path: path} = entry ->
%{
state
| clipboard: entry,
clipboard_operation: :cut,
status_message: "Cut: #{entry.name}"
}
_ ->
state
end
end
def handle_key(state, {:char, ?v})
when state.mode == :browse and state.clipboard != nil do
FileOperations.paste_file(state)
end
def handle_key(state, {:char, ?d}) when state.mode == :browse do
case FileOperations.get_selected_entry(state) do
%{name: name} ->
%{
state
| mode: :confirm_delete,
status_message: "Delete '#{name}'? (y/n)"
}
_ ->
state
end
end
def handle_key(%{mode: :confirm_delete} = state, {:char, ?y}) do
FileOperations.delete_selected(state)
end
def handle_key(%{mode: :confirm_delete} = state, _) do
%{state | mode: :browse, status_message: "Cancelled"}
end
def handle_key(state, {:char, ?r}) when state.mode == :browse do
case FileOperations.get_selected_entry(state) do
%{name: name} ->
%{
state
| mode: :rename,
search_query: name,
status_message: "Rename to: "
}
_ ->
state
end
end
def handle_key(%{mode: :rename} = state, :enter) do
FileOperations.rename_selected(state)
end
def handle_key(state, {:char, ?s}) do
next_sort =
case state.sort_by do
:name -> :size
:size -> :modified
:modified -> :type
:type -> :name
end
%{state | sort_by: next_sort}
|> FileOperations.sort_entries()
end
def handle_key(state, {:char, ?p}) do
next_mode =
case state.preview_mode do
:auto -> :text
:text -> :hex
:hex -> :none
:none -> :auto
end
%{state | preview_mode: next_mode}
|> FileOperations.load_preview()
end
def handle_key(state, {:char, ?b}) do
bookmark = %{
name: Path.basename(state.current_path),
path: state.current_path
}
%{
state
| bookmarks: [bookmark | state.bookmarks],
status_message: "Bookmarked: #{bookmark.name}"
}
end
def handle_key(state, {:char, digit}) when digit >= ?1 and digit <= ?9 do
index = digit - ?1
case Enum.at(state.bookmarks, index) do
%{path: path} ->
FileOperations.enter_directory(state, path)
_ ->
state
end
end
def handle_key(state, {:char, ?q}) do
System.halt(0)
end
def handle_key(state, _), do: state
end