jc-dotfiles – A collection of configuration files for UNIX/Linux systems

The jamescherti/jc-dotfiles repository is a collection of configuration files. You can either install them directly or use them as inspiration your own dotfiles. These dotfiles provide configurations for various tools, enhancing productivity and usability. This article will explore the contents of the jc-dotfiles repository, highlight the main configurations, and guide you through the installation process.

In addition to the jc-dotfiles repository, the author also recommends the following repositories:

  • jamescherti/jc-firefox-settings: Provides the user.js file, which holds settings to customize the Firefox web browser to enhance the user experience and security.
  • jamescherti/jc-xfce-settings: A script that can customize the XFCE desktop environment programmatically, including window management, notifications, keyboard settings, and more, to enhance the user experience.
  • jamescherti/jc-gnome-settings: A script that can customize the GNOME desktop environment programmatically, including window management, notifications, and more.
  • bash-stdops: A collection of Bash helper shell scripts.
  • jc-gentoo-portage: Provides configuration files for customizing Gentoo Linux Portage, including package management, USE flags, and system-wide settings.
  • minimal-emacs.d: A lightweight, bloat-free Emacs base (init.el and early-init.el) that gives you full control over your configuration. It provides better defaults, an optimized startup, and a clean foundation for building your own vanilla Emacs setup.
  • jamescherti/jc-vimrc: The jc-vimrc project is a customizable Vim base that provides better Vim defaults, intended to serve as a solid foundation for a Vim configuration.

The jc-dotfiles Repository Overview

The repository includes configurations for several components of a UNIX/Linux system, ranging from shell settings to terminal multiplexer and input customizations. Here’s a breakdown of the key configurations included:

1. Shell Configuration (.bashrc, .profile, .bash_profile)

The shell configuration files are optimized for efficient Bash shell settings. These files are crucial for:

  • Efficient Command Execution: Predefined aliases, functions, and environment variables to speed up common tasks.
  • Interactive Sessions: Custom prompt configurations and other interactive settings that improve the overall shell experience.

2. Terminal Multiplexer Configuration (.tmux.conf)

Tmux is a tool for managing multiple terminal sessions, and this configuration enhances your Tmux setup. It includes:

  • Session Management: Custom keybindings and layout configurations for improved session switching.
  • Productivity Boosters: Enhanced usability and efficiency for handling multiple tasks within terminal windows.

3. Readline Configuration (.inputrc)

The Readline configuration improves interactive shell input by allowing additional keybindings:

  • Custom Keybindings: Use Alt-h, Alt-j, Alt-k, and Alt-l for cursor movement, enabling Vim-style HJKL navigation within the terminal.

4. Other Configurations

The repository also includes a variety of other configuration files and scripts:

  • .gitconfig: Custom Git settings to improve version control workflow. (Here is an article about .gitconfig: Optimized Git configuration ~/.gitconfig for performance and usability)
  • ranger: File manager configuration for enhanced navigation and file handling.
  • .fdignore: Ignore rules for fd, the fast search tool, to filter out unwanted files during searches.
  • .wcalcrc: Configuration for wcal, a command-line calculator.
  • mpv: Media player settings for a better viewing experience.
  • picom: Window compositor configuration for optimized display and transparency effects.
  • feh: Image viewer configuration with useful options and custom keybindings.

Conclusion

The jamescherti/jc-dotfiles configuration scripts can enhance your workflow. Whether you install them directly or use them as inspiration for your own dotfiles, you’ll gain access to optimized settings for your shell, terminal, Git, and various other tools, all aimed at boosting productivity and efficiency.

bash-stdops – A collection of useful Bash Shell Scripts

The jamescherti/bash-stdops project is a collection of helpful Bash scripts that simplify various operations, including file searching, text replacement, and content modification.

I use these scripts in conjunction with text editors like Emacs and Vim to automate tasks, including managing Tmux sessions, replacing text across a Git repository, securely copying and pasting from the clipboard by prompting the user before executing commands in Tmux, fix permissions, among other operations.

The bash-stdops Script Collection Overview

Files, Paths, and Strings

  • walk: Recursively lists files from the specified directory.
  • walk-run: Executes a command on all files.
  • sre: Replaces occurrences of a specified string or regular expression pattern, with support for case-insensitive matching and regular expressions.
  • git-sre: Executes sre at the root of a Git repository to replace text within files.
  • path-tr, path-uppercase, path-lowercase: Processes a file path to convert the filename to uppercase or lowercase.
  • autoperm: Sets appropriate permissions for files or directories (e.g., 755 for directories).
  • path-is: Prints the path and exits with status 0 if the file is binary or text.

Git

  • git-dcommit: Automates the process of adding, reviewing, and committing changes in Git.
  • git-squash: Squashes new Git commits between the current branch and a specified branch.

SSH

  • esa: Manages the SSH agent, including starting, stopping, adding keys, and executing commands.
  • sshwait: Waits for an SSH server to become available on a specified host.

Tmux

  • tmux-cbpaste: Pastes clipboard content into the current tmux window with user confirmation.
  • tmux-run: Executes a command in a new tmux window. If inside tmux, it adds a new window to the current session; otherwise, it creates a window in the first available tmux session.
  • tmux-session: Attaches to an existing tmux session or creates a new one if it doesn’t exist.

X11/Wayland

  • xocrshot: Captures a screenshot, performs OCR on it, displays the extracted text, and copies it to the clipboard.

Misc

  • haide: Uses AIDE to monitor the file integrity of the user’s home directory.
  • cbcopy, cbpaste, cbwatch: Manages clipboard content by copying, pasting, or monitoring for changes.
  • outonerror: Redirects the command output to stderr only if the command fails.
  • over: Displays a notification once a command completes execution.
  • largs: Executes a command for each line of input from stdin, replacing {} with the line.
  • xargs-loop: Similar to xargs but allows placeholder substitution and processes each line individually.

Conclusion

The jamescherti/bash-stdops scripts provide a variety of tasks, including file manipulation, Git management, and SSH automation, improving efficiency and usability.

How to make cron notify the user about a failed command by redirecting its output to stderr only when it fails (non-zero exit code)

Cron jobs can handle everything from system maintenance to running backups, but monitoring their success or failure can be difficult. One effective way to handle cron job errors is by utilizing a Bash script that sends the output to stderr only if the job fails, which generally makes cron to notify the user about the error that occurred.

Script overview

The script provided below ensures that any command passed to it will redirect its output to a temporary file. If the command fails (i.e., returns a non-zero exit code), the script sends the content of the temporary file to stderr, which causes cron to notify the user.

Here is the complete script to be installed in /usr/local/bin/outonerror:

#!/usr/bin/env bash
# Description:
# Redirect the command's output to stderr only if the command fails (non-zero
# exit code). No output is shown when the command succeeds.
#
# Author: James Cherti
# License: MIT
# URL: https://www.jamescherti.com/cron-email-output-failed-commands-only/

set -euf -o pipefail

if [[ "$#" -eq 0 ]]; then
  echo "Usage: $0 <command> [args...]" >&2
  exit 1
fi

cleanup() {
  if [[ "$OUTPUT_TMP" != "" ]] && [[ -f "$OUTPUT_TMP" ]]; then
    rm -f "$OUTPUT_TMP"
  fi

  OUTPUT_TMP=""
}

trap 'cleanup' INT TERM EXIT
OUTPUT_TMP=$(mktemp --suffix=.outonerror)

ERRNO=0
"$@" >"$OUTPUT_TMP" 2>&1 || ERRNO="$?"
if [[ "$ERRNO" -ne 0 ]]; then
  cat "$OUTPUT_TMP" >&2
  echo "$0: '$*' exited with status $ERRNO" >&2
fi

cleanup
exit "$ERRNO"
Code language: Bash (bash)

To use this script with a cron job, save it as /usr/local/bin/outonerror and make it executable by runnning:

chmod +x /usr/local/bin/outonerrorCode language: plaintext (plaintext)

Integration with Cron

Cron sends an email by default whenever a job produces output, whether standard output or error output. This is typically configured through the MAILTO environment variable in the crontab file. If MAILTO is not set, cron sends emails to the user account under which the cron job runs. Cron will only be able to send emails if the mail transfer agent (e.g., Postfix, Exim, Sendmail) is configured properly.

Here is how to schedule the cron job to use the outonerror script:

MAILTO="your-email@example.com"
* * * * * /usr/local/bin/outonerror your_command_hereCode language: plaintext (plaintext)

With this setup, the cron job will execute your_command_here and only send an email if it fails, thanks to cron’s default behavior of emailing stderr output to the user.

Conclusion

This script is a simple yet effective solution for improving cron jobs by ensuring that the user is notified only when something goes wrong. It reduces unnecessary notifications for successful executions and provides clear error messages when failures occur.

Arch Linux: Preserving the kernel modules of the currently running kernel during and after an upgrade

One potential issue when upgrading the Arch Linux kernel is that the modules of the currently running kernel may be deleted. This can lead to a number of problems, including unexpected behavior, system crashes, or the inability to mount certain file systems (e.g. the kernel fails to mount a vfat file system due to the unavailability of the vfat kernel module).

The Arch Linux package linux-keep-modules (also available on AUR: linux-keep-modules @AUR), written by James Cherti, provides a solution to ensure that the modules of the currently running Linux kernel remain available until the operating system is restarted. Additionally, after a system restart, the script automatically removes any unnecessary kernel modules that might have been left behind by previous upgrades (e.g. the kernel modules that are not owned by any Arch Linux package and are not required by the currently running kernel).

The linux-keep-modules package keeps your system running smoothly and maintains stability even during major Linux kernel upgrades.

Make and install the linux-keep-modules package

Clone the repository and change the current directory to ‘archlinux-linux-keep-modules/’:

$ git clone https://github.com/jamescherti/archlinux-linux-keep-modules.git
$ cd archlinux-linux-keep-modules/Code language: plaintext (plaintext)

Use makepkg to make linux-keep-modules package:

$ makepkg -fCode language: plaintext (plaintext)

Install the linux-keep-modules package:

$ sudo pacman -U linux-keep-modules-*-any.pkg.tar.*Code language: plaintext (plaintext)

Finally, enable the cleanup-linux-modules service:

$ sudo systemctl enable cleanup-linux-modulesCode language: plaintext (plaintext)

(The cleanup-linux-modules service will delete the Linux kernel modules that are not owned by any a package at boot time)

The linux-keep-modules Arch Linux package offers a solution to preserve kernel modules during and after upgrades, ensuring that the necessary modules for the currently running kernel remain present in the system even after the kernel is upgraded. This solution keeps your system running smoothly and maintains stability even during major upgrades.

Links related to the pacman package linux-keep-modules

How to make Vim edit/diff files from outside of Vim? (e.g. from a shell like Bash, Zsh, Fish..)

The Vim editor offers the ability to connect to a Vim server and make it perform various tasks from outside of Vim. The command-line tools vim-client-edit, vim-client-diff and the vim_client Python module, written by James Cherti, can be used to easily find and connect to a Vim server and make it perform the following tasks:

  • Edit files or directories in new tabs (The command-line tool vim-client-edit),
  • Diff/Compare up to eight files (The command-line tool vim-client-diff),
  • Evaluate expressions and return their result (The Python module vim_client),
  • Send commands and expressions to Vim (The Python module vim_client).

The command-line tools vim-client-edit and vim-client-diff are especially useful when a quick edit or comparison needs to be performed on a file from outside of Vim (e.g. from a shell like Bash, Zsh, Fish, etc.).

Additionally, the vim_client Python module allows running expressions on a Vim server and retrieving their output, which can be useful for automating tasks or scripting. For example, you can use vim-client to run a search and replace operation on a file or directory, or to perform a complex diff operation between two files.

Overall, vim-client is a powerful tool for interacting with Vim from the vim-client-edit and vim-client-diff command-line tools. The vim_client Python module can also be used to run and retrieve the output of Vim expressions, which can help automate various tasks.

Please star vim-client on GitHub to support the project!

Requirements

To use vim-client, you will need to have Vim and Python installed on your system.

Installation

The vim-client package can be installed with pip:

$ sudo pip install vim-clientCode language: Bash (bash)

Execute Vim server

The Vim editor must be started with the option “–servername”, which enables the Vim server feature that allows clients to connect and send commands to Vim:

$ vim --servername SERVERNAMECode language: plaintext (plaintext)

Make Vim server edit multiple files in tabs

Editing a list of files in new tabs:

$ vim-client-edit file1 file2 file3 

Make Vim server diff files (like vimdiff)

Comparing/diff up to eight files:

$ vim-client-diff file1 file2

Useful ~/.bashrc aliases:

Adding the following aliases to ~/.bashrc is recommended as it makes it easy to execute the command-line tools vim-client-edit and vim-client-diff:

alias gvim=vim-client-edit
alias vim=vim-client-edit
alias vi=vim-client-edit
alias vimdiff=vim-client-diff

Links related to vim-client

Bash shell: Perform tab-completion for aliases (bash-completion)

# Author: James Cherti
# License: MIT
# Requirements: bash-completion
# Description: Perform tab-completion for aliases in Bash (bash-completion).
# URL: https://www.jamescherti.com/bash-shell-perform-tab-completion-for-aliases/
#
# Add the following function to ~/.bashrc :

alias_completion() {
  local func_name='alias_completion'
  if [[ $# -lt 2 ]]; then
    echo "Usage: $func_name <cmd> <alias> <alias2> <...>" >&2
    return 1
  fi

  local cmd; cmd="$1"
  shift

  # Load the completion
  if ! type _completion_loader >/dev/null 2>&1; then
    echo "Error: $func_name: '_completion_loader' was not found." >&2
    return 1
  fi

  _completion_loader "$cmd"

  if ! complete -p "$cmd" >/dev/null; then
    echo "Error: $func_name: 'complete -p $cmd' failed." >&2
    return 1
  fi

  # Add aliases
  local alias
  for alias in "$@"; do
    complete_cmd=$(complete -p "$cmd" 2>/dev/null | sed -e 's/[[:space:]][^[:space:]]\+$//')
    complete_cmd="${complete_cmd} $alias"

    if ! ( echo "$complete_cmd" | grep -P '^\s*complete\s' >/dev/null 2>&1 ); then
      echo "Error: $func_name: alias '$alias': '$complete_cmd' is an invalid command." >&2
      return 1
    fi

    eval "$complete_cmd"
  done

  return 0
}Code language: Bash (bash)

Examples of aliases:

alias s='ssh'
alias_completion ssh s

alias g='git'
alias_completion git gCode language: Bash (bash)

Bash shell: A better version of the default bash built-in command “cd”

#!/usr/bin/env bash
# Author: James Cherti
# License: MIT
# URL: https://www.jamescherti.com/shell-bash-replacement-bash-cd-change-directory/
#
# Description:
# 1. 'cd path/to/file' will change the directory to 'path/to'
#    (the parent directory of 'file').
#
# 2. 'cd path/to/dir with spaces' will change the directory to
#    "path/to/dir with spaces".
#
# 3. 'cd file:///home/user' will change the directory to "/home/user".
# 
# 4. You can switch to the previous directory with 'popd' or 'cd -'.
#
# Add the following function and alias to ~/.bashrc :
#

_better_cd() {
  # Previous directory ('cd -')
  if [[ $# -eq 1 ]] && [[ $1 = '-' ]]; then
    popd >/dev/null || return 1
    return 0
  fi

  # Join paths
  local path
  if [[ $# -eq 0 ]]; then
    path="$HOME"
  else
    path=$(echo "$1" | sed -e 's/^file:\/\///')
    shift

    local item
    for item in "$@"; do
      path="${path} ${item}"
    done
  fi

  # Checks
  local errno=0
  if [[ -f "$path" ]]; then
    path=$(dirname "$path")
  fi

  if ! [[ -d "$path" ]]; then
    echo "$(basename "$0"):" "cd: $path: No such file or directory" >&2
    return 1
  fi

  # Change the directory
  local oldcwd; oldcwd=$(pwd)
  pushd . >/dev/null || return 1
  builtin cd "$path" >/dev/null 2>&1 || errno=1
  if [[ $oldcwd = "$(pwd)" ]]; then
    popd >/dev/null || return 1
  fi

  return "$errno"
}

alias cd=_better_cdCode language: Bash (bash)