Show HN: Fff – A terminal file manager written in bash

(github.com)

55 points | by 2211 1929 days ago

7 comments

  • 2211 1929 days ago
    The entire program was rewritten and the source is now highly readable. The rewrite also made features like 'LS_COLORS' support possible. A lot of optimization was done and the program no longer redraws the entire screen per key-press[!].

    For those wondering "Why bash?"; I wanted something I could 'wget'/'curl' on other machines that would "just work". The program only requires 'bash 3+' and a POSIX compliant 'coreutils' to function. Also, it's really fun to push bash to its limits!

    I'm the developer, happy to answer any questions.

    Note: I noticed this has been posted before so I added a '#' to bypass the filter. I think this merits a re-post as the project is 100% different to how it was before. The old program was 100~ lines of obfuscated spaghetti and the new program is around 700~ lines of commented "well structured" code.

    • JoshuaRLi 1928 days ago
      The obfuscation wasn't that bad, I recall it was quite fun to parse through for inspiration while trying to implement a similarly spirited file manager, only in posix-compliant shell (well, at least in `dash`). No arrays were a major pain point, and mainly why I gave up halfway.

      Anyways, thanks for the `fff` rewrite, it's pretty wonderful.

      • 2211 1928 days ago
        You could probably pull it off in POSIX sh if you basically made a file manager TUI around 'ls' (this isn't a bad idea actually). ;)
    • sephoric 1927 days ago
      This is very cool, thanks for resubmitting it, I actually checked out the source code this time, as opposed to last time only reading the readme.

      Having learned all that you needed to in order to write (and rewrite) this, do you have any similar future projects in the works?

      • 2211 1927 days ago
        I'm working on a guide that will cover the entire process of creating a terminal user interface in bash. I want to create a central location for the information I've gathered so it may be of benefit to others.

        I also hope that people will contribute their own snippets, methods and ideas. It'd be great to find out if there are better ways of implementing the code.

        The guide is on GitHub [0] and is a heavy work in progress. Its currently structured in a way I'm not too happy with. I want to change it to a series of 'How to implement x' instead of an ever growing implementation.

        Other than the TUI guide I have 4 other major projects which I am working on (neofetch, pywal, fff and the Pure Bash Bible).

        [0] https://github.com/dylanaraps/writing-a-tui-in-bash

        • sephoric 1927 days ago
          Along those lines, I think a heavily commented version of fff would be a great learning tool. The concepts of fff are simple enough that anyone could follow along easily without really having to learn fff first. This idea came partly from the fact that when I tried reading fff's new source code yesterday, while knowing exactly what fff does and understanding the comments completely, I was still pretty lost as to what it was doing and how it worked.
  • michaelpb 1928 days ago
    Added it to my dotfiles repo. Might be a useful tool, has search with `/`, uses <Esc> and uses hjkl vim hotkeys so using it was pretty natural for me. Also I'll see how it works out!
  • Evidlo 1928 days ago
    What challenges did you encounter implementing this in bash that you wouldn't expect from a conventional programming language?
    • 2211 1928 days ago
      There's no library to handle all of this for you ('ncurses' etc). It has to all be done manually by hand. This involved scouring through VT100 and other terminal manuals to figure out escape sequences and other terminal behavior. Also the installation of something like 30~ terminal emulators to make sure the escape sequences behaved everywhere.

      I stuck to VT100 sequences (which are supported pretty much everywhere nowadays) with the exception of 1 or 2 newer sequences (which are ignored in older terminals and not required). I didn't want to use 'tput' since it would add the dependency of 'ncurses' and it would slow the program down quite a lot. Each 'tput' call is an external process which adds '10-15ms' to the program per call.

      I also ran into some funny bash behavior. The main loop waits for user input (with 'read') and if the script received a 'SIGWINCH' signal that ran a second 'read' asynchronously, it would break the terminal.

      The other big issue is you can't write anything widely portable in bash without supporting bash '3.2+' (which is over 10(?) years old at this point). macOS is forever stuck on this version due to Apple's issues with GPLv3. This means useful features like associative arrays, 'declare -n' etc are unavailable for use.

      Other than these issues it wasn't that difficult to pull off. It was a lot of fun actually!

  • igoose1 1928 days ago
    Looks really fast! Thanks for "just bash". It's great for me 'cause of portability. I'm not bash scripts pro but I found code is simple to understand. vi-like keys and functions of multiple moving and removing are also great.

    I definitely will try it next day. I'm sure it can be my #1 cli file manager!

    • 2211 1928 days ago
      Thanks, that's the idea. The project is still young so don't hesitate to bug me with issues etc. I'm sure you'll come across some. :)
  • zuern 1928 days ago
    I'm really happy to see this come up again. I've been using the original version and love it! Will be sure to use this newer version. Thanks for the awesome (and simple!) script.
  • someguy101010 1928 days ago
    Pretty cool! I'm gonna try it out, any plans to implement fuzzy search?
    • 2211 1928 days ago
      I can very easily add optional support for either 'fzf' or another fuzzy matcher. I'll take a look at implementing this in pure bash but I doubt it'd match the speed of a dedicated tool in this instance.

      The current search is just bash creating an array using a glob 'list=(/path/to/current_dir/"$search_query")'. bash gets a lot slower when you start adding more levels to the search (2 or more deep).

      I'll get to implementing fuzzy searching algorithms first and we'll see what steps I take from there. Who knows? It might work fast enough in pure bash for file searching.

    • apjana 1928 days ago
      The C utility nnn (https://github.com/jarun/nnn) integrates fzy for this.
  • thatoneuser 1928 days ago
    Looks like a great tool. Do you find hay it saves time if you’re already pretty smooth on the command line?
    • 2211 1928 days ago
      I use the search feature to quickly navigate through directories. I have 'CD on exit' configured as well so I can quit 'fff' and I'm in the new directory ready to type commands.

      I also like that I can hit 'l' (or enter) to open files and I don't have to think about what program I need to use to open them. Text files are handled by '$EDITOR' and everything else is opened through mime-type using 'xdg-open' (which is configurable to your opener of choice).