diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-06-30 01:15:07 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-07-01 04:16:05 +0100 |
commit | 12b62f7cea6a149b8b21d9e483944810495b0833 (patch) | |
tree | 77c7be1d74c6fc483f6c56f7c9651dc4f6c52019 /Emacs | |
parent | 9d327e4f702512b6833c9af582c0d1361d7bd3f6 (diff) | |
download | dotfiles-12b62f7cea6a149b8b21d9e483944810495b0833.tar.gz dotfiles-12b62f7cea6a149b8b21d9e483944810495b0833.tar.bz2 dotfiles-12b62f7cea6a149b8b21d9e483944810495b0833.zip |
(Emacs/elisp|config)+new package that generates a mode-line
Using left, centre and right segments generates a mode line with
padded strings that actually achieves this.
Diffstat (limited to 'Emacs')
-rw-r--r-- | Emacs/.config/emacs/config.org | 131 | ||||
-rw-r--r-- | Emacs/.config/emacs/elisp/better-mode-line.el | 89 |
2 files changed, 137 insertions, 83 deletions
diff --git a/Emacs/.config/emacs/config.org b/Emacs/.config/emacs/config.org index 1d523fd..92fc8f5 100644 --- a/Emacs/.config/emacs/config.org +++ b/Emacs/.config/emacs/config.org @@ -293,93 +293,58 @@ the borders for Emacs. (fringe-mode 0)) #+end_src ** Mode line -The mode line is a little bar at the bottom of the buffer, just above -the minibuffer (where you do completions). It can store quite +The mode line is the little bar at the bottom of the buffer, just +above the minibuffer (where you do completions). It can store quite literally anything, but generally stuff like the buffer name, file type, column and line info, etc is put there. The default mode-line is just... disgusting. It displays information -in an unintelligible format that you just have to learn and seems to -smash together a bunch of information without much care for ordering. -Most heartbreaking is that any mode can just insert new information -onto the mode-line without any purview, which can be really annoying. -It's also very overstimulating. - -Here I define a "nicer" (imo) mode-line-format which contains just the -information I need to know what that buffer does. It also looks a bit -more aesthetically pleasing from being centred along the window. - -*** A better evil state tag -[[*Evil][Evil]], defined later, has a mode-line-tag for -mode-line-format. It's not awful but not exactly amazing either. So -I'm defining a little function which makes the tag for me -#+begin_src emacs-lisp -(defun +mode-line/evil-state () - "Returns either the empty string if no evil-state is defined or -the first character of the evil state capitalised" - (with-eval-after-load "evil" - (if (bound-and-true-p evil-state) - (upcase - (substring - (format "%s" - evil-state) - 0 1)) - ""))) -#+end_src -*** +mode-line/format -Here I declare a new variable ~+mode-line/format~ which contains the -usual contents for ~mode-line-format~. Looking at the -[[info:elisp#Mode Line Top][info page]] for the mode-line, it's -essentially a list of either format strings (specially defined by -mode-line), variables or special forms. The only special form I use -here is ~:eval~ which evaluates the following expression every time -the mode-line is constructed. -#+begin_src emacs-lisp -(defvar +mode-line/format - '("%l:%c " ;; Line and column - "%p" ;; %into file - ("[" ;; evil state - (:eval (+mode-line/evil-state)) - "] ") - "%+" ;; Buffer state (changed or not) - "%b" ;; Buffer name - ("(" ;; Major mode - (:eval (format "%s" major-mode)) - ") ") - "%I " ;; Buffer size (in bytes) - (:eval (if (project-current) ;; Name of current project (if any) - (project-name - (project-current)))) - (vc-mode vc-mode) ;; Git branch (if any) - " " - (:eval ;; LSP information - (with-eval-after-load "eglot" - (if eglot--managed-mode - (eglot--mode-line-format)))) - mode-line-misc-info ;; Any other information - ) - "General format of mode line") -#+end_src -*** Left padding for the mode line -Here's the main logic for centring the entire mode-line. Essentially -just generate a string with enough spaces that the mode-line is in the -exact centre. -#+begin_src emacs-lisp -(defun +mode-line/left-padding () - "Returns a string of spaces which will centre the mode-line if put -to the left of it." - (let* ((mode-line-size (length (format-mode-line +mode-line/format))) - (string-size (/ (- (window-width) mode-line-size) 2))) - ;; ?\s means a whitespace character (why not #\Space Stallman?!) - (make-string string-size ?\s))) -#+end_src -*** mode-line-format -Put the left padded string and the rest of the format together to get -a nice little mode-line. -#+begin_src emacs-lisp -(setq-default mode-line-format - `((:eval (+mode-line/left-padding)) - ,@+mode-line/format)) +in an unintelligible format and seems to smash together a bunch of +information without much care for ordering. Most heartbreaking is +that any mode can just insert new information onto the mode-line +without any purview, which can be really annoying. It's also very +overstimulating. + +I've got a custom Emacs lisp package +([[file:elisp/better-mode-line.el][here]]) which sets up the default +mode line as a set of 3 segments: left, centre and right. It pads out +the mode line to achieve this. +#+begin_src emacs-lisp +(use-package better-mode-line + :load-path "elisp/" + :demand t + :init + (setq +better-mode-line/left-segment ;; LEFT SEGMENT + '("%l:%c" ;; Line and column count + " " + "%p" ;; Percentage into buffer + ("[" ;; Evil state + (:eval + (+better-mode-line/evil-state)) + "]")) + +better-mode-line/centre-segment ;; CENTRE SEGMENT + '("%+" ;; Buffer state (changed or not) + "%b" ;; Buffer name + ("(" ;; Major mode + (:eval (format "%s" major-mode)) + ")") + " " + "%I" ;; Buffer size (in bytes) + ) + +better-mode-line/right-segment ;; RIGHT SEGMENT + '((:eval (if (project-current) ;; Name of current project (if any) + (project-name + (project-current)))) + (vc-mode vc-mode) ;; Git branch (if any) + " " + (:eval ;; LSP information + (with-eval-after-load "eglot" + (if eglot--managed-mode + (eglot--mode-line-format)))) + mode-line-misc-info ;; Any other information + )) + :config + (+better-mode-line/setup-mode-line)) #+end_src ** Mouse Who uses a mouse? 🤮 diff --git a/Emacs/.config/emacs/elisp/better-mode-line.el b/Emacs/.config/emacs/elisp/better-mode-line.el new file mode 100644 index 0000000..a5cce16 --- /dev/null +++ b/Emacs/.config/emacs/elisp/better-mode-line.el @@ -0,0 +1,89 @@ +;;; better-mode-line.el --- A better mode-line system designed by me -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Aryadev Chavali + +;; Author: Aryadev Chavali <aryadev@aryadevchavali.com> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; There are 3 lists for the left, centre and right of the mode-line. They're +;; the same as mode-line-format in terms of general schema as they're fed +;; directly into that variable. Padding strings are automatically generated +;; based on these segments so be sure to set these. + +;;; Code: + +(defun +better-mode-line/evil-state () + "Returns either the empty string if no evil-state is defined or +the first character of the evil state capitalised" + (with-eval-after-load "evil" + (if (bound-and-true-p evil-state) + (upcase + (substring + (format "%s" + evil-state) + 0 1)) + ""))) + +(defvar +better-mode-line/left-segment nil + "List of elements that are placed on the left of the mode-line") + +(defvar +better-mode-line/centre-segment nil + "List of elements that should be on the centre of the mode-line") + +(defvar +better-mode-line/right-segment nil + "List of elements that should be on the right of the mode-line") + +(defconst +better-mode-line/--minimum-padding 4 + "Minimum size of padding string.") + +(defun +better-mode-line/--left->centre-padding () + "Returns a string which pads the centre segment perfectly relative +to the left segment." + (let* ((left-segment-size (length (format-mode-line +better-mode-line/left-segment))) + (centre-segment-size (length (format-mode-line +better-mode-line/centre-segment))) + (padding-size (- (/ (window-width) 2) (/ centre-segment-size 2) left-segment-size))) + (make-string (if (< padding-size +better-mode-line/--minimum-padding) + +better-mode-line/--minimum-padding + padding-size) + ?\s))) + +(defun +better-mode-line/--centre->right-padding () + "Returns a string which pads the right segment perfectly relative +to the centre segment" + (let* ((centre-segment-size (length (format-mode-line +better-mode-line/centre-segment))) + (right-segment-size (length (format-mode-line +better-mode-line/right-segment))) + (padding-size (- (/ (window-width) 2) (/ centre-segment-size 2) right-segment-size))) + (make-string (if (< padding-size +better-mode-line/--minimum-padding) + +better-mode-line/--minimum-padding + padding-size) + ?\s))) + + +(defun +better-mode-line/setup-mode-line () + "Call this to setup the mode-line when: +- first loading the package. +- segments are updated." + (setq-default mode-line-format + `(,@+better-mode-line/left-segment + (:eval (+better-mode-line/--left->centre-padding)) + ,@+better-mode-line/centre-segment + (:eval (+better-mode-line/--centre->right-padding)) + ,@+better-mode-line/right-segment))) + +(provide 'better-mode-line) +;;; better-mode-line.el ends here |