This commit is contained in:
Aleksandr Mikhailov 2024-09-20 12:18:47 +03:00
commit 0ad03f0890
28 changed files with 1531 additions and 0 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# EditorConfig is awesome: https://editorconfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = space
indent_size = 2

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
etc
elpa
auto-save-list
.cache
var
straight
*~
\#*#

18
custom.el Normal file
View File

@ -0,0 +1,18 @@
;;; -*- lexical-binding: t -*-
(custom-set-variables
;; custom-set-variables was added by Custom.
;; 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.
'(custom-safe-themes
'("9f297216c88ca3f47e5f10f8bd884ab24ac5bc9d884f0f23589b0a46a608fe14"
"6a5584ee8de384f2d8b1a1c30ed5b8af1d00adcbdcd70ba1967898c265878acf"
"e1f4f0158cd5a01a9d96f1f7cdcca8d6724d7d33267623cc433fe1c196848554"
"9a977ddae55e0e91c09952e96d614ae0be69727ea78ca145beea1aae01ac78d2"
default)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; 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.
)

55
early-init.el Normal file
View File

@ -0,0 +1,55 @@
;;; -*- lexical-binding: t; -*-
;; Some snake oil during the startup. Probably won't hurt and is
;; reverted right after the Emacs initialization finishes.
(setq inhibit-startup-message t)
(global-display-line-numbers-mode 1)
(add-hook 'after-init-hook
`(lambda ()
(setq gc-cons-threshold ,gc-cons-threshold))
'append)
(setq gc-cons-threshold most-positive-fixnum)
(defun bootstrap-straight ()
"Install and configure straight.el"
(setq straight-vc-git-default-clone-depth
(if-let ((depth (getenv "EMACS_STRAIGHT_DEPTH")))
(string-to-number depth)
'full))
(setq straight-check-for-modifications '(check-on-save find-when-checking)
straight-build-dir (format "build-%s" emacs-version)
straight-use-package-by-default t)
(setq straight-host-usernames '((github . "vifon")))
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage)))
(defun bootstrap-use-package ()
"Install use-package.el"
(setq use-package-enable-imenu-support t)
(straight-use-package 'use-package)
(straight-use-package 'diminish))
(bootstrap-straight)
(bootstrap-use-package)
;; This is not needed in general, but my specific init.el tries to
;; explicitly load early-init.el if it wasn't loaded yet.
;; This `provide' is used to load it only once.
(provide 'early-init)

107
init-lib.el Normal file
View File

@ -0,0 +1,107 @@
;;; init-lib.el --- Facilities for loading the rest of my config. -*- lexical-binding: t; -*-
;; Author: Wojciech Siewierski
;; Keywords: lisp, maint, local
;; 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:
;; Facilities for loading and maintaining the rest of my config.
;;; Code:
;;;###autoload
(defun load-parts (directory &optional regexp recursive)
"Load all the Elisp files from DIRECTORY, in the lexicographical order.
REGEXP defaults to `load-parts--regexp'.
If RECURSIVE is non-nil, load files recursively, sorted by their
full paths.
Inspired by: https://manpages.debian.org/stable/debianutils/run-parts.8.en.html"
(interactive "D")
(dolist (part (load-parts--gather directory regexp recursive))
(load part)))
(defun require-parts (directory &optional regexp recursive)
"The same as `load-parts' but uses `require' instead of `load'.
Should be used instead `load-parts' if loading a feature multiple
times is a concern.
If RECURSIVE is non-nil, require files recursively, sorted by
their full paths."
(dolist (part (load-parts--gather directory regexp recursive))
(require (intern (file-name-nondirectory part))
part)))
(defconst load-parts--regexp
(rx string-start
(not ".")
(zero-or-more any)
".el"
(opt "c")
string-end)
"A regexp matching *.el and *.elc files, but not dotfiles.")
(defun load-parts--gather (directory &optional regexp recursive)
"Gather the files from DIRECTORY for `load-parts'.
REGEXP defaults to `load-parts--regexp'.
If RECURSIVE is non-nil, gather files recursively, sorted by
their full paths. Skips directories starting with a dot."
(setq regexp (or regexp "\\`[^.].*\\.elc?\\'"))
(delete-dups
(mapcar #'file-name-sans-extension
(if recursive
(sort (directory-files-recursively
(file-name-as-directory directory) regexp
nil
(lambda (dir)
;; Omit directories starting with a dot.
(not (string-match-p
"\\`\\."
(file-name-nondirectory dir)))))
#'string<)
(directory-files (file-name-as-directory directory)
t regexp)))))
(defconst load-numbered-parts--regexp
(rx string-start
(= 2 digit)
"-"
(one-or-more any)
".el"
(opt "c")
string-end)
"A regexp matching files like 10-name.el")
(defun load-numbered-parts (directory &optional max)
"Load numbered config parts from DIRECTORY.
Optionally load only the parts up to the MAX numbered part (inclusive)."
(dolist (part (load-parts--gather directory load-numbered-parts--regexp))
(if (null max)
(load part)
(let* ((part-name (file-name-nondirectory part))
(part-number-as-string (substring part-name 0 2))
(part-number (string-to-number part-number-as-string)))
(when (<= part-number max)
(load part))))))
(provide 'init-lib)
;;; init-lib.el ends here

47
init.el Normal file
View File

@ -0,0 +1,47 @@
;; Load early-init.el regardless of the way Emacs was started.
(require 'nano-defaults (expand-file-name "nano-defaults" user-emacs-directory))
(require 'nano-splash (expand-file-name "nano-splash" user-emacs-directory))
(require 'early-init (expand-file-name "early-init" user-emacs-directory))
;; Load no-littering.el before anything else to keep ~/.emacs.d/ tidy.
(use-package no-littering :straight t)
(no-littering-theme-backups)
(when (and (fboundp 'startup-redirect-eln-cache)
(fboundp 'native-comp-available-p)
(native-comp-available-p))
(startup-redirect-eln-cache
(convert-standard-filename
(expand-file-name "var/eln-cache/" user-emacs-directory))))
;; Expose the packages integrated into the config repository.
(add-to-list 'load-path (expand-file-name "vendor/" user-emacs-directory))
;; Load the machine-local custom.el, versioned separately.
;; Possibly absent.
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file 'noerror)
;; Load the config management and maintenance helper library.
(require 'init-lib (expand-file-name "init-lib" user-emacs-directory))
;; Load all the config parts.
(load-numbered-parts (expand-file-name "lisp/" user-emacs-directory))
(custom-set-variables
;; custom-set-variables was added by Custom.
;; 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.
'(custom-safe-themes
'("9a977ddae55e0e91c09952e96d614ae0be69727ea78ca145beea1aae01ac78d2"
default)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; 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.
)

82
lisp/00-sane-defaults.el Normal file
View File

@ -0,0 +1,82 @@
;; -*- lexical-binding: t -*-
(setq gc-cons-threshold (* 100 1024 1024))
(setq read-process-output-max (* 1024 1024)) ;; 1mb
(setq uniquify-buffer-name-style 'forward)
(save-place-mode 1)
(set-default 'cursor-type '(bar . 1))
(blink-cursor-mode 0)
(setq visible-bell t)
(setq ring-bell-function 'ignore)
(show-paren-mode t)
(defun mode-line-render (left right)
"Function to render the modeline LEFT to RIGHT."
(concat left
(propertize " " 'display `(space :align-to (- right ,(length right))))
right))
(setq-default mode-line-format
'((:eval
(mode-line-render
(format-mode-line (list
(propertize "" 'face `(:inherit mode-line-buffer-id)
'help-echo "Mode(s) menu"
'mouse-face 'mode-line-highlight
'local-map mode-line-major-mode-keymap)
" %b "
(if (and buffer-file-name (buffer-modified-p))
(propertize "(modified)" 'face `(:inherit face-faded)))))
(format-mode-line
(propertize "%4l:%2c" 'face `(:inherit face-faded)))))))
;;; -------------------------------------------------------------------
;;; -------------------------------------------------------------------
;;; Vertical window divider
;;; -------------------------------------------------------------------
(setq window-divider-default-right-width 3)
(setq window-divider-default-places 'right-only)
(window-divider-mode)
(setq backup-directory-alist '(("." . "~/.backups"))
make-backup-files t ; backup of a file the first time it is saved.
backup-by-copying t ; don't clobber symlinks
version-control t ; version numbers for backup files
delete-old-versions t ; delete excess backup files silently
kept-old-versions 6 ; oldest versions to keep when a new numbered
; backup is made (default: 2)
kept-new-versions 9 ; newest versions to keep when a new numbered
; backup is made (default: 2)
auto-save-default t ; auto-save every buffer that visits a file
auto-save-timeout 20 ; number of seconds idle time before auto-save
; (default: 30)
auto-save-interval 200) ; number of keystrokes between auto-saves
; (default: 300)
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
(when (getenv "WAYLAND_DISPLAY")
(setq wl-copy-process nil)
(defun wl-copy (text)
(setq wl-copy-process (make-process :name "wl-copy"
:buffer nil
:command '("wl-copy" "-f" "-n")
:connection-type 'pipe))
(process-send-string wl-copy-process text)
(process-send-eof wl-copy-process))
(defun wl-paste ()
(if (and wl-copy-process (process-live-p wl-copy-process))
nil ; should return nil if we're the current paste owner
(shell-command-to-string "wl-paste -n | tr -d \r")))
(setq interprogram-cut-function 'wl-copy)
(setq interprogram-paste-function 'wl-paste)
)
(pixel-scroll-precision-mode)

185
lisp/10-ui.el Normal file
View File

@ -0,0 +1,185 @@
(set-face-attribute 'default nil :font "BlexMono Nerd Font Mono" :height 150 :weight 'semi-light)
(use-package doom-modeline
:straight t
:config
(setq doom-modeline-hud nil)
(setq doom-modeline-icon nil)
(setq doom-modeline-buffer-encoding nil)
(setq doom-modeline-height 24)
:init
(doom-modeline-mode 1)
)
(use-package all-the-icons
:straight t)
(use-package doom-themes
:ensure t
:straight t
:config
;; Global settings (defaults)
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-one-light t)
;; Enable flashing mode-line on errors
(doom-themes-visual-bell-config)
;; Enable custom neotree theme (all-the-icons must be installed!)
;; (doom-themes-neotree-config)
;; or for treemacs users
;; (setq doom-themes-treemacs-theme "doom-colors") ; use "doom-colors" for less minimal icon theme
;; (doom-themes-treemacs-config)
(setq doom-modeline-bar-width 0)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config)
)
(use-package aggressive-indent
:straight t)
(use-package rainbow-delimiters
:straight t
:config
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
(use-package dashboard
:straight t
:ensure t
:init
(setq dashboard-startup-banner 3)
(setq dashboard-items '((recents . 5)
(projects . 5)))
;; Content is not centered by default. To center, set
(setq dashboard-center-content t)
;; vertically center content
(setq dashboard-vertically-center-content t)
;; To disable shortcut "jump" indicators for each section, set
(setq dashboard-show-shortcuts nil)
(setq dashboard-startupify-list '(dashboard-insert-banner
dashboard-insert-newline
dashboard-insert-navigator
dashboard-insert-newline
dashboard-insert-items
dashboard-insert-init-info
))
(add-to-list 'dashboard-items '(agenda) t)
(setq dashboard-week-agenda t)
:config
(dashboard-setup-startup-hook))
(use-package which-key
:config
(which-key-mode 1))
(use-package treemacs
:straight t
:ensure t
:defer t
:init
(add-hook 'treemacs-mode-hook (lambda() (display-line-numbers-mode -1)))
(with-eval-after-load 'winum
(define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
:config
(progn
(setq treemacs-collapse-dirs (if treemacs-python-executable 3 0)
treemacs-deferred-git-apply-delay 0.5
treemacs-directory-name-transformer #'identity
treemacs-display-in-side-window t
treemacs-eldoc-display 'simple
treemacs-file-event-delay 2000
treemacs-file-extension-regex treemacs-last-period-regex-value
treemacs-file-follow-delay 0.2
treemacs-file-name-transformer #'identity
treemacs-follow-after-init t
treemacs-expand-after-init t
treemacs-find-workspace-method 'find-for-file-or-pick-first
treemacs-git-command-pipe ""
treemacs-goto-tag-strategy 'refetch-index
treemacs-header-scroll-indicators '(nil . "^^^^^^")
treemacs-hide-dot-git-directory t
treemacs-indentation 2
treemacs-indentation-string " "
treemacs-is-never-other-window nil
treemacs-max-git-entries 5000
treemacs-missing-project-action 'ask
treemacs-move-files-by-mouse-dragging t
treemacs-move-forward-on-expand nil
treemacs-no-delete-other-windows t
treemacs-project-follow-cleanup nil
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
treemacs-position 'left
treemacs-read-string-input 'from-child-frame
treemacs-recenter-distance 0.1
treemacs-recenter-after-file-follow nil
treemacs-recenter-after-tag-follow nil
treemacs-recenter-after-project-jump 'always
treemacs-recenter-after-project-expand 'on-distance
treemacs-litter-directories '("/node_modules" "/.venv" "/.cask")
treemacs-project-follow-into-home nil
treemacs-show-cursor nil
treemacs-show-hidden-files t
treemacs-silent-filewatch nil
treemacs-silent-refresh nil
treemacs-sorting 'alphabetic-asc
treemacs-select-when-already-in-treemacs 'move-back
treemacs-space-between-root-nodes t
treemacs-tag-follow-cleanup t
treemacs-tag-follow-delay 1.5
treemacs-text-scale nil
treemacs-user-mode-line-format nil
treemacs-user-header-line-format nil
treemacs-wide-toggle-width 70
treemacs-width 35
treemacs-width-increment 1
treemacs-width-is-initially-locked :on-nil
treemacs-workspace-switch-cleanup nil
treemacs-no-png-images t
)
;; The default width and height of the icons is 22 pixels. If you are
;; using a Hi-DPI display, uncomment this to double the icon size.
;;(treemacs-resize-icons 44)
(treemacs-follow-mode t)
(treemacs-filewatch-mode t)
(treemacs-fringe-indicator-mode 'always)
(when treemacs-python-executable
(treemacs-git-commit-diff-mode t))
(pcase (cons (not (null (executable-find "git")))
(not (null treemacs-python-executable)))
(`(t . t)
(treemacs-git-mode 'deferred))
(`(t . _)
(treemacs-git-mode 'simple)))
(treemacs-hide-gitignored-files-mode nil)))
(use-package treemacs-magit
:after (treemacs magit)
:ensure t
:straight t)
(with-eval-after-load 'treemacs
(define-key treemacs-mode-map [mouse-1] #'treemacs-single-click-expand-action))
(setq truncate-lines t)
(use-package centaur-tabs
:demand
:config
(setq centaur-tabs-set-bar 'under)
(setq x-underline-at-descent-line t)
(setq centaur-tabs-plain-icons t)
:custom
(centaur-tabs-mode t))

245
lisp/20-completion.el Normal file
View File

@ -0,0 +1,245 @@
(use-package corfu
:straight t
:custom
(corfu-cycle t) ;; Enable cycling for `corfu-next/previous'
(corfu-auto t) ;; Enable auto completion
;; (corfu-separator ?\s) ;; Orderless field separator
;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary
;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match
(corfu-preview-current nil) ;; Disable current candidate preview
;; (corfu-preselect 'prompt) ;; Preselect the prompt
(corfu-on-exact-match nil) ;; Configure handling of exact
;; (corfu-scroll-margin 5) ;; Use scroll margin
;; Enable Corfu only for certain modes. See also `global-corfu-modes'.
;; :hook ((prog-mode . corfu-mode)
;; (shell-mode . corfu-mode)
;; (eshell-mode . corfu-mode))
;; Use Company backends as Capfs.
(setq-local completion-at-point-functions
(mapcar #'cape-company-to-capf
(list #'company-files #'company-keywords #'company-dabbrev)))
;; Recommended: Enable Corfu globally. This is recommended since Dabbrev can
;; be used globally (M-/). See also the customization variable
;; `global-corfu-modes' to exclude certain modes.
:init
(global-corfu-mode))
;; Add extensions
(use-package cape
:init
;; Add to the global default value of `completion-at-point-functions' which is
;; used by `completion-at-point'. The order of the functions matters, the
;; first function returning a result wins. Note that the list of buffer-local
;; completion functions takes precedence over the global list.
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-elisp-block)
;; (add-hook 'completion-at-point-functions #'cape-history)
;; ...
)
;; Example configuration for Consult
(use-package consult
;; Replace bindings. Lazily loaded by `use-package'.
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; "C-+"
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (keymap-set consult-narrow-map (concat consult-narrow-key " ?") #'consult-narrow-help)
)
(use-package consult-lsp
:straight t
:ensure t)
;; Enable vertico
(use-package vertico
:straight t
:custom
;; (vertico-scroll-margin 0) ;; Different scroll margin
(vertico-count 10) ;; Show more candidates
(vertico-resize t) ;; Grow and shrink the Vertico minibuffer
(vertico-cycle t) ;; Enable cycling for `vertico-next/previous'
;; Option 2: Replace `vertico-insert' to enable TAB prefix expansion.
;; (keymap-set vertico-map "TAB" #'minibuffer-complete)
:init
(vertico-mode))
(use-package vertico-multiform
:straight nil
:after vertico
:ensure nil
:custom
(setq vertico-multiform-commands
'((consult-line buffer)
(consult-imenu reverse buffer)
(execute-extended-command flat)))
(setq vertico-multiform-categories
'((file buffer grid)
(imenu (:not indexed mouse))
(symbol (vertico-sort-function . vertico-sort-alpha))))
:init
(vertico-multiform-mode)
)
(use-package vertico-posframe
:straight t
:after vertico-multiform
:ensure nil
:config
(setq vertico-posframe-poshandler #'posframe-poshandler-frame-top-center)
;; (vertico-posframe-border-width . 10)
;; NOTE: This is useful when emacs is used in both in X and
;; terminal, for posframe do not work well in terminal, so
;; vertico-buffer-mode will be used as fallback at the
;; moment.
;; (vertico-posframe-fallback-mode . vertico-buffer-mode)
:init
;; (require 'vertico-posframe)
(vertico-posframe-mode 1)
)
;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
:straight t
:init
(savehist-mode))
;; A few more useful configurations...
(use-package emacs
:straight t
:custom
;; Support opening new minibuffers from inside existing minibuffers.
(enable-recursive-minibuffers t)
;; Hide commands in M-x which do not work in the current mode. Vertico
;; commands are hidden in normal buffers. This setting is useful beyond
;; Vertico.
(read-extended-command-predicate #'command-completion-default-include-p)
;; TAB cycle if there are only few candidates
;; (completion-cycle-threshold 3)
;; Enable indentation+completion using the TAB key.
;; `completion-at-point' is often bound to M-TAB.
(tab-always-indent 'complete)
;; Emacs 30 and newer: Disable Ispell completion function. As an alternative,
;; try `cape-dict'.
(text-mode-ispell-word-completion nil)
;; Hide commands in M-x which do not apply to the current mode. Corfu
;; commands are hidden, since they are not used via M-x. This setting is
;; useful beyond Corfu.
(read-extended-command-predicate #'command-completion-default-include-p)
:init
;; Add prompt indicator to `completing-read-multiple'.
;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
(defun crm-indicator (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
)
(use-package hotfuzz
:straight t)
;; Optionally use the `orderless' completion style.
(use-package orderless
:straight t
:custom
;; Configure a custom style dispatcher (see the Consult wiki)
;; (orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch))
;; (orderless-component-separator #'orderless-escapable-split-on-space)
(completion-styles '(hotfuzz orderless partial-completion basic))
(completion-category-defaults nil)
(completion-category-overrides nil))
(use-package marginalia
:straight t
:config
(marginalia-mode 1))
(use-package embark
:ensure t
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
;; Show the Embark target at point via Eldoc. You may adjust the
;; Eldoc strategy, if you want to see the documentation from
;; multiple providers. Beware that using this can be a little
;; jarring since the message shown in the minibuffer can be more
;; than one line, causing the modeline to move up and down:
;; (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:ensure t ; only need to install it, embark loads it after consult if found
:hook
(embark-collect-mode . consult-preview-at-point-mode))

7
lisp/20-meow.el Normal file
View File

@ -0,0 +1,7 @@
(use-package meow
:straight t
:demand t
:config
(require 'meow)
(meow-global-mode 1))

0
lisp/25-navigation.el Normal file
View File

4
lisp/25-wakatime.el Normal file
View File

@ -0,0 +1,4 @@
(use-package wakatime-mode
:straight t
:init
(global-wakatime-mode))

7
lisp/40-checks.el Normal file
View File

@ -0,0 +1,7 @@
;; (use-package flymake-posframe
;; :ensure t
;; :straight (:host github :repo "Ladicle/flymake-posframe")
;; :hook (flymake-mode . flymake-posframe-mode))
;; (add-hook 'prog-mode-hook #'flymake-mode)

10
lisp/40-dap.el Normal file
View File

@ -0,0 +1,10 @@
;; Posframe is a pop-up tool that must be manually installed for dap-mode
(use-package posframe
:straight t)
;; Use the Debug Adapter Protocol for running tests and debugging
(use-package dap-mode
:straight t
:hook
(lsp-mode . dap-mode)
(lsp-mode . dap-ui-mode))

12
lisp/40-editorconfig.el Normal file
View File

@ -0,0 +1,12 @@
(use-package editorconfig
:ensure t
:init
(editorconfig-mode 1))
(use-package format-all
:ensure t
:init
(format-all-mode))
(use-package envrc
:hook (after-init . envrc-global-mode))

74
lisp/40-lsp.el Normal file
View File

@ -0,0 +1,74 @@
(use-package lsp-mode
:straight t
;; Optional - enable lsp-mode automatically in scala files
;; You could also swap out lsp for lsp-deffered in order to defer loading
:hook
(scala-mode . lsp)
(lsp-mode . lsp-lens-mode)
(lsp-completion-mode . my/lsp-mode-setup-completion)
:init
(defun my/orderless-dispatch-flex-first (_pattern index _total)
(and (eq index 0) 'orderless-flex))
(defun my/lsp-mode-setup-completion ()
(setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
'(orderless))
;; Optionally configure the first word as flex filtered.
(add-hook 'orderless-style-dispatchers #'my/orderless-dispatch-flex-first nil 'local)
;; Optionally configure the cape-capf-buster.
(setq-local completion-at-point-functions (list (cape-capf-buster #'lsp-completion-at-point))))
:config
;; Uncomment following section if you would like to tune lsp-mode performance according to
;; https://emacs-lsp.github.io/lsp-mode/page/performance/
(setq lsp-idle-delay 0.500)
(setq lsp-log-io nil)
(setq lsp-completion-provider nil)
(setq lsp-modeline-code-actions-segments '(count name))
(setq lsp-headerline-breadcrumb-segments '(path symbols))
(setq lsp-prefer-flymake t)
;; Makes LSP shutdown the metals server when all buffers in the project are closed.
;; https://emacs-lsp.github.io/lsp-mode/page/settings/mode/#lsp-keep-workspace-alive
(setq lsp-keep-workspace-alive nil)
(setq lsp-auto-execute-action nil)
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.bloop\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.metals\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.ammonite\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.ivy2\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.sbt\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]target\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]project/target\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]project/\\..+\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]dist\\'"))
)
(use-package lsp-ui
:config
(setq lsp-ui-sideline-show-diagnostics t)
(setq lsp-ui-sideline-show-code-actions t)
(setq lsp-ui-sideline-update-mode 'line)
(setq lsp-ui-peek-enable t)
(setq lsp-ui-doc-enable t)
(setq lsp-ui-doc-side 'right)
(setq lsp-ui-doc-position 'bottom)
(setq lsp-ui-doc-delay 3)
(setq lsp-ui-doc-show-with-cursor t)
(setq lsp-ui-doc-show-with-mouse t)
:straight t)
(use-package lsp-treemacs
:straight t
:init
(lsp-treemacs-sync-mode 1)
)
(use-package dap-mode
:straight t)

2
lisp/40-magit.el Normal file
View File

@ -0,0 +1,2 @@
(use-package magit
:straight t)

35
lisp/40-projectile.el Normal file
View File

@ -0,0 +1,35 @@
(defvar user-cache-directory (concat user-emacs-directory "var/"))
(use-package projectile
:demand t
:straight t
:init
;; ensure projectile saves its files in a nice location
(setq projectile-cache-file
(concat user-cache-directory "projectile.cache"))
(setq projectile-known-projects-file
(concat user-cache-directory "projectile-bookmarks.eld"))
:config
(projectile-mode 1)
(setq projectile-globally-ignored-file-suffixes
'(
;; unity stuff
".meta" ".unity" ".asset" ".mat" ".cginc" ".prefab"
".renderTexture" ".lighting" ".shadergraph" ".shadersubgraph"
".shader" ".sceneWithBuildSettings" ".hlsl" ".vfx"
;; images
".png" ".xcf" ".jpg" ".jpeg" ".tif"
;; fonts
".ttf"
;; misc
".pdf"
))
(setq projectile-indexing-method 'hybrid)
;; :general
;; (leader-keys
;; "p" 'projectile-command-map)
)

8
lisp/40-tree-sitter.el Normal file
View File

@ -0,0 +1,8 @@
(use-package tree-sitter
:straight t
:config
(global-tree-sitter-mode))
(use-package tree-sitter-langs
:straight t)

4
lisp/50-dockerfiles.el Normal file
View File

@ -0,0 +1,4 @@
(use-package dockerfile-mode
:straight t
:init
(require 'dockerfile-mode))

9
lisp/50-gpt.el Normal file
View File

@ -0,0 +1,9 @@
(use-package dash)
(use-package editorconfig)
(use-package f)
(use-package s)
(use-package copilot
:straight (:host github :repo "copilot-emacs/copilot.el" :files ("*.el"))
:ensure t)

2
lisp/50-nix.el Normal file
View File

@ -0,0 +1,2 @@
(use-package nix-mode :straight t
:mode "\\.nix\\'")

24
lisp/50-scala.el Normal file
View File

@ -0,0 +1,24 @@
(use-package scala-mode
:straight t
:interpreter ("scala" . scala-mode))
;; Enable sbt mode for executing sbt commands
(use-package sbt-mode
:straight t
:commands sbt-start sbt-command
:config
;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31
;; allows using SPACE when in the minibuffer
(substitute-key-definition
'minibuffer-complete-word
'self-insert-command
minibuffer-local-completion-map)
;; sbt-supershell kills sbt-mode: https://github.com/hvesalai/emacs-sbt-mode/issues/152
(setq sbt:program-options '("-Dsbt.supershell=false")))
;; Add metals backend for lsp-mode
(use-package lsp-metals
:straight t)

3
lisp/50-yaml.el Normal file
View File

@ -0,0 +1,3 @@
(use-package yaml-mode
:straight t
)

30
lisp/70-utils.el Normal file
View File

@ -0,0 +1,30 @@
;; (use-package rg
;; :straight t
;; :config (rg-enable-default-bindings))
;; (use-package fzf
;; :straight t
;; :ensure t
;; ;;:config
;; ;; (setq fzf/args "-x --color bw --print-query --margin=1,0 --no-hscroll"
;; ;; fzf/executable "fzf"
;; ;; fzf/git-grep-args "-i --line-number %s"
;; ;; ;; command used for `fzf-grep-*` functions
;; ;; ;; example usage for ripgrep:
;; ;; ;; fzf/grep-command "rg --no-heading -nH"
;; ;; fzf/grep-command "grep -nrH"
;; ;; ;; If nil, the fzf buffer will appear at the top of the window
;; ;; fzf/position-bottom t
;; ;; fzf/window-height 15)
;; )
(use-package projectile
:straight t
:config
(projectile-mode +1))
(use-package which-key
:straight t
:ensure t
:config (which-key-mode))

206
lisp/99-keybindings.el Normal file
View File

@ -0,0 +1,206 @@
(use-package bind-key
:straight t)
(require 'meow)
(require 'bind-key)
;; :bind
;; (("C-." . embark-act) ;; pick some comfortable binding
;; ("C-;" . embark-dwim) ;; good alternative: M-.
;; ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
;; :bind (;; C-c bindings in `mode-specific-map'
;; ("C-c M-x" . consult-mode-command)
;; ("C-c h" . consult-history)
;; ("C-c k" . consult-kmacro)
;; ("C-c m" . consult-man)
;; ("C-c i" . consult-info)
;; ([remap Info-search] . consult-info)
;; ;; C-x bindings in `ctl-x-map'
;; ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
;; ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
;; ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
;; ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
;; ("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
;; ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
;; ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; ;; Custom M-# bindings for fast register access
;; ("M-#" . consult-register-load)
;; ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
;; ("C-M-#" . consult-register)
;; ;; Other custom bindings
;; ("M-y" . consult-yank-pop) ;; orig. yank-pop
;; ;; M-g bindings in `goto-map'
;; ("M-g e" . consult-compile-error)
;; ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
;; ("M-g g" . consult-goto-line) ;; orig. goto-line
;; ("M-g M-g" . consult-goto-line) ;; orig. goto-line
;; ("M-g o" . consult-outline) ;; Alternative: consult-org-heading
;; ("M-g m" . consult-mark)
;; ("M-g k" . consult-global-mark)
;; ("M-g i" . consult-imenu)
;; ("M-g I" . consult-imenu-multi)
;; ;; M-s bindings in `search-map'
;; ("M-s d" . consult-find) ;; Alternative: consult-fd
;; ("M-s c" . consult-locate)
;; ("M-s g" . consult-grep)
;; ("M-s G" . consult-git-grep)
;; ("M-s r" . consult-ripgrep)
;; ("M-s l" . consult-line)
;; ("M-s L" . consult-line-multi)
;; ("M-s k" . consult-keep-lines)
;; ("M-s u" . consult-focus-lines)
;; ;; Isearch integration
;; ("M-s e" . consult-isearch-history)
;; :map isearch-mode-map
;; ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
;; ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
;; ("M-s l" . consult-line) ;; needed by consult-line to detect isearch
;; ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; ;; Minibuffer history
;; :map minibuffer-local-map
;; ("M-s" . consult-history) ;; orig. next-matching-history-element
;; ("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; :bind (
;; ("C-c p" . cape-prefix-map)
;; ) ;; Alternative keys: M-p, M-+, ...
;; :bind
;; ("C-<prior>" . centaur-tabs-backward)
;; ("C-<next>" . centaur-tabs-forward)
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
;; (meow-replace-state-name-list
;; '(normal . "NORMAL")
;; '(motion . "MOTION")
;; '(keypad . "KEYPAD")
;; '(insert . "INSERT")
;; '(beacon . "BEACON"))
(meow-motion-overwrite-define-key
'("j" . meow-next)
'("k" . meow-prev)
'("<escape>" . ignore))
(meow-leader-define-key
;; SPC j/k will run the original command in MOTION state.
'("j" . "H-j")
'("k" . "H-k")
;; Use SPC (0-9) for digit arguments.
'("1" . meow-digit-argument)
'("2" . meow-digit-argument)
'("3" . meow-digit-argument)
'("4" . meow-digit-argument)
'("5" . meow-digit-argument)
'("6" . meow-digit-argument)
'("7" . meow-digit-argument)
'("8" . meow-digit-argument)
'("9" . meow-digit-argument)
'("0" . meow-digit-argument)
'("/" . meow-keypad-describe-key)
'("?" . meow-cheatsheet))
(meow-normal-define-key
'("0" . meow-expand-0)
'("9" . meow-expand-9)
'("8" . meow-expand-8)
'("7" . meow-expand-7)
'("6" . meow-expand-6)
'("5" . meow-expand-5)
'("4" . meow-expand-4)
'("3" . meow-expand-3)
'("2" . meow-expand-2)
'("1" . meow-expand-1)
'("-" . negative-argument)
'(";" . meow-reverse)
'("," . meow-inner-of-thing)
'("." . meow-bounds-of-thing)
'("[" . meow-beginning-of-thing)
'("]" . meow-end-of-thing)
'("a" . meow-append)
'("A" . meow-open-below)
'("b" . meow-back-word)
'("B" . meow-back-symbol)
'("c" . meow-change)
'("d" . meow-delete)
'("D" . meow-backward-delete)
'("e" . meow-next-word)
'("E" . meow-next-symbol)
'("f" . meow-find)
'("g" . meow-cancel-selection)
'("G" . meow-grab)
'("h" . meow-left)
'("H" . meow-left-expand)
'("i" . meow-insert)
'("I" . meow-open-above)
'("j" . meow-next)
'("J" . meow-next-expand)
'("k" . meow-prev)
'("K" . meow-prev-expand)
'("l" . meow-right)
'("L" . meow-right-expand)
'("m" . meow-join)
'("n" . meow-search)
'("o" . meow-block)
'("O" . meow-to-block)
'("p" . meow-yank)
'("q" . meow-quit)
'("Q" . meow-goto-line)
'("r" . meow-replace)
'("R" . meow-swap-grab)
'("s" . meow-kill)
'("t" . meow-till)
'("u" . meow-undo)
'("U" . meow-undo-in-selection)
'("v" . meow-visit)
'("w" . meow-mark-word)
'("W" . meow-mark-symbol)
'("x" . meow-line)
'("X" . meow-goto-line)
'("y" . meow-save)
'("Y" . meow-sync-grab)
'("z" . meow-pop-selection)
'("'" . repeat)
'("<escape>" . ignore))
(defvar my-keys-minor-mode-map
(let ((map (make-sparse-keymap)))
map)
"my-keys-minor-mode keymap.")
(define-minor-mode my-keys-minor-mode
"A minor mode so that my key settings override annoying major modes."
:init-value t
:lighter " my-keys")
(defun consult-switch-buffer-kill ()
"Kill candidate buffer at point within the minibuffer completion."
(interactive)
; The vertico--candidate has a irregular char at the end.
(let ((name (substring (vertico--candidate) 0 -1)))
(when (bufferp (get-buffer name))
(kill-buffer name))))
(bind-keys :map minibuffer-local-map
("C-s" . consult-switch-buffer-kill)
)
(bind-keys :map my-keys-minor-mode-map
("C-c C-f C-b" . consult-line)
("C-c C-f C-p" . consult-ripgrep)
("C-c C-t C-t" . treemacs-select-window)
("C-c C-t T" . treemacs)
("C-c M-x" . consult-mode-command)
("C-c C-b C-b" . consult-buffer)
("C-c C-b C-s" . kill-buffer)
("C-c C-l C-s" . consult-lsp-symbols)
)
(my-keys-minor-mode 1)

177
nano-defaults.el Normal file
View File

@ -0,0 +1,177 @@
;; ---------------------------------------------------------------------
;; GNU Emacs / N Λ N O - Emacs made simple
;; Copyright (C) 2020 - N Λ N O developers
;;
;; 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 <http://www.gnu.org/licenses/>.
;; ---------------------------------------------------------------------
;; No startup screen
(setq inhibit-startup-screen t)
;; No startup message
(setq inhibit-startup-message t)
(setq inhibit-startup-echo-area-message t)
;; No message in scratch buffer
(setq initial-scratch-message nil)
;; Initial buffer
(setq initial-buffer-choice nil)
;; No frame title
(setq frame-title-format nil)
;; No file dialog
(setq use-file-dialog nil)
;; No dialog box
(setq use-dialog-box nil)
;; No popup windows
(setq pop-up-windows nil)
;; No empty line indicators
(setq indicate-empty-lines nil)
;; No cursor in inactive windows
(setq cursor-in-non-selected-windows nil)
;; Text mode is initial mode
(setq initial-major-mode 'text-mode)
;; Text mode is default major mode
(setq default-major-mode 'text-mode)
;; Moderate font lock
(setq font-lock-maximum-decoration nil)
;; No limit on font lock
(setq font-lock-maximum-size nil)
;; No line break space points
(setq auto-fill-mode nil)
;; Fill column at 80
(setq fill-column 80)
;; No confirmation for visiting non-existent files
(setq confirm-nonexistent-file-or-buffer nil)
;; Completion style, see
;; gnu.org/software/emacs/manual/html_node/emacs/Completion-Styles.html
;; (setq completion-styles '(basic substring))
;; Use RET to open org-mode links, including those in quick-help.org
(setq org-return-follows-link t)
;; Mouse active in terminal
(unless (display-graphic-p)
(xterm-mouse-mode 1)
(global-set-key (kbd "<mouse-4>") 'scroll-down-line)
(global-set-key (kbd "<mouse-5>") 'scroll-up-line))
;; No scroll bars
(if (fboundp 'scroll-bar-mode) (set-scroll-bar-mode nil))
;; No toolbar
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(dolist (mode '(scroll-bar-mode
horizontal-scroll-bar-mode
menu-bar-mode
tooltip-mode
tool-bar-mode))
(when (fboundp mode)
(funcall mode 0)))
;; Tab behavior
;; (setq tab-always-indent 'complete)
;; (global-company-mode)
;; (define-key company-mode-map [remap indent-for-tab-command]
;; #'company-indent-or-complete-common)
;; Pixel scroll (as opposed to char scrool)
;; (pixel-scroll-mode t)
;; Mac specific
;; (when (eq system-type 'darwin)
;; (setq ns-use-native-fullscreen t
;; mac-option-key-is-meta nil
;; mac-command-key-is-meta t
;; mac-command-modifier 'meta
;; mac-option-modifier nil
;; mac-use-title-bar nil))
;; Make sure clipboard works properly in tty mode on OSX
;; (defun copy-from-osx ()
;; (shell-command-to-string "pbpaste"))
;; (defun paste-to-osx (text &optional push)
;; (let ((process-connection-type nil))
;; (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
;; (process-send-string proc text)
;; (process-send-eof proc))))
;; (when (and (not (display-graphic-p))
;; (eq system-type 'darwin))
;; (setq interprogram-cut-function 'paste-to-osx)
;; (setq interprogram-paste-function 'copy-from-osx))
;; y/n for answering yes/no questions
(fset 'yes-or-no-p 'y-or-n-p)
;; No tabs
(setq-default indent-tabs-mode nil)
;; Tab.space equivalence
(setq-default tab-width 4)
;; Size of temporary buffers
(temp-buffer-resize-mode)
(setq temp-buffer-max-height 8)
;; Minimum window height
(setq window-min-height 1)
;; Buffer encoding
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment 'utf-8)
;; Unique buffer names
(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse
uniquify-separator ""
uniquify-after-kill-buffer-p t
uniquify-ignore-buffers-re "^\\*")
;; Default shell in term
;; (unless
;; (or (eq system-type 'windows-nt)
;; (not (file-exists-p "/bin/zsh")))
;; (setq-default shell-file-name "/bin/zsh")
;; (setq explicit-shell-file-name "/bin/zsh"))
;; Kill term buffer when exiting
;; (defadvice term-sentinel (around my-advice-term-sentinel (proc msg))
;; (if (memq (process-status proc) '(signal exit))
;; (let ((buffer (process-buffer proc)))
;; ad-do-it
;; (kill-buffer buffer))
;; ad-do-it))
;; (ad-activate 'term-sentinel)
(provide 'nano-defaults)

157
nano-splash.el Normal file
View File

@ -0,0 +1,157 @@
;; ---------------------------------------------------------------------
;; GNU Emacs / N Λ N O - Emacs made simple
;; Copyright (C) 2020 - N Λ N O developers
;;
;; 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 <http://www.gnu.org/licenses/>.
;; ---------------------------------------------------------------------
;;
;; This file defines the splash screen
;; - No logo, no modeline, no scrollbars
;; - Any key / mouse click kills the splash screen
;; - With emacs-mac (Mituharu), splash screen is faded out after .5 seconds
;;
;; Note: The screen is not shown if there are opened file buffers. For
;; example, if you start emacs with a filename on the command
;; line, the splash screen is not shown.
;;
;; Usage:
;; (require 'nano-splash)
(require 'subr-x)
(require 'cl-lib)
(defun nano-splash ()
"Nano Emacs splash screen"
(interactive)
;; Hide modeline before window-body-height is computed
(let* ((splash-buffer (get-buffer-create "*splash*")))
(with-current-buffer splash-buffer
(setq header-line-format nil)
(setq mode-line-format nil)))
(let* ((splash-buffer (get-buffer-create "*splash*"))
(height (round (- (window-body-height nil) 1) ))
(width (round (window-body-width nil) ))
(padding-center (+ (/ height 2) 1)))
;; If there are buffer associated with filenames,
;; we don't show the splash screen.
(if (eq 0 (length (cl-loop for buf in (buffer-list)
if (buffer-file-name buf)
collect (buffer-file-name buf))))
(with-current-buffer splash-buffer
(erase-buffer)
;; Buffer local settings
(if (one-window-p) (setq mode-line-format nil))
(setq cursor-type nil)
(setq line-spacing 0)
(setq vertical-scroll-bar nil)
(setq horizontal-scroll-bar nil)
(setq fill-column width)
(face-remap-add-relative 'link :underline nil)
(if (not (display-graphic-p)) (menu-bar-mode 0))
;; Vertical padding to center
(insert-char ?\n padding-center)
(center-line)
(insert (propertize " _______ _____ ______ ________ ________ ________" 'face 'nano-face-strong) "\n")
(insert (propertize "|\\ ___ \\ |\\ _ \\ _ \\|\\ __ \\|\\ ____\\|\\ ____\\" 'face 'nano-face-strong) "\n")
(insert (propertize "\\ \\ __/|\\ \\ \\\\\\__\\ \\ \\ \\ \\|\\ \\ \\ \\___|\\ \\ \\___|_" 'face 'nano-face-strong) "\n")
(insert (propertize " \\ \\ \\_|/_\\ \\ \\\\|__| \\ \\ \\ __ \\ \\ \\ \\ \\_____ \\" 'face 'nano-face-strong) "\n")
(insert (propertize " \\ \\ \\_|\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\____\\|____|\\ \\" 'face 'nano-face-strong) "\n")
(insert (propertize " \\ \\_______\\ \\__\\ \\ \\__\\ \\__\\ \\__\\ \\_______\\____\\_\\ \\" 'face 'nano-face-strong) "\n")
(insert (propertize " \\|_______|\\|__| \\|__|\\|__|\\|__|\\|_______|\\_________\\" 'face 'nano-face-strong) "\n")
(insert (propertize " \\|_________|" 'face 'nano-face-strong) "\n")
(goto-char 0)
(read-only-mode t)
(local-set-key [t] 'nano-splash-kill)
(display-buffer-same-window splash-buffer nil)
(run-with-idle-timer 0.05 nil (lambda() (message nil)))
;; (run-with-idle-timer 0.50 nil 'nano-splash-fade-out-slow)
;; (if (fboundp 'nano-splash-help-message)
;; (run-with-idle-timer 0.55 nil 'nano-splash-help-message))
)
)))
(defun center-string (string)
"Pad a string with space on the left such as to center it"
(let* ((padding (/ (- (window-body-width) (length string)) 2))
(padding (+ (length string) padding)))
;; If the string is displayed as a tooltip, don't pad it
(if (and tooltip-mode (fboundp 'x-show-tip))
string
(format (format "%%%ds" padding) string))))
;; Mac only animation , available from
;; https://bitbucket.org/mituharu/emacs-mac/src/master/
;; https://github.com/railwaycat/homebrew-emacsmacport
(defvar mac-animation-locked-p nil)
(defun mac-animation-toggle-lock ()
(setq mac-animation-locked-p (not mac-animation-locked-p)))
(defun mac-animation-fade-out (duration &rest args)
(unless mac-animation-locked-p
(mac-animation-toggle-lock)
(mac-start-animation nil :type 'fade-out :duration duration)
(run-with-timer duration nil 'mac-animation-toggle-lock)))
(defun nano-splash-fade-out (duration)
"Fade out current frame for duration and goes to command-or-bufffer"
(interactive)
(defalias 'mac-animation-fade-out-local
(apply-partially 'mac-animation-fade-out duration))
(if (get-buffer "*splash*")
(progn (if (and (display-graphic-p) (fboundp 'mac-start-animation))
(advice-add 'set-window-buffer
:before 'mac-animation-fade-out-local))
(message nil)
(kill-buffer "*splash*")
(if (and (display-graphic-p) (fboundp 'mac-start-animation))
(advice-remove 'set-window-buffer
'mac-animation-fade-out-local)))))
(defun nano-splash-fade-out-slow ()
(interactive) (nano-splash-fade-out 1.00))
(defun nano-splash-fade-out-fast ()
(interactive) (nano-splash-fade-out 0.25))
(defun nano-splash-kill ()
"Kill the splash screen buffer (immediately)."
(interactive)
(if (get-buffer "*splash*")
(progn (message nil)
(cancel-function-timers 'nano-splash-fade-out-slow)
(cancel-function-timers 'nano-spash-help-message)
(kill-buffer "*splash*"))))
;; Install hook after frame parameters have been applied and only if
;; no option on the command line
(if (and (not (member "-no-splash" command-line-args))
(not (member "--file" command-line-args))
(not (member "--insert" command-line-args))
(not (member "--find-file" command-line-args))
;; (not inhibit-startup-screen)
)
(progn
(add-hook 'window-setup-hook 'nano-splash)
(setq inhibit-startup-screen t
inhibit-startup-message t
inhibit-startup-echo-area-message t)))
(nano-splash)
(provide 'nano-splash)