diff options
author | Blendoit <blendoit@gmail.com> | 2020-08-03 21:14:39 -0700 |
---|---|---|
committer | Blendoit <blendoit@gmail.com> | 2020-08-03 21:14:39 -0700 |
commit | d4402a9acf9df537d2eeff459859cfa5d371fa1e (patch) | |
tree | 686e770ed0a17cb484a3431e0aebfe9f0a5cfbf2 /blendoit/blendoit-init.org | |
parent | e47650852b8aa4da6d0b0cea3b5421955795cc64 (diff) |
Theme lookin' good B-)
Diffstat (limited to 'blendoit/blendoit-init.org')
-rw-r--r-- | blendoit/blendoit-init.org | 974 |
1 files changed, 974 insertions, 0 deletions
diff --git a/blendoit/blendoit-init.org b/blendoit/blendoit-init.org new file mode 100644 index 0000000..4dd4f4e --- /dev/null +++ b/blendoit/blendoit-init.org @@ -0,0 +1,974 @@ +#+TITLE: Blendoit's literate GNU Emacs config +#+AUTHOR: Marius Peter +#+DATE: <2020-07-23 Thu> + +#+STARTUP: customtime showall +#+SETUPFILE: ~/org/templates/documents/personal.org + +#+INCLUDE: ~/org/templates/documents/personal-title.org + +\begin{abstract} +GNU Emacs is most often used as a text editor. The utmost level of +customisation is afforded by enabling the user to rewrite /any/ part of the +source code and observe the editor's modified behaviour in real time. Since its +inception in 1984, GNU Emacs has grown to be much more than a full-featured, +high-productivity text editor---new /modes/ have been written to interact with +hundreds of file formats, including =.txt=, =.pdf=, =.jpg=, =.csv=, and =.zip= just to +name a few. This configuration file itself was written in /Org mode/, a +collection of functions enabling the harmonious mixing of code and comments in +view of publication: this is the endgame of /literate programming/. +\end{abstract} + +# ** Test + +# #+BEGIN_SRC emacs-lisp +# (org-babel-load-file "~/.emacs.d/blendoit/test.org") +# #+END_SRC + +* Preliminary setup + +** Garbage collection + +First, we increase the RAM threshold beyond which the garbage collector is +activated. + +#+NAME: garbage-collection +#+BEGIN_SRC emacs-lisp +(setq gc-cons-threshold 100000000) +#+END_SRC + +** Emacs client + +Makes opening emacs faster for following instances. + +#+NAME: emacs-client +#+BEGIN_SRC emacs-lisp + +; (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*"))) +#+END_SRC + +** Profiling --- start + +We start the profiler now , and will interrupt it in section [[Profiling --- +stop]]. We will then present profiling report in [[Profiling --- report]]. + +#+NAME: profiler-start +#+BEGIN_SRC emacs-lisp +; (profiler-start) +#+END_SRC + +** Custom file + +Load settings created automatically by GNU Emacs Custom. (For example, any +clickable option/toggle is saved here.) Useful for fooling around with M-x +customize-group <package>. + +#+NAME: custom-file +#+BEGIN_SRC emacs-lisp + (setq custom-file "~/.emacs.d/init-custom.el") + (load custom-file) +#+END_SRC + +** Customization shortcuts + +We begin by defining a user shortcut to this very file: + +#+NAME: shortcut-config +#+BEGIN_SRC emacs-lisp + (defun find-init-blendoit () + "Jump to this very file." + (interactive) + (find-file "~/.emacs.d/blendoit/blendoit-init.org")) + + (global-set-key (kbd "C-c c") 'find-init-blendoit) +#+END_SRC + +Now, different shortcuts for other customization actions: + +#+NAME: shortcuts-customization +#+BEGIN_SRC emacs-lisp + (global-set-key (kbd "C-c v") 'customize-variable) + (global-set-key (kbd "C-c f") 'customize-face) +#+END_SRC + +** Backups + +Backups are so important that they should be described right after the shortcut +to this file. + +#+BEGIN_SRC emacs-lisp + (setq backup-directory-alist `((".*" . ,temporary-file-directory)) + auto-save-file-name-transforms `((".*" ,temporary-file-directory t)) + backup-by-copying t ; Don't delink hardlinks + version-control t ; Use version numbers on backups + delete-old-versions t ; Automatically delete excess backups + kept-new-versions 20 ; how many of the newest versions to keep + kept-old-versions 5 ; and how many of the old + ) +#+END_SRC + +** Secrets + +#+INCLUDE: ./secrets.org + +#+BEGIN_SRC emacs-lisp + (setq user-full-name "Marius Peter" + user-mail-address "blendoit@gmail.com") +#+END_SRC + +* Global key bindings + +The following bindings strive to further enhance CUA[fn::Common User Access.] +mode. + +** Navigation + +#+BEGIN_SRC emacs-lisp + (global-set-key (kbd "C-`") 'delete-other-windows) + (global-set-key (kbd "C-s") 'save-buffer) + (global-set-key (kbd "C-b") 'ibuffer-sidebar-toggle-sidebar) + (global-set-key (kbd "C-o") 'menu-find-file-existing) + (global-set-key (kbd "C-r") 'counsel-recentf) +; (global-set-key (kbd "C-n") 'make-frame) ; 7aram! +#+END_SRC + +The following bindings lead to more natural exit behaviors. + +#+BEGIN_SRC emacs-lisp + (defun delete-window-or-previous-buffer () + "Delete window; if sole window, previous buffer." + (interactive) + (if (> (length (window-list)) 2) + (delete-window) + (previous-buffer))) + +(global-set-key (kbd "C-w") 'delete-window-or-previous-buffer) +(global-set-key (kbd "C-q") 'save-buffers-kill-terminal) +#+END_SRC + +** Mouse zoom + + Zoom in/out of selected buffer using Alt + mouse wheel. + +#+BEGIN_SRC emacs-lisp + (global-set-key [M-mouse-4] 'text-scale-increase) + (global-set-key [M-mouse-5] 'text-scale-decrease) +#+END_SRC + +* Packages + +** Package archives + +List of package archives. + +#+NAME: packages +#+BEGIN_SRC emacs-lisp + (require 'package) + (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) + (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t) + (package-initialize) +#+END_SRC + +** use-package + +Ensure =use-package= is installed, as well as all packages described in this +configuration file. + +#+BEGIN_SRC emacs-lisp + (unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package) + (eval-when-compile (require 'use-package))) + (setq use-package-always-ensure t) +#+END_SRC + +** Convenient package update + +One-function rollup of upgradeable package tagging, download and lazy install. + +** Ivy + +Auto completion. + +#+BEGIN_SRC emacs-lisp + (use-package ivy + :config + (setq ivy-use-virtual-buffers t + ivy-count-format "%d/%d " + enable-recursive-minibuffers t)) + (ivy-mode t) +#+END_SRC + +** Evil + +Forgive me, for I have sinned. + +#+BEGIN_SRC emacs-lisp + (use-package evil) + ;; (evil-mode 1) +#+END_SRC + +*** Counsel + + Wonderful counsellor! + +#+BEGIN_SRC emacs-lisp + (use-package counsel + :bind ("M-x" . counsel-M-x) + :config (counsel-mode t)) + + (global-set-key (kbd "C-f") 'counsel-grep-or-swiper) +#+END_SRC + +*** Swiper + +#+BEGIN_SRC emacs-lisp +(use-package swiper + :bind (("C-f" . counsel-grep-or-swiper))) +#+END_SRC + +** Org + +Phew, I can finally introduce Org mode! I am so *excited*. + +Org mode replaces aword processor, a presentation creator, and a spreadsheet +editor. IMHO, the spreadsheet ability captures more than 80% use cases wherein +one wishes to include a table in a text document destined for physical +publication. (It is clear that Excel spreadsheets are /not/ destined for physical +publication---simply attempt to print an Excel spreadsheet with the default +settings.) In my opinion, Org mode matches all /useful/ features of the +Microsoft Office suite 1-to-1. + +What follows are customizations designed to make Org mode behave more like +Microsoft Word. The end goal is, once again, to draw as many new users to Emacs +as possible! + +*** Basic customization + +First, we hide markup symbols for *bold*, /italic/, _underlined_ and +strikethrough+ +text, and ensure our document appears indented upon loading:[fn::It /appears/ +indented, but the underlying plaintext file does not contain tab characters!] + +#+NAME: org-basic +#+BEGIN_SRC emacs-lisp + (setq org-hide-emphasis-markers t) + (setq org-startup-indented t) +#+END_SRC + +Then, we customize Org headings to emulate WYSIWYG[fn::What You See Is What You +Get (input and output are identical), as opposed to What You See Is What You +Mean (the input contains instructions that can modify the output).] behavior +normally found in Word: + +#+NAME: org-list-bullets +#+BEGIN_SRC emacs-lisp + (setq org-directory "~/org") + (font-lock-add-keywords + 'org-mode + '(("^ *\\([-]\\) " + (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•")))))) +#+END_SRC + +- Look at +- This beautifully indented + - List... + - Of lists! +- (Rendered with pretty bullets in Emacs) + +The following prettifies Org mode heading bullets: + +#+NAME: org-headings-bullets +#+BEGIN_SRC emacs-lisp + (use-package org-bullets + :hook + (org-mode . org-bullets-mode) + ) +#+END_SRC + +Thank you Diego +Zamboni![fn::https://zzamboni.org/post/beautifying-org-mode-in-emacs/] + +#+NAME: org-cosmetics +#+BEGIN_SRC emacs-lisp + ;; (let* ((variable-tuple + ;; (cond ((x-list-fonts "Dejavu Sans") '(:font "Dejavu Sans")) + ;; ((x-family-fonts "Sans Serif") '(:family "Sans Serif")) + ;; (nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro.")))) + ;; (base-font-color (face-foreground 'default nil 'default)) + ;; (headline `(:inherit default :weight bold))) + + ;; (custom-theme-set-faces + ;; 'user + ;; `(org-level-8 ((t (,@headline ,@variable-tuple)))) + ;; `(org-level-7 ((t (,@headline ,@variable-tuple)))) + ;; `(org-level-6 ((t (,@headline ,@variable-tuple)))) + ;; `(org-level-5 ((t (,@headline ,@variable-tuple)))) + ;; `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1)))) + ;; `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.25)))) + ;; `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.5)))) + ;; `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.75)))) + ;; `(org-document-title ((t (,@headline ,@variable-tuple :height 2.0 :underline nil)))))) + + ;(custom-theme-set-faces + ; 'user + ; '(variable-pitch ((t (:family "Liberation Sans")))) + ; '(fixed-pitch ((t ( :family "Hack"))))) + +#+END_SRC + +*** Invisible edits + +#+BEGIN_SRC emacs-lisp +(setq org-catch-invisible-edits t) +#+END_SRC + +*** Agenda + +The agenda displays a chronological list of headings across all agenda files +for which the heading or body contain a matching =org-time-stamp=.[fn::An +=org-time-stamp= can be inserted with =C-c .= (period)] + +#+BEGIN_SRC emacs-lisp +(global-set-key (kbd "C-c a") 'org-agenda) +#+END_SRC + +*** Publish + +In the following /alist/ (association list), we describe the projects publishable +via =org-publish=. We separate the publishing of =.org= files and attachments, +because an online tutorial recommended we do so. + +#+BEGIN_SRC emacs-lisp +(require 'ox-publish) +(setq org-publish-project-alist + '( + ("Safran-VIP-html" + :base-directory "~/org/WORK/Safran/programs/B787/VIP/doc/org/" + :base-extension "org" + :publishing-directory "~/org/WORK/Safran/programs/B787/VIP/doc/wiki/" + :recursive t + :publishing-function org-html-publish-to-html + :auto-preamble t + :auto-sitemap t + :sitemap-title "" ) + + ("Safran-VIP-static" + :base-directory "~/org/WORK/Safran/programs/B787/VIP/doc/org/" + :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|mp4\\|ogg\\|swf" + :publishing-directory "~/org/WORK/Safran/programs/B787/VIP/doc/wiki/" + :recursive t + :publishing-function org-publish-attachment ) + + ("Safran-VIP-all" + :components ("Safran-VIP-html" "Safran-VIP-static")) + + ("Safran-MA700-html" + :base-directory "~/org/WORK/Safran/programs/MA700/doc/org/" + :base-extension "org" + :publishing-directory "~/org/WORK/Safran/programs/MA700/doc/wiki/" + :recursive t + :publishing-function org-html-publish-to-html + :auto-preamble t + :auto-sitemap t + :sitemap-title "" ) + + ("Safran-MA700-static" + :base-directory "~/org/WORK/Safran/programs/MA700/doc/org/" + :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|mp4\\|ogg\\|swf" + :publishing-directory "~/org/WORK/Safran/programs/MA700/doc/wiki/" + :recursive t + :publishing-function org-publish-attachment ) + + ("Safran-MA700-all" + :components ("Safran-MA700-html" "Safran-MA700-static")))) + + (add-to-list 'org-latex-packages-alist '("table" "xcolor" + t ("pdflatex"))) + (add-to-list 'org-latex-packages-alist '("AUTO" "babel" + t ("pdflatex"))) + (add-to-list 'org-latex-packages-alist '("AUTO" "polyglossia" + t ("xelatex" "lualatex"))) +#+END_SRC + +*** Export + +This creates a shorter binding for the most common Org export: Org \rightarrow +LaTeX \rightarrow PDF. + +#+BEGIN_SRC emacs-lisp +(defun blendoit-org-quick-export () + "Org export to PDF and open. + This basically reimplements `C-c C-e l o'." + (interactive) + (org-latex-export-to-pdf) + (org-open-file + (concat (substring buffer-file-truename 0 -3) "pdf"))) + +(global-set-key (kbd "C-c e") 'blendoit-org-quick-export) +#+END_SRC + +** undo tree + +#+BEGIN_SRC emacs-lisp +(global-undo-tree-mode) +#+END_SRC + +** dumb jump + +#+BEGIN_SRC emacs-lisp +(use-package dumb-jump) +#+END_SRC + +** gnuplot + +#+BEGIN_SRC emacs-lisp +(use-package gnuplot) +#+END_SRC + +** Ledger + +#+BEGIN_SRC emacs-lisp + (use-package ledger-mode + :bind + ("C-c r" . ledger-report) + ("C-c C" . ledger-mode-clean-buffer)) +#+END_SRC + +** ibuffer-sidebar + +#+BEGIN_SRC emacs-lisp +(use-package ibuffer-sidebar) +(ibuffer-sidebar-show-sidebar) + +; :bind ("mouse-1" . ibuffer-mouse-visit-buffer) +; :bind ("mouse-3" . ibuffer-mouse-toggle-mark)) + +; (add-hook 'ibuffer-sidebar-mode-hook +; (lambda () +; (local-unset-key (quote mouse-1)) +; (local-unset-key (quote mouse-2)) +; (local-set-key (quote mouse-1) (quote ibuffer-mouse-visit-buffer)) +; (local-set-key (quote mouse-2) (quote ibuffer-mouse-toggle-mark)))) +#+END_SRC + +** Which-key + +#+BEGIN_SRC emacs-lisp +(use-package which-key +:init + (which-key-mode) +;; :config +;; (setq which-key-idle-delay 1000) +;; (setq which-key-idle-secondary-delay 0.05) +;; (setq which-key-show-early-on-C-h t) +) +#+END_SRC + +** Company + +#+NAME: company +#+BEGIN_SRC emacs-lisp + (add-hook 'after-init-hook 'global-company-mode) +#+END_SRC + +** Flycheck + +#+NAME: flycheck +#+BEGIN_SRC emacs-lisp +(use-package flycheck + :init (global-flycheck-mode)) +#+END_SRC + +** CSV + +#+BEGIN_SRC emacs-lisp + (use-package csv-mode) +#+END_SRC + +* JSON + +Oí, Jason! + +#+BEGIN_SRC emacs-lisp + (use-package json-mode) +#+END_SRC + +** Magit + +#+BEGIN_SRC emacs-lisp + (use-package magit + :bind ("C-c g" . magit-status)) +#+END_SRC + +** PDF-tools + +#+BEGIN_SRC emacs-lisp +(use-package pdf-tools + :config (pdf-loader-install)) +#+END_SRC + +** Dashboard + +We replace the standard welcome screen with our own. + +#+BEGIN_SRC emacs-lisp +(setq inhibit-startup-message t) +(use-package dashboard + :config + (dashboard-setup-startup-hook) + (setq dashboard-startup-banner "~/.emacs.d/blendoit/img/Safran_logo.svg") + (setq dashboard-items '((recents . 5) + (projects . 5))) + (setq dashboard-banner-logo-title "The editor for the 2nd millenium.")) +#+END_SRC + +** rainbow + +This highlights hexadecimal numbers which look like colors, in that same color. + +#+BEGIN_SRC emacs-lisp +(use-package rainbow-mode + :ensure t + :init + (add-hook 'prog-mode-hook 'rainbow-mode)) +#+END_SRC + +** Projectile + +This enables us to better manage our =.git= projects. + +#+BEGIN_SRC emacs-lisp + (use-package projectile + :bind ("C-c p" . 'projectile-command-map) + :init (projectile-mode 1) + (setq projectile-completion-system 'ivy)) +#+END_SRC + +** Better parentheses + +#+BEGIN_SRC emacs-lisp +(show-paren-mode 1) + + (use-package smartparens + :config + (add-hook 'prog-mode-hook #'smartparens-mode)) + + (use-package rainbow-delimiters + :config + (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)) +#+END_SRC + +* Cosmetics + +** Faces & cursors + +In order to imitate other modern text editors, we'll resort to a blinking bar +cursor. We choose red, the most captivating color, because the cursor is +arguably the region on our screen: + +1. most often looked at; +2. most often searched when lost. + +The default cursor already blinks. + +*** Default cursor + +In files containing only fixed-pitch fonts (i.e. files containing only code), +the cursor becomes a high-visibility box. + +#+BEGIN_SRC emacs-lisp +(setq-default cursor-type (quote box)) +#+END_SRC + +*** Mixed pitch in Org mode + +Fixed-pitch and variable-pitch fonts will be used intelligently in all hooked +modes. + +#+BEGIN_SRC emacs-lisp + (use-package mixed-pitch + :hook ((org-mode . mixed-pitch-mode) + (Info-mode . mixed-pitch-mode))) +#+END_SRC + +** Initial frame + +These settings affect the first and subsequent frames spawned by Emacs. + +Thank you Xah Lee![fn::http://ergoemacs.org/emacs/emacs_customize_default_window_size.html] + +#+BEGIN_SRC emacs-lisp + (if (display-graphic-p) + (progn + (setq initial-frame-alist + '( + (tool-bar-lines . 1) + (width . 100) ; chars + (height . 48) ; lines + (alpha . (90 . 50)))) + (setq default-frame-alist + '( + (tool-bar-lines . 1) + (width . 100) + (height . 48) + (alpha . (90 . 50)))))) +#+END_SRC + +** Theme + +#+BEGIN_SRC emacs-lisp +;; (use-package zenburn-theme +;; :config +;; (load-theme 'zenburn)) + +(load-theme 'blendoit-light) +#+END_SRC + +** All the icons + +#+BEGIN_SRC emacs-lisp +(use-package all-the-icons) +#+END_SRC + +* Editing preferences + +These customizations enhance editor usability. + +#+BEGIN_SRC emacs-lisp + (setq-default fill-column 79) + (defalias 'yes-or-no-p 'y-or-n-p) +#+END_SRC + +Disable minibuffer scroll bar. + +#+BEGIN_SRC emacs-lisp +(set-window-scroll-bars (minibuffer-window) nil nil) +; (set-window-scroll-bars (ibuffer-sidebar-window) nil nil) +#+END_SRC + +** Clean up menus + +We reduce the burden on the user by reducing total amount of entries in GUI +menus. + +*** File + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-file-menu [print-buffer] nil) +(define-key menu-bar-file-menu [print-region] nil) +(define-key menu-bar-file-menu [ps-print-buffer-faces] nil) +(define-key menu-bar-file-menu [ps-print-region-faces] nil) +(define-key menu-bar-file-menu [ps-print-buffer] nil) +(define-key menu-bar-file-menu [ps-print-region] nil) +(define-key menu-bar-file-menu [split-window-below] nil) +(define-key menu-bar-file-menu [split-window-right] nil) +(define-key menu-bar-file-menu [dired] nil) +#+END_SRC + +*** Edit + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Options + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Buffers + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Tools + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Org + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Tbl + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Text + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Projectile + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +*** Help + +#+BEGIN_SRC emacs-lisp +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +(define-key menu-bar-file-menu [dired] nil) +(define-key menu-bar-help-menu [emacs-psychotherapist] nil) +#+END_SRC + +** Coding standards + +This is just a better default. + +#+BEGIN_SRC emacs-lisp +(setq c-default-style "linux" + c-basic-offset 4) +#+END_SRC + +** Tabs + +#+BEGIN_SRC emacs-lisp +(use-package tabbar) +#+END_SRC + +Thank you +https://andreyorst.gitlab.io/posts/2020-05-10-making-emacs-tabs-look-like-in-atom/ + +#+BEGIN_SRC emacs-lisp +(when (and window-system + (not (version< emacs-version "27"))) + (use-package tab-line + :hook (after-init . global-tab-line-mode) + :config + (defun tab-line-close-tab (&optional e) + "Close the selected tab. + +If tab is presented in another window, close the tab by using +`bury-buffer` function. If tab is unique to all existing +windows, kill the buffer with `kill-buffer` function. Lastly, if +no tabs left in the window, it is deleted with `delete-window` +function." + (interactive "e") + (let* ((posnp (event-start e)) + (window (posn-window posnp)) + (buffer (get-pos-property 1 'tab (car (posn-string posnp))))) + (with-selected-window window + (let ((tab-list (tab-line-tabs-window-buffers)) + (buffer-list (flatten-list + (seq-reduce (lambda (list window) + (select-window window t) + (cons (tab-line-tabs-window-buffers) list)) + (window-list) nil)))) + (select-window window) + (if (> (seq-count (lambda (b) (eq b buffer)) buffer-list) 1) + (progn + (if (eq buffer (current-buffer)) + (bury-buffer) + (set-window-prev-buffers window (assq-delete-all buffer (window-prev-buffers))) + (set-window-next-buffers window (delq buffer (window-next-buffers)))) + (unless (cdr tab-list) + (ignore-errors (delete-window window)))) + (and (kill-buffer buffer) + (unless (cdr tab-list) + (ignore-errors (delete-window window))))))))) + + + (defcustom tab-line-tab-min-width 10 + "Minimum width of a tab in characters." + :type 'integer + :group 'tab-line) + + + (defcustom tab-line-tab-max-width 30 + "Maximum width of a tab in characters." + :type 'integer + :group 'tab-line) + + (defcustom tab-line-ellipsis-string "…" + "String for indicating truncated names" + :type 'string + :group 'tab-line) + + (defun aorst/tab-line--tab-width (window-width tab-amount) + "Calculate width of single tab dividing WINDOW-WIDTH by TAB-AMOUNT." + (let* ((close-button-size + (if tab-line-close-button-show + (length (substring-no-properties tab-line-close-button)) 0)) + (tab-width (/ window-width tab-amount))) + (- (cond ((< window-width 0) + tab-line-tab-min-width) + ((>= tab-width tab-line-tab-max-width) + tab-line-tab-max-width) + ((< tab-width tab-line-tab-min-width) + tab-line-tab-min-width) + (t tab-width)) + close-button-size))) + + (defun aorst/tab-line--max-width (window) + "Calculate free width of the WINDOW. + +Free width means amount of space we can use to display tabs +without truncation." + (- (window-width window) + (length (substring-no-properties tab-line-left-button)) + (length (substring-no-properties tab-line-right-button)) + (if tab-line-new-button-show + (length (substring-no-properties tab-line-new-button)) + 0))) + + + (defun aorst/tab-line--make-pad (tab-width name-width) + "Generate padding string based on TAB-WIDTH and NAME-WIDTH." + (let* ((width (- tab-width name-width)) + (padding (/ (if (oddp width) (+ width 1) width) 2))) + (make-string padding ?\s))) + + + (defun aorst/tab-line-name-buffer (buffer &rest _buffers) + "Create name for tab with padding and truncation. + +If buffer name is shorter than `tab-line-tab-max-width' it gets +centered with spaces, otherwise it is truncated, to preserve +equal width for all tabs. This function also tries to fit as +many tabs in window as possible, so if there are no room for tabs +with maximum width, it calculates new width for each tab and +truncates text if needed. Minimal width can be set with +`tab-line-tab-min-width' variable." + (with-current-buffer buffer + (let* ((amount (length (tab-line-tabs-window-buffers))) + (width (aorst/tab-line--tab-width + (aorst/tab-line--max-width (get-buffer-window buffer)) + amount)) + (buffer (string-trim (buffer-name))) + (name-width (length buffer)) + (right-pad (if tab-line-close-button-show "" " ")) + (truncate-width (- width + (length tab-line-ellipsis-string) + (length right-pad)))) + (if (>= name-width truncate-width) + (concat " " (truncate-string-to-width buffer truncate-width) tab-line-ellipsis-string right-pad) + (let* ((padding (aorst/tab-line--make-pad width name-width)) + (tab-text (concat padding buffer)) + (text-width (length tab-text))) + (concat tab-text (make-string (- width text-width) ?\s))))))) + + + (setq tab-line-close-button-show t + tab-line-new-button-show nil + tab-line-separator "" + tab-line-tab-name-function #'aorst/tab-line-name-buffer + tab-line-right-button (propertize (if (char-displayable-p ?▶) " ▶ " " > ") + 'keymap tab-line-right-map + 'mouse-face 'tab-line-highlight + 'help-echo "Click to scroll right") + tab-line-left-button (propertize (if (char-displayable-p ?◀) " ◀ " " < ") + 'keymap tab-line-left-map + 'mouse-face 'tab-line-highlight + 'help-echo "Click to scroll left") + tab-line-close-button (propertize (if (char-displayable-p ?×) " × " " x ") + 'keymap tab-line-tab-close-map + 'mouse-face 'tab-line-close-highlight + 'help-echo "Click to close tab")) + + + (let ((bg (if (facep 'solaire-default-face) + (face-attribute 'solaire-default-face :background) + (face-attribute 'default :background))) + (fg (face-attribute 'default :foreground)) + (base (if (facep 'solaire-default-face) + (face-attribute 'default :background) + (face-attribute 'mode-line :background))) + (box-width (/ (line-pixel-height) 2))) + (when (and (color-defined-p bg) + (color-defined-p fg) + (color-defined-p base) + (numberp box-width)) + (set-face-attribute 'tab-line nil + :background base + :foreground fg + :height 1.0 + :inherit nil + :box (list :line-width -1 :color base)) + (set-face-attribute 'tab-line-tab nil + :foreground fg + :background bg + :weight 'normal + :inherit nil + :box (list :line-width box-width :color bg)) + (set-face-attribute 'tab-line-tab-inactive nil + :foreground fg + :background base + :weight 'normal + :inherit nil + :box (list :line-width box-width :color base)) + (set-face-attribute 'tab-line-tab-current nil + :foreground fg + :background bg + :weight 'normal + :inherit nil + :box (list :line-width box-width :color bg)))) + (setq tab-line-exclude-modes '()) + (dolist (mode '(ediff-mode + process-menu-mode + term-mode + vterm-mode)) + (add-to-list 'tab-line-exclude-modes mode)) + + (defun aorst/tab-line-drop-caches () + "Drops `tab-line' cache in every window." + (dolist (window (window-list)) + (set-window-parameter window 'tab-line-cache nil))) + + (add-hook 'window-configuration-change-hook #'aorst/tab-line-drop-caches))) +#+END_SRC + +** auto fill + +Automatically break lines longer than =fill-column=. + +#+BEGIN_SRC emacs-lisp + (add-hook 'org-mode-hook 'turn-on-auto-fill) +#+END_SRC + +** Recent files + +#+BEGIN_SRC emacs-lisp + (recentf-mode 1) + (setq recentf-max-menu-items 25) + (setq recentf-max-saved-items 25) + (run-at-time nil (* 5 60) 'recentf-save-list) +#+END_SRC + +* Profiling --- stop + +#+BEGIN_SRC emacs-lisp +;; (profiler-stop) +#+END_SRC + +* Profiling --- report + +#+BEGIN_SRC emacs-lisp +;; (profiler-report) +#+END_SRC |