the problem#

I just connected to a remote machine. Maybe I just have to run a couple commands, maybe I am logging in with a functional user… but for whatever reason I cannot load my trusty dotfiles on it.
No biggie, let’s get to work!

z
# z: command not found
l
# l: command not found
ll
# ll: command not found
Yeah…

In case you were wondering, here are the definition

type z l ll
# z is aliased to `eza --icons -A'
# l is aliased to `ls -CF'
# ll is aliased to `ls -lah'
l and ll are pretty standard, available by default almost everywhere, z calls eza, a modern replacement for ls

This is the first (and maybe last) post about surviving without pretty prompts, modern shells, fzf, tmux, etc

The solution: navigate like it’s the ’80s!

looking around#

my favorite alias: alias t='eza --tree --icons --almost-all --git-ignore'

 .
├── 󱆃 .bashrc
├──  .gdbinit
├──  .gitignore
├──  .inputrc
├──  nvim
│   ├──  colors
│   │   ├──  derpy.vim
│   │   └──  solarized.vim
│   ├──  echomargs.lua
│   ├──  init.lua
│   ├──  plugin
│   │   └──  after
│   │       ├──  cmp_settings.lua
...
│   │       ├──  oil_settings.lua
│   │       └──  treesitter_settings.lua
│   ├──  statusline.vim
│   └──  to_errorformat.awk
├──  README.md
└──  write_and_run.tmux
bonus: Add -L3 to limit recursion to 3 levels

can we do it with just “built-ins”? no, but we can get closer with find. Just find, no arguments, lists all files:

./Shada.vim
./write_and_run.tmux
./.inputrc
./nvim
./nvim/init.lua
./nvim/colors
./nvim/colors/solarized.vim
./nvim/colors/derpy.vim
./nvim/Shada.vim
./nvim/plugin
./nvim/plugin/after
./nvim/plugin/after/oil_settings.lua
./nvim/plugin/after/cmp_settings.lua
./nvim/plugin/after/treesitter_settings.lua
...
./nvim/echomargs.lua
./nvim/to_errorformat.awk
./nvim/statusline.vim
./.gdbinit
./.tmux.sh
./gitconfig_global
./lfrc
./.local_tmp
./.pythonrc
./.bashrc
./.tmux.conf
./.nvim.lua
./.gitignore_global
./.git
./.git/refs
./.git/refs/heads
./.git/refs/heads/master
./.git/refs/tags
./.git/refs/remotes
./.git/refs/remotes/origin
...
./.gitignore
./README.md
./Session.vim
It is not pretty, does not ignore .git stuff, but gets the job done. Pipe it to less or, more if less is not available and scroll away!

useful options#

maybe you need an overview of the folder structure:

  • -maxdepth 2 self explanatory
  • -tpye d only show dirs

or to exclude some folder full of trash:

  • ! -iwholename '*.git/*' is a bit ugly
  • find’s arguments are wired… I would use | grep -v '.git/'

looking into files#

vim & fzf plugins like fzf-lua, with its builtin grep and live_grep searches, allows us to look around very fast.

vi is almost certainly available, but out of the box won’t help much if we are just looking around. cat and less are great if we only have a couple files, but…

What if we have a bunch of files, and we are not even sure of what we are looking for? grep to the rescue!
This time we have to use a couple of short arguments: grep -r . . yes, very short!

  • -r is for recursive
  • . the first dot is the PATTERN, a dot matches everything but empty lines
  • . the second dot is the FILE, here the current directory

finds everything, everywhere! again, pipe it to less or more

grep -r . .
# content/posts/surviving_without_dotfiles_1.md:+++
# content/posts/surviving_without_dotfiles_1.md:title = "Surviving without Dotfiles (part 1)"
# content/posts/surviving_without_dotfiles_1.md:date = "2025-07-27T00:05:48+02:00"
# ...
# content/posts/setting_up_the_blog.md:+++
# content/posts/setting_up_the_blog.md:title = "setting up the blog"
# content/posts/setting_up_the_blog.md:date = "2025-07-19T00:31:40+02:00"
# content/posts/setting_up_the_blog.md:author = "fbtd"
# ...
# content/posts/setting_up_the_blog.md:# index.html                       ...
# content/posts/setting_up_the_blog.md:Done! if nginx is working properly ...
# content/posts/initial_post.md:+++
# content/posts/initial_post.md:title = "Initial Post"
# content/posts/initial_post.md:date = "2025-07-18T22:15:06+02:00"
# content/posts/initial_post.md:author = "fbtd"
# ...
Again, not pretty, but works!

jumping back and forth#

Using a terminal multiplexer like tmux made moving around almost obsolete: open a new pane, cd to whatever folder you need and voilà, a presistent shell at the right place.
Jumping between panes (or windows (or sessions)) is the new meta!

Sure, usually it is possible to open a second terminal to the same machine, and alt-tab between sessions.

In the vast majority of cases we are working between two directories (/etc/SOMETHING and /var/log/SOMETHING for example).
If that’s the case then the builtin cd - is what we are looking for: it jumps back to the last folder (equivalent to cd $OLDPWD)

~/blog/public $ vi index.html
~/blog/public $ cd /etc/nginx/sites-available/
/etc/nginx/sites-available $ vi blog
/etc/nginx/sites-available $ cd -
/home/boris/blog/public
~/blog/public $ # ...and we are back
~/blog/public $ cd -
/etc/nginx/sites-available
/etc/nginx/sites-available $ # oups, forgot something

bonus: cd by itself will bring you $HOME!

dirstack#

If you need more than two directory, Bash can maintain a stack of paths, check out the dirs, popd and pushd builtin in bash’s man page.

That’s it for this first part, see you next time!