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

5/5

The Emacs theme jamescherti/emacs-tomorrow-night-deepblue-theme 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

Open a terminal and execute the following commands. These commands will create a directory for themes if it doesn’t already exist, navigate into it, and then clone the theme files from the official Git repository:

mkdir -p ~/.emacs.d/themes
cd ~/.emacs.d/themes
git clone https://github.com/jamescherti/emacs-tomorrow-night-deepblue-theme
Code language: plaintext (plaintext)

After downloading the theme, you need to modify your Emacs configuration file to include this theme. Open or create the ~/.emacs.d/init.el directory and add the following lines of code:

;; Add the theme's directory to the path where Emacs searches for loading files
;; and require the Tomorrow Night Deepblue theme
(add-to-list 'load-path "~/.emacs.d/themes/emacs-tomorrow-night-deepblue-theme")
(require 'tomorrow-night-deepblue-theme)

;; Disable all other themes
(mapc #'disable-theme custom-enabled-themes)

;; Load the Tomorrow Night Deepblue theme
(load-theme 'tomorrow-night-deepblue)
Code language: Lisp (lisp)

What are the differences between Tomorrow Night Blue and Deepblue themes?

The main differences lie in the background color and additional faces (cursor, fill-column-indicator, lsp-face-highlight-read, highlight, and others). Currently, Tomorrow Night Deepblue supports over 345 faces, with a background color reminiscent of traditional DOS programs. I plan to make further changes to support even more faces. Contributions are also 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

If you’re an Emacs user who appreciates the appearance of Vim, you might frequently attempt to incorporate some of Vim’s minimalist elements into Emacs. One such element is the color scheme, especially how Emacs built-in tab-bar tabs are displayed.

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. In this article, you will discover a function I developed called my-tab-bar-vim-like-colors, designed to modify the appearance of the tab-bar in Emacs to mimic the color scheme of Vim.

This is how the tabs will appear if you execute the function below or add it to your init.el after the theme is loaded. More screenshots below.

The Emacs Lisp (Elisp) code below customizes the appearance of the tab bar and makes sure that its appearance remains consistent with the overall color scheme of the current theme.

;; Description: Making the Emacs Tab Bar Look Like Vim's Tab Bar
;; License: MIT
;; Author: James Cherti
;; URL: https://www.jamescherti.com/emacs-tab-bar-vim-style-colors/

(defun my-tab-bar-vim-name-format-function (tab i)
  "Add a space on the sides of every tab."
  (let ((current-p (eq (car tab) 'current-tab)))
    (propertize
     (concat " "
             (if tab-bar-tab-hints (format "%d " i) "")
             (alist-get 'name tab)
             (or (and tab-bar-close-button-show
                      (not (eq tab-bar-close-button-show
                               (if current-p 'non-selected 'selected)))
                      tab-bar-close-button)
                 "")
             " ")
     'face (funcall tab-bar-tab-face-function tab))))

(defun my-tab-bar-vim-like-colors ()
  "Apply Vim-like color themes to Emacs tab bars."
  (let* ((fallback-light "white")
         (fallback-dark "#333333")
         (bg-default (or (face-attribute 'default :background) fallback-light))
         (fg-default (or (face-attribute 'default :foreground) fallback-dark))
         (bg-modeline-inactive (or (face-attribute 'mode-line-inactive :background)
                                   fallback-dark))
         (fg-modeline-inactive (or (face-attribute 'mode-line-inactive :foreground)
                                   fallback-light))
         (bg-tab-inactive bg-modeline-inactive)
         (fg-tab-inactive fg-modeline-inactive)
         (fg-tab-active fg-default)
         (bg-tab-active bg-default))
    (setq tab-bar-tab-name-format-function #'my-tab-bar-vim-name-format-function)
    (setq tab-bar-format '(tab-bar-format-tabs tab-bar-separator))
    (setq tab-bar-separator "\u200B")  ;; Zero width space to fix color bleeding
    (setq tab-bar-tab-hints nil)  ;; Tab numbers of the left of the label
    (setq tab-bar-new-button-show nil)
    (setq tab-bar-close-button-show nil)
    (setq tab-bar-auto-width nil)
    (custom-set-faces
     ;; The tab bar's appearance
     `(tab-bar
       ((t (:background ,bg-tab-inactive
                        :foreground ,fg-tab-inactive
                        :box (:line-width 3 :color ,bg-tab-inactive :style nil)))))
     ;; Inactive tabs
     `(tab-bar-tab-inactive
       ((t (:background ,bg-tab-inactive
                        :foreground ,fg-tab-inactive
                        :box (:line-width 3 :color ,bg-tab-inactive :style nil)))))
     ;; Active tab
     `(tab-bar-tab
       ((t (:background ,bg-tab-active :foreground ,fg-tab-active
                        :box (:line-width 3 :color ,bg-tab-active :style nil))))))))

;; Customize the appearance of the tab bar
;; Make sure to load your theme using 'load-theme' before
;; calling 'my-tab-bar-vim-like-colors'.
(tab-bar-mode 1)
(my-tab-bar-vim-like-colors)
Code language: Lisp (lisp)

Here are a few more screenshots showing how the Elisp function above adapts Emacs tab-bar colors to any loaded theme:

The above theme is the Tomorrow Night Deepblue Emacs theme

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

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.

Emacs: Functions to evaluate Elisp Code, then display the result or copy it to the clipboard

Rate this post

The Elisp code below introduces three functions designed to evaluate Emacs Lisp code, either under the cursor or within a selected text region. These functions can return the evaluation result, copy it to the clipboard, or display it in the minibuffer. The functions allow obtaining immediate feedback from the code evaluation.

;; License: MIT
;; Author: James Cherti
;; URL: https://www.jamescherti.com/emacs-evaluate-elisp-display-result-copy-clipboard/
;;
;; Description: The following source code snippet introduces three functions
;; designed to evaluate Emacs Lisp code, either under the cursor or within a
;; selected text region. These functions can return the evaluation result, copy
;; it to the clipboard, or display it in the minibuffer. The functions are
;; especially useful for obtaining immediate feedback from the code evaluation.

(defun my-eval-and-get-result ()
  "Evaluate Elisp code under cursor or in the active region, then return the
result. If there is a syntax error or any other error during evaluation, an
error message is displayed."
  (interactive)
  (let* ((elisp-code (if (use-region-p)
                         (buffer-substring-no-properties (region-beginning)
                                                         (region-end))
                       (buffer-substring-no-properties (line-beginning-position)
                                                       (line-end-position)))))
    (condition-case err
        (let ((result (format "%S" (eval (read elisp-code)))))
          result)
      (error (message "Error: %s" (error-message-string err)))
      nil)))

(defun my-eval-and-copy-result-to-clipboard (&optional display-result)
  "Evaluate Elisp code under cursor or in the active region, copy the result to
the clipboard. With a prefix argument, also display the result using message."
  (interactive)
  (let ((result (my-eval-and-get-result)))
    (when result
      (kill-new result)
      (when display-result
        (message "%s" result)))))

(defun my-eval-and-copy-clipboard-and-print-result ()
  "Evaluate Elisp code under cursor or in the active region, copy the result to
  the clipboard, and display the result."
  (interactive)
  (my-eval-and-copy-result-to-clipboard t))

(defun my-eval-and-print ()
  "Evaluate Elisp code under cursor or in the active region, display the
result."
  (interactive)
  (let ((result (my-eval-and-get-result)))
    (when result
      (message "%s" result))))
Code language: Lisp (lisp)

Configure Emacs org-mode to automatically add the TODO keyword to new Org Mode headings

5/5

The built-in method used by Emacs Org mode to insert new headings does not automatically prepend the inserted heading with TODO, except when C-S-<return> is pressed. I prefer using C-<return> for all headings, whether they are to-do tasks or not, to maintain my workflow efficiency. This motivated me to write the function outlined in this article.

The function below can be triggered by pressing C-<return> to insert a new Org heading. If activated while on a TODO task, it will prefix the inserted heading with TODO, effectively creating a new to-do item. Additionally, for users of evil-mode, the function transitions into insert mode.

;; Function: (my-org-insert-heading-respect-content-and-prepend-todo)
;; Author: James Cherti
;; License: MIT
;; Key binding: Ctrl-Enter
;; URL: https://www.jamescherti.com/emacs-add-todo-keyword-to-new-org-mode-headings/
;;
;; Description: The function inserts a new heading at the current cursor
;; position, and prepends it with "TODO " if activated while on a "TODO" task,
;; thus creating a new to-do item. In addition to that, for those utilizing
;; evil-mode the function transitions the user into insert mode right after the
;; "TODO " insertion.

(defun my-org-insert-heading-respect-content-and-prepend-todo ()
    "Insert a new org-mode heading respecting content and prepend it with 'TODO'.
  Additionally, ensure entry into insert state when evil-mode is active."
    (interactive)
    (let ((entry-is-todo (org-entry-is-todo-p)))
      (when (bound-and-true-p evil-mode)
        (evil-insert-state))
      (org-insert-heading-respect-content)
      (when entry-is-todo
        (just-one-space)
        (insert "TODO")
        (just-one-space))))

;; Replace the key bindings for inserting headings in Org mode
(define-key org-mode-map (kbd "C-<return>")
            'my-org-insert-heading-respect-content-and-prepend-todo)
Code language: Lisp (lisp)

Emacs: Open a Vertico/Consult or Ivy/Counsel candidate in a new tab

Rate this post

In this article, you will find code snippets designed to simplify the task of opening Vertico/Consult/Embark or Ivy/Counsel candidates in a new Emacs tab using tab-bar.

The generic function that opens candidates in a new tab

This function below, tab-new-func-buffer-from-other-window, is designed to open the buffer generated by a specified function (func) in the other window and subsequently create a new tab. It also ensures that the state of the original window and tab is preserved.

;; License: MIT
;; Author: James Cherti
;; URL: https://www.jamescherti.com/emacs-open-vertico-consult-ivy-counsel-candidate-new-tab/

(defun tab-new-func-buffer-from-other-window (func)
  "Open the buffer created by the FUNC function in the other window in a new tab."
  (let* ((original-tab-index (1+ (tab-bar--current-tab-index)))
         (original-window (selected-window)))
    ;; Save the state of the other window
    (other-window 1)
    (let* ((other-window (selected-window))
           (other-window-buf (current-buffer))
           (other-window-point (point))
           (other-window-view (window-start)))
      ;; Move back to the original window
      (other-window -1)

      ;; Call the specified function (e.g., embark-dwim, ivy-call...)
      (funcall func)

      ;; Switch back to the other window
      (other-window 1)
      (unless (eq (selected-window) original-window)
        (let* ((preview-buf (current-buffer)))
          ;; Create a new tab and switch to the preview buffer
          (tab-bar-new-tab)
          (switch-to-buffer preview-buf)

          ;; Go back to the original tab
          (tab-bar-select-tab original-tab-index)

          ;; Restore the state of the other window
          (select-window other-window)
          (switch-to-buffer other-window-buf)
          (goto-char other-window-point)
          (set-window-start nil other-window-view)

          ;; Switch to the original window
          (select-window original-window))))))Code language: Lisp (lisp)

Option 1: Open Vertico, Consult, and Embark candidate in a new tab (embark-dwim)

For users of Vertico/Consult/Embark, the following function utilizes the generic function to open the default Embark action buffer in a new tab:

(defun tab-new-embark-dwim ()
  "Open embark-dwim in a new tab."
  (interactive)
  (tab-new-func-buffer-from-other-window #'embark-dwim))Code language: Lisp (lisp)

You can add the following key mapping to Vertico:

(keymap-set vertico-map "C-t" #'tab-new-embark-dwim)Code language: Lisp (lisp)

For Emacs Evil users, you can also add the following mappings:

(evil-define-key '(insert normal) vertico-map (kbd "C-t") 'tab-new-embark-dwim)
Code language: Lisp (lisp)

Option 2: Open Ivy, Counsel candidates in a new tab (ivy-call)

For users of Counsel/Ivy, the following function utilizes the generic function above to open the buffer created by ivy-call in a new tab:

(defun tab-new-ivy-call ()
  "Open ivy-call in a new tab."
  (interactive)
  (tab-new-func-buffer-from-other-window #'ivy-call))Code language: Lisp (lisp)

You can add the following key mapping to ivy-minibuffer-map:

(keymap-set ivy-minibuffer-map "C-t" #'tab-new-ivy-call)Code language: Lisp (lisp)

For Emacs Evil users, you can also add the following mappings:

(evil-define-key '(insert normal) ivy-minibuffer-map (kbd "C-t") 'tab-new-ivy-call)Code language: Lisp (lisp)

Preventing Emacs from entering the debugger when a specific error occurs

Rate this post

Emacs provides a built-in feature called debug-on-error, which can be activated with (setq debug-on-error t). The feature determines whether Emacs should enter the debugger when an error occurs. By default, Emacs enters the debugger for all errors, which can be helpful for diagnosing issues. However, there are cases where one may want to ignore specific errors that are not critical to their workflow.

Ignoring specific errors when (setq debug-on-error t) is activated

Open the Emacs configuration file, typically located at ~/.emacs or ~/.emacs.d/init.el. Then use the debug-ignored-errors variable to make Emacs ignore a specific error:

(add-to-list 'debug-ignored-errors 'specific-error-symbol)Code language: plaintext (plaintext)

Replace 'specific-error-symbol with the actual error that the specific function might raise.

Example

Suppose you encounter the search-failed error in Emacs (Evil package) when searching for a non-existent pattern:

Debugger entered--Lisp error: (search-failed "my-pattern")
  signal(search-failed ("my-pattern"))
  evil-ex-start-search(forward nil)
  evil-ex-search-forward(nil)
  funcall-interactively(evil-ex-search-forward nil)
  command-execute(evil-ex-search-forward)Code language: plaintext (plaintext)

To make Emacs ignore the search-failed error above, the following can be used:

(add-to-list 'debug-ignored-errors 'search-failed)Code language: plaintext (plaintext)

Emacs .dir-locals.el – Add project path to $PYTHONPATH (Python Development in Emacs)

Rate this post

In order to ensure that the processes executed by Emacs and its packages, such as Flycheck or Flymake, can access the Python modules of a project, it is essential to correctly configure the $PYTHONPATH environment variable.

This article provides a solution by introducing a .dir-locals.el file that adds the directory path of .dir-locals.el to the $PYTHONPATH environment variable.

The .dir-locals.el file should be placed in the root directory of a Python project.

File name: .dir-locals.el

;; -*- mode: emacs-lisp; -*-
;; File: .dir-locals.el
;; Description:
;; This file adds the path where `.dir-locals.el` is located to the
;; `$PYTHONPATH` environment variable to ensure that processes executed by
;; Emacs and its packages, such as Flycheck or Flymake, can access the Python
;; modules of a project.
;;
;; Author: James Cherti
;; License: MIT
;; URL: https://www.jamescherti.com/emacs-dir-locals-add-path-to-pythonpath/

((python-mode . ((eval . (progn
                           (let ((project_path
                                  (car (dir-locals-find-file
                                        (buffer-file-name))))
                                 (python_path_env (getenv "PYTHONPATH")))
                             (setq-local process-environment
                                         (cons
                                          (concat "PYTHONPATH="
                                                  project_path
                                                  (if python_path_env
                                                      (concat ":" python_path_env)
                                                    ""))
                                          process-environment))))))))
Code language: Lisp (lisp)

Vim to Emacs: Converting code snippets from Ultisnips to YASnippet format

Rate this post

Ultyas is a command-line tool, written by James Cherti, designed to simplify the process of converting code snippets from Ultisnips (Vim) to YASnippet (Emacs) format. With Ultyas, you can effortlessly migrate your code snippets to the YASnippet format, saving you valuable time and effort.

Installation

Ultyas can be installed locally to ~/.local/bin/ultyas using pip:

pip install --user ultyasCode language: plaintext (plaintext)

Usage

You can convert Ultisnips snippets to the Yasnippet format by using the following command:

~/.local/bin/ultyas ~/.vim/UltiSnips/python.snippets -o ~/.emacs.d/snippets/python-mode/Code language: plaintext (plaintext)

Available command line options

Here are the available command line options for Ultyas:

usage: ultyas <file.snippets> -o <yasnippet-major-mode-dir>

A command-line tool for converting code snippets from Ultisnips to YASnippet format.

positional arguments:
  ultisnips_file        The Ultisnips .snippets file (e.g.
                        '~/.vim/UltiSnips/python.snippets')

options:
  -h, --help            show this help message and exit
  -o YASNIPPET_DIR, --yasnippet-dir YASNIPPET_DIR
                        The YASnippet snippets major mode directory (e.g.
                        '~/.emacs.d/snippets/python-mode/')
  -i {auto,fixed,nothing}, --yas-indent-line {auto,fixed,nothing}
                        Add one of the following comments to the YASnippet snippets that
                        will be generated: "# expand-env: ((yas-indent-line 'fixed))" or "#
                        expand-env: ((yas-indent-line 'auto))". For more information on
                        'yas-indent-line', visit:
                        https://joaotavora.github.io/yasnippet/snippet-reference.html#yas-
                        indent-line
  -t CONVERT_TABS_TO, --convert-tabs-to CONVERT_TABS_TO
                        Convert the tabs that are in the generated snippets to the string
                        passed to this option (Default: The indentation marker '$>')
  -m, --mkdir           Ensure that the directory passed to the --yasnippet-dir flag exists
  -v, --verbose         Verbose mode
  -q, --quiet           Quiet modeCode language: plaintext (plaintext)

Links related to Ultyas