diff --git a/.gitignore b/.gitignore index cd24c4b..d8c2b3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,58 +1,58 @@ # Gitignore file # Remove backup files + +!/tree-sitter/bin/ +# Emacs tmp files & Misc +# Emacs packages *# *. *.elc *.eln *~ -.#* -.lsp-session* . - -# Emacs packages -var/ - -# Emacs tmp files & Misc -/eln-cache -/bbdb -/.cache/ -/emms -/recentf -/.mc-lists.el +.#* +.dap-breakpoints +.lsp-session* +.org-id-locations /.DS_Store -/network-security.data +/.cache/ /.emacs.desktop /.emacs.desktop.lock +/.mc-lists.el +/.python-environments/ /.watsonresults /ac-comphist.dat /auto-save-list +/bbdb +/bookmarks +/eln-cache +/elpa +/emms +/eshell /eshell/history /eshell/lastdir -/newsticker/feeds/ -/snippets/ -/tramp -/transient/ -/url/ -/.python-environments/ -/ido.last -/places -/secrets.el /games/ -/bookmarks +/ido.last +/image-dired +/network-security.data +/newsticker/feeds/ +/places /projectile-bookmarks.eld /projectile.cache /projects +/recentf +/secrets.el +/snippets/ +/tramp /transient -/image-dired -.dap-breakpoints -.org-id-locations -p/.extension/ -/eshell -/elpa +/transient/ /tree-sitter/ /tree-sitter/bin/* -!/tree-sitter/bin/ +/url/ +custom-vars.el gnus.el history +ielm-history.eld +p/.extension/ savehist -ielm-history.eld \ No newline at end of file +var/ \ No newline at end of file diff --git a/README.org b/README.org new file mode 100644 index 0000000..733768f --- /dev/null +++ b/README.org @@ -0,0 +1,137 @@ +* Emacs-Kick(starter) for Vim/Neovim Users + +Welcome to **Emacs-Kick**, a feature-rich Emacs configuration designed +for users familiar with **Vim**, **Neovim**, and **Vi**. With this +setup, you don't need to leave behind your favorite terminal or tools +like **yazi**, **starship**, **lazygit**, and **lazydocker** just to give +Emacs a try. + +Use Emacs the same way you'd use **Neovim**, seamlessly integrating it +into your workflow inside terminal multiplexers like **tmux** or +**Zellij**, while also enjoying modern features such as **treesitter** +and **LSP**—no hassle. + +TODO: [Insert nice screenshot here] + +**Emacs-Kick** is not a distribution, but a starting point for your +own configuration. It’s designed to be accessible to Vim/Neovim users +without needing to adopt all of Emacs' ecosystem. You can still enjoy +the power of Emacs without having to learn every Emacs-specific +workflow. + +**Minimum Requirements**: +- Emacs version **29+** + - You can verify your version by running: + + #+BEGIN_SRC bash + emacs --version + #+END_SRC + +**Installation Instructions**: + +1. **Clone the repository**: + + **Note**: If you already have an existing Emacs configuration in + `~/.emacs.d`, please back it up before proceeding. You can do this + by renaming the directory: + + #+BEGIN_SRC bash + mv ~/.emacs.d ~/.emacs.d.backup + #+END_SRC + + After backing up, clone the repository: + + #+BEGIN_SRC bash + git clone https://github.com/LionyxML/emacs-kick.git ~/.emacs.d + #+END_SRC + + +2. **Run the setup**: + + After cloning, install the configuration by running: + + #+BEGIN_SRC bash + emacs -nw --eval="(ek/first-install)" + #+END_SRC + + Alternatively, you can run the provided script `ek-reinstall.sh` + from inside `~/.emacs.d/`, which will achieve the same result: + + #+BEGIN_SRC bash + cd ~/.emacs.d/ && ./ek-reinstall.sh + #+END_SRC + + Both methods will install all necessary packages and apply the + configuration. + + +3. **Set terminal mode by default**: + + **Note on Emacs modes**: Emacs automatically adapts to either + graphical or terminal mode depending on the environment. But if you're + in a graphical session and prefer terminal mode, just use: + + #+BEGIN_SRC bash + emacs -nw + #+END_SRC + + To ensure Emacs always opens in terminal mode, add the following to + your `.bashrc` or `.zshrc`: + + #+BEGIN_SRC bash + alias emacs='emacs -nw' + #+END_SRC + + Then, reload your shell configuration with: + + #+BEGIN_SRC bash + source ~/.bashrc # for bash + source ~/.zshrc # for zsh + #+END_SRC + +4. **Start Emacs**: + + Once set up, start Emacs with: + + #+BEGIN_SRC bash + emacs + #+END_SRC + +**Usage Tips**: +- **Leader Key**: The leader key is set to `SPC` (spacebar), similar + to Vim. +- **Help Commands**: + - `SPC h i` opens the Emacs info documentation (`M-x info`). + - `SPC h v` allows you to explore available variables. + - `SPC h f` lets you explore functions. + - `SPC h k` displays keybindings. + +**Troubleshooting**: +- If you encounter any issues during installation, check the + `*Messages*` buffer for more information. You can switch between + buffers with `SPC SPC`, and navigate options using `C-p` and `C-n`. + +--- + +This configuration is tailored for Vim/Neovim users looking to explore +Emacs while keeping their existing workflow intact. Feel free to +explore and customize it further as you go. + +Enjoy your Emacs experience! + + +* Contributing + +This package is intentionally designed with a specific vision in mind, +reflecting my own opinions and preferences. While contributions are +welcome, please understand that this configuration is quite +opinionated. + +If you have suggestions or requests, they will be considered +carefully, but I cannot make any promises regarding implementation or +acceptance. Your input is valuable, and I appreciate any help or +feedback to improve the project. + +To contribute, feel free to open an issue or submit a pull +request. Let's make this configuration even better together! + diff --git a/custom-vars.el b/custom-vars.el index 616476d..1618e2c 100644 --- a/custom-vars.el +++ b/custom-vars.el @@ -5,7 +5,8 @@ ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(custom-safe-themes - '("691d671429fa6c6d73098fc6ff05d4a14a323ea0a18787daeb93fde0e48ab18b" + '("dfab4d4e2904967f208647d14b15015a613c4ab904db491116a7c0968e44a115" + "691d671429fa6c6d73098fc6ff05d4a14a323ea0a18787daeb93fde0e48ab18b" "48042425e84cd92184837e01d0b4fe9f912d875c43021c3bcb7eeb51f1be5710" default)) '(package-selected-packages nil)) @@ -14,4 +15,6 @@ ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. - ) + '(diff-hl-change ((t (:background nil :foreground "#89b4fa")))) + '(diff-hl-delete ((t (:background nil :foreground "#f38ba8")))) + '(diff-hl-insert ((t (:background nil :foreground "#a6e3a1"))))) diff --git a/ek-reinstall.sh b/ek-reinstall.sh index 1d5c61e..9cb6937 100755 --- a/ek-reinstall.sh +++ b/ek-reinstall.sh @@ -1,7 +1,7 @@ #!/bin/sh clear -echo ">>> (re)Istalling Emacs Kicks ..." +echo ">>> (re)Istalling Emacs Kick ..." sleep 2 echo ">>> Deleting packages, grammars and native compilation cache ..." diff --git a/init.el b/init.el index d1c45d7..0e76cba 100644 --- a/init.el +++ b/init.el @@ -1,13 +1,17 @@ -;;; init.el --- Emacs-Kicks --- A feature rich Emacs config for (neo)vi(m)mers -*- lexical-binding: t; -*- +;;; init.el --- Emacs-Kick --- A feature rich Emacs config for (neo)vi(m)mers -*- lexical-binding: t; -*- +;; Author: Rahul Martim Juliato +;; Version: 0.1.0-rc0 +;; License: GPL-2.0-or-later ;;; Commentary: -;; - [ ] Ask for permission on official kickstarter.nvim -;; - [ ] Intro doc -;; - [ ] Assumption that user already knows vim -;; - [ ] Document init.el +;; - [X] Ask for permission on official kickstarter.nvim +;; - [X] Intro doc +;; - [X] Assumption that user already knows vim +;; - [X] Document init.el ;; - [ ] Create README.org -;; - [ ] Create optional nerd fonts option -;; - [ ] Decide either nerdtree or treemacs or nothing (just dired)... +;; - [ ] Nice gif/pic +;; - [X] Create optional nerd fonts option +;; - [X] Decide either nerdtree or treemacs or nothing (just dired)... ;; ===================================================================== @@ -17,7 +21,7 @@ ;; ======== .----------------------. | === | ======== ;; ======== |.-""""""""""""""""""-.| |-----| ======== ;; ======== || || | === | ======== -;; ======== || EMACS KICK || |-----| ======== +;; ======== || EMACS-KICK || |-----| ======== ;; ======== || || | === | ======== ;; ======== || || |-----| ======== ;; ======== ||M-x || |:::::| ======== @@ -30,181 +34,245 @@ ;; ===================================================================== ;; ===================================================================== -;; What is Emacs Kick? +;; What is Emacs-Kick? ;; -;; Emacs Kick is *not* a distribution. +;; Emacs-Kick is `not' a distribution. ;; -;; Emacs Kick is a starting point for your own configuration. -;; The goal is that you can read every line of code, top-to-bottom, understand -;; what your configuration is doing, and modify it to suit your needs. +;; Emacs-Kick is a starting point for your own configuration. The goal +;; is that you can read every line of code, top-to-bottom, understand +;; what your configuration is doing, and modify it to suit your needs. ;; -;; Once you've done that, you can start exploring, configuring and tinkering to -;; make Neovim your own! That might mean leaving Emacs Kick just the way it is for a while -;; or immediately breaking it into modular pieces. It's up to you! +;; Once you've done that, you can start exploring, configuring, and +;; tinkering to make Emacs your own! That might mean leaving Emacs +;; Kick just the way it is for a while or immediately breaking it into +;; modular pieces. It's up to you! ;; -;; If you don't know anything about Lua, I recommend taking some time to read through -;; a guide. One possible example which will only take 10-15 minutes: -;; - https://learnxinyminutes.com/docs/lua/ +;; If you don't know anything about Emacs Lisp, I recommend taking +;; some time to read through a guide. +;; One possible example which will only take 10-15 minutes: +;; - https://learnxinyminutes.com/docs/elisp/ ;; -;; After understanding a bit more about Lua, you can use `:help lua-guide` as a -;; reference for how Neovim integrates Lua. -;; - :help lua-guide -;; - (or HTML version): https://neovim.io/doc/user/lua-guide.html +;; After understanding a bit more about Emacs Lisp, you can use `M-x +;; info RET` (info) for a reference on how Emacs integrates it. ;; -;; Emacs Kick Guide: +;; Emacs-Kick Guide: ;; -;; TODO: The very first thing you should do is to run the command `:Tutor` in Neovim. +;; Well, this config ASSUMES you already knows (neo)vi(m) bindings, +;; and the bases of how it works. This is the `Emacs config for +;; vimmers'. So, if you're not familiar with it, go for +;; `kickstart,nvim`, get used to it, and than come back. ;; -;; If you don't know what this means, type the following: -;; - -;; - : -;; - Tutor -;; - +;; On Emacs help can be found multiple ways. +;; With this config, the leader key as SPC. +;; - SPC h i opens the info (Also `M-x info RET') +;; - SPC h v explores available variables +;; - SPC h f explores avaliable functions +;; - SPC h k explores avaliable keybindings ;; -;; (If you already know the Neovim basics, you can skip this step.) +;; If, at any time you need to find some functionality, Emacs `M-x' +;; (Meta is alt on most cases, option or command), works like a +;; command pallete, you can for example type `M-x quit' and be +;; presented with various options to quit Emacs. ;; -;; Once you've completed that, you can continue working through **AND READING** the rest -;; of the kickstart init.lua. +;; Once you've completed that, you can continue working through +;; `AND READING' the rest of the kickstart configuration. ;; -;; Next, run AND READ `:help`. -;; This will open up a help window with some basic information -;; about reading, navigating and searching the builtin help documentation. +;; I have left several comments throughout the configuration. These +;; are hints about where to find more information about the relevant +;; settings, packages, or Emacs features used in Emacs-Kick. ;; -;; This should be the first place you go to look when you're stuck or confused -;; with something. It's one of my favorite Neovim features. +;; Feel free to delete them once you know what you're doing, but they +;; should serve as a guide for when you are first encountering a few +;; different constructs in your Emacs config. ;; -;; MOST IMPORTANTLY, we provide a keymap "sh" to [s]earch the [h]elp documentation, -;; which is very useful when you're not exactly sure of what you're looking for. +;; If you experience any errors while trying to install Emacs-Kick, +;; check the *Messages* buffer for more information, you can switch +;; buffers with `SPC SPC', and all options menus are navigable with +;; `C-p' and `C-n'. ;; -;; I have left several `:help X` comments throughout the init.lua -;; These are hints about where to find more information about the relevant settings, -;; plugins or Neovim features used in Emacs Kick. +;; I hope you enjoy your Emacs journey, +;; - Rahul ;; -;; NOTE: Look for lines like this -;; -;; Throughout the file. These are for you, the reader, to help you understand what is happening. -;; Feel free to delete them once you know what you're doing, but they should serve as a guide -;; for when you are first encountering a few different constructs in your Neovim config. -;; -;; If you experience any errors while trying to install kickstart, run `:checkhealth` for more info. -;; -;; I hope you enjoy your Neovim journey, -;; - TJ -;; -;; P.S. You can delete this when you're done too. It's your config now! :) +;; P.S. You can delete this when you're done too. It's your config +;; now! :) ;;; Code: -;; Some performance Hacks +;; Performance Hacks +;; Emacs is an Elisp interpreter, and when running programs or packages, +;; it can occasionally experience pauses due to garbage collection. +;; By increasing the garbage collection threshold, we reduce these pauses +;; during heavy operations, leading to smoother performance. (setq gc-cons-threshold #x40000000) + +;; Set the maximum output size for reading process output, allowing for larger data transfers. (setq read-process-output-max (* 1024 1024 4)) +;; Do I really need a speedy startup? +;; Well, this config launches Emacs in about ~0.3 seconds, +;; which, in modern terms, is a miracle considering how fast it starts +;; with external packages. +;; It wasn’t until the recent introduction of tools for lazy loading +;; that a startup time of less than 20 seconds was even possible. +;; Other fast startup methods were introduced over time. +;; You may have heard of people running Emacs as a server, +;; where you start it once and open multiple clients instantly connected to that server. +;; Some even run Emacs as a systemd or sysV service, starting when the machine boots. +;; While this is a great way of using Emacs, we WON’T be doing that here. +;; I think 0.3 seconds is fast enough to avoid issues that could arise from +;; running Emacs as a server, such as 'What version of Node is my LSP using?'. +;; Again, this setup configures Emacs much like how a Vimmer would configure Neovim. -;; Adding the MELPA packages repository +;; Emacs already comes with its on package manager. +;; Others are available, but let's stick with the defaults when it makes sense. +;; +;; Requires the Emacs default package manager, so we can set it. Kind of an 'import'. (require 'package) +;; Add MELPA (Milkypostman's Emacs Lisp Package Archive) to the list of package archives. +;; This allows you to install packages from this widely-used repository, similar to how +;; pip works for Python or npm for Node.js. While Emacs comes with ELPA (Emacs Lisp +;; Package Archive) configured by default, which contains packages that meet specific +;; licensing criteria, MELPA offers a broader range of packages and is considered the +;; standard for Emacs users. You can also add more package archives later as needed. (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) + +;; Initialize the package system. In Emacs, a package is a collection of Elisp code +;; that extends the functionality of the editor, similar to plugins in Neovim. +;; By calling `package-initialize`, we load the list of available packages from +;; the configured archives (like MELPA) and make them ready for installation and use. +;; This process is akin to using lazy.nvim or packer.nvim in Neovim, which manage +;; plugin installations and configurations. While there are third-party package managers +;; available for Emacs, such as straight.el and use-package, we are sticking with +;; the default package manager for simplicity in this configuration. (package-initialize) + +;; Define a global customizable variable `ek-use-nerd-fonts' to control the use of +;; Nerd Fonts symbols throughout the configuration. This boolean variable allows +;; users to easily enable or disable the use of symbols from Nerd Fonts, providing +;; flexibility in appearance settings. By setting it to `t', we enable Nerd Fonts +;; symbols; setting it to `nil' would disable them. (defcustom ek-use-nerd-fonts t "Configuration for using Nerd Fonts Symbols." :type 'boolean :group 'appearance) + +;; From now on, you'll see configurations using the `use-package' macro, which +;; allows us to organize our Emacs setup in a modular way. These configurations +;; look like this: +;; +;; (use-package some-package +;; :ensure t ;; Ensure the package is installed. +;; :config ;; Configuration settings for the package. +;; ;; Additional settings can go here. +;; ) +;; +;; This approach simplifies package management, enabling us to easily control +;; both built-in (first-party) and external (third-party) packages. While Emacs +;; is a vast and powerful editor, using `use-package` helps streamline our +;; configuration for better organization and customization. As we proceed, +;; you'll see smaller `use-package` declarations for specific packages, which +;; will help us enable the desired features and improve our workflow. + + ;;; EMACS +;; This is biggest one. Keep going, plugins (oops, I mean packages) will be shorter :) (use-package emacs - :ensure nil - :bind - (("M-o" . other-window) - ("C-x C-b" . ibuffer)) - :custom - (column-number-mode t) - (auto-save-default nil) - (create-lockfiles nil) - (delete-by-moving-to-trash t) - (delete-selection-mode 1) - (display-line-numbers-type 'relative) - (global-auto-revert-non-file-buffers t) - (history-length 25) - (inhibit-startup-message t) - (initial-scratch-message "") - (ispell-dictionary "en_US") - (make-backup-files nil) - (pixel-scroll-precision-mode t) - (pixel-scroll-precision-use-momentum nil) - (ring-bell-function 'ignore) - (split-width-threshold 300) - (switch-to-buffer-obey-display-actions t) - (switch-to-prev-buffer-skip-regexp "\*[^*]+\*") - (switch-to-next-buffer-skip-regexp "\*[^*]+\*") - (tab-always-indent 'complete) ;; TAB serves as M-TAB to completion - (tab-width 4) - (treesit-font-lock-level 4) - (truncate-lines t) - (use-dialog-box nil) - (use-short-answers t) - (warning-minimum-level :emergency) - :hook - (prog-mode . display-line-numbers-mode) + :ensure nil + :custom ;; Set custom variables to configure Emacs behavior. + (column-number-mode t) ;; Display the column number in the mode line. + (auto-save-default nil) ;; Disable automatic saving of buffers. + (create-lockfiles nil) ;; Prevent the creation of lock files when editing. + (delete-by-moving-to-trash t) ;; Move deleted files to the trash instead of permanently deleting them. + (delete-selection-mode 1) ;; Enable replacing selected text with typed text. + (display-line-numbers-type 'relative) ;; Use relative line numbering in programming modes. + (global-auto-revert-non-file-buffers t) ;; Automatically refresh non-file buffers. + (history-length 25) ;; Set the length of the command history. + (inhibit-startup-message t) ;; Disable the startup message when Emacs launches. + (initial-scratch-message "") ;; Clear the initial message in the *scratch* buffer. + (ispell-dictionary "en_US") ;; Set the default dictionary for spell checking. + (make-backup-files nil) ;; Disable creation of backup files. + (pixel-scroll-precision-mode t) ;; Enable precise pixel scrolling. + (pixel-scroll-precision-use-momentum nil) ;; Disable momentum scrolling for pixel precision. + (ring-bell-function 'ignore) ;; Disable the audible bell. + (split-width-threshold 300) ;; Prevent automatic window splitting if the window width exceeds 300 pixels. + (switch-to-buffer-obey-display-actions t) ;; Make buffer switching respect display actions. + (tab-always-indent 'complete) ;; Make the TAB key complete text instead of just indenting. + (tab-width 4) ;; Set the tab width to 4 spaces. + (treesit-font-lock-level 4) ;; Use advanced font locking for Treesit mode. + (truncate-lines t) ;; Enable line truncation to avoid wrapping long lines. + (use-dialog-box nil) ;; Disable dialog boxes in favor of minibuffer prompts. + (use-short-answers t) ;; Use short answers in prompts for quicker responses (y instead of yes) + (warning-minimum-level :emergency) ;; Set the minimum level of warnings to display. + + :hook ;; Add hooks to enable specific features in certain modes. + (prog-mode . display-line-numbers-mode) ;; Enable line numbers in programming modes. + :config + ;; Configure font settings based on the operating system. + ;; Ok, this kickstart is meant to be used on the terminal, not on graphical. + ;; But without this, I fear you could start Graphical Emacs and be sad :( + (set-face-attribute 'default nil :family "JetBrainsMono Nerd Front" :height 100) + (when (eq system-type 'darwin) ;; Check if the system is macOS. + (setq mac-command-modifier 'meta) ;; Set the Command key to act as the Meta key. + (set-face-attribute 'default nil :family "JetBrainsMono Nerd Front" :height 140)) - ;; TODO: themessss - (load-theme 'modus-vivendi-tinted) + ;; Save manual customizations to a separate file instead of cluttering `init.el`. + ;; You can M-x customize, M-x customize-group, or M-x customize-themes, etc. + ;; The saves you do manually using the Emacs interface would overwrite this file. + ;; The following makes sure those customizations are in a separate file. + (setq custom-file (locate-user-emacs-file "custom-vars.el")) ;; Specify the custom file path. + (load custom-file 'noerror 'nomessage) ;; Load the custom file quietly, ignoring errors. - ;; TODO: explain transparency - (defun on-after-init () - (unless (display-graphic-p (selected-frame)) - (set-face-background 'default "unspecified-bg" (selected-frame)))) - (add-hook 'window-setup-hook 'on-after-init) - - ;; Configure fonts per OS - ;; Explain GUI - (set-face-attribute 'default nil :height 100) - (when (eq system-type 'darwin) - (setq mac-command-modifier 'meta) - (set-face-attribute 'default nil :height 140)) - - ;; Save manual customizations to other file than init.el - (setq custom-file (locate-user-emacs-file "custom-vars.el")) - (load custom-file 'noerror 'nomessage) - - :init - (tool-bar-mode -1) - (menu-bar-mode -1) + :init ;; Initialization settings that apply before the package is loaded. + (tool-bar-mode -1) ;; Disable the tool bar for a cleaner interface. + (menu-bar-mode -1) ;; Disable the menu bar for a more streamlined look. (when scroll-bar-mode - (scroll-bar-mode -1)) + (scroll-bar-mode -1)) ;; Disable the scroll bar if it is active. - (global-auto-revert-mode 1) - (indent-tabs-mode -1) - (recentf-mode 1) - (savehist-mode 1) - (save-place-mode 1) - (winner-mode) - (xterm-mouse-mode 1) - (file-name-shadow-mode 1) + (global-auto-revert-mode 1) ;; Enable global auto-revert mode to keep buffers up to date with their corresponding files. + (indent-tabs-mode -1) ;; Disable the use of tabs for indentation (use spaces instead). + (recentf-mode 1) ;; Enable tracking of recently opened files. + (savehist-mode 1) ;; Enable saving of command history. + (save-place-mode 1) ;; Enable saving the place in files for easier return. + (winner-mode) ;; Enable winner mode to easily undo window configuration changes. + (xterm-mouse-mode 1) ;; Enable mouse support in terminal mode. + (file-name-shadow-mode 1) ;; Enable shadowing of filenames for clarity. + ;; Set the default coding system for files to UTF-8. (modify-coding-system-alist 'file "" 'utf-8) - - (select-frame-set-input-focus (selected-frame)) - (toggle-frame-maximized) - + + ;; Add a hook to run code after Emacs has fully initialized. (add-hook 'after-init-hook (lambda () (message "Emacs has fully loaded. This code runs after startup.") + ;; Insert a welcome message in the *scratch* buffer displaying loading time and activated packages. (with-current-buffer (get-buffer-create "*scratch*") - (insert (format " + (insert (format + ";; Welcome to Emacs! +;; ;; Loading time : %s ;; Packages : %s " (emacs-init-time) - (number-to-string (length package-activated-list))))))) + (number-to-string (length package-activated-list)))))))) + - ) +;; WINDOW +;; This section configures window management in Emacs, enhancing the way buffers +;; are displayed for a more efficient workflow. The `window` use-package helps +;; streamline how various buffers are shown, especially those related to help, +;; diagnostics, and completion. + +;; Note: I have left some commented-out code below that may facilitate your +;; Emacs journey later on. These configurations can be useful for displaying +;; other types of buffers in side windows, allowing for a more organized workspace. -;;; WINDOW (use-package window - :ensure nil + :ensure nil ;; This is built-in, no need to fetch it. :custom (display-buffer-alist '( @@ -220,112 +288,195 @@ ;; (side . bottom) ;; (slot . 0)) + ;; Example configuration for the LSP help buffer, + ;; keeps it always on bottom using 25% of the available space: ("\\*\\(lsp-help\\)\\*" (display-buffer-in-side-window) (window-height . 0.25) (side . bottom) (slot . 0)) - + + ;; Configuration for displaying various diagnostic buffers on + ;; bottom 25%: ("\\*\\(Flymake diagnostics\\|xref\\|ivy\\|Swiper\\|Completions\\)" (display-buffer-in-side-window) (window-height . 0.25) (side . bottom) (slot . 1)) - ))) + ))) + ;;; DIRED +;; In Emacs, the `dired` package provides a powerful and built-in file manager +;; that allows you to navigate and manipulate files and directories directly +;; within the editor. If you're familiar with `oil.nvim`, you'll find that +;; `dired` offers similar functionality natively in Emacs, making file +;; management seamless without needing external plugins. + +;; This configuration customizes `dired` to enhance its usability. The settings +;; below specify how file listings are displayed, the target for file operations, +;; and associations for opening various file types with their respective applications. +;; For example, image files will open with `feh`, while audio and video files +;; will utilize `mpv`. (use-package dired - :ensure nil + :ensure nil ;; This is built-in, no need to fetch it. :custom - (dired-listing-switches "-lah --group-directories-first") - (dired-dwim-target t) + (dired-listing-switches "-lah --group-directories-first") ;; Display files in a human-readable format and group directories first. + (dired-dwim-target t) ;; Enable "do what I mean" for target directories. (dired-guess-shell-alist-user - '(("\\.\\(png\\|jpe?g\\|tiff\\)" "feh" "xdg-open" "open") - ("\\.\\(mp[34]\\|m4a\\|ogg\\|flac\\|webm\\|mkv\\)" "mpv" "xdg-open" "open") - (".*" "open" "xdg-open"))) - (dired-kill-when-opening-new-dired-buffer t) + '(("\\.\\(png\\|jpe?g\\|tiff\\)" "feh" "xdg-open" "open") ;; Open image files with `feh` or the default viewer. + ("\\.\\(mp[34]\\|m4a\\|ogg\\|flac\\|webm\\|mkv\\)" "mpv" "xdg-open" "open") ;; Open audio and video files with `mpv`. + (".*" "open" "xdg-open"))) ;; Default opening command for other files. + (dired-kill-when-opening-new-dired-buffer t) ;; Close the previous buffer when opening a new `dired` instance. :config (when (eq system-type 'darwin) - (let ((gls (executable-find "gls"))) + (let ((gls (executable-find "gls"))) ;; Use GNU ls on macOS if available. (when gls (setq insert-directory-program gls))))) - ;;; ERC +;; In this section, we introduce ERC (Emacs Relay Chat), a built-in IRC client +;; that allows you to engage in real-time chat directly within Emacs. While +;; we're aiming to maintain functionality similar to Neovim, it's important to +;; recognize that Emacs is often viewed as more than just a text editor. Many +;; users leverage Emacs for a variety of tasks beyond editing text: from watching +;; videos and listening to music, to managing emails and even serving as a window +;; manager in Xorg, freeing themselves from traditional desktop environments. + +;; While this kickstarter focuses on essential configurations, I wanted to present +;; ERC as a glimpse into Emacs's versatility. With ERC, you can seamlessly connect +;; to IRC channels and interact with communities without leaving your editor. (use-package erc - :defer t + :defer t ;; Load ERC when needed rather than at startup. (Load it with `M-x erc RET') :custom - (erc-join-buffer 'window) - ;; (erc-interactive-display ...) ;; this option will be available on next ERC release (5.6) - (erc-hide-list '("JOIN" "PART" "QUIT")) - (erc-timestamp-format "[%H:%M]") - (erc-autojoin-channels-alist '((".*\\.libera\\.chat" "#emacs")))) + (erc-join-buffer 'window) ;; Open a new window for joining channels. + (erc-hide-list '("JOIN" "PART" "QUIT")) ;; Hide messages for joins, parts, and quits to reduce clutter. + (erc-timestamp-format "[%H:%M]") ;; Format for timestamps in messages. + (erc-autojoin-channels-alist '((".*\\.libera\\.chat" "#emacs"))));; Automatically join the #emacs channel on Libera.Chat. -;; ISEARCH +;;; ISEARCH +;; In this configuration, we're setting up isearch, Emacs's incremental search feature. +;; Since we're utilizing Vim bindings, keep in mind that classic Vim search commands +;; (like `/` and `?`) are not bound in the same way. Instead, you'll need to use +;; the standard Emacs shortcuts: +;; - `C-s` to initiate a forward search +;; - `C-r` to initiate a backward search +;; The following settings enhance the isearch experience: (use-package isearch + :ensure nil ;; This is built-in, no need to fetch it. :config - (setq isearch-lazy-count t) - (setq lazy-count-prefix-format "(%s/%s) ") - (setq lazy-count-suffix-format nil) - (setq search-whitespace-regexp ".*?")) + (setq isearch-lazy-count t) ;; Enable lazy counting to show current match information. + (setq lazy-count-prefix-format "(%s/%s) ") ;; Format for displaying current match count. + (setq lazy-count-suffix-format nil) ;; Disable suffix formatting for match count. + (setq search-whitespace-regexp ".*?") ;; Allow searching across whitespace. + :bind (("C-s" . isearch-forward) ;; Bind C-s to forward isearch. + ("C-r" . isearch-backward))) ;; Bind C-r to backward isearch. ;;; VC -;; Notes about why this is here and why magit is better for git... +;; The VC (Version Control) package is included here for awareness and completeness. +;; While its support for Git is limited and generally considered subpar, it is good to know +;; that it exists and can be used for other version control systems like Mercurial, +;; Subversion, and Bazaar. +;; Magit, which is often regarded as the "father" of Neogit, will be configured later +;; for an enhanced Git experience. +;; The keybindings below serve as a reminder of some common VC commands. +;; But don't worry, you can always use `M-x command' :) (use-package vc - ;; This is not needed, but it is left here as a reminder of some of the keybindings + :ensure nil ;; This is built-in, no need to fetch it. :defer t :bind - (("C-x v d" . vc-dir) - ("C-x v =" . vc-diff) - ("C-x v D" . vc-root-diff) - ("C-x v v" . vc-next-action))) + (("C-x v d" . vc-dir) ;; Open VC directory for version control status. + ("C-x v =" . vc-diff) ;; Show differences for the current file. + ("C-x v D" . vc-root-diff) ;; Show differences for the entire repository. + ("C-x v v" . vc-next-action))) ;; Perform the next version control action. ;;; SMERGE +;; Smerge is included for resolving merge conflicts in files. It provides a simple interface +;; to help you keep changes from either the upper or lower version during a merge. +;; This package is built-in, so there's no need to fetch it separately. +;; The keybindings below did not needed to be setted, are here just to show +;; you how to work with it in case you are curious about it. (use-package smerge-mode + :ensure nil ;; This is built-in, no need to fetch it. :defer t :bind (:map smerge-mode-map - ("C-c ^ u" . smerge-keep-upper) - ("C-c ^ l" . smerge-keep-lower) - ("C-c ^ n" . smerge-next) - ("C-c ^ p" . smerge-previous))) + ("C-c ^ u" . smerge-keep-upper) ;; Keep the changes from the upper version. + ("C-c ^ l" . smerge-keep-lower) ;; Keep the changes from the lower version. + ("C-c ^ n" . smerge-next) ;; Move to the next conflict. + ("C-c ^ p" . smerge-previous))) ;; Move to the previous conflict. ;;; ELDOC +;; Eldoc provides helpful inline documentation for functions and variables +;; in the minibuffer, enhancing the development experience. It can be particularly useful +;; in programming modes, as it helps you understand the context of functions as you type. +;; This package is built-in, so there's no need to fetch it separately. +;; The following line enables Eldoc globally for all buffers. (use-package eldoc + :ensure nil ;; This is built-in, no need to fetch it. :init - (global-eldoc-mode)) + (global-eldoc-mode)) ;;; FLYMAKE +;; Flymake is an on-the-fly syntax checking extension that provides real-time feedback +;; about errors and warnings in your code as you write. This can greatly enhance your +;; coding experience by catching issues early. The configuration below activates +;; Flymake mode in programming buffers. (use-package flymake + :ensure nil ;; This is built-in, no need to fetch it. :defer t - :hook (prog-mode . flymake-mode) - :bind (:map flymake-mode-map - ("C-c ! n" . flymake-goto-next-error) - ("C-c ! p" . flymake-goto-prev-error) - ("C-c ! l" . flymake-show-buffer-diagnostics))) + :hook (prog-mode . flymake-mode)) ;;; ORG-MODE +;; Org-mode is a powerful system for organizing and managing your notes, +;; tasks, and documents in plain text. It offers features like task management, +;; outlining, scheduling, and much more, making it a versatile tool for +;; productivity. The configuration below simply defers loading Org-mode until +;; it's explicitly needed, which can help speed up Emacs startup time. (use-package org - :defer t) + :ensure nil ;; This is built-in, no need to fetch it. + :defer t) ;; Defer loading Org-mode until it's needed. -;;; --------------- External packages + + +;;; ==================== EXTERNAL PACKAGES ==================== +;; +;; From this point onward, all configurations will be for third-party packages +;; that enhance Emacs' functionality and extend its capabilities. + +;;; VERTICO +;; Vertico enhances the completion experience in Emacs by providing a +;; vertical selection interface for both buffer and minibuffer completions. +;; Unlike traditional minibuffer completion, which displays candidates +;; in a horizontal format, Vertico presents candidates in a vertical list, +;; making it easier to browse and select from multiple options. +;; +;; In buffer completion, `switch-to-buffer` allows you to select from open buffers. +;; Vertico streamlines this process by displaying the buffer list in a way that +;; improves visibility and accessibility. This is particularly useful when you +;; have many buffers open, allowing you to quickly find the one you need. +;; +;; In minibuffer completion, such as when entering commands or file paths, +;; Vertico helps by showing a dynamic list of potential completions, making +;; it easier to choose the correct one without typing out the entire string. (use-package vertico :ensure t :hook - (after-init . vertico-mode) + (after-init . vertico-mode) ;; Enable vertico after Emacs has initialized. :custom - (vertico-count 10) ; Number of candidates to display - (vertico-resize nil) - (vertico-cycle nil) ; Go from last to first candidate and first to last (cycle)? + (vertico-count 10) ;; Number of candidates to display in the completion list. + (vertico-resize nil) ;; Disable resizing of the vertico minibuffer. + (vertico-cycle nil) ;; Do not cycle through candidates when reaching the end of the list. :config - ;; Prefix the current candidate with “» ”. From - ;; https://github.com/minad/vertico/wiki#prefix-current-candidate-with-arrow + ;; Customize the display of the current candidate in the completion list. + ;; This will prefix the current candidate with “» ” to make it stand out. + ;; Reference: https://github.com/minad/vertico/wiki#prefix-current-candidate-with-arrow (advice-add #'vertico--format-candidate :around (lambda (orig cand prefix suffix index _start) (setq cand (funcall orig cand prefix suffix index _start)) @@ -336,48 +487,75 @@ cand)))) +;;; ORDERLESS +;; Orderless enhances completion in Emacs by allowing flexible pattern matching. +;; It works seamlessly with Vertico, enabling you to use partial strings and +;; regular expressions to find files, buffers, and commands more efficiently. +;; This combination provides a powerful and customizable completion experience. (use-package orderless :ensure t - :defer t - :after vertico + :defer t ;; Load Orderless on demand. + :after vertico ;; Ensure Vertico is loaded before Orderless. :init - (setq completion-styles '(orderless basic) - completion-category-defaults nil - completion-category-overrides '((file (styles partial-completion))))) + (setq completion-styles '(orderless basic) ;; Set the completion styles. + completion-category-defaults nil ;; Clear default category settings. + completion-category-overrides '((file (styles partial-completion))))) ;; Customize file completion styles. +;;; MARGINALIA +;; Marginalia enhances the completion experience in Emacs by adding +;; additional context to the completion candidates. This includes +;; helpful annotations such as documentation and other relevant +;; information, making it easier to choose the right option. (use-package marginalia :ensure t :hook (after-init . marginalia-mode)) +;;; CONSULT +;; Consult provides powerful completion and narrowing commands for Emacs. +;; It integrates well with other completion frameworks like Vertico, enabling +;; features like previews and enhanced register management. It's useful for +;; navigating buffers, files, and xrefs with ease. (use-package consult :ensure t :defer t :init - ;; Optionally tweak the register preview window. - ;; This adds thin lines, sorting and hides the mode line of the window. + ;; Enhance register preview with thin lines and no mode line. (advice-add #'register-preview :override #'consult-register-window) - ;; Use Consult to select xref locations with preview + ;; Use Consult for xref locations with a preview feature. (setq xref-show-xrefs-function #'consult-xref xref-show-definitions-function #'consult-xref)) -;; EMBARK +;;; EMBARK +;; Embark provides a powerful contextual action menu for Emacs, allowing +;; you to perform various operations on completion candidates and other items. +;; It extends the capabilities of completion frameworks by offering direct +;; actions on the candidates. (use-package embark :ensure t :defer t) +;;; EMBARK-CONSULT +;; Embark-Consult provides a bridge between Embark and Consult, ensuring +;; that Consult commands, like previews, are available when using Embark. +;; Just "SPC ." over any word, explore it :) (use-package embark-consult - :ensure t ; only need to install it, embark loads it after consult if found + :ensure t :hook - (embark-collect-mode . consult-preview-at-point-mode)) + (embark-collect-mode . consult-preview-at-point-mode)) ;; Enable preview in Embark collect mode. -;; TreeSitter Grammars +;;; TREESITTER-AUTO +;; Treesit-auto simplifies the use of Tree-sitter grammars in Emacs, +;; providing automatic installation and mode association for various +;; programming languages. This enhances syntax highlighting and +;; code parsing capabilities, making it easier to work with modern +;; programming languages. (use-package treesit-auto :ensure t :after emacs @@ -388,20 +566,29 @@ (global-treesit-auto-mode t)) -;; Markdown Mode +;;; MARKDOWN-MODE +;; Markdown Mode provides support for editing Markdown files in Emacs, +;; enabling features like syntax highlighting, previews, and more. +;; It’s particularly useful for README files, as it can be set +;; to use GitHub Flavored Markdown for enhanced compatibility. (use-package markdown-mode - :defer t + :defer t :ensure t - :mode ("README\\.md\\'" . gfm-mode) - :init (setq markdown-command "multimarkdown")) + :mode ("README\\.md\\'" . gfm-mode) ;; Use gfm-mode for README.md files. + :init (setq markdown-command "multimarkdown")) ;; Set the Markdown processing command. -;; Company +;;; COMPANY +;; Company Mode provides a text completion framework for Emacs. +;; It enhances the editing experience by offering context-aware +;; suggestions as you type. With support for multiple backends, +;; Company Mode is highly customizable and can be integrated with +;; various modes and languages. (use-package company - :defer t + :defer t :ensure t :custom - (company-tooltip-align-annotations t) + (company-tooltip-align-annotations t) ;; Align annotations with completions. :config (define-key company-active-map (kbd "C-y") (lambda () (interactive) (company-show-doc-buffer t))) (define-key company-active-map [tab] 'company-complete-selection) @@ -409,139 +596,192 @@ (define-key company-active-map [ret] 'company-complete-selection) (define-key company-active-map (kbd "RET") 'company-complete-selection) :hook - (after-init . global-company-mode)) + (after-init . global-company-mode)) ;; Enable Company Mode globally after initialization. -;; LSP +;;; LSP +;; Emacs comes with an integrated LSP client called `eglot`, which offers basic LSP functionality. +;; However, `eglot` has limitations, such as not supporting multiple language servers +;; simultaneously within the same buffer (e.g., handling both TypeScript, Tailwind and ESLint +;; LSPs together in a React project). For this reason, the more mature and capable +;; `lsp-mode` is included as a third-party package, providing advanced IDE-like features +;; and better support for multiple language servers and configurations. (use-package lsp-mode :ensure t :defer t - :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode) - (bash-ts-mode . lsp) - (typescript-ts-mode . lsp) - (tsx-ts-mode . lsp) - (js-mode . lsp) - (js-ts-mode . lsp) - (lsp-mode . lsp-enable-which-key-integration)) + :hook (;; Replace XXX-mode with concrete major mode (e.g. python-mode) + (bash-ts-mode . lsp) ;; Enable LSP for Bash + (typescript-ts-mode . lsp) ;; Enable LSP for TypeScript + (tsx-ts-mode . lsp) ;; Enable LSP for TSX + (js-mode . lsp) ;; Enable LSP for JavaScript + (js-ts-mode . lsp) ;; Enable LSP for JavaScript (TS mode) + (lsp-mode . lsp-enable-which-key-integration)) ;; Integrate with Which Key :commands lsp :custom - (lsp-keymap-prefix "C-c l") - (lsp-inlay-hint-enable t) - (lsp-completion-provider :none) - (lsp-session-file (locate-user-emacs-file ".lsp-session")) - (lsp-log-io nil) ;; for speed - (lsp-idle-delay 0) ;; debouncing, if needed 0.5 - (lsp-keep-workspace-alive nil) - ;; core - (lsp-enable-xref t) - (lsp-auto-configure t) - (lsp-enable-links nil) - (lsp-eldoc-enable-hover t) - (lsp-enable-dap-auto-configure t) - (lsp-enable-file-watchers nil) - (lsp-enable-folding nil) - (lsp-enable-imenu t) - (lsp-enable-indentation nil) - (lsp-enable-on-type-formatting nil) - (lsp-enable-suggest-server-download t) - (lsp-enable-symbol-highlighting t) - (lsp-enable-text-document-color nil) - ;; modeline - (lsp-modeline-code-actions-enable nil) ; Modeline should be relatively clean - (lsp-modeline-diagnostics-enable nil) ; Already supported through `flycheck'/ `flymake' - (lsp-modeline-workspace-status-enable t) ; Modeline displays "LSP" when lsp-mode is enabled - (lsp-signature-doc-lines 1) ; Don't raise the echo area. It's distracting - (lsp-eldoc-render-all t) - ;; completion - (lsp-completion-enable t) - (lsp-completion-enable-additional-text-edit t) ; Ex: auto-insert an import for a completion candidate - (lsp-enable-snippet nil) ; Important to provide full JSX completion - (lsp-completion-show-kind t) ; Optional - ;; lens - (lsp-lens-enable t) - ;; headerline - (lsp-headerline-breadcrumb-enable-symbol-numbers t) - (lsp-headerline-arrow "▶") - (lsp-headerline-breadcrumb-enable-diagnostics nil) - (lsp-headerline-breadcrumb-icons-enable nil) - ;; semantic - (lsp-semantic-tokens-enable nil)) + (lsp-keymap-prefix "C-c l") ;; Set the prefix for LSP commands. + (lsp-inlay-hint-enable t) ;; Enable inlay hints. + (lsp-completion-provider :none) ;; Disable the default completion provider. + (lsp-session-file (locate-user-emacs-file ".lsp-session")) ;; Specify session file location. + (lsp-log-io nil) ;; Disable IO logging for speed. + (lsp-idle-delay 0) ;; Set the delay for LSP to 0 (debouncing). + (lsp-keep-workspace-alive nil) ;; Disable keeping the workspace alive. + ;; Core settings + (lsp-enable-xref t) ;; Enable cross-references. + (lsp-auto-configure t) ;; Automatically configure LSP. + (lsp-enable-links nil) ;; Disable links. + (lsp-eldoc-enable-hover t) ;; Enable ElDoc hover. + (lsp-enable-dap-auto-configure t) ;; Enable DAP auto-configuration. + (lsp-enable-file-watchers nil) ;; Disable file watchers. + (lsp-enable-folding nil) ;; Disable folding. + (lsp-enable-imenu t) ;; Enable Imenu support. + (lsp-enable-indentation nil) ;; Disable indentation. + (lsp-enable-on-type-formatting nil) ;; Disable on-type formatting. + (lsp-enable-suggest-server-download t) ;; Enable server download suggestion. + (lsp-enable-symbol-highlighting t) ;; Enable symbol highlighting. + (lsp-enable-text-document-color nil) ;; Disable text document color. + ;; Modeline settings + (lsp-modeline-code-actions-enable nil) ;; Keep modeline clean. + (lsp-modeline-diagnostics-enable nil) ;; Use `flymake` instead. + (lsp-modeline-workspace-status-enable t) ;; Display "LSP" in the modeline when enabled. + (lsp-signature-doc-lines 1) ;; Limit echo area to one line. + (lsp-eldoc-render-all t) ;; Render all ElDoc messages. + ;; Completion settings + (lsp-completion-enable t) ;; Enable completion. + (lsp-completion-enable-additional-text-edit t) ;; Enable additional text edits for completions. + (lsp-enable-snippet nil) ;; Disable snippets + (lsp-completion-show-kind t) ;; Show kind in completions. + ;; Lens settings + (lsp-lens-enable t) ;; Enable lens support. + ;; Headerline settings + (lsp-headerline-breadcrumb-enable-symbol-numbers t) ;; Enable symbol numbers in the headerline. + (lsp-headerline-arrow "▶") ;; Set arrow for headerline. + (lsp-headerline-breadcrumb-enable-diagnostics nil) ;; Disable diagnostics in headerline. + (lsp-headerline-breadcrumb-icons-enable nil) ;; Disable icons in breadcrumb. + ;; Semantic settings + (lsp-semantic-tokens-enable nil)) ;; Disable semantic tokens. -;; LSP aditional servers +;;; LSP Additional Servers +;; You can extend `lsp-mode` by integrating additional language servers for specific +;; technologies. For example, `lsp-tailwindcss` provides support for Tailwind CSS +;; classes within your HTML files. By using various LSP packages, you can connect +;; multiple LSP servers simultaneously, enhancing your coding experience across +;; different languages and frameworks. (use-package lsp-tailwindcss :ensure t :defer t :config - (add-to-list 'lsp-language-id-configuration '(".*\\.erb$" . "html")) + (add-to-list 'lsp-language-id-configuration '(".*\\.erb$" . "html")) ;; Associate ERB files with HTML. :init (setq lsp-tailwindcss-add-on-mode t)) -;; Diff-HL +;;; Diff-HL +;; The `diff-hl` package provides visual indicators for version control changes +;; directly in the margin of the buffer, showing lines added, deleted, or changed. +;; This is useful for tracking modifications while you edit files. When enabled, +;; it automatically activates in every buffer that has a corresponding version +;; control backend, offering a seamless experience. +;; +;; In comparison, Neovim users often rely on plugins like `gitsigns.nvim` or +;; `vim-signify`, which provide similar functionalities by displaying Git +;; changes in the gutter and offer additional features like highlighting +;; changed lines and displaying blame information. `diff-hl` aims to provide +;; a comparable experience in Emacs with its own set of customizations. (use-package diff-hl :defer t :ensure t :hook (find-file . (lambda () - (global-diff-hl-mode) - (diff-hl-flydiff-mode) - (diff-hl-margin-mode))) + (global-diff-hl-mode) ;; Enable Diff-HL mode for all files. + (diff-hl-flydiff-mode) ;; Automatically refresh diffs. + (diff-hl-margin-mode))) ;; Show diff indicators in the margin. :custom - (diff-hl-side 'left) - :bind - (("M-9" . 'diff-hl-previous-hunk) - ("M-0" . 'diff-hl-next-hunk))) + (diff-hl-side 'left) ;; Set the side for diff indicators. + (diff-hl-margin-symbols-alist '((insert . "│") ;; Customize symbols for each change type. + (delete . "-") + (change . "│") + (unknown . "?") + (ignored . "i")))) -;; Magit +;;; Magit +;; `magit` is a powerful Git interface for Emacs that provides a complete +;; set of features to manage Git repositories. With its intuitive interface, +;; you can easily stage, commit, branch, merge, and perform other Git +;; operations directly from Emacs. Magit’s powerful UI allows for a seamless +;; workflow, enabling you to visualize your repository's history and manage +;; changes efficiently. +;; +;; In the Neovim ecosystem, similar functionality is provided by plugins such as +;; `fugitive.vim`, which offers a robust Git integration with commands that +;; allow you to perform Git operations directly within Neovim. Another popular +;; option is `neogit`, which provides a more modern and user-friendly interface +;; for Git commands in Neovim, leveraging features like diff views and staging +;; changes in a visual format. Both of these plugins aim to replicate and +;; extend the powerful capabilities that Magit offers in Emacs. (use-package magit :ensure t :defer t) -;; Minions -(use-package minions - :defer t - :ensure t - :hook - (after-init . minions-mode) - :config - ;; Set the icon or text shown for hidden minor modes - (setq minions-mode-line-lighter "λ") ;; You can change this to any icon or text - - ;; List of modes to display directly in the modeline - (setq minions-prominent-modes - '(flymake-mode - lsp-mode))) - - -;; Which-Key +;;; Which-Key +;; `which-key` is an Emacs package that displays available keybindings in a +;; popup window whenever you partially type a key sequence. This is particularly +;; useful for discovering commands and shortcuts, making it easier to learn +;; Emacs and improve your workflow. It helps users remember key combinations +;; and reduces the cognitive load of memorizing every command. (use-package which-key :ensure t :defer t :hook - (after-init . which-key-mode)) + (after-init . which-key-mode)) ;; Enable which-key mode after initialization. -;; XCLIP +;;; XCLIP +;; `xclip` is an Emacs package that integrates the X Window System clipboard +;; with Emacs. It allows seamless copying and pasting between Emacs and other +;; applications using the clipboard. When `xclip` is enabled, any text copied +;; in Emacs can be pasted in other applications, and vice versa, providing a +;; smooth workflow when working across multiple environments. (use-package xclip :ensure t :defer t :hook - (after-init . xclip-mode)) + (after-init . xclip-mode)) ;; Enable xclip mode after initialization. +;;; INDENT-GUIDE +;; The `indent-guide` package provides visual indicators for indentation levels +;; in programming modes, making it easier to see code structure at a glance. +;; It draws vertical lines (by default, a character of your choice) at each +;; level of indentation, helping to improve readability and navigation within +;; the code. (use-package indent-guide :defer t :ensure t :hook - (prog-mode . indent-guide-mode) + (prog-mode . indent-guide-mode) ;; Activate indent-guide in programming modes. :config - (setq indent-guide-char "│")) + (setq indent-guide-char "│")) ;; Set the character used for the indent guide. -;; Add-Node-Modules-Path +;;; ADD-NODE-MODULES-PATH +;; The `add-node-modules-path` package ensures that Emacs uses the local +;; `node_modules/.bin` for a project rather than globally installed binaries. +;; This is essential in JavaScript/TypeScript projects where different versions +;; of tools like `eslint` and `typescript-language-server` might be needed +;; per project. +;; +;; This setup helps prevent conflicts between global and local versions of +;; Node.js tools and ensures consistency across different environments. +;; +;; Example in the wild: This is an example of a real-world issue often faced +;; by developers using modern tech stacks. When working on multiple projects +;; with different dependencies, Emacs must use the correct local versions +;; instead of relying on globally installed packages. This configuration +;; ensures that the environment is accurate and project-specific tools are +;; properly utilized. (use-package add-node-modules-path :ensure t :defer t @@ -559,25 +799,32 @@ ;; EVIL +;; The `evil` package provides Vim emulation within Emacs, allowing +;; users to edit text in a modal way, similar to how Vim +;; operates. This setup configures `evil-mode` to enhance the editing +;; experience. (use-package evil :ensure t :defer t :hook (after-init . evil-mode) :init - (setq evil-want-integration t) ;; This is optional since it's already set to t by default. - (setq evil-want-keybinding nil) + (setq evil-want-integration t) ;; Integrate `evil` with other Emacs features (optional as it's true by default). + (setq evil-want-keybinding nil) ;; Disable default keybinding to set custom ones. :config - ;; Set the leader key to space - (setq evil-want-leader t) - (setq evil-leader/in-all-states t) - (setq evil-undo-system 'undo-tree) - (evil-set-leader 'normal (kbd "SPC")) - (evil-set-leader 'visual (kbd "SPC")) + ;; Set the leader key to space for easier access to custom commands. (setq evil-want-leader t) + (setq evil-leader/in-all-states t) ;; Make the leader key available in all states. + (setq evil-undo-system 'undo-tree) ;; Use `undo-tree` for better visual undo history. - ;; Define leader key bindings - (evil-define-key 'normal 'global (kbd "C-d") 'scroll-up) - (evil-define-key 'normal 'global (kbd "C-u") 'scroll-down) + ;; Define the leader key as Space + (evil-set-leader 'normal (kbd "SPC")) + (evil-set-leader 'visual (kbd "SPC")) + + ;; Scrolls with C-d, C-u + (evil-define-key 'normal 'global (kbd "C-d") 'scroll-up) ;; Scroll down in normal mode. + (evil-define-key 'normal 'global (kbd "C-u") 'scroll-down) ;; Scroll up in normal mode. + + ;; Keybindings for searching and finding files. (evil-define-key 'normal 'global (kbd " s f") 'consult-find) (evil-define-key 'normal 'global (kbd " s g") 'consult-grep) (evil-define-key 'normal 'global (kbd " s G") 'consult-git-grep) @@ -585,174 +832,276 @@ (evil-define-key 'normal 'global (kbd " s h") 'consult-info) (evil-define-key 'normal 'global (kbd " /") 'consult-line) + ;; Flymake navigation (evil-define-key 'normal 'global (kbd " x x") 'consult-flymake) - (evil-define-key 'normal 'global (kbd "] d") 'flymake-goto-next-error) - (evil-define-key 'normal 'global (kbd "[ d") 'flymake-goto-prev-error) + (evil-define-key 'normal 'global (kbd "] d") 'flymake-goto-next-error) ;; Go to next Flymake error + (evil-define-key 'normal 'global (kbd "[ d") 'flymake-goto-prev-error) ;; Go to previous Flymake error - (evil-define-key 'normal 'global (kbd "] c") 'diff-hl-next-hunk) - (evil-define-key 'normal 'global (kbd "[ c") 'diff-hl-previous-hunk) + ;; Dired commands for file management + (evil-define-key 'normal 'global (kbd " x d") 'dired) + (evil-define-key 'normal 'global (kbd " x j") 'dired-jump) + (evil-define-key 'normal 'global (kbd " x f") 'find-file) + ;; Diff-HL navigation for version control + (evil-define-key 'normal 'global (kbd "] c") 'diff-hl-next-hunk) ;; Next diff hunk + (evil-define-key 'normal 'global (kbd "[ c") 'diff-hl-previous-hunk) ;; Previous diff hunk + + ;; NeoTree command for file exploration (evil-define-key 'normal 'global (kbd " e e") 'neotree-toggle) - (evil-define-key 'normal 'global (kbd " g g") 'magit-status) - (evil-define-key 'normal 'global (kbd " g l") 'magit-log-current) - (evil-define-key 'normal 'global (kbd " g d") 'magit-diff-buffer-file) + ;; Magit keybindings for Git integration + (evil-define-key 'normal 'global (kbd " g g") 'magit-status) ;; Open Magit status + (evil-define-key 'normal 'global (kbd " g l") 'magit-log-current) ;; Show current log + (evil-define-key 'normal 'global (kbd " g d") 'magit-diff-buffer-file) ;; Show diff for the current file + (evil-define-key 'normal 'global (kbd " g D") 'diff-hl-show-hunk) ;; Show diff hunk + (evil-define-key 'normal 'global (kbd " g b") 'vc-annotate) ;; Annotate buffer with version control info - (evil-define-key 'normal 'global (kbd "] b") 'switch-to-next-buffer) - (evil-define-key 'normal 'global (kbd "[ b") 'switch-to-prev-buffer) - (evil-define-key 'normal 'global (kbd " b i") 'consult-buffer) - (evil-define-key 'normal 'global (kbd " b d") 'kill-current-buffer) - (evil-define-key 'normal 'global (kbd " b k") 'kill-current-buffer) - (evil-define-key 'normal 'global (kbd " b x") 'kill-current-buffer) - (evil-define-key 'normal 'global (kbd " b s") 'save-buffer) - (evil-define-key 'normal 'global (kbd " b l") 'consult-buffer) - (evil-define-key 'normal 'global (kbd "SPC") 'consult-buffer) + ;; Buffer management keybindings + (evil-define-key 'normal 'global (kbd "] b") 'switch-to-next-buffer) ;; Switch to next buffer + (evil-define-key 'normal 'global (kbd "[ b") 'switch-to-prev-buffer) ;; Switch to previous buffer + (evil-define-key 'normal 'global (kbd " b i") 'consult-buffer) ;; Open consult buffer list + (evil-define-key 'normal 'global (kbd " b b") 'ibuffer) ;; Open Ibuffer + (evil-define-key 'normal 'global (kbd " b d") 'kill-current-buffer) ;; Kill current buffer + (evil-define-key 'normal 'global (kbd " b k") 'kill-current-buffer) ;; Kill current buffer + (evil-define-key 'normal 'global (kbd " b x") 'kill-current-buffer) ;; Kill current buffer + (evil-define-key 'normal 'global (kbd " b s") 'save-buffer) ;; Save buffer + (evil-define-key 'normal 'global (kbd " b l") 'consult-buffer) ;; Consult buffer + (evil-define-key 'normal 'global (kbd "SPC") 'consult-buffer) ;; Consult buffer - (evil-define-key 'normal 'global (kbd " p b") 'consult-project-buffer) - (evil-define-key 'normal 'global (kbd " p p") 'project-switch-project) - (evil-define-key 'normal 'global (kbd " p f") 'project-find-file) - (evil-define-key 'normal 'global (kbd " p g") 'project-find-regexp) - (evil-define-key 'normal 'global (kbd " p k") 'project-kill-buffers) - (evil-define-key 'normal 'global (kbd " p D") 'project-dired) + ;; Project management keybindings + (evil-define-key 'normal 'global (kbd " p b") 'consult-project-buffer) ;; Consult project buffer + (evil-define-key 'normal 'global (kbd " p p") 'project-switch-project) ;; Switch project + (evil-define-key 'normal 'global (kbd " p f") 'project-find-file) ;; Find file in project + (evil-define-key 'normal 'global (kbd " p g") 'project-find-regexp) ;; Find regexp in project + (evil-define-key 'normal 'global (kbd " p k") 'project-kill-buffers) ;; Kill project buffers + (evil-define-key 'normal 'global (kbd " p D") 'project-dired) ;; Dired for project + ;; Yank from kill ring (evil-define-key 'normal 'global (kbd "P") 'consult-yank-from-kill-ring) + (evil-define-key 'normal 'global (kbd " P") 'consult-yank-from-kill-ring) + ;; Embark actions for contextual commands (evil-define-key 'normal 'global (kbd " .") 'embark-act) + ;; Undo tree visualization (evil-define-key 'normal 'global (kbd " u") 'undo-tree-visualize) - (evil-define-key 'normal 'global (kbd " h m") 'describe-mode) - (evil-define-key 'normal 'global (kbd " h f") 'describe-function) - (evil-define-key 'normal 'global (kbd " h v") 'describe-variable) - (evil-define-key 'normal 'global (kbd " h k") 'describe-key) + ;; Help keybindings + (evil-define-key 'normal 'global (kbd " h m") 'describe-mode) ;; Describe current mode + (evil-define-key 'normal 'global (kbd " h f") 'describe-function) ;; Describe function + (evil-define-key 'normal 'global (kbd " h v") 'describe-variable) ;; Describe variable + (evil-define-key 'normal 'global (kbd " h k") 'describe-key) ;; Describe key - (evil-define-key 'normal 'global (kbd "] t") 'tab-next) - (evil-define-key 'normal 'global (kbd "[ t") 'tab-previous) + ;; Tab navigation + (evil-define-key 'normal 'global (kbd "] t") 'tab-next) ;; Go to next tab + (evil-define-key 'normal 'global (kbd "[ t") 'tab-previous) ;; Go to previous tab - (evil-define-key 'normal 'global (kbd " m p") (lambda () - (interactive) - (shell-command (concat "prettier --write " (shell-quote-argument (buffer-file-name)))) - (revert-buffer t t t))) + ;; Prettier formatting command + (evil-define-key 'normal 'global (kbd " m p") + (lambda () + (interactive) + (shell-command (concat "prettier --write " (shell-quote-argument (buffer-file-name)))) + (revert-buffer t t t))) + ;; LSP commands keybindings (evil-define-key 'normal lsp-mode-map - ;; (kbd "gd") 'lsp-find-definition ;; Emacs already provides a better gd - ;; (kbd "gr") 'lsp-find-references ;; Emacs already provides a better gr - (kbd "K") 'lsp-describe-thing-at-point ;; Show hover documentation - (kbd " c a") 'lsp-describe-thing-at-point ;; Show hover documentation - (kbd " r n") 'lsp-rename ;; Rename symbol - (kbd "gI") 'lsp-find-implementation ;; Find implementation - (kbd " l f") 'lsp-format-buffer) ;; Format buffer via lsp - - - + ;; (kbd "gd") 'lsp-find-definition ;; Emacs already provides a better gd + ;; (kbd "gr") 'lsp-find-references ;; Emacs already provides a better gr + (kbd "K") 'lsp-describe-thing-at-point ;; Show hover documentation + (kbd " c a") 'lsp-describe-thing-at-point ;; Show hover documentation + (kbd " r n") 'lsp-rename ;; Rename symbol + (kbd "gI") 'lsp-find-implementation ;; Find implementation + (kbd " l f") 'lsp-format-buffer) ;; Format buffer via lsp + ;; Commenting functionality for single and multiple lines (evil-define-key 'normal 'global (kbd "gcc") (lambda () (interactive) (if (not (use-region-p)) (comment-or-uncomment-region (line-beginning-position) (line-end-position))))) + (evil-define-key 'visual 'global (kbd "gc") (lambda () (interactive) (if (use-region-p) (comment-or-uncomment-region (region-beginning) (region-end))))) + ;; Enable evil mode (evil-mode 1)) ;; EVIL COLLECTION +;; The `evil-collection` package enhances the integration of +;; `evil-mode` with various built-in and third-party packages. It +;; provides a better modal experience by remapping keybindings and +;; commands to fit the `evil` style. (use-package evil-collection :after evil :defer t :ensure t + ;; Hook to initialize `evil-collection` when `evil-mode` is activated. :hook (evil-mode . evil-collection-init) - :config) + :config + (evil-collection-init)) + +;; UNDO TREE +;; The `undo-tree` package provides an advanced and visual way to +;; manage undo history. It allows you to navigate and visualize your +;; undo history as a tree structure, making it easier to manage +;; changes in your buffers. (use-package undo-tree :defer t :ensure t :hook (after-init . global-undo-tree-mode) + :init + (setq undo-tree-visualizer-timestamps t + undo-tree-visualizer-diff t + ;; Increase undo limits to avoid losing history due to Emacs' garbage collection. + ;; These values can be adjusted based on your needs. + ;; 10X bump of the undo limits to avoid issues with premature + ;; Emacs GC which truncates the undo history very aggressively. + undo-limit 800000 ;; Limit for undo entries. + undo-strong-limit 12000000 ;; Strong limit for undo entries. + undo-outer-limit 120000000) ;; Outer limit for undo entries. :config + ;; Set the directory where `undo-tree` will save its history files. + ;; This keeps undo history across sessions, stored in a cache directory. (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/.cache/undo")))) -;; RAINBOWN DELIMITERS + +;; RAINBOW DELIMITERS +;; The `rainbow-delimiters` package provides colorful parentheses, brackets, and braces +;; to enhance readability in programming modes. Each level of nested delimiter is assigned +;; a different color, making it easier to match pairs visually. (use-package rainbow-delimiters :defer t :ensure t :hook - (prog-mode . rainbow-delimiters-mode) - :config) + (prog-mode . rainbow-delimiters-mode)) +;; DOOM MODELINE +;; The `doom-modeline` package provides a sleek, modern mode-line that is visually appealing +;; and functional. It integrates well with various Emacs features, enhancing the overall user +;; experience by displaying relevant information in a compact format. (use-package doom-modeline :ensure t :defer t :custom - (doom-modeline-buffer-file-name-style 'buffer-name) - (doom-modeline-project-detection 'project) - (doom-modeline-buffer-name t) - (doom-modeline-vcs-max-length 25) + (doom-modeline-buffer-file-name-style 'buffer-name) ;; Set the buffer file name style to just the buffer name (without path). + (doom-modeline-project-detection 'project) ;; Enable project detection for displaying the project name. + (doom-modeline-buffer-name t) ;; Show the buffer name in the mode line. + (doom-modeline-vcs-max-length 25) ;; Limit the version control system (VCS) branch name length to 25 characters. :config - (if ek-use-nerd-fonts - (setq doom-modeline-icon t) - (setq doom-modeline-icon nil)) + (if ek-use-nerd-fonts ;; Check if nerd fonts are being used. + (setq doom-modeline-icon t) ;; Enable icons in the mode line if nerd fonts are used. + (setq doom-modeline-icon nil)) ;; Disable icons if nerd fonts are not being used. :hook (after-init . doom-modeline-mode)) +;; NEOTREE +;; The `neotree` package provides a file tree explorer for Emacs, allowing easy navigation +;; through directories and files. It presents a visual representation of the file system +;; and integrates with version control to show file states. (use-package neotree :ensure t :custom - (neo-theme 'nerd) - (neo-vc-integration '(face char)) - :defer t + (neo-show-hidden-files t) ;; By default shows hidden files (toggle with H) + (neo-theme 'nerd) ;; Set the default theme for Neotree to 'nerd' for a visually appealing look. + (neo-vc-integration '(face char)) ;; Enable VC integration to display file states with faces (color coding) and characters (icons). + :defer t ;; Load the package only when needed to improve startup time. :config - (if ek-use-nerd-fonts - (setq neo-theme 'nerd-icons) - (setq neo-theme 'nerd))) + (if ek-use-nerd-fonts ;; Check if nerd fonts are being used. + (setq neo-theme 'nerd-icons) ;; Set the theme to 'nerd-icons' if nerd fonts are available. + (setq neo-theme 'nerd))) ;; Otherwise, fall back to the 'nerd' theme. +;; NERD ICONS +;; The `nerd-icons` package provides a set of icons for use in Emacs. These icons can +;; enhance the visual appearance of various modes and packages, making it easier to +;; distinguish between different file types and functionalities. (use-package nerd-icons - :if ek-use-nerd-fonts - :ensure t - :defer t) + :if ek-use-nerd-fonts ;; Load the package only if the user has configured to use nerd fonts. + :ensure t ;; Ensure the package is installed. + :defer t) ;; Load the package only when needed to improve startup time. + +;; NERD ICONS Dired +;; The `nerd-icons-dired` package integrates nerd icons into the Dired mode, +;; providing visual icons for files and directories. This enhances the Dired +;; interface by making it easier to identify file types at a glance. (use-package nerd-icons-dired - :if ek-use-nerd-fonts - :ensure t - :defer t + :if ek-use-nerd-fonts ;; Load the package only if the user has configured to use nerd fonts. + :ensure t ;; Ensure the package is installed. + :defer t ;; Load the package only when needed to improve startup time. :hook (dired-mode . nerd-icons-dired-mode)) +;; NERD ICONS COMPLETION +;; The `nerd-icons-completion` package enhances the completion interfaces in +;; Emacs by integrating nerd icons with completion frameworks such as +;; `marginalia`. This provides visual cues for the completion candidates, +;; making it easier to distinguish between different types of items. +(use-package nerd-icons-completion + :if ek-use-nerd-fonts ;; Load the package only if the user has configured to use nerd fonts. + :ensure t ;; Ensure the package is installed. + :after (:all nerd-icons marginalia) ;; Load after `nerd-icons` and `marginalia` to ensure proper integration. + :config + (nerd-icons-completion-mode) ;; Activate nerd icons for completion interfaces. + (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup)) ;; Setup icons in the marginalia mode for enhanced completion display. -;; Utilitary function to install Emacs-Kicks + +;; CATPPUCCIN THEME +;; The `catppuccin-theme` package provides a visually pleasing color theme +;; for Emacs that is inspired by the popular Catppuccin color palette. +;; This theme aims to create a comfortable and aesthetic coding environment +;; with soft colors that are easy on the eyes. +(use-package catppuccin-theme + :ensure t + :config + (custom-set-faces + ;; Set the color for changes in the diff highlighting to blue. + `(diff-hl-change ((t (:background nil :foreground ,(catppuccin-get-color 'blue)))))) + + (custom-set-faces + ;; Set the color for deletions in the diff highlighting to red. + `(diff-hl-delete ((t (:background nil :foreground ,(catppuccin-get-color 'red)))))) + + (custom-set-faces + ;; Set the color for insertions in the diff highlighting to green. + `(diff-hl-insert ((t (:background nil :foreground ,(catppuccin-get-color 'green)))))) + + ;; Load the Catppuccin theme without prompting for confirmation. + (load-theme 'catppuccin :no-confirm)) + + +;; UTILITARY FUNCTION TO INSTALL EMACS-KICK (defun ek/first-install () "Install tree-sitter grammars and compile packages on first run..." - (interactive) - (switch-to-buffer "*Messages*") - - (message ">>> All required packages installed.") - (message ">>> Configuring LEmacs...") - - (message ">>> Configuring Tree Sitter parsers...") - (require 'treesit-auto) - (treesit-auto-install-all) - - (message ">>> Native compile 3rd-party packages...\n") - (require 'comp) - (native-compile-prune-cache) + (interactive) ;; Allow this function to be called interactively. + (switch-to-buffer "*Messages*") ;; Switch to the *Messages* buffer to display installation messages. + (message ">>> All required packages installed.") ;; Inform the user that all required packages have been installed. + (message ">>> Configuring LEmacs...") ;; Notify the user about the configuration of LEmacs. + (message ">>> Configuring Tree Sitter parsers...") ;; Notify the user about the configuration of Tree Sitter parsers. + (require 'treesit-auto) ;; Load the treesit-auto package for automatic Tree Sitter parser installation. + (treesit-auto-install-all) ;; Install all available Tree Sitter grammars. + (message ">>> Native compile 3rd-party packages...\n") ;; Inform the user about the native compilation of third-party packages. + (require 'comp) ;; Load the comp package for compilation-related functions. + (native-compile-prune-cache) ;; Prune the native compilation cache to free up resources. + ;; Iterate through all directories in the user's package directory. (dolist (dir (directory-files package-user-dir t "^[^.]" t)) - (when (file-directory-p dir) - (byte-recompile-directory dir 0 t) - (native-compile-async dir 'recursively))) - - (message ">>> Emacs-Kicks installed!!! Presss any key to close the installer and open Emacs normally.") - (read-key) - (kill-emacs)) + (when (file-directory-p dir) ;; Check if the current entry is a directory. + (byte-recompile-directory dir 0 t) ;; Byte compile all files in the directory. + (native-compile-async dir 'recursively))) ;; Asynchronously compile the directory and its subdirectories. + (message ">>> Emacs-Kick installed!!! Press any key to close the installer and open Emacs normally.") ;; Notify the user that the installation is complete. + (read-key) ;; Wait for the user to press any key. + (kill-emacs)) ;; Close Emacs after installation is complete. (provide 'init) ;;; init.el ends here