<!DOCTYPE HTML>
< html lang = "en" class = "sidebar-visible no-js light" >
< head >
<!-- Book generated using mdBook -->
< meta charset = "UTF-8" >
< title > Introduction - xplr book< / title >
<!-- Custom HTML head -->
< meta content = "text/html; charset=utf-8" http-equiv = "Content-Type" >
< meta name = "description" content = "A hackable, minimal, fast TUI file explorer" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< meta name = "theme-color" content = "#ffffff" / >
< link rel = "icon" href = "favicon.svg" >
< link rel = "shortcut icon" href = "favicon.png" >
< link rel = "stylesheet" href = "css/variables.css" >
< link rel = "stylesheet" href = "css/general.css" >
< link rel = "stylesheet" href = "css/chrome.css" >
< link rel = "stylesheet" href = "css/print.css" media = "print" >
<!-- Fonts -->
< link rel = "stylesheet" href = "FontAwesome/css/font-awesome.css" >
< link rel = "stylesheet" href = "fonts/fonts.css" >
<!-- Highlight.js Stylesheets -->
< link rel = "stylesheet" href = "highlight.css" >
< link rel = "stylesheet" href = "tomorrow-night.css" >
< link rel = "stylesheet" href = "ayu-highlight.css" >
<!-- Custom theme stylesheets -->
< / head >
< body >
<!-- Provide site root to javascript -->
< script type = "text/javascript" >
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
< / script >
<!-- Work around some values being stored in localStorage wrapped in quotes -->
< script type = "text/javascript" >
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') & & theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') & & sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
< / script >
<!-- Set the theme before any content is loaded, prevents flash -->
< script type = "text/javascript" >
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
< / script >
<!-- Hide / unhide sidebar before it is displayed -->
< script type = "text/javascript" >
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
< / script >
< nav id = "sidebar" class = "sidebar" aria-label = "Table of contents" >
< div class = "sidebar-scrollbox" >
< ol class = "chapter" > < li class = "chapter-item expanded " > < a href = "introduction.html" class = "active" > < strong aria-hidden = "true" > 1.< / strong > Introduction< / a > < / li > < li class = "chapter-item expanded " > < a href = "quickstart.html" > < strong aria-hidden = "true" > 2.< / strong > Quickstart< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "install.html" > < strong aria-hidden = "true" > 2.1.< / strong > Install< / a > < / li > < li class = "chapter-item expanded " > < a href = "post-install.html" > < strong aria-hidden = "true" > 2.2.< / strong > Post Install< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "configuration.html" > < strong aria-hidden = "true" > 3.< / strong > Configuration< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "key-bindings.html" > < strong aria-hidden = "true" > 3.1.< / strong > Key Bindings< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "configure-key-bindings.html" > < strong aria-hidden = "true" > 3.1.1.< / strong > Configure Key Bindings< / a > < / li > < li class = "chapter-item expanded " > < a href = "default-key-bindings.html" > < strong aria-hidden = "true" > 3.1.2.< / strong > Default Key Bindings< / a > < / li > < li class = "chapter-item expanded " > < a href = "debug-key-bindings.html" > < strong aria-hidden = "true" > 3.1.3.< / strong > Debug Key Bindings< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "general-config.html" > < strong aria-hidden = "true" > 3.2.< / strong > General Config< / a > < / li > < li class = "chapter-item expanded " > < a href = "modes.html" > < strong aria-hidden = "true" > 3.3.< / strong > Modes< / a > < / li > < li class = "chapter-item expanded " > < a href = "message.html" > < strong aria-hidden = "true" > 3.4.< / strong > Message< / a > < / li > < li class = "chapter-item expanded " > < a href = "layouts.html" > < strong aria-hidden = "true" > 3.5.< / strong > Layouts< / a > < / li > < li class = "chapter-item expanded " > < a href = "node_types.html" > < strong aria-hidden = "true" > 3.6.< / strong > Node Types< / a > < / li > < li class = "chapter-item expanded " > < a href = "style.html" > < strong aria-hidden = "true" > 3.7.< / strong > Style< / a > < / li > < li class = "chapter-item expanded " > < a href = "sorting.html" > < strong aria-hidden = "true" > 3.8.< / strong > Sorting< / a > < / li > < li class = "chapter-item expanded " > < a href = "filtering.html" > < strong aria-hidden = "true" > 3.9.< / strong > Filtering< / a > < / li > < li class = "chapter-item expanded " > < a href = "column-renderer.html" > < strong aria-hidden = "true" > 3.10.< / strong > Column Renderer< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "plugin.html" > < strong aria-hidden = "true" > 4.< / strong > Plugin< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "installing-plugins.html" > < strong aria-hidden = "true" > 4.1.< / strong > Installing Plugins< / a > < / li > < li class = "chapter-item expanded " > < a href = "writing-plugins.html" > < strong aria-hidden = "true" > 4.2.< / strong > Writing Plugins< / a > < / li > < li class = "chapter-item expanded " > < a href = "awesome-plugins.html" > < strong aria-hidden = "true" > 4.3.< / strong > Awesome Plugins< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "integration.html" > < strong aria-hidden = "true" > 5.< / strong > Integration< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "awesome-integrations.html" > < strong aria-hidden = "true" > 5.1.< / strong > Awesome Integrations< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "todo.html" > < strong aria-hidden = "true" > 6.< / strong > TODO< / a > < / li > < li class = "chapter-item expanded " > < a href = "alternatives.html" > < strong aria-hidden = "true" > 7.< / strong > Alternatives< / a > < / li > < li class = "chapter-item expanded " > < a href = "upgrade-guide.html" > < strong aria-hidden = "true" > 8.< / strong > Upgrade Guide< / a > < / li > < li class = "chapter-item expanded " > < a href = "community.html" > < strong aria-hidden = "true" > 9.< / strong > Community< / a > < / li > < li class = "chapter-item expanded " > < a href = "contribute.html" > < strong aria-hidden = "true" > 10.< / strong > Contribute< / a > < / li > < / ol >
< / div >
< div id = "sidebar-resize-handle" class = "sidebar-resize-handle" > < / div >
< / nav >
< div id = "page-wrapper" class = "page-wrapper" >
< div class = "page" >
< div id = "menu-bar-hover-placeholder" > < / div >
< div id = "menu-bar" class = "menu-bar sticky bordered" >
< div class = "left-buttons" >
< button id = "sidebar-toggle" class = "icon-button" type = "button" title = "Toggle Table of Contents" aria-label = "Toggle Table of Contents" aria-controls = "sidebar" >
< i class = "fa fa-bars" > < / i >
< / button >
< button id = "theme-toggle" class = "icon-button" type = "button" title = "Change theme" aria-label = "Change theme" aria-haspopup = "true" aria-expanded = "false" aria-controls = "theme-list" >
< i class = "fa fa-paint-brush" > < / i >
< / button >
< ul id = "theme-list" class = "theme-popup" aria-label = "Themes" role = "menu" >
< li role = "none" > < button role = "menuitem" class = "theme" id = "light" > Light (default)< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "rust" > Rust< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "coal" > Coal< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "navy" > Navy< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "ayu" > Ayu< / button > < / li >
< / ul >
< button id = "search-toggle" class = "icon-button" type = "button" title = "Search. (Shortkey: s)" aria-label = "Toggle Searchbar" aria-expanded = "false" aria-keyshortcuts = "S" aria-controls = "searchbar" >
< i class = "fa fa-search" > < / i >
< / button >
< / div >
< h1 class = "menu-title" > xplr book< / h1 >
< div class = "right-buttons" >
< a href = "print.html" title = "Print this book" aria-label = "Print this book" >
< i id = "print-button" class = "fa fa-print" > < / i >
< / a >
< a href = "https://github.com/sayanarijit/xplr" title = "Git repository" aria-label = "Git repository" >
< i id = "git-repository-button" class = "fa fa-github" > < / i >
< / a >
< a href = "https://github.com/sayanarijit/xplr/edit/main/docs/en/src/introduction.md" title = "Suggest an edit" aria-label = "Suggest an edit" >
< i id = "git-edit-button" class = "fa fa-edit" > < / i >
< / a >
< / div >
< / div >
< div id = "search-wrapper" class = "hidden" >
< form id = "searchbar-outer" class = "searchbar-outer" >
< input type = "search" id = "searchbar" name = "searchbar" placeholder = "Search this book ..." aria-controls = "searchresults-outer" aria-describedby = "searchresults-header" >
< / form >
< div id = "searchresults-outer" class = "searchresults-outer hidden" >
< div id = "searchresults-header" class = "searchresults-header" > < / div >
< ul id = "searchresults" >
< / ul >
< / div >
< / div >
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
< script type = "text/javascript" >
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
< / script >
< div id = "content" class = "content" >
< main >
< h1 id = "introduction" > < a class = "header" href = "#introduction" > Introduction< / a > < / h1 >
< p > xplr is a terminal UI based file explorer that aims to increase our terminal
productivity by being a flexible, interactive orchestrator for the ever growing
awesome command-line utilities that work with the file-system.< / p >
< p > To achieve its goal, xplr strives to be a fast, minimal and more importantly,
hackable file explorer.< / p >
< p > xplr is not meant to be a replacement for the standard shell commands or the
GUI file managers. Rather, it aims to integrate them all and expose an
intuitive, scriptable, keyboard controlled, real-time visual interface, also
being an ideal candidate for further integration, enabling the users to achieve
insane terminal productivity.< / p >
< h2 id = "features" > < a class = "header" href = "#features" > Features< / a > < / h2 >
< h3 id = "hackable" > < a class = "header" href = "#hackable" > Hackable< / a > < / h3 >
< p > xplr is built with configurability in mind. So it allows you to perform a vast
set of operations and make it behave just the way you want.< / p >
< p > A few things you can do with the xplr configuration< / p >
< ul >
< li > < a href = "layouts.html" > Hack the layout< / a > < / li >
< li > < a href = "modes.html" > Hack the key bindings< / a > < / li >
< li > < a href = "awesome-plugins.html" > Extend with plugins< / a > < / li >
< / ul >
< h2 id = "fast" > < a class = "header" href = "#fast" > Fast< / a > < / h2 >
< p > Although speed is not the primary concern, xplr is already fast enough so that
you can take it out for a walk into your < code > node_modules< / code > or < code > /nix/store< / code > any
time you want. I currently
< a href = "https://github.com/sayanarijit/xplr/tree/main/benches" > measure the most commonly used operations< / a >
and I have seen it improve significantly over time, and it's only the start.< / p >
< p > < strong > Tip:< / strong > A quick and easy way to optimize UI rendering is reducing the number
of columns in the table.< / p >
< p > < strong > Note:< / strong > If you feel xplr is not behaving at its optimal, this is probably
because I am waiting for someone to complain. I want to avoid optimizing things
I don't need to, because optimization often requires either complexity or
feature sacrifice or both.< / p >
< h2 id = "minimalist" > < a class = "header" href = "#minimalist" > Minimalist< / a > < / h2 >
< p > xplr prefers to stay minimal, both in terms of features and binary size, but
just like speed, minimalism isn't as aggressively pursued as configurability.
If adding some feature, lines of code, or a dependency allows the users to be a
little more productive or allows xplr to be a little more configurable, it will
be considered. But of-course, the < code > bulk vs productivity gain per user< / code > balance
will also be considered in the decision-making.< / p >
< h2 id = "other-features" > < a class = "header" href = "#other-features" > Other features< / a > < / h2 >
< ul >
< li > < a href = "https://github.com/sayanarijit/xplr/discussions/183" > Embedded LuaJIT< / a > for
portability and extensibility.< / li >
< li > < strong > Switchable recover mode:< / strong > Saves you from doing unwanted things when in a
hurry.< / li >
< li > < strong > Sane (vim-like) defaults:< / strong >
< ul >
< li > Use < code > h< / code > , < code > j< / code > , < code > k< / code > , < code > l< / code > or arrow keys
for basic navigation.< / li >
< li > Go to top using < code > g< / code > < code > g< / code > , and bottom using < code > G< / code > .< / li >
< li > Travel history using < code > ctrl-o< / code > and < code > ctrl-i< / code > .< / li >
< li > Go to home directory using < code > ~< / code > .< / li >
< li > Enter search mode with < code > /< / code > or < code > ctrl-f< / code > .< / li >
< li > Go to absolute index (e.g. < code > 4< / code > ) using < code > 4< / code > < code > enter< / code > or
< code > :< / code > < code > 4< / code > < code > enter< / code > .< / li >
< li > Go to relative index (e.g. < code > 4< / code > < code > down< / code > ) using < code > 4< / code > < code > down< / code > or
< code > :< / code > < code > 4< / code > < code > down< / code > .< / li >
< li > Follow symlink using < code > g< / code > < code > f< / code > .< / li >
< li > Open in GUI using < code > g< / code > < code > x< / code > .< / li >
< li > Spawn terminal using < code > :< / code > < code > !< / code > .< / li >
< li > Toggle selection using < code > v< / code > or < code > space< / code > .< / li >
< li > Toggle select all using < code > V< / code > or < code > ctrl-a< / code > .< / li >
< li > Clear selections using < code > ctrl-u< / code > .< / li >
< / ul >
< / li >
< li > < strong > Separate keys for navigation:< / strong > navigation keys are separated from the
action keys (e.g. file opening action) to avoid mistakenly performing
unwanted actions while navigating.< / li >
< li > < strong > Always visible panels< / strong > to save you brain cycles:
< ul >
< li > Selection list.< / li >
< li > Help menu.< / li >
< li > Input & logs.< / li >
< li > Filter and sort pipeline.< / li >
< / ul >
< / li >
< li > < strong > Batch creation:< / strong > Create multiple files and directories without repeating
keys.< / li >
< li > < strong > Batch sort & filter:< / strong > Apply sorters and filters in without repeating keys.< / li >
< li > < strong > Custom file properties:< / strong > Display custom file properties with custom colors
in the table using Lua functions.< / li >
< li > < strong > Input buffer:< / strong > Read user input using the built-in input buffer with
customizable behavior.< / li >
< li > < strong > Switchable layouts:< / strong > Switch layouts dynamically without leaving < code > xplr< / code > .< / li >
< li > < strong > Saved locations:< / strong > Never lose context when traveling back and forth
directories.< / li >
< li > < strong > Auto refresh state:< / strong > Auto refresh app state when the < code > $PWD< / code > changes.< / li >
< li > < strong > Manually refresh UI< / strong > when other apps mess it up.< / li >
< li > < strong > FIFO-based previews:< / strong > Easy to manage FIFO file that can be used to
< a href = "https://github.com/sayanarijit/xplr/pull/229" > integrate with previewers< / a > .< / li >
< li > < strong > Different quit options:< / strong >
< ul >
< li > Quit with success without any output (< code > q< / code > ).< / li >
< li > Quit with success and the result printed on stdout (< code > enter< / code > ).< / li >
< li > Quit with success and the present working directory printed on stdout
(< code > :< / code > < code > q< / code > < code > p< / code > ).< / li >
< li > Quit with success and the path under focus printed on stdout
(< code > :< / code > < code > q< / code > < code > f< / code > ).< / li >
< li > Quit with success and the selection printed on stdout
(< code > :< / code > < code > q< / code > < code > s< / code > ).< / li >
< li > Quit with failure (< code > ctrl-c< / code > ).< / li >
< / ul >
< / li >
< / ul >
< / main >
< nav class = "nav-wrapper" aria-label = "Page navigation" >
<!-- Mobile navigation buttons -->
< a rel = "next" href = "quickstart.html" class = "mobile-nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
< i class = "fa fa-angle-right" > < / i >
< / a >
< div style = "clear: both" > < / div >
< / nav >
< / div >
< / div >
< nav class = "nav-wide-wrapper" aria-label = "Page navigation" >
< a rel = "next" href = "quickstart.html" class = "nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
< i class = "fa fa-angle-right" > < / i >
< / a >
< / nav >
< / div >
< script type = "text/javascript" >
window.playground_copyable = true;
< / script >
< script src = "elasticlunr.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "mark.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "searcher.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "clipboard.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "highlight.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "book.js" type = "text/javascript" charset = "utf-8" > < / script >
<!-- Custom JS scripts -->
< / body >
< / html >