James Cherti is an experienced Infrastructure and Software engineer. He has written high-quality Python, Bash, C/C++, PHP, JavaScript source codes, administered Linux servers, and delivered several presentations in universities. He is also an active Open Source contributor.
The jamescherti/jc-dotfiles repository is a collection of configuration files. You can either install them directly or use them as inspiration your own dotfiles. These dotfiles provide configurations for various tools, enhancing productivity and usability. This article will explore the contents of the jc-dotfiles repository, highlight the main configurations, and guide you through the installation process.
In addition to the jc-dotfiles repository, the author also recommends the following repositories:
jamescherti/jc-firefox-settings: Provides the user.js file, which holds settings to customize the Firefox web browser to enhance the user experience and security.
jamescherti/jc-xfce-settings: A script that can customize the XFCE desktop environment programmatically, including window management, notifications, keyboard settings, and more, to enhance the user experience.
jamescherti/jc-gnome-settings: A script that can customize the GNOME desktop environment programmatically, including window management, notifications, and more.
bash-stdops: A collection of Bash helper shell scripts.
jc-gentoo-portage: Provides configuration files for customizing Gentoo Linux Portage, including package management, USE flags, and system-wide settings.
minimal-emacs.d: A lightweight, bloat-free Emacs base (init.el and early-init.el) that gives you full control over your configuration. It provides better defaults, an optimized startup, and a clean foundation for building your own vanilla Emacs setup.
jamescherti/jc-vimrc: The jc-vimrc project is a customizable Vim base that provides better Vim defaults, intended to serve as a solid foundation for a Vim configuration.
The jc-dotfiles Repository Overview
The repository includes configurations for several components of a UNIX/Linux system, ranging from shell settings to terminal multiplexer and input customizations. Here’s a breakdown of the key configurations included:
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.
The jamescherti/bash-stdops project is a collection of helpful Bash scripts that simplify various operations, including file searching, text replacement, and content modification.
I use these scripts in conjunction with text editors like Emacs and Vim to automate tasks, including managing Tmux sessions, replacing text across a Git repository, securely copying and pasting from the clipboard by prompting the user before executing commands in Tmux, fix permissions, among other operations.
The bash-stdops Script Collection Overview
Files, Paths, and Strings
walk: Recursively lists files from the specified directory.
walk-run: Executes a command on all files.
sre: Replaces occurrences of a specified string or regular expression pattern, with support for case-insensitive matching and regular expressions.
git-sre: Executes sre at the root of a Git repository to replace text within files.
path-tr, path-uppercase, path-lowercase: Processes a file path to convert the filename to uppercase or lowercase.
autoperm: Sets appropriate permissions for files or directories (e.g., 755 for directories).
path-is: Prints the path and exits with status 0 if the file is binary or text.
Git
git-dcommit: Automates the process of adding, reviewing, and committing changes in Git.
git-squash: Squashes new Git commits between the current branch and a specified branch.
SSH
esa: Manages the SSH agent, including starting, stopping, adding keys, and executing commands.
sshwait: Waits for an SSH server to become available on a specified host.
Tmux
tmux-cbpaste: Pastes clipboard content into the current tmux window with user confirmation.
tmux-run: Executes a command in a new tmux window. If inside tmux, it adds a new window to the current session; otherwise, it creates a window in the first available tmux session.
tmux-session: Attaches to an existing tmux session or creates a new one if it doesn’t exist.
X11/Wayland
xocrshot: Captures a screenshot, performs OCR on it, displays the extracted text, and copies it to the clipboard.
Misc
haide: Uses AIDE to monitor the file integrity of the user’s home directory.
cbcopy, cbpaste, cbwatch: Manages clipboard content by copying, pasting, or monitoring for changes.
outonerror: Redirects the command output to stderr only if the command fails.
over: Displays a notification once a command completes execution.
largs: Executes a command for each line of input from stdin, replacing {} with the line.
xargs-loop: Similar to xargs but allows placeholder substitution and processes each line individually.
Conclusion
The jamescherti/bash-stdops scripts provide a variety of tasks, including file manipulation, Git management, and SSH automation, improving efficiency and usability.
In this article, we’ll explore Git settings that enhance 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.
threads = 0: Configures Git to auto-detect the number of CPUs and set the number of threads accordingly.
windowMemory = 5g: Allocates up to 5GB as the amount of memory consumed by each thread in git-pack-objects for pack window memory when no limit is specified on the command line. This enhances Git’s efficiency for large repositories.
packSizeLimit = 2g: The packSizeLimit configuration in Git determines the maximum size of a packfile that Git will generate. A packfile is a file that contains a collection of objects, such as commits, trees, and blobs, in a compressed format.
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.
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..
Merge and pull settings
[merge]
ff = only
[pull]
ff = onlyCode language:plaintext(plaintext)
This setting enforce fast-forward merges, preventing unnecessary merge commits and maintaining a linear commit history.
Enables automatic resolution of previously encountered merge conflicts, reducing the effort required for repeated merges.
Push behavior
[push]
default = current
autoSetupRemote = true
Code language:plaintext(plaintext)
default = current This configuration 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.
Aliases
Here are aliases that abbreviate common Git commands:
[alias]
up = pull --rebase --autostash
s = show
cia = commit -a
rc = rebase --continue
amend = commit --amend
commend = commit --amend --no-edit
p = push
pf = push --force
a = add
aa = add -A
st = status -s
co = checkout
b = branch
rh = reset --hard HEAD
pl = pull
d = diff HEAD
dc = diff --cached
dt = difftool
dw = diff --color-words HEAD
sw = show --color-words
l = log
ls = log --pretty=format:"%C(yellow)%h\ %ad%Cred%d\ %Creset%s%Cblue\ [%cn]" --decorate --date=short
logs = log --show-signature --stat
lp = log -p
chp = cherry-pick
chpa = cherry-pick --abort
chpc = cherry-pick --continue
chpq = cherry-pick --quit
chps = cherry-pick --skipCode language:plaintext(plaintext)
Conclusion
This Git configuration enhances usability, improves performance, and simplifies repository management through thoughtful settings and powerful aliases.
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:
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.
Unhighlighting the symbol: If the symbol is already highlighted, the function calls hi-lock-unface-buffer with the appropriate regular expression, removing the highlighting.
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:
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.
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...":globalnil
(if highlight-codetags-local-mode
(font-lock-add-keywordsnil highlight-codetags-keywords)
(font-lock-remove-keywordsnil 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:
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.
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"}
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:
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!
Disable notifications: Notifications can constantly pull your attention. Notifications are a major distraction; disable them all!
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.
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.
Disconnect from the internet: If your work doesn’t require internet access, disconnect! This significantly reduces distractions.
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.
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.
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.
Focus your internet searches: Avoid straying into unrelated topics when using search engines. Postpone non-urgent research for later.
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!
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.)
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.
In the pursuit of an optimized Emacs setup, I focused on enhancing defaults and minimizing the number of installed packages to maintain simplicity and efficiency:
The initial step involved creating minimal-emacs.d, a project that has resonated with the Emacs community, providing a foundational template for many users’ init.el and early-init.el vanilla Emacs configuration.
Next, I experimented with hundreds of Emacs packages, carefully selecting the most valuable ones that, ideally, leverage built-in Emacs functions. (This is why I chose corfu over company, eglot over lsp-mode, and flymake over flycheck, etc.)
In this article, I will share the Emacs packages I use daily for software development and general text editing. Please share in the comments the Emacs packages you are using!
Where can I find the third-party packages listed below?
The following Emacs packages installed whether from MELPA or ELPA.
Category: Code completion
corfu: A completion framework that integrates with the built-in completion system in Emacs. For example, it can complete Python code when using the eglot package and a Python language server such as Pylsp.
prescient: Provides smart completion suggestions based on history and context. For example, it can enable fuzzy completion with Corfu/Cape or anticipate your next input based on previous selections.
cape: A completion-at-point extension for various completion frameworks in Emacs, enhancing Corfu.
nerd-icons-corfu: Integrates Nerd Icons with the Corfu completion framework, enhancing the appearance of completion candidates.
Category: Software development (General)
eglot (built-in): An LSP client that provides features like code completion, diagnostics, formatting, and more, powered by language servers. For example, it can be used to add Python code completion using the language server Pylsp. There are many language servers available for many other programming languages.
outline-indent: Enables code folding based on indentation levels. This package is useful for editing indentation-based text files, such as YAML, Python, and other indented text files.
treesit (built-in): This package provides a way to work with tree-sitter, a syntax code parser that performs syntax highlighting, code navigation, and structural editing across various programming languages.
reformatter: Define commands which run reformatters on the current Emacs buffer. (Good alternative to this package: apheleia)
flymake (built-in): An on-the-fly syntax checking system that works well with eglot.
indent-bars: Provides indentation guide-bars.
paren (built-in): Matching parenthesis highlighting. (Modes: show-paren-mode or show-paren-local-mode).
ws-butler: Automatically trim extraneous white-space only in edited lines.
yasnippet: A template system for Emacs that allows for easy insertion of code snippets, improving coding efficiency. (The author is also using ultyas to share the same code snippets in Emacs and Vim)
dtrt-indent: Automatically adjusts indentation based on the surrounding context in code files, improving code readability.
Category: Better minibuffer
consult: Provides intelligent search and navigation commands, powered by the Emacs completion function, completing-read.
consult-dir: insert paths into minibuffer prompts in Emacs. Similar to fasd.
vertico: minimalistic vertical completion UI. (EDIT: There is also built-in alternative to vertico: fido-vertical-mode, but the author prefers vertico because it provides more features.)
marginalia: Enhances the display of completion candidates in the minibuffer.
embark: Enhances minibuffer completion and interaction with various Emacs commands and actions.
Category: Session management / persist and restore
easysession: A lightweight Emacs session manager that can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, the tab-bar, and the Emacs frames (with or without the Emacs frames size, width, and height).
saveplace (built-in): Persist and restore your current cursor position.
savehist (built-in): Persist and restore your Emacs command history.
Category: Themes
ef-themes: A collection of light and dark themes for GNU Emacs whose goal is to provide colorful themes.
modus-themes: Highly accessible themes for GNU Emacs, conforming with the highest standard for color contrast between background and foreground values (WCAG AAA).
doom-themes: An megapack of popular themes, including aesthetic extensions for popular packages (e.g., Tomorrow Night/Day, Solarized, Gruvbox…).
evil: An extensible vi layer for Emacs, providing a modal editing experience similar to Vim.
evil-collection: A collection of Emacs packages that integrate with Evil mode to provide consistent keybindings across multiple modes.
evil-snipe: Provides enhanced search and jump functionality for Evil mode.
evil-surround: Enhances text object handling in Evil mode, allowing for easier manipulation of surrounding characters.
vdiff: Provides a visual interface for comparing two versions of a file that is similar to the Vim editor.
vim-tab-bar: Provides a tab-bar interface reminiscent of Vim.
Category: Terminal Emulators
eat: A terminal emulator, written in Elisp.
vterm: A terminal emulator for Emacs, written in C.
Category: Undo/Redo
undo-fu: An advanced undo/redo system that enhances the default undo behavior in Emacs.
undo-fu-session: Integrates with undo-fu to provide session management for undo history.
Category: Elisp
easy-escape: Improve readability of escape characters.
aggressive-indent: Automatically keeps your code indented as you type. The author mainly uses this package with Elisp.
package-lint: Lints Emacs Lisp packages to ensure compliance with best practices and package standards.
compile-angel: 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.
helpful: An improved help system for Emacs.
Paredit: A minor mode that enforces balanced parentheses while editing Lisp code. (In addition to Paredit, the author uses enhanced-evil-paredit.)
Category: File Manager
dired (built-in): File manager. (EDIT: The author is also using the built-in modes dired-hide-details-mode and dired-omit-mode.)
nerd-icons-dired: Enhances Dired mode with icons from Nerd Fonts, improving file browsing.
Category: Other packages
buffer-terminator: A package that automatically and safely 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.
expand-region: Expands the selected region in code, making it easier to select logical blocks of code or text.
inhibit-mouse: Disables mouse support within Emacs, encouraging keyboard-centric navigation and editing. This can be beneficial for some users who prefer a more traditional text editor experience.
project.el (built-in): A package for managing and navigating projects, providing utilities for project-based operations like searching, switching, and file management within defined project directories.
visual-fill-column: A package that allows wrapping lines at a specified fill-column width.
quick-sdcv: Bring the Stardict’s dictionary functionality directly into your Emacs workflow. This will turn Emacs into a dictionary.
fasd: Offers fast access to files and directories based on your history and usage patterns, optimizing file navigation.
dir-config: Automatically find and evaluate .dir-config.el Elisp files to configure directory-specific settings.
exec-path-from-shell: Ensures Emacs uses the same environment variables as your shell.
wgrep: Allows for in-buffer editing of grep results, improving the usability of search results. (It can be used to modify the occurrences returned by the Embark package embark-export function.)
flyspell-mode (built-in): An interface for spell-checking text using external programs like ispell, aspell, or hunspell for checking and correcting spelling in buffers. (EDIT: The author replaced Jinx with Flyspell because Jinx was slowing down Emacs.)
which-key (built-in): Displays available keybindings in a popup, helping users learn and remember key combinations in Emacs.
Category: Miscellaneous file types
diff-hl: Displays git diff information in the fringe of your Emacs window. (Alternative to diff-hl: git-gutter.)
golden-ratio: Automatic resizing of Emacs windows to the golden ratio.
diminish: This package implements hiding or abbreviation of the mode line displays (lighters) of minor-modes.
org (built-in): A powerful mode for organizing notes, tasks, and project planning within Emacs.
org-appear: Improves the visibility of Org mode elements in the buffer by automatically toggling visibility based on context.
org-bullets: Replace org-mode leading stars with UTF-8 bullets(EDIT: The author is now using the org-ibullets fork)
toc-org: Automatically generates a table of contents for Org mode documents.
markdown-mode: Provides major mode support for editing Markdown files.
markdown-toc: Automatically generates and manages a table of contents for Markdown files, making navigation easier.
lua-mode: Provides major mode support for editing Lua files.
php-mode: Provides major mode support for editing PHP files. (EDIT: The author is now using the built-in php-ts-mode.)
dockerfile-mode: Provides syntax highlighting and editing support for Dockerfile files.(EDIT: The author is now using the built-in dockerfile-ts-mode.)
yaml-mode: Provides major mode support for editing YAML files, complete with syntax highlighting and formatting commands.(EDIT: The author is now using the built-in yaml-ts-mode.)
ansible-doc: Provides documentation lookup for Ansible modules.
flymake-ansible-lint: Provides on-the-fly syntax checking for Ansible playbooks and roles, ensuring code quality.
flymake-bashate: Integrates bashate for syntax checking of Bash scripts in real-time within Emacs. (Emacs also offers a built-in Flymake backend for ShellCheck.)
By focusing on these packages, the Emacs configuration was simplified while still maintaining a highly functional setup.
Running Large Language Models on your machine can enhance your projects, but the setup is often complex. Ollama simplifies this by packaging everything needed to run an Large Language Models. Here’s a concise guide on using Ollama to run LLMs locally.
RAM: A minimum of 16GB is recommended for a decent experience when running models with 7 billion parameters.
Disk Space: A practical minimum of 40GB of disk space is advisable.
GPU: While a GPU is not mandatory, it is recommended for enhanced performance in model inference. Refer to the list of GPUs that are compatible with Ollama. For running quantized models, GPUs that support 4-bit quantized formats can handle large models more efficiently, with VRAM requirements as follows: ~4 GB VRAM for 7B model, ~8 GB VRAM for 13B model, ~16 GB VRAM 30B model, and ~32 GB VRAM for 65B model.
For NVIDIA GPUs: Ollama requires CUDA, a parallel computing platform and API developed by NVIDIA. You can find the instructions to install CUDA on Debian here. Similar instructions can be found in your Linux distribution’s wiki.
The command above downloads the Gemma2 model by Google DeepMind. You can find other models by visiting the Ollama Library.
(Downloading “gemma2:2b” actually downloads “gemma2:2b-instruct-q4_0”, indicating that it retrieves a quantized version of the 2 billion parameter model specifically optimized for instruction-following tasks like chat-bots. This quantization process reduces the model’s precision from the original floating-point representation to a more compact format, such as float32, thereby significantly lowering memory usage and enhancing inference speed. However, this quantization can lead to a slight decrease in accuracy compared to the full-precision floating-point model.)
Step 3: Chat with the model
Run the large language model:
ollama run gemma2:2bCode language:plaintext(plaintext)
This launches an interactive REPL where you can interact with the model.
Step 4: Install open-webui (web interface)
Open-webui offers a user-friendly interface for interacting with large language models downloaded via Ollama. It enables users to run and customize models without requiring extensive programming knowledge.
It can be installed using pip within a Python virtual environment:
You will also have to execute Ollama as a server simultaneously with open-webui:
ollama serve
Conclusion
With Ollama, you can quickly run Large Language Models (LLMs) locally and integrate them into your projects. Additionally, open-webui provides a user-friendly interface for interacting with these models, making it easier to customize and deploy them without extensive programming knowledge.
Links
Ollama Library: A collection of language models available for download through Ollama.
When working with markdown files in Emacs (e.g., README.md), users may need to manually update the table of contents. Automating this process saves time and ensures that the table of contents remains consistent with the document structure. This article presents an Emacs Lisp code snippet that uses:
The markdown-toc package to automatically generate or refresh a table of contents,
A custom function (my-markdown-toc-gen-if-present) that runs before markdown files are saved. It performs the following actions:
Updates the table of contents if one is already present.
Ensures that both the window start and cursor position remain unchanged, addressing a common issue with the markdown-toc package, which can disrupt the editing flow by moving the cursor and/or changing the window start. This behavior can be frustrating, as it interrupts the user’s focus and requires them to navigate back to their original position.
The code snippet that updates the table of contents and ensures that the cursor and window start remain unchanged
The following code snippet updates the table of contents while ensuring that the cursor and window start remain unchanged:
(The table of contents will be updated only if it is already present, so it is necessary to generate it at least once using the (markdown-toc-generate-toc) function. Additionally, ensure that the markdown-mode Emacs package is installed.)
;; Author: James Cherti;; URL: https://www.jamescherti.com/emacs-markdown-table-of-contents-update-before-save/;; License: MIT;; Configure the markdown-toc package
(use-package markdown-toc
:ensuret:defert:commands (markdown-toc-generate-toc
markdown-toc-generate-or-refresh-toc
markdown-toc-delete-toc
markdown-toc--toc-already-present-p))
;; The following functions and hooks guarantee that any existing table of;; contents remains current whenever changes are made to the markdown file,;; while also ensuring that both the window start and cursor position remain;; unchanged.
(defun my-markdown-toc-gen-if-present ()
(when (markdown-toc--toc-already-present-p)
(let* ((window (selected-window))
(buffer-in-selected-window (eq (window-buffer window)
(current-buffer)))
(window-hscrollnil)
(lines-beforenil))
(when buffer-in-selected-window
(setq window-hscroll (window-hscroll))
(setq lines-before (count-screen-lines
(save-excursion (goto-char (window-start))
(vertical-motion0)
(point))
(save-excursion (vertical-motion0)
(point))
nil
window)))
(unwind-protect
(markdown-toc-generate-toc)
(when buffer-in-selected-window
(set-window-start window
(save-excursion
(vertical-motion0)
(line-move-visual (*-1 lines-before))
(vertical-motion0)
(point)))
(set-window-hscroll window window-hscroll))))))
(defun my-setup-markdown-toc ()
"Setup the markdown-toc package."
(add-hook 'before-save-hook #'my-markdown-toc-gen-if-present -100t))
(add-hook 'markdown-mode-hook #'my-setup-markdown-toc)
(add-hook 'markdown-ts-mode-hook #'my-setup-markdown-toc)
(add-hook 'gfm-mode-hook #'my-setup-markdown-toc)Code language:Lisp(lisp)
The above code snippet leverages the markdown-toc Emacs package to automate the generation of a table of contents within markdown documents. This package includes functions such as markdown-toc-generate-toc and markdown-toc-generate-or-refresh-toc, which facilitate the creation and updating of the table of contents as needed.
I implemented the my-setup-markdown-toc function to establish a hook that triggers my-markdown-toc-gen-if-present each time a markdown buffer is saved. This function guarantees that any existing table of contents remains current whenever changes are made to the markdown file, while also ensuring that both the window start and cursor position remain unchanged.
Requirement: Markdown Mode Setup
The table of contents update code snippet above will only function correctly if the markdown-mode package is installed:
The my-markdown-toc-gen-if-present function automates the generation of a table of contents, ensuring that markdown documents consistently remain up-to-date with minimal effort.
As codebases grow, maintaining proper indentation becomes increasingly difficult, especially in languages like Python or YAML, where indentation is not just a matter of style but an important part of the syntax. When working with large code blocks or deeply nested structures, it’s easy to lose track of the correct indentation level, leading to errors and decreased readability. In this post, we’ll explore Emacs packages and an Elisp code snippet that can help manage indentation in these indentation-sensitive languages.
Code snippet: Indenting new lines based on previous non-blank line
The following code snippet configures Emacs to indent based on the indentation of the previous non-blank line:
;; This ensures that pressing Enter will insert a new line and indent it.
(global-set-key (kbd"RET") #'newline-and-indent)
;; Indentation based on the indentation of the previous non-blank line.
(setq-default indent-line-function #'indent-relative-first-indent-point)
;; In modes such as `text-mode', pressing Enter multiple times removes;; the indentation. The following fixes the issue and ensures that text;; is properly indented using `indent-relative' or;; `indent-relative-first-indent-point'.
(setq-default indent-line-ignored-functions '())Code language:Lisp(lisp)
Emacs package: outline-indent.el (Code folding)
The outline-indent.el Emacs package provides a minor mode that enables code folding based on indentation levels for various indentation-based text files, such as YAML, Python, and any other indented text files.
To install the outline-indent from MELPA, add the following code to your Emacs init file:
In addition to code folding, outline-indent allows:
Moving indented blocks up and down.
Indenting/unindenting to adjust indentation levels.
Inserting a new line with the same indentation level as the current line.
Move backward/forward to the indentation level of the current line.
Customizing the ellipsis to replace the default “…” with something more visually appealing, such as “▼”.
Selecting the indented block with.
And other features.
Emacs Package: dtrt-indent (Guessing the original indentation offset)
The dtrt-indent provides an Emacs minor mode that detects the original indentation offset used in source code files and automatically adjusts Emacs settings accordingly, making it easier to edit files created with different indentation styles.
The indent-bars Emacs package, written by JD Smith, enhances code readability by providing visual indentation guides, optimized for speed and customization. It supports both space and tab-based indentation and offers optional tree-sitter integration, which includes features like scope focus. The appearance of the guide bars is highly customizable, allowing you to adjust their color, blending, width, position, and even apply a zigzag pattern. Depth-based coloring with a customizable cyclical palette adds clarity to nested structures. The package also features fast current-depth highlighting, configurable bar changes, and the ability to display bars on blank lines. Additionally, it maintains consistent bar depth within multi-line strings and lists, and it works seamlessly in terminal environments using a vertical bar character. (Send your customizations to JD Smith, the author of indent-bars. He mentioned on Reddit that, “If you or others have customized the bar style settings, I’d be happy to add them to the examples page”.)
The indent-bars package isn’t available in any package database yet, but you can install it using straight.
The indent-bars fancy guide bars when indent-bars-prefer-character is set to nil:
If you are using Linux or macOS (not PGTK on Linux, NS on macOS, or Windows), try setting the indent-bars-prefer-character variable to nil to make indent-bars display fancy guide bars using the :stipple face attribute (see indent-bars compatibility). On macOS, it only works if you are using the non-NS version of Emacs, known as emacs-mac-app, which can be installed from MacPorts using the emacs-mac-app or emacs-mac-app-devel package.
You can have Emacs automatically set the indent-bars-prefer-character variable to nil when the window system is PGTK or NS, where the stipple attribute is not supported and using the character is preferred, with the following Elisp code:
;; Make the indent-bars package decide when to use the stipple attribute
(setq indent-bars-prefer-character
(if (memq initial-window-system '(pgtk ns)) t))Code language:Lisp(lisp)
Code snippet: Inserting a new line before the next line that has the same or less indentation level
(If you’re using outline-indent.el, there’s no need for the Elisp code below. You can simply use the (outline-indent-insert-heading) function.)
You can use the following function to inserts a new line just before the next line that has the same or less indentation level:
(defun my-insert-line-before-same-indentation ()
"Insert a new line with the same indentation level as the current line.
The line is inserted just before the next line that shares the same or less
indentation level. This function finds the nearest non-empty line with the same
or less indentation as the current line and inserts a new line before it.
This function is part of the outline-indent (MELPA) Emacs package.
It was extracted from the function (outline-indent-insert-heading)
written by James Cherti and distributed under the GPL 3.0 or later license."
(interactive)
(let ((initial-indentationnil)
(found-pointnil))
(save-excursion
(beginning-of-visual-line)
(setq initial-indentation (current-indentation))
(while (and (not found-point) (not (eobp)))
(forward-line1)
(if (and (>= initial-indentation (current-indentation))
(not (looking-at-p"^[ \t]*$")))
(setq found-point (point))))
(when (and (not found-point) (eobp))
(setq found-point (point))))
(when found-point
(goto-char found-point)
(forward-line-1)
(end-of-line)
(newline)
(indent-to initial-indentation))))Code language:Lisp(lisp)
If you are an Emacs Evil mode user, here’s an additional function that switches to insert mode after inserting a new line with matching indentation:
(with-eval-after-load"evil"
(defun my-evil-insert-line-before-same-indentation ()
"Insert a new line with the same indentation level as the current line."
(interactive)
(my-insert-line-before-same-indentation)
(evil-insert-state))
;; Pressing Ctrl-Enter calls my-evil-insert-line-before-same-indentation
(evil-define-key '(normal insert) 'global (kbd"C-<return>")
#'my-evil-insert-line-before-same-indentation))Code language:Lisp(lisp)
Built-in feature: indent-rigidly
The indent-rigidly built-in Emacs feature (C-x TAB) allows for manual adjustment of indentation by shifting a block of text left or right. It makes it easy to adjust indentation levels interactively. This can be especially useful for fine-tuning indentation in code or text where automatic tools might not always get it right. (By the way, moving the entire block with indent-rigidly is similar to the promote/demote functions in the outline-indent.el package.)
block-nav: Allows navigation through code based on indentation.
aggressive-indent: Automatically maintains proper indentation throughout your code. Works better with languages such as Elisp, C/C++, Javascript, CSS…
Combobulate: Combobulate enhances structured editing and movement for various programming languages by leveraging Emacs 29’s tree-sitter library. Combobulate uses tree-sitter’s concrete syntax tree for precise code analysis, resulting in more accurate movement and editing.
expand-region: Expand the selected region by semantic units by repeatedly pressing the key until the desired area is highlighted.
outline-indent.el alternative:
origami.el: No longer maintained, slow, and have known to have bugs that affect its reliability and performance.
yafolding.el: No longer maintained and slow. It does not work out of the box with Evil mode and evil-collection.
Indent-bars alternatives (they work, are no longer maintained):
indent-guide: An older indent-bars alternative that uses overlays with | characters. There are some performance concerns reported, and it is incompatible with company and other similar in-buffer modes. (indent-bars is better.)
highlight-indentation-mode: An indent-bars alternative that uses overlays to display indentation guides and includes a mode for showing the current indentation level. It offers partial support for guides on blank lines. (indent-bars is better.)
highlight-indent-guides: An indent-bars alternative that offers a highly customizable indentation highlighting, featuring options for color, style, and current depth indication. (indent-bars is better.)
hl-indent-scope: An indent-bars alternative that highlights indentation based on language scope, requiring specific support for each language, and uses overlays to display indentation guides. (indent-bars is better.)
visual-indentation-mode: An indent-bars alternative that uses full character-based alternating color indentation guides. The package is now archived. (indent-bars is better.)
Conclusion
This article has highlighted various Emacs packages and Elisp code snippets to enhance indentation management in indentation sensitive programming languages.
It took me a while to find the packages mentioned in this article, as I had to test many of them. Unfortunately, many popular packages are unmaintained, slow, or have unresolved bugs. I’ve only shared the packages that work flawlessly. For instance, while the Origami package is widely used, it’s slow, buggy, and no longer maintained. The outline-indent.el package is a more modern alternative for folding indented text, aligning with the trend of utilizing built-in Emacs features (like Corfu, Cape, Vertico, Consult…). Similarly, indent-bars provides a more refined experience than older packages like highlight-indent-guides and highlight-indentation.
If you have any other packages or Elisp code you rely on for managing indentation in sensitive languages, I’d love to hear about them.
The dir-config.el Emacs package automatically loads and evaluates Elisp code from a .dir-config.el file found in the buffer’s current directory or its closest parent directory. This facilitates adjusting settings or executing functions specific to the directory structure of each buffer.
For instance, you can use the dir-config package to:
Configure project-specific settings: Automatically set up environment variables, keybindings, or modes unique to each project.
Apply directory-specific customizations: Set specific behaviors or preferences for files in different directories, such as enabling or disabling certain minor modes based on security considerations. For example, you might disable linters that execute code in directories where you handle untrusted code.
Manage multiple environments: Switch between different coding environments or workflows by loading environment-specific configurations.
Optimizing Emacs for speed and efficiency involves fine-tuning its startup process, managing essential settings, and handling package installations, etc. The minimal-emacs.d repository hosts a minimal Emacs configuration with early-init.el and init.el files designed to serve as a base for your vanilla Emacs configuration, offering a robust foundation for a better vanilla Emacs experience.
Installation
Execute the following command to clone this repository into ~/.emacs.d:
Increases the amount read from processes in a single chunk.
Reduces rendering workload by not rendering cursors or regions in non-focused windows.
Disables warnings from the legacy advice API and suppresses warnings about aliased variables.
Avoids unnecessary UI updates.
Disables font compacting to avoid high memory usage.
Customizes file-name-handler-alist for improved startup time and package load time.
Prefers loading newer compiled files.
Reduces startup screen and message noise, including removing the “For information about GNU Emacs…” message.
Configures Emacs to start with a scratch buffer in fundamental-mode to shave seconds off startup time.
Delays garbage collection during startup to improve performance and resets it to a more reasonable value once Emacs has started.
Native Compilation and Byte Compilation:
Configures native compilation and byte compilation settings
Suppresses compiler warnings and errors during native compilation.
UI Element Management:
Disables the startup screen and messages, including menu bar, tool bar, and scroll bars.
Configures Emacs to avoid resizing frames and minimizes unnecessary UI updates.
Package Management:
Configures package archives and priorities for MELPA, ELPA, and other repositories.
Customizable Initialization Files:
Supports additional configuration files (pre-init.el, post-init.el, pre-early-init.el, and post-early-init.el) to allow further customization at different stages of the startup process.
File Management:
Manages auto-save and backup files, including backup options and version control settings.
User Experience Enhancements:
Configures user interface settings such as cursor behavior, scrolling, and response to prompts.
Disables beeping and blinking to avoid distractions.
Buffer and Window Configuration:
Sets default fringe widths and buffer boundaries.
Configures smooth scrolling and cursor behavior for a more seamless editing experience.
Update
To keep your Emacs configuration up to date, you can pull the latest changes from the repository. Run the following command in your terminal:
git -C ~/.emacs.d pull
Customizations
The init.el and early-init.el files should never be modified directly because they are intended to be managed by Git during an update.
The minimal-emacs.d init files support additional customization files that are loaded at different stages of the Emacs startup process. These files allow you to further customize the initialization sequence:
~/.emacs.d/pre-init.el: This file is loaded before init.el. Use it to set up variables or configurations that need to be available early in the initialization process but after early-init.el.
~/.emacs.d/post-init.el: This file is loaded after init.el. It is useful for additional configurations or package setups that depend on the configurations in init.el.
~/.emacs.d/pre-early-init.el: This file is loaded before early-init.el. Use it for configurations that need to be set even earlier in the startup sequence, typically affecting the initial setup of the Emacs environment.
~/.emacs.d/post-early-init.el: This file is loaded after early-init.el but before init.el. It is useful for setting up configurations that depend on the early initialization but need to be set before the main initialization begins.