A hackable, minimal, fast TUI file explorer, stealing ideas from nnn and fzf.

Overview

xplr

A hackable, minimal, fast TUI file explorer, stealing ideas from nnn and fzf.

[Quickstart] [Features] [Plugins] [Documentation] [Upgrade Guide] [TODO]


Though xplr strives to be fast and minimalist, its speciality is its hackability.

Once you read the documentation, you should be able to configure the key bindings, different run modes, and also the way it looks by modifying one single configuration file.

If you come up with something cool, or if you feel it's lacking somewhere in portability, flexibility or performance, don't hesitate to start a conversation.

Issues
  • Auto disown when opening in gui

    Auto disown when opening in gui

    Upon opening an application in gui the current terminal window is still linked to the gui. Meaning that I cannot close it without it closing the GUI. I am also locked out of the current xplr session. Meaning I cannot browse other files after opening a single file. Upon closing the GUI application the GUI for xplr becomes messed up. (view attached image.) image

    opened by aflyingpumpkin 57
  • Sign releases with PGP key

    Sign releases with PGP key

    Hey!

    I've seen you sign one of the recent commits using your PGP key, that means you must be using PGP 😛

    What do you think about signing releases? Instead of providing hashsums (or in addition, if you want).

    PGP signatures will not only help ensuring that downloaded archive is not corrupted, but will also verify authenticity and in general reduce attack vector when your app is being built by other people and distributed via distro packages.

    For packaging we'd need a signature for sources tarball (.tar.gz) that Github automatically provides for you on every release, signatures for other attachments would be appreciated as well 🙂

    Here's what I would suggest to do:

    1. For transparency, put in README your key ID, something like below would be enough (it's my key in the example below):
    Releases are signed with the following PGP key: `8053EB88879A68CB4873D32B011FDC52DA839335`
    
    1. Publish your key to http://keys.gnupg.net/

    2. The sources tarball is reproducible and can be recreated using the following git command:

    git archive -o xplr-<version>.tar.gz --format tar.gz --prefix "xplr-<version>/" "<tag>"
    

    So for example, to get a signature you'd run this (mind where v before version is used and where is not):

    git archive -o xplr-0.7.2.tar.gz --format tar.gz --prefix "xplr-0.7.2/" "v0.7.2"
    gpg --detach-sign xplr-0.7.2.tar.gz
    rm xplr-0.7.2.tar.gz
    

    Let me know if you need any help! 🙂

    opened by maximbaz 21
  • Fix distorted screen when opening files in GUI

    Fix distorted screen when opening files in GUI

    Fixes: https://github.com/sayanarijit/xplr/issues/111

    opened by sayanarijit 19
  • Improve config defaults

    Improve config defaults

    • Rename custom field for node metadata to meta.
    • Move icon to meta.icon.
    • Rename normal_ui to default_ui.
    • Rename filetypes to node_types.
    • Split modes into modes.builtin and modes.custom.
    • Add the missing create file mode.
    • Rename focused_ui to focus_ui.
    • Make general.table.header non-nullable.
    • Add support for incremental configuration updates.
    • Add key binding ~ to go to homedir.
    • Add customizable cursor and prompts.
    • Improve the help menus.
    • Initial BDD testing setup
    • Improve version compatibility

    Ref: https://github.com/sayanarijit/xplr/issues/45

    opened by sayanarijit 19
  • After editing a file in nvim, xplr is in either action mode or selected the file

    After editing a file in nvim, xplr is in either action mode or selected the file

    What I did:

    • Open xplr
    • navigate to a file
    • press :e to edit it with nvim
    • ...
    • in nvim: :q

    What I expect:

    xplr in default mode, i. e. waiting for input or navigation

    What sometimes happens instead:

    xplr either behaves, as if I pressed : or Space - so it either waits for an action key or selected the file, I edited.

    Additional info

    • version: xplr 0.14.4
    • installed via paru
    • config
    • OS: Artix Linux

    I'd love to give more details, but I can't even reliably reproduce this. If you don't understand, I can also record a video/gif :)

    Kind regards, Maxim

    opened by mrdgo 17
  • Improve the demo at xplr.dev

    Improve the demo at xplr.dev

    The GIF demo hosted on https://xplr.dev is a bit outdated and quite large, slowing the website down.

    Let's create a demo video and display that instead.

    We can keep the video here which will get uploaded to the website.

    Bonus: Showoff some video editing skills.

    help wanted good first issue 
    opened by sayanarijit 17
  • Using Case Statement with Mimetypes

    Using Case Statement with Mimetypes

    Hello,

    I am experiencing difficulties implementing a simple bash script due to my lack of experience.

    - BashExec: | case $(file --mime-type -b $(cat "${XPLR_PIPE_RESULT_OUT:?}") ) in video/*) mpv $(cat "${XPLR_PIPE_RESULT_OUT:?}") < "${XPLR_PIPE_RESULT_OUT:?}") ;; esac

    -PopMode -Refresh

    This did not work on my computer either, - BashExec: | case $(file --mime-type -b $(cat "${XPLR_PIPE_RESULT_OUT:?}") ) in video/*) (while IFS= read -r line; do mpv "${line:?}" done < "${XPLR_PIPE_RESULT_OUT:?}") ;;

    The other cases are effective though,

    text/*) (while IFS= read -r line; do nvim "${line:?}" done < "${XPLR_PIPE_RESULT_OUT:?}") ;;

    What am I doing incorrectly?

    I greatly appreciate your assistance with my inexperience with scripting. 😀

    opened by IcyFlamingArrow 17
  • Add sorting support

    Add sorting support

    Closes: #58

    opened by sayanarijit 16
  • Problems compiling on macOS: “perhaps two different versions of crate `tui` are being used”

    Problems compiling on macOS: “perhaps two different versions of crate `tui` are being used”

    Here's the output of cargo install --force xplr: https://gist.github.com/atroche/82de1ee6aafa1c4f6cc125829caa7306

    error[E0308]: mismatched types
       --> /Users/alistair/.cargo/registry/src/github.com-1ecc6299db9ec823/xplr-0.13.1/src/ui.rs:569:69
        |
    569 | ...                   .unwrap_or_else(|e| Text::raw(format!("{:?}", e))),
        |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `tui::text::Text`, found a different struct `tui::text::Text`
        |
        = note: perhaps two different versions of crate `tui` are being used?
    
    error[E0308]: `match` arms have incompatible types
       --> /Users/alistair/.cargo/registry/src/github.com-1ecc6299db9ec823/xplr-0.13.1/src/ui.rs:570:55
        |
    567 |   ...                   match out {
        |                         --------- `match` arms have incompatible types
    568 |   ...                       Ok(o) => ansi_to_text(o.bytes())
        |  ____________________________________-
    569 | | ...                           .unwrap_or_else(|e| Text::raw(format!("{:?}", e))),
        | |________________________________________________________________________________- this is found to be of type `tui::text::Text<'_>`
    570 |   ...                       Err(e) => Text::raw(e.to_string()),
        |                                       ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `tui::text::Text`, found a different struct `tui::text::Text`
        |
        = note: perhaps two different versions of crate `tui` are being used?
    

    macOS 10.15.17 rustc 1.52.1 cargo 1.52.0

    opened by atroche 12
  • Improve change directory performance

    Improve change directory performance

    The release v0.16.4 improved the performance of operating in a big directory using a plugin that reads the directory_buffer.nodes field (by caching it). By it came at cost. Every time when enter a big directory, it will freeze for a moment to cache the nodes, which isn't necessary if we aren't using plugins that read that specific expensive field.

    Let's not cache things unnecessarily and hide the directory_buffer field. It's already nullable. So, let's provide an option like pass_directoty_buffer which is disabled by default. Plugins that really need to read that field can set it to true.

    opened by sayanarijit 0
  • Figure out what's with the benchmark tests

    Figure out what's with the benchmark tests

    Since this is a critical change for being able to use some plugins, I'll be merging this, and create a separate issue for investigating what's with the benchmark.

    Originally posted by @sayanarijit in https://github.com/sayanarijit/xplr/issues/413#issuecomment-968869572

    opened by sayanarijit 0
  • Support passing argument to lua functions

    Support passing argument to lua functions

    Implement something like CallLuaWithArg, using which, users can pass arguments to the Lua functions. Being able to pass one argument should be enough. Serde Value should support this.

    opened by sayanarijit 2
  • Add a

    Add a "Report error" screen to make it easy for users to report issues

    It'll be similar to the "Recover" mode. Users should be able to turn it off in the config file.

    Display the error, OS, terminal, xplr version and logs in the screen and a link to post the issue.

    opened by sayanarijit 0
  • Timestamp support

    Timestamp support

    Screen Shot 2021-10-31 at 17 46 33
    opened by sux2mfgj 5
  • Add a new column indicates time of last modification

    Add a new column indicates time of last modification

    Related to #379.

    Tasks for supporting the time column.

    • [ ] implement rust backend
      • [ ] Node and NodeUiMetadata
      • [ ] init.lua
      • [ ] Sorter
      • [ ] Filter
    • [ ] Update document

    I think those tasks are needed to support the new column. If there are any tasks that are missing, let me know.

    opened by sux2mfgj 2
  • Bug with color rendering

    Bug with color rendering

    I've resolved this issue by adding spaces around color codes

    xplr.fn.custom.bottom_status = function(ctx)
    	local a = ctx.app
    	local status = ""
    
    	status = status .. " " .. colorString(a.directory_buffer.focus + 1 .. "/" .. a.directory_buffer.total, colorFgYellow) .. " "
    
    	if #a.selection > 0 then
    		status = status
    			.. colorString(colorString(" +" .. tostring(#a.selection) .. " ", colorBgYellow), colorFgBlack)
    			.. " "
    	end
    
    	status = status .. get_permissions(a.focused_node)
    	status = status .. " " .. colorString(tostring(a.focused_node.human_size), colorFgYellow) .. " "
    
    	return status
    end
    

    haven't figured out why it works like that, but for now it's fine for me image

    Thank you!

    Originally posted by @fedoranvar in https://github.com/sayanarijit/xplr/issues/381#issuecomment-952003377

    opened by sayanarijit 0
  • Focused Node. Fields: date_modified, date_created, uid, guid

    Focused Node. Fields: date_modified, date_created, uid, guid

    Good day to you!

    Is it possible to access to date_modified, date_created and user-owner, and group-owner via LuaArgument?

    (example of fields - exa) image

    (example of fields - nnn) image

    Thinking of workaround like getting file details by filepath with some Lua funcs, but i think these fields will be useful in xplr byitself, if they don't exist in it.

    I would like to access and print these fields in CustomContent pane image

    xplr.fn.custom.status = function(ctx)
    	local a = ctx.app
    	-- ' - ' .. a.focused_node.asolute_path ..
    	local status = ""
    	status = status .. "\n" .. a.pwd
    	if #a.selection > 0 then
    		status = status .. "\n" .. "sel " .. tostring(#a.selection)
    	end
    	status = status .. "\n" .. a.directory_buffer.focus + 1 .. "/" .. a.directory_buffer.total
    	status = status .. "\n" .. tostring(a.focused_node.human_size)
    	-- status = status .. "\n" .. tostring(a.focused_node.relative_path)
    	return status
    end
    

    Thank you!

    opened by fedoranvar 1
  • `explore_recursive_async()` results are switched randomly.

    `explore_recursive_async()` results are switched randomly.

    The function calls explore_async() and the explore_async() creates a thread and start to search the directory. As a result, the order of results are switched sometimes in recursive call.

    pub(crate) fn explore_recursive_async(...) {
        explore_async(...);
        if let Some(grand_parent) = parent.parent() {
            explore_recursive_async(...);
        }
    }
    

    Is this behavior as you expected?

    opened by sux2mfgj 6
  • Failed tests of bin/xplr.rs on CI

    Failed tests of bin/xplr.rs on CI

    This issue is for a TODO on xplr.rs.

        // TODO: Fix running GitHub action
        ... some comment outed tests are followed.
    

    I started to investigate this problem.

    Similar problem is occurred when I add a test for a xplr runner. The test just creates runner with default parameter and calls run(). A commit of the test is here in my forked repo.

    A stack trace of the error is shown in a ci log

      17:     0x557526a112d2 - xplr::explorer::explore_async::{{closure}}::{{closure}}::hb453dff62ee96be8
                                   at /home/runner/work/xplr/xplr/src/explorer.rs:59:17
      18:     0x557526a579e4 - core::result::Result<T,E>::map::he62c99987df2a27f
                                   at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/result.rs:748:25
      19:     0x557526a1152f - xplr::explorer::explore_async::{{closure}}::hb4c612bd0ae2e168
                                   at /home/runner/work/xplr/xplr/src/explorer.rs:57:9
    

    I'll update this issue. If you have some related information, please update to here. Thanks.

    opened by sux2mfgj 1
Releases(v0.16.4)
A template for bootstrapping a Rust TUI application with tui-rs & crossterm

rust-tui-template A template for bootstrapping a Rust TUI application with tui-rs & crossterm. tui-rs The library is based on the principle of immedia

Orhun Parmaksız 36 Nov 23, 2021
⚡️ Lightning-fast and minimal calendar command line. Written in Rust 🦀

⚡️ Lightning-fast and minimal calendar command line. It's similar to cal. Written in Rust ??

Arthur Henrique 21 Nov 9, 2021
Rust TUI client for steamcmd

Steam TUI About Just a simple TUI client for steamcmd. Allows for the graphical launching, updating, and downloading of steam games through a simple t

Dylan Madisetti 396 Nov 29, 2021
Another TUI based system monitor, this time in Rust!

Another TUI based system monitor, this time in Rust!

Caleb Bassi 2k Nov 29, 2021
A user-friendly TUI client for Matrix written in Rust!

Konoha A user-friendly TUI client for Matrix written in Rust! Notice: The client is currently not usable and is only hosted on GitHub for version cont

L3af 11 Nov 8, 2021
TUI image viewer

Picterm TUI image viewer install $ cargo install picterm or $ git clone https://github.com/ksk001100/picterm $ cd picterm $ cargo install --path . usa

Keisuke Toyota 4 Jul 27, 2021
A cli prepared with TUI that facilitates your operations.

⚠️ For linux only ⚠️ Helper CLI A cli prepared with TUI that facilitates your operations. Click me to learn more about the theme system. If you just w

Yiğit 4 Jul 10, 2021
A tui to test regexes on the rust regex crate

regex-tui Structure src/ ├── app.rs -> holds the states and renders the widgets ├── event.rs -> handles the terminal events (key press, mouse cl

null 1 Oct 21, 2021
Parse hex colors to tui::style::Color

Color -> Tui Parse hex colors to tui rgb colors #c3f111 -> Color::Rgb(195,241,17) Note that the indexed colors are NOT HEX #142 -> Color::Indexed(142)

Uttarayan Mondal 1 Nov 8, 2021
TUI input library supporting multiple backends

tui-input WARNING: Most of the functionality is only human tested. A TUI input library supporting multiple backends. This crate can be used with tui-r

Arijit Basu 12 Nov 13, 2021
2048 in `tui`, just for fun

TUI 2048 - Have a relax at anytime - ?? ^_^ How to run repo clone this repo, git clone https://github.com/WanderHuang/game-2048-tui.git cd game-2048-t

wander 34 Nov 18, 2021
Tiny color conversion library for TUI application builders

Definition of ANSI, RGB and HSL color types and all the conversions between them. There are many other color conversion crates. This one may be useful

Canop 5 Nov 13, 2021
FastSSH is a TUI that allows you to quickly connect to your services by navigating through your SSH config.

Connect quickly to your services ?? FastSSH is a TUI that allows you to quickly connect to your services by navigating through your SSH config. Instal

Julien 39 Nov 20, 2021
A minimal CLI framework written in Rust

seahorse A minimal CLI framework written in Rust Features Easy to use No dependencies Typed flags(Bool, String, Int, Float) Documentation Here Usage T

Keisuke Toyota 167 Nov 17, 2021
A minimal argument parser

Pieces An argument parser built with control in mind. Parsing The results you get are dependent on what order you parse in. If you want to say only pa

ibx34 3 Sep 30, 2021
Warp is a blazingly fast, Rust-based terminal that makes you and your team more productive at running, debugging, and deploying code and infrastructure.

Warp is a blazingly fast, Rust-based terminal that makes you and your team more productive at running, debugging, and deploying code and infrastructure.

Warp 549 Nov 24, 2021
Add path effects to open glyphs in a UFO file

ufostroker Add path effects to open contours in a UFO file Given a glyph with open contours: You can apply a noodle effect: ufostroker -i Open.ufo -o

Simon Cozens 5 Jun 28, 2021
Save image from your clipboard 📋 as an image file directly from your command line! 🔥

Clpy ?? Save copied image from clipboard as an image file directly from your command line! Note It works only on windows as of now. I'll be adding sup

Piyush Suthar 12 Aug 6, 2021
Edit a file directly on Amazon S3 in CLI.

s3-edit-rs The original idea for this project comes from s3-edit written in Go by tsub. I started this project for educational purposes, and it is my

Gor Hayrapetyan 6 Jul 12, 2020