Linux: Setting the default GDM login monitor in a multi-monitor setup using GNOME display settings

If you’re using a multi-monitor setup with GDM (GNOME Display Manager) and the login screen consistently appears on the wrong monitor, this article presents a tested solution that can be applied either manually or automated, ensuring that the GDM monitor configuration matches that of your primary user setup.

The issue

Consider this configuration: Two monitors connected to an Nvidia graphics card. Despite setting the primary monitor correctly in GNOME, the GDM login screen appears on the secondary monitor. Even if that monitor is turned off, GDM continues to display the login prompt there because it is using the wrong monitor as the default.

The solution

The login screen configuration for GDM can be influenced by copying the monitor layout from your GNOME user session.

This is done by copying the ~/.config/monitors.xml file from your user configuration to GDM’s configuration directory.

Step 1: Configure your display using GNOME

First, configure your display layout as desired using GNOME’s display settings:

gnome-control-center displayCode language: plaintext (plaintext)

Step 2: Copy the resulting monitor configuration to GDM’s configuration directory

Copy the resulting monitor configuration ~/.config/monitors.xml to GDM’s configuration directory:

sudo install -o root -m 644 ~/.config/monitors.xml ~gdm/.config/Code language: plaintext (plaintext)

(the shell will automatically interpret ~gdm as the home directory of the gdm user)

Step 3: Restart GDM

Restart GDM with the following command:

sudo systemctl restart gdmCode language: plaintext (plaintext)

How to automatically copy monitors.xml to the GDM configuration directory?

The copying of the monitors.xml file can be automated by defining a systemd service override for the GDM service.

First, create the following directory using:

sudo mkdir -p /etc/systemd/system/gdm.service.d/Code language: plaintext (plaintext)

Then, create the file /etc/systemd/system/gdm.service.d/override.conf with the following contents:

[Service]
ExecStartPre=/bin/sh -c 'install -o root -m 644 /home/YOUR_USER/.config/monitors.xml ~gdm/.config/monitors.xml || true'Code language: plaintext (plaintext)

Ensure to:

  • Replace YOUR_USER with your actual desktop user name.

Conclusion

Copying the GNOME display settings to the GDM configuration directory ensures that GDM adopts the same monitor layout as your GNOME session, causing the login screen to appear on your preferred monitor.

Suppressing Irrelevant Git Diff Output for Specific Files (e.g., binary files, encrypted files…)

Sometimes, it is useful to suppress certain files from git diff output, especially when the files are large, machine-generated, or not intended for human reading. Typical examples include encrypted files such as *.gpg and *.asc, as well as binary assets like images, audio files, and similar media. These files are usually represented as opaque binary data in diffs, providing no useful information and adding extraneous clutter to git diff output.

Git offers a solution for this through adding YOUR-FILE-PATTERN -diff -text to the .gitattributes file.

Solution: A .gitattributes file that is local to the repository

The .gitattributes file can be defined locally within each individual repository.

For example, to prevent git diff from displaying diffs for files with the .asc and .gpg extensions, include the following lines in the .gitattributes file at the root of your Git repository:

*.asc -diff -text
*.gpg -diff -textCode language: plaintext (plaintext)

Using -diff -text in .gitattributes is beneficial for binary or non-human-readable files because it ensures Git neither attempts to generate textual diffs (-diff) nor applies any text-related processing like end-of-line normalization (-text).

This combination prevents irrelevant or misleading changes from appearing in diffs, avoids potential corruption from automatic text conversions, and keeps version control output clean and focused on meaningful, human-readable changes.

Alternative solution: A global .gitattributes_global file

Rather than adding these rules to every repository individually, you can define them once in a global ~/.gitattributes_global file. This file applies to all Git repositories for your user account unless overridden by a repository-specific .gitattributes.

To set up a global .gitattributes_global file:

Configure Git to use it:

    git config --global core.attributesfile ~/.gitattributes_globalCode language: plaintext (plaintext)

    Add global rules to the ~/.gitattributes_global file. For example:

      *.asc -diff -text -diff
      *.gpg -diff -text -diffCode language: plaintext (plaintext)

      This setup ensures consistent handling of non-human-readable files across all repositories without the need for redundant configuration.

      Conclusion

      Suppressing diffs for non-human-readable files with .gitattributes, whether configured locally or globally, reduces noise in version control workflows. This keeps Git diff output focused on meaningful textual modifications, prevents clutter from binary content, and safeguards against unwanted transformations.

      Related links

      Emacs: stripspace.el – Automatically Remove Trailing Whitespace Before Saving a Buffer, with an Option to Preserve the Cursor Column

      The stripspace Emacs package provides stripspace-local-mode, which automatically removes trailing whitespace and blank lines at the end of the buffer when saving.

      (Trailing whitespace refers to any spaces or tabs that appear at the end of a line, beyond the last non-whitespace character. These characters serve no purpose in the content of the file and can cause issues with version control, formatting, or code consistency. Removing trailing whitespace helps maintain clean, readable files.)

      It also includes an optional feature (stripspace-only-if-initially-clean, disabled by default), which, when enabled, ensures that trailing whitespace is removed only if the buffer was initially clean. This prevents unintended modifications to buffers that already contain changes, making it useful for preserving intentional whitespace or avoiding unnecessary edits in files managed by version control.

      Installation from MELPA

      MELPA
      1. If you haven’t already done so, add MELPA repository to your Emacs configuration.
      2. Add the following code to your Emacs init file to install stripspace from MELPA:
      (use-package stripspace
        :ensure t
        :commands stripspace-local-mode
      
        ;; Enable for prog-mode-hook, text-mode-hook, prog-mode-hook
        :hook ((prog-mode . stripspace-local-mode)
               (text-mode . stripspace-local-mode)
               (conf-mode . stripspace-local-mode))
      
        :custom
        ;; The `stripspace-only-if-initially-clean' option:
        ;; - nil to always delete trailing whitespace.
        ;; - Non-nil to only delete whitespace when the buffer is clean initially.
        ;; (The initial cleanliness check is performed when `stripspace-local-mode'
        ;; is enabled.)
        (stripspace-only-if-initially-clean nil)
      
        ;; Enabling `stripspace-restore-column' preserves the cursor's column position
        ;; even after stripping spaces. This is useful in scenarios where you add
        ;; extra spaces and then save the file. Although the spaces are removed in the
        ;; saved file, the cursor remains in the same position, ensuring a consistent
        ;; editing experience without affecting cursor placement.
        (stripspace-restore-column t))Code language: PHP (php)

      Features

      Here are the features of (stripspace-local-mode):

      • Before saving buffer: Automatically removes all trailing whitespace.
      • After saving buffer: Restores the cursor’s column position on the current line, including any spaces before the cursor. This ensures a consistent editing experience and prevents unintended cursor movement when saving a buffer and removing trailing whitespace. This behavior can be controller by the stripspace-restore-column variable (default: t).
      • Even if the buffer is narrowed, stripspace removes trailing whitespace from the entire buffer. This behavior, controlled by the stripspace-ignore-restrictions variable (default: t).
      • An optional feature stripspace-only-if-initially-clean (default: nil), which, when set to non-nil, instructs stripspace to only delete whitespace when the buffer is clean initially. The check for a clean buffer is optimized using a single regex search for trailing whitespace and another for blank lines.
      • The stripspace-verbose variable, when non-nil, shows in the minibuffer whether trailing whitespaces have been removed or, if not, provides the reason for their retention.
      • The functions for deleting whitespace are customizable, allowing the user to specify a custom function for removing trailing whitespace from the current buffer.
      • The stripspace-clean-function variable allows specifying a function for removing trailing whitespace from the current buffer. This function is called to eliminate any extraneous spaces or tabs at the end of lines. (For example, this can be set to a built-in function such as delete-trailing-whitespace (default) or whitespace-cleanup.)

      Links

      Emacs package: bufferfile – Delete or rename buffer file names with their associated buffers

      The bufferfile Emacs package provides helper functions to delete and rename buffer files:

      • bufferwizard-rename-file: Renames the file that the current buffer is visiting. This command renames the file name on disk, adjusts the buffer name, and updates any indirect buffers or other buffers associated with the old file.
      • bufferwizard-delete-file: Delete the file associated with a buffer and kill all buffers visiting the file, including indirect buffers.

      Installation with straight (Emacs version < 30)

      To install bufferfile with straight.el:

      1. It if hasn’t already been done, add the straight.el bootstrap code to your init file.
      2. Add the following code to the Emacs init file:
      (use-package bufferfile
        :ensure t
        :straight (bufferfile
                   :type git
                   :host github
                   :repo "jamescherti/bufferfile.el"))Code language: Lisp (lisp)

      Alternative installation: Installation with use-package and :vc (Built-in feature in Emacs version >= 30)

      To install bufferfile with use-package and :vc (Emacs >= 30):

      (use-package bufferfile
        :ensure t
        :vc (:url "https://github.com/jamescherti/bufferfile.el"
             :rev :newest))Code language: Lisp (lisp)

      Customization: Making bufferwizard use version control (VC), such as Git, when renaming or deleting files?

      To make bufferwizard use version control (VC) when renaming or deleting files, you can set the variable bufferfile-use-vc to t. This ensures that file operations within bufferwizard interact with the version control system, preserving history and tracking changes properly.

      (setq bufferfile-use-vc t)Code language: plaintext (plaintext)

      Links

      Emacs: persist-text-scale.el – Persist and Restore the Text Scale for All Buffers

      The persist-text-scale Emacs package provides persist-text-scale-mode, which ensures that all adjustments made with text-scale-increase and text-scale-decrease are persisted and restored across sessions. As a result, the text size in each buffer remains consistent, even after restarting Emacs.

      (By default, persist-text-scale-mode saves the text scale individually for each file-visiting buffer and applies a custom text scale for each special buffer. This behavior can be further customized by assigning a function to the persist-text-scale-buffer-category-function variable. The function determines how buffers are categorized by returning a category identifier based on the buffer’s context. Buffers within the same category will share the same text scale.)

      Features

      • Automatically persists and restores the text scale for all buffers.
      • Periodically autosaves at intervals defined by persist-text-scale-autosave-interval (can be set to nil to disable or specified in seconds to enable).
      • Supports unified text scaling across buffer categories.
      • Offers fully customizable logic for categorizing buffers based on text scale.
      • Lightweight and efficient, requiring minimal configuration.
      • Enables custom buffer categorization by specifying a function for the persist-text-scale-buffer-category-function variable, ensuring that groups of buffers share the same persisted and restored text scale.

      Installation: Emacs: Install with straight (Emacs version < 30)

      To install persist-text-scale with straight.el:

      1. It if hasn’t already been done, add the straight.el bootstrap code to your init file.
      2. Add the following code to the Emacs init file:
      (use-package persist-text-scale
        :ensure t
        :straight (persist-text-scale
                   :type git
                   :host github
                   :repo "jamescherti/persist-text-scale.el")
        :custom
        (persist-text-scale-autosave-interval (* 7 60))
        :config
        (persist-text-scale-mode))Code language: JavaScript (javascript)

      Alternative installation 1: Emacs: Installing with use-package and :vc (Built-in feature in Emacs version >= 30)

      To install persist-text-scale with use-package and :vc (Emacs >= 30):

      (use-package persist-text-scale
        :ensure t
        :vc (:url "https://github.com/jamescherti/persist-text-scale.el"
             :rev :newest)
        :custom
        (persist-text-scale-autosave-interval (* 7 60))
        :config
        (persist-text-scale-mode))Code language: JavaScript (javascript)

      Alternative installation 2: Doom Emacs

      Here is how to install persist-text-scale on Doom Emacs:

      1. Add to the ~/.doom.d/packages.el file:
      (package! persist-text-scale
       :recipe
       (:host github :repo "jamescherti/persist-text-scale.el"))Code language: JavaScript (javascript)
      1. Add to ~/.doom.d/config.el:
      ;; TODO: Load the mode here
      (after! persist-text-scale
        (setq persist-text-scale-autosave-interval (* 7 60))
        (persist-text-scale-mode))
      1. Run the doom sync command:
      doom sync

      Links

      Configuring Linux on a ThinkPad T420s or T420 Laptop for Optimal Performance

      ThinkPad T420s and T420 laptops, despite their age, remain reliable for web browsing, word processing, and various other tasks. Linux can breathe new life into such dated computers, allowing them to perform efficiently.

      I configured one of these laptops for my son, and he is now able to do his homework using it. With proper configuration, ThinkPad laptops can achieve optimal performance and power management. This article provides a guide to configuring X11/Xorg, kernel parameters, firmware, fan control, and power management settings to optimize the ThinkPad t420s or t420 for modern use.

      Some instructions in this article are specific to Debian/Ubuntu-based distributions, but they can easily be adapted to other distributions such as Red Hat, Fedora, Arch Linux, Gentoo, and others.

      X11/Xorg

      To ensure proper functionality of Intel graphics and avoid issues such as black screens after waking from sleep, use the Intel driver instead of modesetting.

      Create the configuration file /etc/X11/xorg.conf.d/30-intel.conf:

      Section "Device"
        Identifier "Intel Graphics"
        Driver "intel"
      
        Option "Backlight" "intel_backlight"
      EndSectionCode language: plaintext (plaintext)

      Ensure the intel driver is installed:

      sudo apt-get install xserver-xorg-video-intelCode language: plaintext (plaintext)

      IMPORTANT: Ensure that the integrated graphics are set as the default video card in the ThinkPad BIOS.

      Kernel parameters

      To ensure backlight control is working (increasing and decreasing brightness), add the following kernel parameter: acpi_backlight=native

      On a Debian/Ubuntu based distribution, this can be appended to the kernel command line in the bootloader configuration, typically in /etc/default/grub (for GRUB users):

      GRUB_CMDLINE_LINUX_DEFAULT="quiet splash acpi_backlight=native"Code language: plaintext (plaintext)

      After modifying this file, update GRUB with:

      sudo update-grubCode language: plaintext (plaintext)

      Fan control

      Without software to control the fan, it may run at maximum speed. To enable fan control, create the file /etc/modprobe.d/thinkpad_acpi.conf:

      options thinkpad_acpi fan_control=1Code language: plaintext (plaintext)

      After that, install zcfan. On a Debian/Ubuntu based distribution:

      sudo apt-get install zcfanCode language: plaintext (plaintext)

      Packages

      Ensure the necessary firmware for Atheros and Realtek network devices is installed. On Debian/Ubuntu-based distributions, install the following packages:

      sudo apt install firmware-atheros firmware-realtekCode language: plaintext (plaintext)

      It is also recommended to install essential packages for hardware encoding and decoding, including intel-microcode for the latest processor updates, which improve system stability and performance:

      sudo apt-get install intel-microcode intel-media-va-driver-non-free i965-va-driverCode language: plaintext (plaintext)

      TLP

      TLP is a power management tool that optimizes battery life. Install and configure it as follows:

      sudo apt install tlpCode language: plaintext (plaintext)

      Create the configuration file /etc/tlp.d/00-base.conf:

      DEVICES_TO_DISABLE_ON_BAT="bluetooth wwan"
      DEVICES_TO_ENABLE_ON_STARTUP="wifi"
      DEVICES_TO_DISABLE_ON_LAN_CONNECT="wifi wwan"
      
      TLP_DEFAULT_MODE=BAT
      
      CPU_SCALING_GOVERNOR_ON_AC=performance
      CPU_SCALING_GOVERNOR_ON_BAT=schedutil
      
      # PCIe Active State Power Management (ASPM):
      PCIE_ASPM_ON_AC=performance
      
      # Set Intel CPU performance: 0..100 (%). Limit the
      # max/min to control the power dissipation of the CPU.
      # Values are stated as a percentage of the available
      # performance.
      CPU_MIN_PERF_ON_AC=70
      CPU_MAX_PERF_ON_AC=100
      
      # [default] performance powersave powersupersave. on=disable
      RUNTIME_PM_ON_AC=on
      RUNTIME_PM_ON_BAT=powersupersaveCode language: Python (python)

      Conclusion

      The ThinkPad T420s and T420, though older models, remain reliable machines for everyday tasks. With the right configuration, these laptops can be revitalized, making them well-suited for modern use.

      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.
      • jamescherti/bash-stdops: A collection of Bash helper shell scripts.
      • jamescherti/jc-gentoo-portage: Provides configuration files for customizing Gentoo Linux Portage, including package management, USE flags, and system-wide settings.
      • jamescherti/minimal-emacs.d: A lightweight and optimized 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:

      • 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.

      Conclusion

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

      Enhancing Git configuration ~/.gitconfig for performance, efficiency, data integrity, and workflow automation

      Optimizing your Git configuration is fundamental to enhancing efficiency and productivity in version control workflows. A finely-tuned Git setup not only accelerates operations but also aligns the tool with the specific requirements of both individual developers and teams.

      In this article, we will explore Git configurations that enhance both performance and usability.

      All the configurations mentioned in this article should be added to the ~/.gitconfig file. This file follows the INI format, with [sections] defining categories and variables=values specifying settings.

      Performance tuning

      [pack]
      threads = 0
      windowMemory = 5g
      packSizeLimit = 2g
      Code language: plaintext (plaintext)
      • threads = 0 Configures Git to auto-detect the number of CPUs and set the number of threads accordingly.
      • windowMemory = 5g This enhances Git’s efficiency for large repositories. It tells Git to use up to 5GB of RAM when creating packfiles. (A packfile is a way Git stores changes between versions of files efficiently.) By allocating more memory, Git can compare and store these changes more effectively, which can make the packing process faster.
      • packSizeLimit = 2g The packSizeLimit configuration in Git determines the maximum size of a packfile that Git will generate.

      Garbage collection

      [gc]
      auto = 8000
      
      • auto = 8000 Automatically triggers garbage collection when the number of loose objects exceeds 8000, optimizing repository storage and performance. The default value is 6700.

      Core configurations

      [core]
      whitespace = space-before-tab,trailing-space
      preloadindex = true
      Code language: plaintext (plaintext)
      • whitespace = space-before-tab,trailing-space Configures whitespace handling.
      • preloadindex = true Preloads the index into memory for improved performance when running Git commands like status and diff. Setting this to true will make Git load the index into memory early in the execution of commands. This can lead to performance improvements for operations that involve the index, especially in repositories with a large number of files..

      Rebase

      [rebase]
      autoStash = true
      missingCommitsCheck = warn
      autoSquash = true
      updateRefs = true
      missingCommitsCheck = errorCode language: plaintext (plaintext)
      • autoStash = true Before executing a rebase, automatically stash all uncommitted change. This ensures the rebase proceeds without interference from local modifications. Once the rebase completes, the stashed changes are reapplied, restoring the developer’s original working state.
      • missingCommitsCheck = warn If commits are removed or missing during a rebase, issue a warning rather than # silently ignoring them.
      • autoSquash = true When you use interactive rebase (e.g., git rebase -i), this setting makes Git automatically recognize and handle commits that begin with “fixup!” or “squash!”. A commit with “squash!” means “combine this with another commit and keep both messages”. A commit with “fixup!” means “combine this with another commit and discard this message”.
      • updateRefs = true When you have multiple stacked branches, it can become complex to handle the rebasing process manually for each branch, especially if you have many commits in each branch. Setting updateRefs to true simplifies this process. By enabling this option, whenever you perform a rebase operation on one branch, the references to the other dependent branches are automatically updated as well. This ensures that each branch in the stack remains properly aligned with the others, without requiring you to manually update or rebase each one individually.
      • missingCommitsCheck = error If commits are removed or missing during a rebase, issue an error rather than silently ignoring them.

      Merge

      [merge]
      autoStash = true
      ff = only
      conflictStyle = zdiff3
      summary = true
      diffstat = true
      log = 60Code language: plaintext (plaintext)
      • autoStash = true Before executing a merge, automatically stash all uncommitted changes in the working directory and index. This ensures the merge proceeds without interference from local modifications. Once the merge completes, the stashed changes are reapplied, restoring the developer’s original working state.
      • ff = only This setting enforce fast-forward merges for merge, preventing unnecessary merge commits and maintaining a linear commit history.
      • conflictStyle = zdiff3 Uses the zdiff3 conflict style for merges, which includes additional context by showing the base, local, and remote versions of conflicting changes in a more readable format, making it easier to resolve complex conflicts.
      • summary = true Display a brief summary describing what was merged. This includes information such as the merged branch names and the number of commits.
      • diffstat = true Display a diffstat after the merge completes, which summarizes the changes made, showing how many lines were added and removed in each file.
      • log = 60 Include up to 60 commit messages from the merged branch in the merge commit message. This provides historical context and helps reviewers understand the scope of the merge.

      Pull

      [pull]
      ff = only
      default = currentCode language: plaintext (plaintext)
      • ff = only This setting enforce fast-forward merges for pull, preventing unnecessary merge commits and maintaining a linear commit history.
      • default = current This setting automatically pulls the current branch, which helps prevent “There is no tracking information for the current branch. Please specify which branch you want to merge with. See git-pull(1) for details. git pull “

      Push behavior

      [push]
      default = current
      autoSetupRemote = true
      followTags = true
      Code language: plaintext (plaintext)
      • default = current This setting automatically pushes the current branch, which helps prevent the error: “fatal: The current branch BRANCH has no upstream branch.” When this setting is in place, Git will push the current branch to the remote, assuming the branch has an upstream set.
      • autoSetupRemote = true This setting automatically sets up remote tracking for new branches, eliminating the need to manually run git branch --set-upstream-to after creating a new branch. It automates the process of linking local branches to their corresponding remote branches. This is useful for users who frequently create new branches, as it reduces the need for repetitive configuration.
      • followTags = true Push all annotated tags to the remote repository along with the branch # updates. This ensures that tags created locally are also synchronized with the # remote repository during a push operation.

      Enhanced diffing

      [diff]
      tool = vimdiff
      algorithm = histogram
      renames = copies
      renameLimit = 2400
      context = 5Code language: plaintext (plaintext)
      • tool = vimdiff This setting uses vimdiff as the default diff tool when git difftool is executed.
      • algorithm = histogram Diff algorithm for improved diff accuracy, especially in detecting moved code blocks.
      • renames = copies Configures Git to detect file copies in addition to renames during diff generation. This helps identify files that were copied, improving the accuracy of the diff output for changes involving file copying.
      • renameLimit = 2400 Sets the maximum number of renames to detect in a diff. When there are more than this number of renames, Git will stop trying to detect renames to avoid performance degradation. The default is 1000, but increasing it can help in repos with many file renames.
      • context = 5 Show 5 lines of context around changes in diffs instead of the default 3.

      Rerere (Reuse Recorded Resolution)

      [rerere]
      enabled = 1
      autoUpdate = trueCode language: plaintext (plaintext)
      • enabled = 1 Enables automatic resolution of previously encountered merge conflicts, reducing the effort required for repeated merges.
      • autoUpdate = true After a conflict is resolved manually, Git will automatically store the resolution in the rerere cache, making it available for future use.

      Commit

      [commit]
      verbose = trueCode language: plaintext (plaintext)
      • verbose = true This includes the full commit diff in the text editor when composing the commit message, aiding in recalling the context and purpose of the changes.

      Git log dates

      [log]
      date = isoCode language: plaintext (plaintext)
      • date = iso Display dates as YYYY-MM-DD HH:MM:DD (e.g., 2025-03-25 14:59:12 -0400)

      Data integrity (Fsck objects)

      [transfer]
      fsckObjects = true
      
      [receive]
      fsckObjects = true
      
      [fetch]
      fsckObjects = true
      prune = true
      pruneTags = trueCode language: plaintext (plaintext)
      • [transfer|receive|fetch] fsckObjects = true Verifies the integrity of all objects during data transfer operations like clone, fetch, and receive (data transfer), helping detect corruption or tampering early.
      • [fetch] prune = true Automatically remove remote-tracking branches that no longer exist on the remote repository during a ‘git fetch’. This helps keep the local repository clean by removing outdated references to remote branches that have been # deleted.
      • [fetch] pruneTags = true Automatically delete remote tags in your local repository that have been removed from the remote repository during a ‘git fetch’. This ensures that your local tags list is up-to-date and prevents the accumulation of tags that no longer exist on the remote.

      Branch

      [branch]
      sort = -committerdate
      autoSetupMerge = trueCode language: plaintext (plaintext)
      • sort = -committerdate Configures git branch to sort branches by most recently used rather than alphabetically, making it easier to locate active branches.
      • autoSetupMerge = true Automatically sets up an upstream tracking branch when creating a new branch from a remote-tracking branch This allows ‘git pull’ and ‘git push’ to work without specifying the remote/branch.

      Tag

      [tag]
      sort = taggerdateCode language: plaintext (plaintext)
      • sort = taggerdate Sort tags by the date they were created.

      Help

      [help]
      autoCorrect = promptCode language: plaintext (plaintext)
      • autoCorrect = prompt When a mistyped Git command closely resembles a valid one, this setting prompts the user with a suggestion before executing the corrected command.

      Aliases

      Here are aliases that abbreviate common Git commands:

      [alias]
      # Pull with rebase and automatically stash local changes before the operation
      up = pull --rebase --autostash
      
      # Show details of the most recent commit or a specified object
      s = show
      
      # Commit all tracked changes
      cia = commit -a
      
      # Continue a rebase after resolving conflicts
      rc = rebase --continue
      
      # Amend the most recent commit with staged changes
      amend = commit --amend
      
      # Amend the most recent commit without changing the commit message
      commend = commit --amend --no-edit
      
      # Push commits to the remote repository
      p = push
      
      # Force push to the remote repository, overwriting history
      pf = push --force
      
      # Stage a specific file or files for commit
      a = add
      
      # Stage all changes (including deletions) in the working directory
      aa = add -A
      
      # Show a short summary of the working directory status
      st = status -s
      
      # Switch branches or restore working tree files
      co = checkout
      
      # List, create, or delete branches
      b = branch
      
      # Discard all local changes and reset to the latest commit on the current branch
      rh = reset --hard HEAD
      
      # Fetch and integrate changes from the remote repository
      pl = pull
      
      # Show changes in the working directory relative to the last commit
      d = diff HEAD
      
      # Show staged changes that will be included in the next commit
      dc = diff --cached
      
      # Launch the configured diff tool to view changes
      dt = difftool
      
      # Show word-by-word diff of the working directory against the last commit
      dw = diff --color-words HEAD
      
      # Show word-by-word details of the most recent commit
      sw = show --color-words
      
      # Display the commit history
      l = log
      
      # Show commit history with GPG signature verification and file change summary
      logs = log --show-signature --stat
      
      # Show full commit history with diffs
      lp = log -p
      
      # Apply changes introduced by existing commits
      chp = cherry-pick
      
      # Abort an in-progress cherry-pick operation
      chpa = cherry-pick --abort
      
      # Continue an in-progress cherry-pick after resolving conflicts
      chpc = cherry-pick --continue
      
      # Quit an in-progress cherry-pick without committing
      chpq = cherry-pick --quit
      
      # Skip the current commit during an in-progress cherry-pick
      chps = cherry-pick --skipCode language: Bash (bash)

      Conclusion

      This Git configuration enhances usability, improves performance, and simplifies repository management through thoughtful settings and powerful aliases. The author’s .gitconfig file is available in the jc-dotfiles repository.

      Emacs: Toggling symbol highlighting with unique colors for each symbol using built-in functions

      Symbol highlighting is a useful feature for quickly identifying occurrences of a symbol in a buffer. For example, when reading an algorithm with nested loops and multiple function calls, the distinct colors for each symbol, variable, or function make it easier to identify where each is used by simply scanning the highlighted symbols. This article presents a function that simplifies toggling the highlight for the symbol at point in Emacs using the built-in hi-lock package, which provides dynamic text highlighting.

      (The function provided in this article can serve as a replacement for packages like symbol-overlay or highlight-symbol if your primary goal is simply highlighting symbols. However, if you require advanced features such as jumping between occurrences, I recommend using a more full-featured package.)

      The function to toggle symbol highlighting

      Here is the function that enables or disables highlighting for the symbol at point:

      (require 'hi-lock)  ; Built-in Emacs package
      
      (defun simple-toggle-highlight-symbol-at-point ()
        "Toggle highlighting for the symbol at point."
        (interactive)
        (when-let* ((regexp (find-tag-default-as-symbol-regexp)))
          (if (member regexp (hi-lock--regexps-at-point))
              ;; Unhighlight symbol at point
              (hi-lock-unface-buffer regexp)
            ;; Highlight symbol at point
            (hi-lock-face-symbol-at-point))))Code language: Lisp (lisp)

      One advantage of the built-in hi-lock function is that it highlights each symbol with a unique color, making it easier to distinguish between different symbols.

      Here is how it works:

      1. Checking if the symbol is already highlighted: The function first retrieves a list of regular expressions corresponding to currently highlighted text in the buffer using hi-lock--regexps-at-point. It then checks whether the symbol at point is among the highlighted expressions using member.
      2. Unhighlighting the symbol: If the symbol is already highlighted, the function calls hi-lock-unface-buffer with the appropriate regular expression, removing the highlighting.
      3. Highlighting the symbol: If the symbol is not currently highlighted, the function invokes hi-lock-face-symbol-at-point, which applies highlighting to the symbol.

      Usage

      You can configure a key binding, such as C-c h, with the following:

      (global-set-key (kbd "C-c h") #'simple-toggle-highlight-symbol-at-point)Code language: Lisp (lisp)

      Alternatively, you can use the function interactively by placing the cursor on a symbol and executing:

      M-x simple-toggle-highlight-symbol-at-point

      (If the symbol is not highlighted, it will be highlighted. If it is already highlighted, the function will remove the highlighting.)

      You can also remove a symbol highlight from the entire buffer by selecting it from the list and removing it using:

      M-x hi-lock-unface-buffer

      Conclusion

      The simple-toggle-highlight-symbol-at-point function provides an efficient way to toggle symbol highlighting in Emacs without relying on external packages. It offers a lightweight solution for users who primarily need highlighting functionality. While it does not include advanced navigation features found in third-party packages, it serves as a simple and effective alternative for quick visual identification of symbols in a buffer.

      Emacs: Highlighting Codetags Like TODO, FIXME, BUG, NOTE…

      Highlighting keywords such as TODO, FIXME, NOTE, BUG, and others (often referred to as tags, codetags, or tokens) enhances workflow by making key annotations more visible. This allows developers to quickly identify tasks, warnings, and notes within the code, reducing the time spent searching for unfinished work or potential issues.

      This article outlines an Elisp code that highlights these codetags.

      (There are packages like hl-todo and comment-tags that can highlight these codetags for those who need a more feature-rich solution. However, they contain hundreds of lines of code, which is excessive if your only goal is to just highlight codetags. While these packages likely offer additional features, such as navigating to the next codetag, the Elisp code in this article provides a much simpler solution for those who just want to highlight them.)

      Elisp code to highlight codetags

      To highlight these codetags, you can use the following Emacs Lisp code:

      (defvar highlight-codetags-keywords
        '(("\\<\\(TODO\\|FIXME\\|BUG\\|XXX\\)\\>" 1 font-lock-warning-face prepend)
          ("\\<\\(NOTE\\|HACK\\)\\>" 1 font-lock-doc-face prepend)))
      
      (define-minor-mode highlight-codetags-local-mode
        "Highlight codetags like TODO, FIXME..."
        :global nil
        (if highlight-codetags-local-mode
            (font-lock-add-keywords nil highlight-codetags-keywords)
          (font-lock-remove-keywords nil highlight-codetags-keywords))
      
        ;; Fontify the current buffer
        (when (bound-and-true-p font-lock-mode)
          (if (fboundp 'font-lock-flush)
              (font-lock-flush)
            (with-no-warnings (font-lock-fontify-buffer)))))Code language: Lisp (lisp)

      To apply codetag highlighting across all programming modes, add highlight-codetags-local-mode to the prog-mode-hook:

      (add-hook 'prog-mode-hook #'highlight-codetags-local-mode)Code language: Lisp (lisp)

      If you call highlight-codetags-local-mode interactively, you can toggle the highlighting of codetags on and off.

      Customizations

      If desired (though not required), you can further customize the Elisp code:

      • You can customize the highlighting by substituting font-lock-warning-face or font-lock-doc-face with any other face of your choice. (You can view all available faces by executing the command: M-x list-faces-display)
      • Additionally, you can add more keywords to the regular expression.
        For instance, to add the MAYBE codetag to the \\<\\(NOTE\\|HACK\\)\\> pattern, simply append \\|MAYBE before the closing parenthesis \\):
        \\<\\(NOTE\\|HACK\\|MAYBE\\)>.

      Conslusion

      This simple configuration enhances keyword visibility in Emacs, making it easier to track important annotations while editing source code.

      Ansible: ansible-role-tuned, an Ansible role which configures tuned

      The ansible-role-tuned Ansible playbook manages the installation, configuration, and activation of the tuned service.

      Tuned is a dynamic adaptive system tuning tool used in Linux environments to optimize performance by adjusting various system settings dynamically. It provides pre-defined profiles that target specific use cases, such as high throughput, low latency, and energy saving, and automatically applies these configurations based on system activity.

      For high traffic servers, using Tuned is beneficial as it can enhance network throughput and responsiveness by adjusting parameters like CPU frequency scaling, I/O scheduling, and network stack settings. This optimization results in improved server performance, reduced latency, and better handling of high loads, ultimately leading to a more efficient and reliable infrastructure for handling significant network traffic.

      Example playbook

      Here is an example of how to use ansible-role-tuned after installing it in the roles/tuned directory:

      - hosts: SERVER
      roles:
      - {role: tuned,
      tuned_profile: "throughput-performance"}

      Links

      Productivity: Time-saving tips for the digital age

      Your computer is a powerful tool for enhancing productivity at work, but it can also be a significant source of inefficiency. Your time is a valuable resource. If, after hours of working at your computer, you find yourself accomplishing little, you may be among the many individuals distracted by the lure of the internet and digital technology.

      If you excel at time management, having schedules, goals, and structure in place is commendable. However, the effectiveness of time management diminishes if the time allocated is not directed toward advancing meaningful tasks.

      This article does not aim to teach you how to organize your time. Instead, it provides tips to help you avoid common pitfalls that lead to wasted time.

      Below, you will find practical and tested advice to help you reclaim your day and accomplish significant tasks with the same level of effort:

      1. No mobile phone: Not everyone can do this, but for those who can, it’s worth a reminder. Personal (and sometimes even professional) phones can eat up your time with long, trivial conversations or spontaneous invitations. Put it on silent, or better yet, turn it off!
      2. Disable notifications: Notifications can constantly pull your attention. Notifications are a major distraction; disable them all!
      3. Avoid temptation: If you’ve stopped notifications, don’t actively seek distractions like social media, RSS readers, or irrelevant Google searches. These create even more temptations and waste your time.
      4. Enhance your email usage: Use a single email inbox by redirecting all accounts there. Set filters for less urgent emails, such as newsletters, and check your inbox sparingly; perhaps once an hour. Aim for an empty inbox to ease mental clutter.
      5. Disconnect from the internet: If your work doesn’t require internet access, disconnect! This significantly reduces distractions.
      6. Avoid radio, TV, Youtube, etc.: Background noise from radio or TV can distract you. Instead, consider curated podcasts to enjoy during breaks or after completing critical tasks.
      7. Organize your workspace: A clutter-free desk (physical or virtual) helps your mind focus. Keep only essential items visible. Create a well-organized folder structure on your computer for easy navigation.
      8. Separate work and personal accounts: Use separate user accounts on your computer for work and personal activities. This separation reduces the temptation to engage in distractions during work hours.
      9. Focus your internet searches: Avoid straying into unrelated topics when using search engines. Postpone non-urgent research for later.
      10. Defer non-urgent tasks: Keep a notebook to record non-urgent tasks for later. This helps reduce stress by freeing you from the pressure of trying to remember everything.

      By implementing at least six of these recommendations, you will observe noticeable improvements in productivity and efficiency. You will gain more time and energy to focus on tasks that hold greater significance.

      Regularly take breaks to maintain optimal mental performance and enhance productivity. Scheduling tools such as Workrave, can assist in managing breaks and preventing fatigue.

      It is my hope that this article enables you to optimize your time effectively. If you have additional strategies to share, consider contributing them—they could be invaluable to others!

      Emacs: buffer-terminator.el – Safely Terminate Emacs Buffers Automatically

      The buffer-terminator Emacs package automatically kills buffers to help maintain a clean and efficient workspace, while also improving Emacs’ performance by reducing the number of open buffers, thereby decreasing the number of active modes, timers, and other processes associated with those buffers.

      Activating (buffer-terminator-mode) terminates all buffers that have been inactive for longer than the duration specified by buffer-terminator-inactivity-timeout (default: 30 minutes). It checks every buffer-terminator-interval (default: 10 minutes) to determine if a buffer should be terminated.

      The following buffers are not terminated by default:

      • Special buffers (buffers whose names start with a space, start and end with *, or whose major mode is derived from special-mode).
      • Modified file-visiting buffers that have not been saved; the user must save them first.
      • Buffers currently displayed in any visible window.
      • Buffers associated with running processes.

      (The default parameters above are fully customizable. Users can define specific rules for keeping or terminating certain buffers by specifying a set of rules using buffer-terminator-rules-alist. These rules can include buffer name patterns or regular expressions, major-modes, buffer properties, etc.)

      Installation from MELPA

      MELPA

      To install buffer-terminator from MELPA:

      1. If you haven’t already done so, add MELPA repository to your Emacs configuration.
      2. Add the following code to the Emacs init file:
      (use-package buffer-terminator
        :ensure t
        :custom
        (buffer-terminator-verbose nil)
        :config
        (buffer-terminator-mode 1))Code language: CSS (css)

      Customizations

      To enable verbose mode to log buffer cleanup events:

      (setq buffer-terminator-verbose t)Code language: Lisp (lisp)

      To set the inactivity timeout (in seconds) after which buffers are considered inactive (default is 30 minutes):

      (setq buffer-terminator-inactivity-timeout (* 30 60)) ; 30 minutesCode language: Lisp (lisp)

      To define how frequently the cleanup process should run (default is every 10 minutes):

      (customize-set-variable 'buffer-terminator-interval (* 10 60)) ; 10 minutesCode language: Lisp (lisp)

      (Using customize-set-variable allows buffer-terminator-interval to update the timer dynamically, without the need to restart buffer-terminator-mode.)

      There are other customizable options available in the buffer-terminator.el README.md file.

      Links

      The compile-angel Emacs package: Byte-compile and Native-compile Emacs Lisp libraries Automatically

      The compile-angel Emacs package automatically byte-compiles and native-compiles Emacs Lisp libraries. It offers:

      • (compile-angel-on-load-mode): A global mode that compiles .el files before they are loaded.
      • (compile-angel-on-save-local-mode): A local mode that compiles .el files whenever the user saves them.

      The compile-angel modes speed up Emacs by ensuring all libraries are byte-compiled and native-compiled. Byte-compilation reduces the overhead of loading Emacs Lisp code at runtime, while native compilation optimizes performance by generating machine code specific to your system.

      Why use compile-angel?

      Because you are likely running a significant amount of interpreted, slow Elisp code. Ensuring that Elisp is native-compiled significantly improves Emacs’ performance. This is because functions like package-install and package-recompile-all do not compile .el files in the load-path paths that were not installed using package.el. Since these files are not byte-compiled, the Emacs JIT compiler does not native-compile them either, as a byte-compiled file signals the JIT compiler to perform native compilation. In contrast, compile-angel modes ensure that all loaded .el files are compiled transparently, regardless of whether they are part of a package.

      Install compile-angel from MELPA

      1. If you haven’t already done so, add MELPA repository to your Emacs configuration.
      2. Add the following code at the very beginning of your Emacs init file, before all other packages:
      (use-package compile-angel
        :ensure t
        :demand t
        :custom
        (compile-angel-verbose nil)
        :config
        (compile-angel-on-load-mode)
        (add-hook 'emacs-lisp-mode-hook 
                  #'compile-angel-on-save-local-mode)) Code language: Lisp (lisp)

      Links