74 votes

Share your personal dotfile treats and Unix tool recommendations

I am currently preparing for a new job and cleaning up my dotfile repository. During the process, I had the idea that it would be nice to create a list of amazing tools, aliases, functions, and recommendations together.

I will start.

First, here is a list of nice tools to apt-get install or brew install that I can wholeheartedly recommend:

  • nvim is just an amazing text editor.
  • fzf is a very good fuzzy finder util. For example, you can quickly find files with it.
  • eza is a good ls replacement (and the successor of exa).
  • bat is a great replacement for cat with nice integrations and many options.
  • stow is great for managing your dotfiles. Thanks to @TangibleLight for telling me about it some while ago. I really love it.
  • tmux is a terminal multiplexer, i.e. you can have many sessions in one single terminal window. It's easy to use and super helpful. (When on a mac, I prefer iTerm tabs, though.)
  • nvm is practically a must if you are working with Node.
  • glow is an excellent markdown reader.
  • tldr is a nice man replacement. (You must run tldr -u after installing it to update available texts.)
  • z, an amazing tool for switching directories quickly.

Also, I can recommend Oh My ZSH! which I have been using for years.

Here is a small list of aliases I enjoy (I have 100+ aliases and I tried to pick some others may enjoy as well):

# Serve current dir
alias serve="npx serve ."

# What's my IP?
alias ip="curl --silent --compressed --max-time 5 --url 'https://ipinfo.io/ip' && echo ''"

# This should be the default
alias mkdir="mkdir -p"

# Nice git helpers
alias amend="git add . && git commit --amend --no-edit"
alias nuke="git clean -df && git reset --hard"

# Make which more powerful
which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'

# This saves so many keystrokes, honestly
alias -- +x="chmod +x"

# Turns your path into a nice list and prints it
alias path='echo -e ${PATH//:/\\n}'

# Map over arguments and run a command
# Usage: map <command>
# Example: ls | map cat
alias map="xargs -n1"

And, finally, here are some fun functions:

# Get cheat sheets for almost anything!
# https://github.com/chubin/cheat.sh
cheat() {
    WITH_PLUS=$(echo $@ | sed 's/ /+/g')
    CAT_TOOL=$(command -v batcat || command -v bat || command -v cat)
    curl "cheat.sh/$WITH_PLUS" | $CAT_TOOL
}

# Send everything to /dev/null
nullify() {
  "$@" >/dev/null 2>&1
}

# Create a new dir and enter it
mk() {
  mkdir -p "$@" && cd "$_"
}

# Create a data URL from a file
# Source: https://github.com/mathiasbynens/dotfiles/blob/master/.functions
data-url() {
	local mimeType=$(file -b --mime-type "$1");
	if [[ $mimeType == text/* ]]; then
		mimeType="${mimeType};charset=utf-8";
	fi
	echo "data:${mimeType};base64,$(openssl base64 -in "$1" | tr -d '\n')";
}

37 comments

  1. Jakobeha
    Link
    I may add more to this later: Fish shell: alternative to bash and zsh with colors, git integration, auto-complete, better scripting, and more. Note that fish isn't 100% POSIX-compatible. In...

    I may add more to this later:

    • Fish shell: alternative to bash and zsh with colors, git integration, auto-complete, better scripting, and more.
      • Note that fish isn't 100% POSIX-compatible. In practice, almost any command that works with bash works with fish (especially because most scripts start with #! /usr/bin/env bash). But in particular, nvm doesn't, you need nvm.fish.
    • rg (ripgrep): grep (search text in files) but better.
    • fd: find (search files by name and type) but better.
    • ninja: make (build C/C++) but faster. You use it to build CMake projects by passing -GNinja to the command that generates the CMakeFile.
    • mold: ld (link C/C++/Rust/nim object files) but faster. Similarly, you can configure CMake projects to use mold via DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold". It also works with Rust and Nim according to the README.
    • rename for macOS (via brew install rename): batch rename files.
    • restic: command-line backup tool.
    • ncdu: command-line disk cleaner (find and remove large files).
    13 votes
  2. [2]
    wycy
    Link
    nnn: a very fast and lightweight TUI file manager with vim like key bindings. I use it less for file management and more as a faster way to cd around the file system. yazi: another TUI file...
    • Exemplary

    nnn: a very fast and lightweight TUI file manager with vim like key bindings. I use it less for file management and more as a faster way to cd around the file system.

    yazi: another TUI file manager, a bit slower than nnn because it does more (previews). I tend to use yazi for actual file management.

    nnn is so critical to my workflow. Even just going up one directory is fewer keystrokes with nnn. cd ..<Enter> (6 strokes) vs n<Enter>hq (4 strokes). The strokes saved increase with more cd complexity (eg, going up and over a directory).

    8 votes
    1. crdpa
      Link Parent
      Being a nnn user for some years I was intrigued by yazi and tried for a few days. It is indeed very good, but I still prefer nnn. I need to do many more keystrokes to achieve the same things in...

      Being a nnn user for some years I was intrigued by yazi and tried for a few days. It is indeed very good, but I still prefer nnn.

      I need to do many more keystrokes to achieve the same things in yazi. Nnn is way better at this.

      Also I am very diligent with my filenames and organization so I don't see a need for file preview and icons. I find these nerd font icons quite ugly.

      Great project anyway.

      4 votes
  3. xk3
    (edited )
    Link
    cb I can't recommend cb enough! https://github.com/niedzielski/cb It's a pretty simple concept: run different things depending on whether stdin is connected to a terminal which allows you to write...

    cb

    I can't recommend cb enough!

    https://github.com/niedzielski/cb

    It's a pretty simple concept: run different things depending on whether stdin is connected to a terminal which allows you to write a pipeline like this:

    $ cb | sort | cb
    

    This sorts the contents of your clipboard and then puts it back to your clipboard. It totally bust my brain when I first saw it.

    I wrote a similar thing but for images. I don't use it very often but it is handy for checking clipboard screenshots before pasting them into a website.

    moreutils is also interesting to checkout. One of the commands in that package is sponge which let's you do a similar thing to the above and buffer output for files.

    htop

    I've been using htop for about ten years but I never took the time to configure it until last weekend! The defaults are pretty good but htop can do a lot more than showing you which process is hogging all your RAM!!

    • t will display a process tree
    • s will run strace on the highlighted process
    • l (lowercase L) will show all open files for the highlighted process (using lsof)
    • You can add RBYTES WBYTES columns to view how much data each process has read or written to disk. This information is in /proc/$pid/io but sometimes it is useful to see it across all processes
    • You can highlight programs which have been replaced on disk (like if they were updated and need to be restarted)
    • .config/htop/htoprc

    freerdp

    Recently I was having trouble with nomachine on HiDPI displays and I discovered freerdp which I hadn't prior heard of before. The screen is much clearer now:

    On server:

    sudo dnf install freerdp-server freerdp-shadow-cli
    

    On client:

    sudo dnf install freerdp-client
    
    ssh pc -L 35589:localhost:35589 freerdp-shadow-cli -auth /port:35589 /bind-address:127.0.0.1
    
    expect -c '
    set timeout -1
    spawn xfreerdp -authentication +auto-reconnect /network:auto -audio -decorations /v:127.0.0.1:35589 /smart-sizing /workarea /bpp:16 /rfx /gdi:hw /gfx:AVC420,rfx
    expect "Domain:"
    send "\r"
    expect "Password:"
    send "\r"
    expect eof
    '
    

    Quickemu

    handy for spinning up Windows when you need it:

    git clone --filter=blob:none https://github.com/wimpysworld/quickemu
    quickget windows 11
    ./quickemu --vm windows-11.conf --display spice
    

    systemd

    Some people like https://github.com/Nukesor/pueue but I like systemd. For temporary commands I want to run (download jobs, etc) I put them in text files and they run...

    This is a work-in-progress but I'm enjoying it a lot so far:

    progress

    You can use progress to track a bunch of ffmpeg jobs

    progress -wc ffmpeg
    

    And of course I put my whole home folder in git:

    9 votes
  4. [10]
    LunamareInsanity
    Link
    NixOS has been the biggest boon to my enjoyment of computing in a long, long time. The biggest feature for me is consolidating the endless methods and formats of config files into both a...

    NixOS has been the biggest boon to my enjoyment of computing in a long, long time.

    The biggest feature for me is consolidating the endless methods and formats of config files into both a centralized location and - most importantly - a standardized language with standardized logic.

    My favorite example is vim configuration. The various methods of configuring neovim (old vimscript options, the new lua config, plugin managers, plugin installation, and various plugin-specific configs) have all been consolidated. This makes maintaining and adding to the configuration an absolute breeze. A small edited excerpt:

      programs.neovim.defaultEditor = true;
      programs.nixvim = {
        enable = true;
        opts = {
          number = true;
          relativenumber = true;
          undofile = true;
        };
        plugins = {
          floaterm = {
             enable = true;
             keymaps.toggle = "<C-t>";
           };
        };
        colorschemes = {
          rose-pine = {
            enable = true;
          };
        };
      }
    
    Full neovim config
    {
      programs.neovim.defaultEditor = true;
    
      programs.nixvim = {
    
        enable = true;
    
        globals.mapleader = " ";
        globals.maplocalleader = " ";
    
        opts = {
          number = true;
          relativenumber = true;
    
          shiftwidth = 2; # Size of an indent
          tabstop = 2; # Number of spaces tabs count for
          softtabstop = 2; # Backspace by group of spaces instead of single space
          expandtab = true; # Use spaces instead of tabs
          smartindent = true; # Insert indents automatically
    
          cursorline = true; # Highlighting of the current line
    
          undofile = true; # Save undo history after closing buffer
        };
    
        keymaps = [
          {
            key = "Space";
            action = " ";
          }
    
          {
            key = "<leader>sc";
            action = ":source $MYVIMRC<cr>";
          }
    
          {
            key = "<C-g>";
            action = ":FloatermNew --height=500 --width=500 --wintype=float --positon=center --name=lazygit --autoclose=2 --cwd=<buffer> lazygit<cr>";
          }
    
          {
            key = "<S-Up>";
            action = "";
    
          }
    
          {
            key = "<S-Down>";
            action = "";
          }
        ];
    
        plugins = {
          lastplace = {
            # Reopen files to previous location
            enable = true;
          };
    
          floaterm = {
            # Floating terminal
            enable = true;
            keymaps.toggle = "<C-t>";
          };
    
          leap = {
            # Press "s" to seek in the file
            enable = true;
          };
    
          nvim-autopairs = {
            # Auto-insert pairs { }
            enable = true;
          };
    
          treesitter = {
            enable = true;
            indent = true;
            nixvimInjections = true;
          };
    
          hmts = {
            # home-manager tree-sitter: highlight code within nix
            enable = true;
          };
    
          mini = {
            enable = true;
    
            modules = {
              surround = { };
            };
          };
    
          twilight = {
            enable = true;
          };
    
          lsp = {
            enable = true;
    
            keymaps = {
              silent = true;
    
              diagnostic = {
                "<leader>k" = "goto_prev";
                "<leader>j" = "goto_next";
              };
    
              lspBuf = {
                gd = "definition";
                K = "hover";
              };
            };
    
            servers = {
              pylsp = {
                enable = true;
                settings.plugins.ruff = {
                  enabled = true;
                  lineLength = 88;
                };
              };
    
              nixd = {
                enable = true;
              };
            };
          };
        };
    
        colorschemes = {
          rose-pine = {
            enable = true;
          };
        };
    
      };
    }
    

    Consolidation of how to configure things extends to pretty much every other part of the system you can think of. Once you understand the syntax of the language and where to find the options (search.nixos.org), system configuration becomes extremely easy to maintain. It has been much less painful than the old-school way of needing to learn all the different ways base Linux wants to be configured, let alone 3rd-party programs.

    Indeed, most of the common options of both the Linux OS and 3rd-party programs have been pre-packaged into simple true/false flags by the community or otherwise are much more consistent to configure. Failing that, nearly every program includes an option to get back down into the config files themselves, for non-standard needs.

    Some choice examples:

    • Generic auto-login = services.displayManager.autoLogin.enable = true;

    • Install, enable, and run a service = programs.jellyfin.enable = true;

    • Change user shell:

       users.users 
         { 
           luna = { 
             shell = pkgs.fish; 
         }; 
       };
      
    • Extremely standard boilerplate for most self-hosted services:

        services.audiobookshelf = {
          enable = true;
          port = 8389;
          host = "0.0.0.0";
          openFirewall = true;
        };
      
    • Slightly more in-depth configuration for the Transmission torrenting service - config is extremely typical of a service with many options
      services.transmission = {
        enable = true;
        webHome = pkgs.flood-for-transmission;
        home = "/media/torrents";
        user = "transmission";
        group = "media";
        openRPCPort = true;
        downloadDirPermissions = "775";
      
        settings = {
          rpc-bind-address = "0.0.0.0";
          rpc-whitelist = "192.168.*.*, 100.*.*.*";
          rpc-authentication-required = "true";
          rpc-username = "*******";
          rpc-password = "*******";
          download-dir = "/media/torrents/data";
          dht-enabled = "false";
          pex-enabled = "false";
          speed-limit-down = 20000;
          speed-limit-up = 400;
          speed-limit-down-enabled = true;
          speed-limit-up-enabled = true;
        };
      };
      

    The main con is that NixOS does have a learning curve. Its not overly difficult, but NixOS needs things done in its own particular way. Pre-existing Linux knowledge will lead you astray until you learn which parts you can keep and which parts you need to forget. And, admittedly, the documentation and wider community assumes a level of understanding about Nix (the language) that makes the initial learning hurdle harder than it needs to be. However, once NixOS (and to a lesser extent Nix) clicked for me, I fell in love and have not gone back to a "regular" distro ever since.

    I also intentionally stayed away from gushing over the usual Nix(OS) features I hear praised all the time (immutable systems, dev shells for per project package management, easy building of specific versions of packages) in favor of what has been my own favorite feature (and something I hear much less about) - the return of the pure joy of configuration.

    8 votes
    1. [3]
      crdpa
      Link Parent
      I always want to try and end up overwhelmed. If I need to learn all of that and than still maintain my home directory full of dotfiles, I don't see much of a point. But then I heard there is home...

      I always want to try and end up overwhelmed.

      If I need to learn all of that and than still maintain my home directory full of dotfiles, I don't see much of a point.

      But then I heard there is home manager to solve that, and then I heard about something called flakes and by that time I was too overwhelmed with information and dropped. I'll give it a try again sometime soon.

      5 votes
      1. hungariantoast
        (edited )
        Link Parent
        Gradually experimenting and configuring Nix on a spare computer if you have one, or a virtual machine, is definitely a less stressful and easier way to get into Nix. That’s how I did it. And...

        Gradually experimenting and configuring Nix on a spare computer if you have one, or a virtual machine, is definitely a less stressful and easier way to get into Nix. That’s how I did it.

        And personally, I would focus on learning regular Nix stuff and setting up home-manager before learning about flakes. In my opinion, flakes solve a very specific problem, and it’s not a problem that someone starting out with Nix or just using NixOS as a desktop Linux environment is going to run into very often. Even then, flakes aren’t the only way to solve that problem.

        (And to be clear, that problem is: “I need to reproduce this software at this exact version/commit, including all of its dependencies”.)

        4 votes
      2. LunamareInsanity
        Link Parent
        You're right that NixOS+home-manager will replace maintaining almost all other configuration files. And you're also absolutely right that its an information-dense overload all at once. Personally,...

        You're right that NixOS+home-manager will replace maintaining almost all other configuration files.

        And you're also absolutely right that its an information-dense overload all at once. Personally, I'd recommend starting with a small, pre-made template (I like nix-starter-configs - use the minimal version for minimal info overload) and just jumping in one day in with the intention to configure a system and install things. Ignore flakes and anything fancy for now. Its easy to come back to those later, but you can only start once!

        I hope NixOS treats you well when you give a try again!

        3 votes
    2. [3]
      fxgn
      Link Parent
      How do you configure Neovim through Nix when you need something more complicated than basic options? (Eg writing a custom lua function)

      How do you configure Neovim through Nix when you need something more complicated than basic options? (Eg writing a custom lua function)

      4 votes
      1. [2]
        hungariantoast
        (edited )
        Link Parent
        I’m not a (Neo)Vim user so I’ve never configured it with Nix, but you can almost certainly just write your custom Lua code inside your configuration.nix file, and it will be added to a declarative...

        I’m not a (Neo)Vim user so I’ve never configured it with Nix, but you can almost certainly just write your custom Lua code inside your configuration.nix file, and it will be added to a declarative init.lua.

        This seems to be a program/package for nix that helps make that process cleaner: https://github.com/nix-community/nixvim

        As for whether that’s better/nicer than just managing your init.lua normally, that’s up to you.

        Personally, I keep my Emacs and Nix configs separate. It’s the only program I don’t configure with Nix, though, and that’s only because I have some very specific requirements for my Emacs configuration that Nix doesn’t fit into.

        1 vote
        1. LunamareInsanity
          Link Parent
          All of this is correct, as far as neovim goes. And to be clear, my example in the OP of this thread was with using nixvim. Here's how you'd add lua: programs.nixvim = { extraConfigLua = ''...

          All of this is correct, as far as neovim goes.

          And to be clear, my example in the OP of this thread was with using nixvim. Here's how you'd add lua:

            programs.nixvim = {
              extraConfigLua = ''
                print("Hello world!")
              '';
            };
          

          which will be added to init.lua.

          @fxgn Its worth noting that under the hood, nixvim is just filling out pre-made templates in vimscript (for editor settings) and lua (for plugin installation/settings, etc.)

          The end-user also has the ability to tap into this and use the same framework to configure at whatever abstract level they want. See these docs for details.

    3. [3]
      ebonGavia
      Link Parent
      Thanks for sharing your experience. Can you add proprietary drivers on Nix..? Run Steam..? Play games?

      Thanks for sharing your experience. Can you add proprietary drivers on Nix..? Run Steam..? Play games?

      1 vote
      1. [2]
        hungariantoast
        Link Parent
        Of course! Here's a video about some common configurations for playing games on NixOS: https://www.youtube.com/watch?v=qlfm3MEbqYA

        Of course! Here's a video about some common configurations for playing games on NixOS:

        https://www.youtube.com/watch?v=qlfm3MEbqYA

        4 votes
        1. ebonGavia
          Link Parent
          Thanks! I always appreciate your feedback on these topics. I'm thinking about it. Right now Fedora is working for me but I've been intrigued by Nix. Thanks for the research material.

          Thanks! I always appreciate your feedback on these topics. I'm thinking about it. Right now Fedora is working for me but I've been intrigued by Nix. Thanks for the research material.

          3 votes
  5. Boojum
    Link
    Tools stow -- I don't use this for dot files, but I do use it heavily for managing locally built "packages" in /usr/local/ that I've compiled from source. (This was kind of its original purpose)...

    Tools

    • stow -- I don't use this for dot files, but I do use it heavily for managing locally built "packages" in /usr/local/ that I've compiled from source. (This was kind of its original purpose)
    • magick -- Working with graphics programming for a living, I do a ton with images. At its simplest it'll just convert images between formats. But it can also do a ton of image processing and other operations on them. Think of a CLI for Photoshop filters and you start to get the idea. I often prefer Imagemagick to GUI tools because it's so easy to rerun a filter chain if the input changes. There's an insane amount of power here.
    • difftastic -- A nice, somewhat more syntax aware CLI diff tool.
    • pandoc -- It's nice to be able write markdown or org-mode files and then export to other formats. I'd much rather write something in my text editor and convert it to Jira markup than fight Atlassian's on-line editing tools, for example.
    • emacs -- Another amazing text editor. :-)
    • pdfimages -- Rip embedded image files out of a PDF file. It just extracts all the embedded data streams to numbered files, so it's effectively lossless and gets you the images at their full resolution after a bit of spelunking to figure out which is which.

    Aliases

    • alias rshare="chmod -R go=u-w" -- Recursively copy user read and exec perms to group and other to make a subdirectory readable to others.
    • alias runshare="chmod -R go=" -- Undo that by recursively stripping off the perms for groups and others.
    • alias ccat="pygmentize -fterminal16m" -- Like cat but with a colorization filter. (I should probably try bat sometime, but I've been using this for many years.)
    • alias pdiff="git --no-pager diff --no-index --patience --color=auto -U15" -- Run git's patience diff on two arbitrary files.

    Functions

    Note that I use zsh. YMMV with these.

    • function pdf2png() { gs -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=png16m -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r600 -dEPSCrop -dUseCropBox -dFirstPage=1 -dLastPage=1 -sOutputFile=$2 $1 } -- Render the first page of a PDF file to a PNG image at high-ish resolution.
    • function para() { xargs -I{} -P$2 sh -x -c "{}" < $1 } -- Take a file of command lines and a process count and run the commands in parallel.
    • function countdn() { local c; for c in {$1..1}; do echo -ne " $c... \\r"; sleep 1; done } -- Take a time in seconds and give me a countdown. Sometimes useful when I want a cooldown or to rate-limit steps in a larger script.
    • function vbreak() { echo "\033[1;95m\n"; for r in {1..3}; do for c in {1..$COLUMNS}; do echo -n \#; done; done; date; echo "\n" } -- Gives me a big magenta bar across my terminal, along with the current date and time. Useful when I want something of an easily visible section break in my terminal's scroll-back buffer.
    • function semis() { tr -d -c ';' < $1 | wc -c } -- Count semicolons in C-like source code to get a rough estimate of size. (I'll use other tools like cloc, sloccount, or tokei, too, but this one is simple and easy to understand.)
    7 votes
  6. [6]
    fxgn
    (edited )
    Link
    Here's my dotfiles repo and here's some stuff that I use: Fish shell. This was already mentioned by @Jakobeha, but I think he didn't give it nearly enough credit. Fish is a shell done right. If...

    Here's my dotfiles repo and here's some stuff that I use:

    • Fish shell. This was already mentioned by @Jakobeha, but I think he didn't give it nearly enough credit. Fish is a shell done right. If you only use your shell for running external commands, it provides you a ton of built-in convenience features. If you write some scripts, it'll be even more useful, since the syntax is so much better than any POSIX compliant shell.

      For example, to make a custom prompt in bash, you need to mess with $PS1 and ANSI color codes. In fish, you just need to define a function called fish_prompt in your config, and inside of that function you can do whatever you want and just echo stuff out, and that'll become your prompt. And yes, you don't need to google color codes - fish has a built-in set_color command.

    • zoxide. Incredibly useful. It automatically remembers every single directory you cd into, and allows you to quickly switch between them. For example, if you are often in a directory ~/Documents/Projects/foobar, then just typing z f will bring you to that directory.

    • autorestic. This allows to automatically back up all of your files to basically any cloud storage, eg. S3, Google Drive or whatever else you use. Very configurable and easy to set up.

    • xdg-ninja. I hate when programs put their files straight in my home directory. Things like ~/.config or ~/.local/share were made for a reason, but unfortunately not all programs use those directories by default. Running xdg-ninja will scan your home directory and show you all the ways you can clean it up by setting env vars or config options that force programs to use proper locations for their stuff.

    • numbat. A super cool calculator with support for a lot of units and automatic conversion between them. So you can just type something like 200 km / 50 min -> mph and it'll show you the result. It's actually a fully functional programming language, so you can even write scripts in it if you need to calculate something more complicated.

    • chezmoi. GNU stow, but cooler. This is the thing I use to manage my dotfiles, and it's awesome. It automatically puts everything into the right place, supports templating for things that differ depending on the system, can extract secrets from your password managers in case some configs contain private information that you don't want to have in your public dotfiles repo, and a lot of other awesome stuff. Highly recommend.

    People are also mentioning aliases their use, so I'll give one recommendation.

    alias tmp="cd (mktemp -d)"
    

    It's very common that I need to just quickly test something but don't want to create a directory for it and then delete it. This command makes a temporary directory that I can use to do whatever and it'll all be deleted on the next system reboot.

    I also use this little helper function that allows me to use ipython as a python repl and regular python for running scripts:

    function python --wraps=python3 --description 'Smart IPython alias'
      if test -z "$argv"
        ipython;
      else
        python3 $argv;
      end
    end
    
    7 votes
    1. [3]
      first-must-burn
      Link Parent
      That is really interesting, thanks for the tip. I like this one, but that would mean things hang around for a month. Forced reboot due to windows updates is usually the only time I actually shut...

      can extract secrets from your password managers in case some configs contain private information that you don't want to have in your public dotfiles repo

      That is really interesting, thanks for the tip.

      This command makes a temporary directory that I can use to do whatever and it'll all be deleted on the next system reboot.

      I like this one, but that would mean things hang around for a month. Forced reboot due to windows updates is usually the only time I actually shut the machine down, just hibernate otherwise.

      3 votes
      1. [2]
        fxgn
        Link Parent
        Here's an example from my dotfiles: https://github.com/flexagoon/dotfiles/blob/3fed42126ce7773812ed85b5efeac99e76190819/dot_config/autorestic/dot_autorestic.yml.tmpl#L24-L27 I mean, sure? You'll...

        That is really interesting, thanks for the tip

        Here's an example from my dotfiles:

        https://github.com/flexagoon/dotfiles/blob/3fed42126ce7773812ed85b5efeac99e76190819/dot_config/autorestic/dot_autorestic.yml.tmpl#L24-L27

        I like this one, but that would mean things hang around for a month

        I mean, sure? You'll have some random stuff in a directory named /tmp/tmp.h8UqJo that will eventually be deleted. Doesn't really seem like an issue. It also seems like systemd automatically deletes untouched files in /tmp after 10 days of inactivity, even if you haven't rebooted your system.

        3 votes
        1. first-must-burn
          Link Parent
          I missed the fact that the folder is located in /tmp. I was picturing my home directory and repos littered with these temporary folders. That makes much more sense and is very cool!

          I mean, sure? You'll have some random stuff in a directory named /tmp/tmp.h8UqJo that will eventually be deleted.

          I missed the fact that the folder is located in /tmp. I was picturing my home directory and repos littered with these temporary folders. That makes much more sense and is very cool!

          4 votes
    2. [2]
      CunningFatalist
      Link Parent
      I like that one, thanks for sharing.

      alias tmp="cd (mktemp -d)"

      I like that one, thanks for sharing.

      1. fxgn
        Link Parent
        I've also seen people do something like alias tmp="docker run -ti --rm ..." Which runs a shell in a temporary Docker container that gets deleted when you exit it. Could also be useful depending on...

        I've also seen people do something like

        alias tmp="docker run -ti --rm ..."
        

        Which runs a shell in a temporary Docker container that gets deleted when you exit it. Could also be useful depending on what you need.

        2 votes
  7. borntyping
    Link
    Some of my favourites I don't think have been mentioned yet: atuin for storing shell history in sqlite and syncing across machines. kubectx + kubens for switching between Kubernetes contexts and...

    Some of my favourites I don't think have been mentioned yet:

    • atuin for storing shell history in sqlite and syncing across machines.
    • kubectx + kubens for switching between Kubernetes contexts and namespaces quickly.
    • micro for a terminal text editor using modern conventions and keybindings.
    5 votes
  8. [2]
    Toric
    Link
    qalc, a command line (and GUI) calculator that can do algebra, unit conversions, and a ton more, while still being easy enough to use for quick calculations. It should be available in your package...

    qalc, a command line (and GUI) calculator that can do algebra, unit conversions, and a ton more, while still being easy enough to use for quick calculations. It should be available in your package manager as libqualc

    5 votes
  9. vord
    Link
    Tools: nmap - If you need to connect to things, you'll find this handy, to see if the port is open wl-clipboard - pipe your outputs to your gui clipboard Aliases: alias external-ip4='curl -4...

    Tools:
    nmap - If you need to connect to things, you'll find this handy, to see if the port is open
    wl-clipboard - pipe your outputs to your gui clipboard

    Aliases:

    alias external-ip4='curl -4 ipconfig.io'
    alias external-ip6='curl -6 ipconfig.io'
    alias ls='ls -h'
    alias la='ls -lha'
    alias ll='ls -lh'
    alias ..='cd ..'
    alias ...='cd ../..'
    alias ....='cd ../../..'
    alias du='du -h --max-depth=1'
    alias add_path='export PATH=$PWD:$PATH'
    
    4 votes
  10. Macha
    (edited )
    Link
    Show git history in fzf with searchable commit summaries on left and a diff on the right. function git-history --wraps='git log' --description 'Show git history in browseable fzf window' git log...

    Show git history in fzf with searchable commit summaries on left and a diff on the right.

    function git-history --wraps='git log' --description 'Show git history in browseable fzf window'
      git log --oneline --color=always $argv | 
        fzf --reverse --ansi \
            --preview "git show --color=always {1}" \
            --bind "enter:execute(git show --color=always {1} | less),pgdn:preview-page-down,pgup:preview-page-up,j:preview-down,k:preview-up"
    end
    

    Browse a git diff with searchable files on the left and diffs on the right:

    function git-browse-diff
        if count $argv >/dev/null
            set target $argv[1]
        else
            set target "HEAD"
        end
        git diff $target --name-only --color=always | \
            fzf --ansi \
                --preview "git diff $target --color=always --no-ext-diff {1}" \
                --preview-window ",70%" \
                --bind 'pgdn:preview-page-down,pgup:preview-page-up,j:preview-down,k:preview-up'
    end
    

    Both are fish functions, but you can extract the git/fzf one liner to get the core of the command.

    3 votes
  11. carrotflowerr
    Link
    Here's some of my aliases. I really like the last one. alias log="journalctl -f" # get system messages alias cppwd="pwd | wl-copy" # copy pwd to clip alias pstree="ps -ejH" # display processes in...

    Here's some of my aliases. I really like the last one.

    alias log="journalctl -f" # get system messages
    alias cppwd="pwd | wl-copy" # copy pwd to clip
    alias pstree="ps -ejH" # display processes in tree format
    
    # ask before doing
    alias rm="rm -iv"
    alias cp="cp -iv"
    alias mv="mv -iv"
    
    alias fkill="ps -e | fzf | awk '{print $1}' | xargs kill" # fuzzy find processes to kill
    
    3 votes
  12. [2]
    first-must-burn
    Link
    Lots of good tools, but I also like improving the prompt text. Here is a screenshot of the current version. I've been using this format for 20 years. Between the color and the longish line, it...

    Lots of good tools, but I also like improving the prompt text. Here is a screenshot of the current version. I've been using this format for 20 years. Between the color and the longish line, it makes a good visual separation between the output of commands.

    • the hostname of the machine
    • the current date and time
    • the current directory
    • the status (if nonzero) of the last
    • (sometimes) the git branch I'm on if I'm in a git repo. That part uses a script called git_prompt from the git source. I currently have it commented out because I'm working with someone's overgrown repos and it slows the prompt down. If I had a lot of free time, I might try to make a timeout in the script so it will abort and return an error if checking the repo takes too long.
    • newline (the prompt is actually two lines)
    # export GIT_PS1_SHOWDIRTYSTATE=1
    # source ~/.git-prompt.sh
    __prompt_command() {
        local LAST_STATUS="$?"
        PS1='\[\e[38;5;33m\][\h]' #hostname
        #PS1+=' \[\e[37m\]\u' #username
        PS1+=' \[\e[38;5;196m\]{\D{%Y-%m-%d} \t}' #time and date
        PS1+=' \[\e[38;5;34m\]\w\[\e[0m\]'  #path
    #    PS1+=' \[\e[93m\]$(__git_ps1 " (%s)")' #git status
        if [ "$LAST_STATUS" -ne 0 ]; then
            PS1+=' \[\e[7;31m\]'
            PS1+=" $LAST_STATUS "
        fi
        PS1+='\[\e[0m\]\n\$ '
    }
    PROMPT_COMMAND=__prompt_command
    
    3 votes
    1. fxgn
      Link Parent
      I like how the Starship prompt looks, but it's too slow for me due to all of the additional features that I don't need. So I made a simple prompt that looks just like Starship but in a few lines...

      I like how the Starship prompt looks, but it's too slow for me due to all of the additional features that I don't need. So I made a simple prompt that looks just like Starship but in a few lines of fish:

      function fish_prompt
          echo
      
          # Indicate if running inside of toolbx/distrobox
          if test -e /run/.toolboxenv
              echo -n "📦 "
          end
      
          echo -s (set_color -o cyan)(prompt_pwd -D 3 $pwd) (set_color magenta)(fish_vcs_prompt)
          echo -ns (set_color green) "❯" (set_color normal) " "
      end
      
      3 votes
  13. [4]
    sqew
    Link
    Meta comment because I read every post like this I see but rarely end up actually learning any of the tools: How do people handle scenarios like SSHing into a machine that you don't have...

    Meta comment because I read every post like this I see but rarely end up actually learning any of the tools:

    How do people handle scenarios like SSHing into a machine that you don't have configuration control over? For me, even just the lack of my .ssh/config file on remote machines breaks my muscle memory and annoys me.

    I've wanted to build out a nice (n)vim/tmux configuration for a while, since the context switch between VS Code on my local machine and vim for little edits on remote machines is a pain, but it seems like it'll be a hassle to bring my configs along with me to every machine I touch.

    3 votes
    1. hungariantoast
      Link Parent
      For transporting your shell, aliases, plugins, and other customizations to a remote device, this might work: https://github.com/xxh/xxh Emacs has TRAMP, which makes editing remote files seamless,...

      For transporting your shell, aliases, plugins, and other customizations to a remote device, this might work: https://github.com/xxh/xxh

      Emacs has TRAMP, which makes editing remote files seamless, as if they were local files.

      Visual Studio Code has a similar feature documented here: https://code.visualstudio.com/docs/remote/ssh

      I'm sure (Neo)Vim has something as well.


      xxh works well, but it can take some time to set up, depending on how extensively you have customized your shell. In college I briefly used it to access two systems:

      In both of those cases it worked pretty well, but I don't know how well it would work while trying to access a Linux server from a macOS machine, for example. It shouldn't matter. Shell is supposed to be portable and all that, but it might make a difference.


      Also, because it's a cool story:

      In college, our parallel programming courses required us to test and submit our projects on Frontera, which the professor would also use to grade our submissions. The class was tough. Each week, we were cutting our teeth on a new way to write parallel code in C++. It was by far the most interesting and rewarding class I took at university though.

      It was also really cool watching code that would take hours to run on your local machine finish in seconds on Frontera.

      They gave each student a crazy high computation budget, way more than we were ever going to use for the class projects. So, we had a lot of opportunities to experiment with writing our own parallel code, and to just generally dick around on a computer that was easily the most computationally powerful thing we ever had access to. As long as we weren't running intensive Monte Carlo simulations or plotting funny parabolas from Russia to the US, the admins really didn't care how much we burned through our computation budget.

      3 votes
    2. xk3
      (edited )
      Link Parent
      I use syncthing to synchronize .config and .local between machines that I own, and git to synchronize other folders including .ssh/config. For .ssh/config specifically, I think it is possible to...

      even just the lack of my .ssh/config file on remote machines breaks my muscle memory

      I use syncthing to synchronize .config and .local between machines that I own, and git to synchronize other folders including .ssh/config.

      For .ssh/config specifically, I think it is possible to use SSH Agent Forwarding. Does that not include hostnames? I haven't used it often but I would be surprised if it didn't include config like that

      But for docker containers and other servers I generally just type everything in my shell and then prepend ssh -t $server_name at the beginning. Even when running interactive programs like top or sudoedit I'll take advantage of ControlMaster shared sockets but I don't rely too much on the remote shell... Sometimes it is a little more tedious but this way I'll always have the command history.

      1 vote
    3. eggy
      Link Parent
      Sorry if I am misunderstanding your problem, but for .ssh/config, you could use the ssh-agent to forward your keys and such I think? This video might do better at showing what I am thinking

      Sorry if I am misunderstanding your problem, but for .ssh/config, you could use the ssh-agent to forward your keys and such I think? This video might do better at showing what I am thinking

      1 vote
  14. tauon
    (edited )
    Link
    As usual, the new(ish) cool “basic” necessities (fzf, ripgrep, fd, tldr etc.) have already been mentioned. Here is my answer from the last time this topic came up, hopefully you’ll find something...

    As usual, the new(ish) cool “basic” necessities (fzf, ripgrep, fd, tldr etc.) have already been mentioned.

    Here is my answer from the last time this topic came up, hopefully you’ll find something new and/or interesting there, haha.

    I may update this comment once I get back home and have time to think of some more tools.

    Edits:

    • a sort of “meta” suggestion is to try Kitty as your Terminal emulator program of choice if you haven’t done so yet. icat – cat for images – is amazing.
    • I use the following to hot-reload my theme from the config (add to your shell config file, replace theme names with your favorites; tested & written for Mac key shortcuts but should work the same under Linux):
    kitty_theme () {
    	if [ "$1" = "--light" ]
    	then
    		theme="Rosé Pine Dawn" 
    	elif [ "$1" = "--night" ] || [ "$1" = "--dark" ]
    	then
    		theme="Rosé Pine Moon" 
    	fi
    	if [ -n "$theme" ]
    	then
    		if \cp -f "$HOME/.config/kitty/$theme.conf" "$HOME/.config/kitty/current-theme.conf"
    		then
    			echo "Done (theme copied successfully)! Reload kitty preferences with ⌃⌘,"
    		else
    			echo "Something went wrong while copying the theme file!"
    		fi
    	fi
    }
    

    …, and then aliases to make it even quicker/easier to remember:

    alias kl="kitty_theme --light"
    alias kd="kitty_theme --dark"
    
    • in the same vein, mpv is an excellent video player you can launch from the command line – and even with remote files/URLs (all that are supported by yt-dlp should work).
    • (macOS-only) quickly change the format your screenshots are saved in:
    chscrsformat () {
    	if [ "$1" = "-h" ] || [ "$1" = "" ]
    	then
    		echo "Change the format which macOS saves screenshots in"
    		echo "Options: png jpg pdf gif tiff bmp psd tga "
    		echo "         Read and show current value: -r"
    		echo "         Set to default (png): -d"
    	elif [ "$1" = "-r" ]
    	then
    		defaults read com.apple.screencapture "type"
    	elif [ "$1" = "-d" ]
    	then
    		defaults write com.apple.screencapture "type" -string "png"
    	else
    		defaults write com.apple.screencapture "type" -string "$1"
    	fi
    }
    
    2 votes
  15. [2]
    silfilim
    Link
    Tools vcsh is my stow. I don't think I really evaluated one against the other; just saw a blog post that talked about vcsh at one point and stuck with it. Nix for operating system level package...

    Tools

    • vcsh is my stow. I don't think I really evaluated one against the other; just saw a blog post that talked about vcsh at one point and stuck with it.
    • Nix for operating system level package management. I use this outside of NixOS.
    • Nix home manager for declaratively managing which packages to install and some of their config files. I was skeptical for a while after I started using Nix for package management (why go to the trouble of having to rebuild files after making a minor edit?), but I've learned to let it manage packages and config files that are a good fit, and continue to maintain the rest of config files just directly.
    • Ansible for packages that need to be installed without using Nix or for system-level config files. Its common use is for server configuration management, but it can be run against just the local machine referencing local config files.
    • vivid for nice-looking ls outputs.

    With the combo of vcsh, home manager, and Ansible, I'm at a point where I can set up a new machine to have the same set of tools I use day to day after pulling down my dotfiles repo, creating a new config entry for the new machine, and running a few commands (and dealing with edge cases and errors).

    Aliases and functions

    Dealing with Git conflicts when merging or rebasing changes to a package manager's lockfile.

    alias fix-poetry-lock-merging="git checkout --theirs poetry.lock && poetry lock --no-update"
    alias fix-poetry-lock-rebasing="git checkout --ours poetry.lock && poetry lock --no-update"
    alias fix-yarn-lock-merging="git checkout --theirs yarn.lock && yarn install"
    alias fix-yarn-lock-rebasing="git checkout --ours yarn.lock && yarn install"
    

    Almost always what I want to do is to reset the lockfile to the 'upstream' state first and then regenerate it to apply my local change. This wasn't always a smooth process as I needed to stop and think whether to use --theirs or --ours for the first step, and one day I made these aliases.


    Remove author and commiter names and emails from Git history.

    anonymize_git() {
        printf -v filter_cmd '%q ' git-filter-repo --name-callback "return b''" --email-callback "return b''" --force
        nix-shell -p git-filter-repo --run "$filter_cmd"
        # or with git-filter-repo available in the PATH:
        # git-filter-repo --name-callback 'return b""' --email-callback 'return b""' --force
    }
    

    As part of my day job, I review submissions for a take-home coding challenge that's part of my team's work sample interview set. They come in Git repos, which I clone locally, and I remove author and commiter names and emails in an attempt to ward off any bias that might seep in as a result of seeing names or emails while inspecting commits.


    Move to the root of the current Git repository.

    groot() {
        cd $(git rev-parse --show-toplevel)
    }
    

    Can't remember why I defined this as a function and not an alias.


    (I'm amused that all of the aliases and functions that I thought worthy of sharing turned out to be Git related.)

    2 votes
    1. tauon
      Link Parent
      This feels like one of those cases where ShellCheck would go “expands when defined, not when used” when trying to set it up as an alias – i.e., on shell session startup, it tries to set the...

      Can't remember why I defined this as a function and not an alias.

      This feels like one of those cases where ShellCheck would go “expands when defined, not when used” when trying to set it up as an alias – i.e., on shell session startup, it tries to set the directory that it would later cd to (so something like your home directory) just once and statically keeps it that way, ignoring working directory later.

      But I could also be totally wrong here, haha.

  16. Pistos
    Link
    I use the silver searcher (ag) instead of ripgrep or ack. I made a little wrapper script which lets you search just for words, and it will find results regardless of snake_case,...

    I use the silver searcher (ag) instead of ripgrep or ack. I made a little wrapper script which lets you search just for words, and it will find results regardless of snake_case, SCREAMING_SNAKE_CASE, CamelCase, lowerCamelCase.

    #!/bin/zsh
    
    terms=(${@:#-*})
    switches=(${(M)@:#-*})
    
    echo; echo; echo; echo
    ag --pager less -i "${switches[@]}" `echo "$terms" | sed 's/ /[^a-z]?/g'`
    

    The key part is | sed 's/ /[^a-z]?/g', which you could probably use with ripgrep, etc.


    Also wanted to mention jq, which I use often for pretty-printing JSON (and occasionally doing searches in them).

    2 votes