outline-indent.el – Indentation based Folding and Outlining in Emacs

5/5

The outline-indent.el Emacs package provides a minor mode that enables code folding and outlining based on indentation levels for various indentation-based text files, such as YAML, Python, and other indented text files.

In addition to code folding, outline-indent.el allows moving indented sub-trees up and down, promoting and demoting sections to adjust indentation levels, customizing the ellipsis, and inserting a new line with the same indentation level as the current line, among other features.

The outline-indent.el package leverages the built-in outline-minor-mode, which is maintained by the Emacs developers and has less chance of being abandoned like origami.el.

The outline-indent.el Emacs package offers a similar functionality to Vim’s set foldmethod=indent setting. Just as in Vim, it allows to fold and unfold code sections based on their indentation levels.

Installation

To install the outline-indent using straight.el:

  1. If you haven’t already done so, add the straight.el bootstrap code to your init file.
  2. Add the following code to your Emacs init file:
(use-package outline-indent
  :ensure t
  :straight (outline-indent
             :type git
             :host github
             :repo "jamescherti/outline-indent.el")
  :custom
  (outline-indent-ellipsis " ▼ "))Code language: Lisp (lisp)

Usage

Once installed, the minor mode can be activated using:

(outline-indent-minor-mode)Code language: Lisp (lisp)

The minor mode can also be automatically activated for a certain mode. For example for Python and YAML:

(add-hook 'python-mode-hook #'outline-indent-minor-mode)
(add-hook 'python-ts-mode-hook #'outline-indent-minor-mode)

(add-hook 'yaml-mode-hook #'outline-indent-minor-mode)
(add-hook 'yaml-ts-mode-hook #'outline-indent-minor-mode)Code language: Lisp (lisp)

(You can also adjust the indentation offset by modifying the variable outline-indent-default-offset)

Once outline-indent-minor-mode is activated, you can use the built-in outline-minor-mode functions to fold or unfold indented sections:

  • outline-hide-body: Hide all body lines in buffer, leaving all headings visible.
  • outline-hide-other: Hide everything except current body and parent and top-level headings.
  • outline-hide-entry: Hide the body directly following this heading.
  • outline-hide-leaves: Hide the body after this heading and at deeper levels.
  • outline-hide-subtree: Hide everything after this heading at deeper levels.
  • outline-show-children: Show all direct subheadings of this heading.
  • outline-hide-sublevels: Hide everything but the top LEVELS levels of headers, in whole buffer.
  • outline-show-all: Show all of the text in the buffer.
  • outline-show-entry: Show the body directly following this heading.
  • outline-show-subtree: Show everything after this heading at deeper levels.
  • outline-show-branches: Show all subheadings of this heading, but not their bodies.
  • outline-show-children: Show all direct subheadings of this heading.

You can also indent/unindent and move subtree up and down:

  • (outline-indent-demote) and (outline-indent-promote): Indent or unindent the entire subtree.
  • (outline-indent-move-subtree-down) and (outline-indent-move-subtree-up) to move the current subtree up or down.
  • (outline-insert-heading) to insert a new line with the same indentation level/depth as the current line just before the next heading that shares the same or less indentation level.

In Evil mode, outline-indent-minor-mode works out of the box, and you can use the Evil keyboard mappings: zo, zc, zO, zC, za, zr, and zm to manage folds.

Related links

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)

Rate this post

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.

Emacs: Enhancing up and down subtree movement in outline-mode and outline-minor-mode

4.5/5

When editing outlined files (e.g., using the built-in outline-minor-mode, or packages like outline-indent.el, outline-yaml.el, etc.), handling subtrees efficiently can significantly enhance productivity, especially when working with complex documents. If you’re familiar with outline-mode or outline-minor-mode, you might have noticed that the built-in functions for moving subtrees up and down, outline-move-subtree-up and outline-move-subtree-down:

  • Blank line exclusion: outline-move-subtree-up and outline-move-subtree-down exclude the last blank line of the subtree when the outline-blank-line variable is set to t. Setting outline-blank-line to t is worthwhile because it retains a visible blank line after the subtree and before the next heading, improving the readability of the document.
  • Cursor position reset: After moving a subtree up or down, the cursor position is often reset, which can be disruptive during editing.

Here’s how you can address these issues by using custom functions to enhance subtree movement:

(require 'outline)

(defun my-advice-outline-hide-subtree (orig-fun &rest args)
  "Advice for `outline-hide-subtree'.
This ensures that the outline is folded correctly by
outline-move-subtree-up/down, preventing it from being unable to open the fold."
  (let ((outline-blank-line
         (if (bound-and-true-p my-outline-hide-subtree-blank-line-enabled)
             my-outline-hide-subtree-blank-line
           outline-blank-line)))
    (apply orig-fun args)))

(defun my-advice-outline-move-subtree-up-down (orig-fun &rest args)
  "Move the current subtree up/down past ARGS headlines of the same level.
This function ensures the last blank line is included, even when
`outline-blank-line' is set to t. It also restores the cursor position,
addressing the issue where the cursor might be reset after the operation."
  (interactive "p")
  (let ((column (current-column))
        (outline-blank-line nil)
        (my-outline-hide-subtree-blank-line-enabled t)
        (my-outline-hide-subtree-blank-line outline-blank-line))
    (apply orig-fun (or args 1))
    (move-to-column column)))

(advice-add 'outline-hide-subtree
            :around #'my-advice-outline-hide-subtree)
(advice-add 'outline-move-subtree-up
            :around #'my-advice-outline-move-subtree-up-down)
(advice-add 'outline-move-subtree-down
            :around #'my-advice-outline-move-subtree-up-down)Code language: Lisp (lisp)

I also recommend using Ctrl-Up and Ctrl-Down key bindings for moving subtrees up and down.

(define-key outline-mode-map (kbd "C-<up>") 'outline-move-subtree-up)
(define-key outline-mode-map (kbd "C-<down>") 'outline-move-subtree-down)

(defun my-setup-outline-minor-mode-keybindings ()
    "Set up keybindings for moving subtrees in `outline-minor-mode'."
  (define-key outline-minor-mode-map (kbd "C-<up>") 'outline-move-subtree-up)
  (define-key outline-minor-mode-map (kbd "C-<down>") 'outline-move-subtree-down))
(add-hook 'outline-minor-mode-hook 'my-setup-outline-minor-mode-keybindings) Code language: Lisp (lisp)

With this setup, you will ensure that every time you use outline-move-subtree-up or outline-move-subtree-down, the last blank line of the subtree is included and the cursor position is restored.

Introducing elispcomp: Compiling Elisp code directly from the command line

5/5

The elispcomp command line tool allows compiling Emacs Lisp (Elisp) code directly from the terminal or from a shell script. It facilitates the generation of optimized .elc (byte-compiled) and .eln (native-compiled) files, which can significantly improve the performance of Emacs.

The tool executes a headless instance of Emacs that recursively scans the specified directories, byte compiling and native compiling all the .el files that haven’t been compiled yet. It supports various configuration options, allowing you to adapt the compilation process to suit your needs.

When configured appropriately, Emacs can compile to both .elc and .eln files. However, for those who wish to automate the background compilation of .el files using a script, the elispcomp command-line tool can be beneficial in ensuring that their Emacs setup remains up-to-date without manual intervention and without starting an Emacs instance. I personally use elispcomp compile multiple Elisp files across various machines and Emacs versions.

Installation

To get started with elispcomp, you can install it using pip, Python’s package installer. Here’s how:

pip install --user elispcomp

This command installs elispcomp and places the executable in your ~/.local/bin/ directory, making it easily accessible from your command line.

Usage

The elispcomp command line tool is straightforward to use.

First example: To compile all .el files located in the ~/.emacs.d/lisp:

elispcomp ~/.emacs.d/lispCode language: plaintext (plaintext)

Second example: To compile all .el files located in the ~/.emacs.d/lisp directory, and store the native-compiled files in the ~/.emacs.d/eln-cache directory:

elispcomp --eln-cache ~/.emacs.d/.eln-cache ~/.emacs.d/lispCode language: plaintext (plaintext)

Command line options

usage: elispcomp [--option] [N]

Recursively byte and native compile .el files.

positional arguments:
  N                     The directories to be scanned recursively by Emacs to 
                        locate the '.el' files for compilation.

options:
  -h, --help            show this help message and exit
  -c ELN_CACHE, --eln-cache ELN_CACHE
                        The eln-cache directory where Emacs stores the
                        compiled native compiled code. Defaults to the
                        default Emacs eln-cache directory.
  -e EMACS_BIN, --emacs-bin EMACS_BIN
                        Path to the Emacs binary. Defaults: emacs
  -j JOBS, --jobs JOBS  Specify the number of parallel jobs for compilation.
                        Default: Half the number of available CPUs
  -b, --disable-byte-comp
                        Disable byte-compile. Default: enabled
  -n, --disable-native-comp
                        Disable native compilation. Default: enabled
  -i LOAD_PATH, --load-path LOAD_PATH
                        Recursively adds the subdirectories of the specified
                        directory to the Emacs `load-path`. This option can
                        be used multiple times to include several directories.
Code language: plaintext (plaintext)

The elispcomp command-line tool offers an alternative approach to managing Emacs Lisp code. Try it out and experience a new way to compile your Elisp codebase from the command line or from a script.

Links

Emacs Evil Mode: Disabling the automatic removal of spaces after leaving Insert mode

5/5

By default, Emacs evil-mode removes newly inserted spaces when exiting insert mode. However, some users may find this disruptive to their workflow. This is particularly true for those who edit file formats where trailing spaces are significant or who simply prefer to manage whitespace manually.

To prevent the automatic removal of trailing spaces when leaving insert mode, add the following Elisp code to the Emacs init file:

(with-eval-after-load 'evil
  (defun my-evil-disable-remove-spaces ()
    "Disable automatic removal of trailing spaces in `evil-mode'."
    (setq-local evil-maybe-remove-spaces nil))

  (add-hook 'evil-insert-state-entry-hook #'my-evil-disable-remove-spaces))Code language: Lisp (lisp)

The function above sets the evil-maybe-remove-spaces variable to nil when entering insert mode, preventing the evil-maybe-remove-spaces function from deleting whitespace after leaving insert mode.

The evil-insert-state function, which Evil uses to switch to insert mode, behaves as follows:

  • When entering insert mode: It sets the evil-maybe-remove-spaces variable to t.
  • When exiting insert mode, it calls the evil-maybe-remove-spaces function, which removes trailing spaces if the evil-maybe-remove-spaces variable is set to t. Because the my-evil-disable-remove-spaces function above sets the evil-maybe-remove-spaces variable to nil when entering insert mode, it prevents the evil-maybe-remove-spaces function from deleting whitespace after leaving insert mode.

If you want to compare the behavior before and after the function above, use whitespace-mode. This mode visually highlights different types of whitespace characters, such as spaces, tabs, and newlines, making it easier to see the differences.

Customizing evil-mode with the simple piece of Elisp code above can prevent the automatic removal of trailing spaces when exiting insert mode. This adjustment allows for better control over whitespace in files.

Emacs: Customizing the Ellipsis (…) in Outline Mode and Outline Minor Mode

5/5

The built-in Emacs outline-mode and outline-minor-mode allow structuring documents with collapsible sections. By default, these modes use an ellipsis (“…”) to indicate folded text. However, the default ellipsis and its face can make it hard to distinguish between folded text and regular text. This is why it can be beneficial to customize the ellipsis.

The code snippets provided in this article allow for customizing the ellipsis either globally or locally within a buffer.

Set the global outline ellipsis

The following function can be used to change the ellipsis in both outline-mode and outline-minor-mode to ▼:

(defun my-outline-set-global-ellipsis (ellipsis)
  "Apply the ellipsis ELLIPSIS to outline mode globally."
  (let* ((face-offset (* (face-id 'shadow) (ash 1 22)))
         (value (vconcat (mapcar (lambda (c) (+ face-offset c)) ellipsis))))
    (set-display-table-slot standard-display-table 'selective-display value)))

(my-outline-set-global-ellipsis " ▼ ")
Code language: Lisp (lisp)

The Elisp code above will change the outline-mode and outline-minor-mode ellipsis to:

(The screenshot above shows a YAML file folded using outline-indent.el or outline-yaml.el, which leverages outline-minor-mode to outline and enable code folding in YAML files.)

Set the buffer local outline ellipsis

To apply the ellipsis locally to a buffer, the following Elisp code snippet modifies the display settings within that buffer. This ensures that any changes made affect only the current buffer, leaving the global Emacs environment unaffected. This approach is particularly useful for customizing displays in specific files or testing new configurations without affecting other buffers or sessions.

Here is the Emacs Lisp code snippet to achieve this:

(defun my-outline-set-buffer-local-ellipsis (ellipsis)
  "Apply the ellipsis ELLIPSIS to outline mode locally to a buffer."
  (let* ((display-table (or buffer-display-table (make-display-table)))
         (face-offset (* (face-id 'shadow) (ash 1 22)))
         (value (vconcat (mapcar (lambda (c) (+ face-offset c)) ellipsis))))
    (set-display-table-slot display-table 'selective-display value)
    (setq buffer-display-table display-table)))Code language: Lisp (lisp)

And here is an example of applying the buffer-local ellipsis to text-mode:

(add-hook 'text-mode-hook
          #'(lambda() (my-outline-set-buffer-local-ellipsis " ▼ ")))Code language: PHP (php)

Conclusion

Customizing the ellipsis in outline-mode and outline-minor-mode is a simple yet effective way to personalize your Emacs and create a more visually appealing way to handle folds.

Emacs: YAML file code Folding and Outlining

5/5

Working with long and complex YAML files can be a daunting task. In such cases, code folding becomes an invaluable tool, allowing the collapse and expansion of sections of the file and enhancing readability and navigation. This makes it easier to focus on specific parts of the code without being overwhelmed by the entire document.

To address this need, I would like to introduce you to outline-yaml.el, a minor mode for Emacs that brings code folding and outlining capabilities to YAML files, making editing YAML files more efficient and enjoyable. Leveraging Emacs’ built-in outline-minor-mode, outline-yaml.el provides a structured and navigable view of YAML content, simplifying the editing of even the most difficult YAML files.

Installation of outline-yaml.el

  1. Install and configure yaml-mode or yaml-ts-mode.
  2. If you haven’t already done so, add the straight.el bootstrap code to your init file.
  3. After that, add the following code to your Emacs init file:
(use-package outline-yaml
  :ensure t
  :straight (outline-yaml
             :type git
             :host github
             :repo "jamescherti/outline-yaml.el")
  :hook
  ((yaml-mode . outline-yaml-minor-mode)
   (yaml-ts-mode . outline-yaml-minor-mode)))Code language: Lisp (lisp)

How to change the Ellipsis (…) to (▼)?

The code snippet in this article can be used to to change the Ellipsis to ▼.

Links

Emacs: Enabling native compilation and dynamically adjusting the number of Elisp files compiled in parallel

5/5

Emacs has experienced a significant performance boost with the introduction of native compilation, available from version 27 and above. This feature converts Emacs Lisp code into machine-level code, enabling faster execution and enhanced responsiveness.

Speeding up compilation by using the maximum number of available CPU cores significantly reduces compilation time. However, it’s also necessary to leave a few CPU cores free to ensure the operating system runs smoothly, including the graphical user interface, shells, and other processes. The source code snippet outlined in this article is designed to effectively manage resources by allocating CPU cores for native compilation while reserving some for system operations.

Configuring native compilation and adjusting the number of parallel compilations

To configure native compilation and dynamically adjust the number of parallel compilations, add the following code snippet to early-init.el or init.el:

;; Description: Enable native compilation and dynamically adjust
;; the number of Elisp files compiled in parallel.
;;
;; Compatible with: Emacs >= 28.1 (because `num-processors' is required)
;;
;; URL: https://www.jamescherti.com/emacs-native-compilation-config-jobs/
;; License: MIT
;; Author: James Cherti

(defvar my-native-comp-reserved-cpus 2
  "Number of CPUs to reserve and not use for `native-compile'.")

(defun my-calculate-native-comp-async-jobs ()
  "Set `native-comp-async-jobs-number' based on the available CPUs."
  ;; The `num-processors' function is only available in Emacs >= 28.1
  (max 1 (- (num-processors) my-native-comp-reserved-cpus)))

(if (and (featurep 'native-compile)
         (fboundp 'native-comp-available-p)
         (native-comp-available-p))
    ;; Activate `native-compile'
    (setq native-comp-async-jobs-number (my-calculate-native-comp-async-jobs)
          native-comp-deferred-compilation t
          package-native-compile t)
  ;; Deactivate the `native-compile' feature if it is not available
  (setq features (delq 'native-compile features)))Code language: Lisp (lisp)

What does the source code snippet above do?

  • Reserves CPUs: Sets aside 2 CPUs to not be used by the native compilation feature in Emacs.
  • Calculates Available CPUs for Compilation: Determines how many CPUs can be used for compiling Emacs Lisp files by subtracting the reserved CPUs from the total count.
  • Sets Native Compilation Parameters: Configures Emacs to use the calculated number of CPUs for parallel compilation tasks.
  • Ensures Feature Availability: Activates native compilation settings only if the feature is supported and available, otherwise deactivates it.
  • Optimizes Performance: Aims to enhance Emacs performance by efficiently using system resources without overloading the system.

How to check if native compilation is available?

To check whether native compilation is supported, you can run the following Emacs Lisp code:

(message (if (and (fboundp 'native-comp-available-p)
                  (native-comp-available-p))
             "Native compilation is available"
           "Native compilation is *not* available"))
Code language: Lisp (lisp)

Conclusion

Managing system resources efficiently is key to maintaining optimal performance in Emacs, especially when using the native compilation feature. The source code snippet outlined in this article provides a dynamic method for adjusting the number of native compilation jobs according to the number of available CPUs. This enhances the responsiveness and efficiency of Emacs without overloading the system.

Ansible: Installing and configuring Gitolite using Ansible for secure Git repository management

Rate this post

Gitolite provides a way to manage Git repositories, control access to those repositories, and maintain a central configuration using simple configuration files and SSH keys.

Automating Gitolite Installation with Ansible

The Ansible tasks outlined in this article are designed to simplify the installation and configuration of Gitolite on your server. These tasks can automatically handle the entire setup process, including prerequisites like installing necessary packages and configuring system users and groups.

This automation significantly reduces the risk of human error and ensures a consistent setup across different environments.

The Ansible tasks:

---
# Automating Gitolite Installation with Ansible
# License: MIT
# Author: James Cherti
# URL: https://www.jamescherti.com/ansible-install-gitolite-linux/

- name: Install Gitolite
  block:
    - name: Check if the Operating System is supported
      fail:
        msg: "Operating System family is not supported: {{ ansible_os_family }}"
      when: ansible_os_family not in ["Debian", "RedHat"]

    - name: Install Gitolite on Debian-based Systems
      apt:
        name: gitolite3
      when: ansible_os_family == "Debian"

    - name: Install Gitolite on RedHat-based Systems
      yum: name=gitolite3
      when: ansible_os_family == "RedHat"

    - name: Create Gitolite system group
      group:
        name: "{{ gitolite_group }}"
        system: true

    - name: Create Gitolite system user
      user:
        name: "{{ gitolite_user }}"
        group: "{{ gitolite_group }}"
        home: "{{ gitolite_home }}"
        shell: "{{ gitolite_shell }}"
        create_home: true
        system: true

    - name: Ensure Gitolite home directory exists with proper permissions
      file:
        state: directory
        path: "{{ gitolite_home }}"
        owner: "{{ gitolite_user }}"
        group: "{{ gitolite_group }}"
        mode: 0700

- name: Configure Gitolite SSH key
  block:
    - name: Generate Gitolite SSH key pair if it does not exist
      become: true
      become_user: "{{ gitolite_user }}"
      command: ssh-keygen -t rsa -b 4096 -f {{ gitolite_ssh_key_path | quote }} -N ""
      args:
        creates: "{{ gitolite_ssh_key_path }}"

    - name: Set permissions for the Gitolite .ssh directory
      file:
        path: "{{ gitolite_ssh_directory }}"
        owner: "{{ gitolite_user }}"
        group: "{{ gitolite_user }}"
        mode: 0700

    - name: Set permissions for the SSH public key
      file:
        path: "{{ gitolite_ssh_key_path }}.pub"
        owner: "{{ gitolite_user }}"
        group: "{{ gitolite_user }}"
        mode: 0644

    - name: Set permissions for the SSH private key
      file:
        path: "{{ gitolite_ssh_key_path }}"
        owner: "{{ gitolite_user }}"
        group: "{{ gitolite_user }}"
        mode: 0600

- name: Setup Gitolite
  block:
    - name: Initialize Gitolite with the admin public key
      become: true
      become_user: "{{ gitolite_user }}"
      command:
        argv:
          - "gitolite"
          - "setup"
          - "-pk"
          - "{{ gitolite_ssh_public_key_path }}"
      args:
        creates: /var/lib/gitolite/repositories/gitolite-admin.gitCode language: YAML (yaml)

The required Ansible variables:

---
# Automating Gitolite Installation with Ansible
# License: MIT
# Author: James Cherti
# URL: https://www.jamescherti.com/ansible-install-gitolite-linux/

gitolite_user: gitolite
gitolite_group: gitolite
gitolite_shell: /bin/bash
gitolite_home: "/var/lib/{{ gitolite_user }}"
gitolite_ssh_directory: "{{ gitolite_home }}/.ssh"
gitolite_ssh_key_path: "{{ gitolite_ssh_directory }}/id_rsa"
gitolite_ssh_public_key_path: "{{ gitolite_ssh_directory }}/id_rsa.pub"Code language: YAML (yaml)

Related links

Emacs Theme: Tomorrow Night Deepblue, a beautiful theme with a deep blue background

5/5

The Emacs theme jamescherti/tomorrow-night-deepblue-theme.el is a beautiful deep blue variant of the Tomorrow Night colorscheme, which is renowned for its elegant color palette. It is pleasing to the eyes and is easy to read.

The Tomorrow Night Deepblue Emacs theme features a deep blue background color that creates a calming atmosphere. The contrasting colors make it easy to distinguish between different elements of your code. The theme is also a great choice for programmer who miss the blue themes that were trendy a few years ago.

The theme was inspired by classic DOS text editors such as QuickBASIC, RHIDE, and Turbo Pascal, which featured blue backgrounds by default. There’s something special about the early days of programming and the tools we used that brings back fond memories.

Installation

MELPA

To install the tomorrow-night-deepblue-theme.el from MELPA, you need to add the following code to the Emacs init file:

(use-package tomorrow-night-deepblue-theme
  :ensure t
  :config
  ;; Disable all themes and load the Tomorrow Night Deep Blue theme
  (mapc #'disable-theme custom-enabled-themes)
  (load-theme 'tomorrow-night-deepblue t))
Code language: Lisp (lisp)

What are the differences between Tomorrow Night Blue and Deepblue?

The main differences lie in the large number of additional faces and the background color, which enable support for many more modern Emacs packages. Currently, Tomorrow Night Deepblue supports over 1170 faces (compared to 333 in the original version), with a background color reminiscent of traditional editors. The author plans to make further changes to support even more faces. Contributions are welcome!

This is the background color of the Tomorrow Night Deepblue, the theme featured in this article:

This background color or the Tomorrow Night Blue, the previous version upon which this theme is based:

Conclusion

In summary, the Tomorrow Night Deepblue Emacs theme offers a calming deep blue background that helps you focus. Its clear colors make it easy to see different parts of your code. It’s a great choice for programmers who miss the popular blue themes from a few years ago.

Related links

Making the Emacs built-in tab-bar Look Like Vim’s Tab Bar

4.5/5

The vim-tab-bar.el Emacs package modifies the appearance of the Emacs tab-bar to resemble Vim’s tabbed browsing interface. It also ensures that the tab-bar’s appearance remains consistent with the overall color scheme of the current theme.

The Emacs built-in tab-bar feature, which enables users to manage multiple buffers through a visual interface at the top of the Emacs window, is available in Emacs version 27 or higher.

Installation

MELPA

The vim-tab-bar.el package can be installed from MELPA by adding the following lines to your Emacs init file:

(use-package vim-tab-bar
  :ensure t
  :config
  (vim-tab-bar-mode 1))Code language: CSS (css)

Screenshots

Here are a few more screenshots showing how the jamescherti/vim-tab-bar.el package adapts Emacs tab-bar colors to any loaded theme:

The above theme is the Tomorrow Night Deepblue Emacs theme

How do Vim tabs look like?

For those who have never used Vim and are curious about the appearance of Vim tabs, here is a screenshot:

Ansible: Reintegrating /etc/rc.local in Linux systems that use Systemd as their init system

Rate this post

For years, /etc/rc.local has been a staple in Linux administration, providing a straightforward means to execute scripts or commands automatically upon system startup. However, with the transition to newer init systems like systemd, the /etc/rc.local script is no longer executed at boot time.

Ansible tasks that restore the /etc/rc.local script

The following Ansible tasks will create and configure /etc/rc.local and also ensure its execution by Systemd at boot time.

---
# Description: Reintegrate /etc/rc.local in Linux systems that use Systemd 
#              as their init system.
# Author: James Cherti
# License: MIT
# URL: https://www.jamescherti.com/ansible-config-etc-rc-local-linux-systemd/

- name: Check if /etc/rc.local exists
  stat:
    path: "/etc/rc.local"
  register: etc_rc_local_file

- name: Create the file /etc/rc.local should it not already exist
  copy:
    dest: /etc/rc.local
    owner: root
    group: root
    mode: 0750
    content: |
      #!/usr/bin/env bash
  when: not etc_rc_local_file.stat.exists

- name: Create the systemd service rc-local.service
  register: rc_local
  copy:
    dest: /etc/systemd/system/rc-local.service
    owner: root
    group: root
    mode: 0644
    content: |
      [Unit]
      Description=/etc/rc.local compatibility

      [Service]
      Type=oneshot
      ExecStart=/etc/rc.local
      TimeoutSec=0
      RemainAfterExit=yes
      SysVStartPriority=99

      [Install]
      WantedBy=multi-user.target

- name: Reload systemd daemon
  systemd:
    daemon_reload: yes
  when: rc_local.changed|bool

- name: Enable rc-local.service
  systemd:
    name: rc-local
    enabled: true
Code language: YAML (yaml)

Emacs Evil Mode: How to restore both the line and column number of a mark, not just the line number

Rate this post

In Emacs with Evil mode, similar to Vim, a mark represents a position in the buffer that you can set and later return to, facilitating quick navigation between different locations within a file.

Set and restore a mark

You can set a mark by pressing the m button followed by a letter. For example, pressing ma sets a mark at the current cursor position and associates it with the letter a. To restore a mark, press either the backtick (`) or the single quote (') followed by the associated letter. For instance, pressing 'a restores the cursor to the line of the mark, while pressing `a moves the cursor to the exact line and column of the mark.

How to use a single quote instead of a backtick to restore both the line and column numbers of a mark

If you prefer using the single quote (') to restore both the line and column number of a mark, I’ve made a small change to accommodate this preference. The following Elisp code ensures that the single quote (') restores both the line and column, while the backtick (`) restores only the line:

(define-key evil-motion-state-map "`" 'evil-goto-mark-line)
(define-key evil-motion-state-map "'" 'evil-goto-mark)Code language: Lisp (lisp)

Emacs: Striking through Org Mode DONE tasks

Rate this post

It’s always satisfying to cross something off a to-do list, almost like declaring to yourself, ‘I did it!’ That’s the feeling I wanted to bring into Emacs Org Mode.

The following Emacs Lisp (Elisp) code instructs Emacs to apply a strike-through to any task marked as DONE:

;; Enable the fontification of headlines for tasks that have been marked as
;; completed.
(setq org-fontify-done-headline t)

(custom-set-faces
 ;; Face used for todo keywords that indicate DONE items.
 '(org-done ((t (:strike-through t))))

 ;; Face used to indicate that a headline is DONE. This face is only used if
 ;; ‘org-fontify-done-headline’ is set. If applies to the part of the headline
 ;; after the DONE keyword.
 '(org-headline-done ((t (:strike-through t)))))
Code language: Lisp (lisp)

By adding strike-through for completed items, Emacs Org Mode becomes clearer and more satisfying to use.

Emulating Cherry MX Blue Mechanical Keyboard Sounds on Linux

Rate this post

For people nostalgic for the era of tactile and audible feedback from typing on a mechanical keyboard, Cherrybuckle allow simulating the sounds of a mechanical keyboard with Cherry MX Blue key switches.

Cherrybuckle operates as a background process within a computer system, capturing and emitting a sound for each key pressed and released. It is a fork of the Bucklespring project that adds Cherry MX sounds to the default Bucklespring keyboard sounds.

Installing dependencies

The dependencies can be installed on a Debian or Ubuntu system using the following commands:

sudo apt-get install build-essential git
sudo apt-get install libalure-dev libx11-dev libxtst-dev pkg-configCode language: plaintext (plaintext)

Compiling and running Cherrybuckle on Debian/Ubuntu

Retrieve the project source code for the Git repository:

git clone https://github.com/jamescherti/cherrybuckleCode language: plaintext (plaintext)

Change the current working directory to “cherrybuckle”:

cd cherrybuckleCode language: plaintext (plaintext)

Compile the source code into an executable program:

makeCode language: plaintext (plaintext)

Finally, execute Cherrybuckle:

./cherrybuckleCode language: plaintext (plaintext)