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.

Comments
  • 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
  • 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
  • PGP signatures could not be verified for 0.20.0 releases

    PGP signatures could not be verified for 0.20.0 releases

    Repro script:

    #!/usr/bin/env bash
    
    set -eux
    
    REPO_URL="https://github.com/sayanarijit/xplr"
    
    wget -qO source.tar.gz.asc "$REPO_URL/releases/download/v$1/source.tar.gz.asc"
    wget -qO source.tar.gz "$REPO_URL/archive/refs/tags/v$1.tar.gz"
    gpg --verify source.tar.gz.asc
    

    Results:

    $ ./repro.sh 0.20.0
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.20.0/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.20.0.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Sat 29 Oct 2022 12:30:03 AM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: BAD signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    
    $ ./repro.sh 0.20.0-beta.3
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.20.0-beta.3/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.20.0-beta.3.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Thu 27 Oct 2022 08:53:58 PM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: BAD signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    
    $ ./repro.sh 0.20.0-beta.2
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.20.0-beta.2/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.20.0-beta.2.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Thu 27 Oct 2022 02:39:12 PM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: BAD signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    
    $ ./repro.sh 0.20.0-beta.1
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.20.0-beta.1/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.20.0-beta.1.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Wed 26 Oct 2022 10:29:10 PM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: BAD signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    
    $ ./repro.sh 0.20.0-beta.0
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.20.0-beta.0/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.20.0-beta.0.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Wed 26 Oct 2022 01:52:21 AM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: BAD signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    
    $ ./repro.sh 0.19.3
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.19.3/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.19.3.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Sun 11 Sep 2022 05:49:47 AM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: Good signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    gpg: WARNING: This key is not certified with a trusted signature!
    gpg:          There is no indication that the signature belongs to the owner.
    Primary key fingerprint: D59C A147 10C1 7C6B 2471  7AF9 0F8E F525 8DC3 8077
    
    $ ./repro.sh 0.19.2
    + REPO_URL=https://github.com/sayanarijit/xplr
    + wget -qO source.tar.gz.asc https://github.com/sayanarijit/xplr/releases/download/v0.19.2/source.tar.gz.asc
    + wget -qO source.tar.gz https://github.com/sayanarijit/xplr/archive/refs/tags/v0.19.2.tar.gz
    + gpg --verify source.tar.gz.asc
    gpg: assuming signed data in 'source.tar.gz'
    gpg: Signature made Sat 10 Sep 2022 11:36:52 PM +03
    gpg:                using RSA key D59CA14710C17C6B24717AF90F8EF5258DC38077
    gpg: Good signature from "Arijit Basu (June 3, 2021) <[email protected]>" [unknown]
    gpg: WARNING: This key is not certified with a trusted signature!
    gpg:          There is no indication that the signature belongs to the owner.
    Primary key fingerprint: D59C A147 10C1 7C6B 2471  7AF9 0F8E F525 8DC3 8077
    

    As you can see, none of the 0.20.0 releases cannot be verified with gpg. I'm not sure why it happens and I will look more into this when I have time.

    opened by orhun 18
  • 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
  • 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
  • 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
  • Xplr Neovim plugin development - Thoughts/Ideas/Improvements

    Xplr Neovim plugin development - Thoughts/Ideas/Improvements

    After being able to require C modules inside Xplr I've started playing around with nvim xplr plugin pairs to integrate xplr into nvim. Xplr is my favourite file manager and having xplr seamlessly integrate within xplr would be an ideal workflow.

    Starting features and implementation status

    features of nnn fork of xplr: mappings, layout - working Hover selection to nvim - currently unstable open selection in nvim - through msgpack - working, would like to create some additional configuration so users can decide how they would like to open simple msgpack API callings custom functions/commands from xplr functions - working

    Ideas - why?

    If the relevant xplr data is available within nvim, the user can do whatever they want with it. e.g: Send xplr selected files to qflist, preview hovered file in telescope driven previews (working on atm as an extra feature, very awesome :D ), change cwd, modify other plugins based on xplr data (switch nvim file managers cwd), run custom lua functions inside nvim on xplr selected files...

    My questions

    Do you know of anyone already creating something similar? If so, would could work together. Any other features that would be a good addition to above?


    And regarding hover selection instability, I was trying to find a way to access the hover selection in the lua environment (to send it over msgpack). Is this possible?

    Currently the hover selection is implemented like this:
    xplr keybind triggers xplr lua function that executes StartFifo and calls an nvim function that connects to pipe using libuv (job) on nvim side. Currently sometimes get broken pipe error or xplr closing when executing this function which most likely can be fixed by working on it some more, but feels like this would be a lot cleaner doing xplr lua env --> nvim lua env with msgpack and bypassing pipes completely.


    Testing

    if anyone would like to try out the plugins above, let me know about the install process etc, any feedback/improvements, that would be awesome, a major help. It's definitely a WIP state atm, just uploaded so I can share to test. There are definitely some bugs. (hover selection/Telescope previewer is broken atm), apart from that all the other features should work.

    opened by fhill2 16
  • An attempt at safer message passing.

    An attempt at safer message passing.

    In order to address #515, messages have to be able to contain newline characters. In order to do that, the messages must be delimited with something other than newlines, and nulls are the most appropriate.

    In init.lua, nulls needed to be added to the end of all messages being sent, and they had to be anticipated whenever any messages were being iterated. This didn't end up being too bad, and the resulting change from using echo to printf is actually easier to read in most cases. Not to mention, printf is actually built in to bash, whereas echo is a separate program. I'm thinking this could be made even easier to read and less error-prone by including a lib.bash file somehow that defines message passing functions available to BashExec etc.

    Overall, I think this code can probably be improved on a lot. I'm not sure I've addressed everything that might be impacted by such a change, and I haven't added any tests yet. I mainly just wanted to get a proof of concept working to see if it's a reasonable approach.

    opened by jmcantrell 14
  • Helix editor panics when started from xplr

    Helix editor panics when started from xplr

    • OS: MacOS 11.2.1
    • Terminal: iTerm2 3.4.12
    • xplr version: 0.17.2
    • Helix version: source build from commit 368064e3

    When I try to start Helix from xplr, either via :e or even by typing hx into the shell opened by :!, it panics with the following panic message from crossterm:

    thread 'main' panicked at 'reader source not set'
    

    The panic message also gives that it occurred at src/event/read.rs:38:30 in crossterm.

    opened by Omnikar 14
  • Implement a plugin manager

    Implement a plugin manager

    Now that we got enough plugins, we need a plugin manager to make installing and managing xplr plugins simpler.

    A few properties I'd like in the plugin manager:

    • The plugin manager will itself be a Lua plugin, to avoid touching the core.
    • An interface to manage the plugins interactively, without leaving xplr (with support for auto reload).
    • Pre and post install scripts.
    • luarocks support.
    • fennel support.
    • Custom Lua path.
    • Plugin load time benchmark.
    • Ignore plugins that fail to load.
    • Debug failures.
    • Dependency plugins.
    • Dependency binary validation and installation support.
    • As declarative as possible.
    • Display plugin readme.
    • Plugin development utilities (watch, hot reload, inspection etc.)
    • Install from any git hosting platform.
    opened by sayanarijit 13
  • configurable pipes

    configurable pipes

    would it be possible to add an argument of some sort (or probably multiple) to at runtime specify where to put or what to call the "named" pipes for piped in-out data

    this could be used to have external programs interact directly with a spesific xplr session without needing to be in the form of a plugin

    one example could be interacting with xplr using a keybinding in a compleately different program, such as a terminal(wezterm) or integreating it with an existing bookmark manager for example

    it allso makes it possible to write the external code in something other than bash/lua (I would love to be able to write a pluggin in fennel(lisp) as an example)

    opened by erikLundstedt 5
  • 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
  • Simplify runner::Runner::run

    Simplify runner::Runner::run

    The runner::Runner::run method is quite complicated and deals with a lot of variables. This can be simplified by consolidating the variables into one or multiple structs.

    opened by sayanarijit 3
  • Optimize scrolling UI

    Optimize scrolling UI

    $ cd "$(mktemp -d)"
    $ for i in `seq 0 1000`; do echo $i > $i; done
    $ xplr
    

    I expect xplr to show as much files as it could possibly fit, but in fact there is a lot of empty unused space:

    image

    If I begin to scroll down, it's not using more space:

    image

    If I resize terminal such that there is less vertical space, xplr even adjusts on the fly - but if I resize back, at some point it just stops using extra space, resulting in the pictures above.

    It would be nice to always use all the available space ๐Ÿ™‚

    Furthermore, once you scroll down (like on the second picture above - so I'm on 946), and then I begin to scroll up again, I expect the cursor to go up but I expect 946 to still be in the view, i.e. view should not be scrolled at this point - like try scrolling up and down in vim in a long document, cursor goes up but screen scrolling should only begin when cursor reaches the top of the screen. Does this make sense? And what do you think in general? ๐Ÿ™‚

    help wanted 
    opened by maximbaz 4
Releases(v0.20.1)
Integrate Mcfly with fzf to combine a solid command history database with a widely-loved fuzzy search UI

McFly fzf integration Integrate McFly with fzf to combine a solid command history database with a widely-loved fuzzy search UI Features: Advanced hist

null 11 Jan 25, 2023
๐Ÿ–ฅ A feature rich terminal UI file transfer and explorer with support for SCP/SFTP/FTP/S3

?? A feature rich terminal UI file transfer and explorer with support for SCP/SFTP/FTP/S3

Christian Visintin 574 Jan 5, 2023
A simple library fot creating file explorer for the ratatui crate.

ratatui-explorer ratatui-explorer is a simple library for creating file explorers for ratatui. Features: File explorer functionality. Input handling (

null 5 Feb 29, 2024
Ideas => Creations, a multi-language CMS(Content Management System) based on Rust Web stacks, with long-term upgrade and maintenance.

Ideas => Creations ไธญๆ–‡ RustHub: Rust ideas yesterday, shining creations today! This repository holds source code used to run https://rusthub.org, it's

rusthub.org 4 May 9, 2023
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 72 Dec 31, 2022
Minimal and blazing-fast file server. For real, this time.

Zy Minimal and blazing-fast file server. For real, this time. Features Single Page Application support Partial responses (Range support) Cross-Origin

Miraculous Owonubi 17 Dec 18, 2022
Git Explorer: cross-platform git workflow improvement tool inspired by Magit

Gex Git workflow improvement CLI tool inspired by Magit. This project is still under initial development, but I am actively dogfooding it and features

Peter Hebden 204 Jan 6, 2023
Rust File Management CLI is a command-line tool written in Rust that provides essential file management functionalities. Whether you're working with files or directories, this tool simplifies common file operations with ease.

Rust FileOps Rust File Management CLI is a command-line tool written in Rust that provides essential file management functionalities. Whether you're w

Harikesh Ranjan Sinha 5 May 2, 2024
A user-friendly TUI for secure file transfers, with arrow-key and VIM-style navigation

gsftp SFTP with an interactive text-based user interface (TUI). Transfer files through an encrypted connection with a visual interface, so you can see

Ben Jiron 3 Jul 7, 2022
Simple file manager to practice using tui-rs

simple-tui-file-manager Simple file manager to practice using tui-rs Keymap Key description j, up move up k, down move down h, Left move parent dir l,

Slug 3 Nov 12, 2022
A fast, simple TUI for interacting with systemd services and their logs

systemctl-tui A fast, simple TUI for interacting with systemd services and their logs. systemctl-tui can quickly browse service status and logs, and s

Reilly Wood 11 Sep 1, 2023
Minimal recursive "truncate file/directory names to meet requirements" tool

trunc_filenames ssokolow@monolith ~ % trunc_filenames --help trunc_filenames 0.1.0 Rename files and directories to fit length limits. WARNING: Will n

Stephan Sokolow 2 Nov 20, 2022
A minimal file exchange server designed for clients with browsers only.

XIAO-Files Xiao-Files is a minimal file exchange server designed for clients with browsers only. Example Let's say we have a host with IP 10.8.20.1, a

EvianZhang 3 Apr 2, 2024
โšก๏ธ 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 36 Jan 1, 2023
โ˜„๐ŸŒŒ๏ธ The minimal, blazing-fast, and infinitely customizable prompt for any shell

โ˜„??๏ธ The minimal, blazing-fast, and infinitely customizable prompt for any shell

Starship Command 31.6k Dec 30, 2022
Fast, minimal, feature-rich, extended formatting syntax for Rust!

Formatting Tools Fast, minimal, feature-rich, extended formatting syntax for Rust! Features include: Arbitrary expressions inside the formatting brace

Casper 58 Dec 26, 2022
Minimal, blazing fast Node.js script runner

nrr Minimal, blazing fast Node.js script runner. Why? nrr initializes and resolves scripts way faster than package managers. It achieves this by provi

Ryan Cao 3 Nov 17, 2023
A command-line tool aiming to upload the local image used in your markdown file to the GitHub repo and replace the local file path with the returned URL.

Pup A command line tool aiming to upload the local image used in your markdown file to the GitHub repo and replace the local file path with the return

SteveLau 11 Aug 17, 2022
My own image file format created for fun! Install the "hif_opener.exe" to open hif files. clone the repo and compile to make your own hif file

Why am i creating this? I wanted to create my own image format since I was 12 years old using Windows 7, tryna modify GTA San Andreas. That day, when

hiftie 3 Dec 17, 2023