This configuration uses the use-package package from John Wiegley, which is a fantastic way to manage package configurations.
This file is used to generate config.el
using org-babel
in init.el
.
I’ve installed Emacs from source (git://git.savannah.gnu.org/emacs.git
).
git clone git://git.savannah.gnu.org/emacs.git
I used the instructions provided by Xah Lee given here.
But first, the following command has to be run.
git pull
./autogen.sh
Then to compile and install, do the following.
./configure --with-native-compilation --prefix=/usr/local --with-modules --with-json --with-cairo --with-rsvg
make -j4
sudo make install
(setq user-full-name "Nelson Loyola"
user-mail-address "[email protected]")
Set up the customize file to its own separate file, instead of saving customize settings in init.el.
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file)
Silence compiler warnings in native-mode
.
(setq comp-async-report-warnings-errors nil)
Also see: all-the-icons-dired package installation
(defvar nl/gui-fixed-font-name "FiraCode Nerd Font")
;;(defvar nl/gui-fixed-font-name "Ubuntu Nerd Font")
;; (defvar nl/gui-fixed-font-name "IBM Plex Mono Medium")
;; (defvar nl/gui-variable-font-name "DejaVu Sans")
;;(defvar nl/gui-fixed-font-name "GoMono Nerd Font")
(defvar nl/gui-variable-font-name "Go")
(defconst nl/gui-fixed-font-size-normal "10")
(defconst nl/gui-fixed-font-size-large "18")
(defconst nl/gui-variable-font-size-normal "12")
(defconst nl/gui-variable-font-size-large "18")
(defvar nl/gui-current-fixed-font-size nl/gui-fixed-font-size-normal)
(defvar nl/gui-current-variable-font-size nl/gui-variable-font-size-normal)
(defun nl/gui-font (font-name font-size)
(concat font-name "-" font-size))
(defun nl/gui-fixed-font-normal ()
(nl/gui-font nl/gui-fixed-font-name nl/gui-fixed-font-size-normal))
(defun nl/gui-fixed-font-large ()
(nl/gui-font nl/gui-fixed-font-name nl/gui-fixed-font-size-large))
(defun nl/gui-variable-font-normal ()
(nl/gui-font nl/gui-variable-font-name nl/gui-variable-font-size-normal))
(defun nl/gui-variable-font-large ()
(nl/gui-font nl/gui-variable-font-name nl/gui-variable-font-size-large))
;; see: https://github.com/daviwil/emacs-from-scratch/blob/d24357b488862223fecaebdad758b136b0ca96e7/show-notes/Emacs-Tips-08.org#configuring-the-ui-for-new-frames
(defun nl/set-fonts (frame)
"Set the desired fonts for a frame. FRAME can be nil."
(let ((fixed-font (nl/gui-fixed-font-normal)))
(set-face-font 'default fixed-font)
(set-face-font 'fixed-pitch fixed-font))
(set-face-font 'variable-pitch (nl/gui-variable-font-normal))
;;(set-face-attribute 'default frame :font nl/gui-fixed-font-name)
(set-face-attribute 'italic frame :font nl/gui-fixed-font-name :weight 'normal :slant 'italic)
(set-face-attribute 'bold frame :font nl/gui-fixed-font-name :weight 'bold :weight 'normal)
(set-face-attribute 'bold-italic frame :font nl/gui-fixed-font-name :weight 'bold :slant 'italic)
(set-fontset-font "fontset-default" nil (font-spec :size 20 :name "Fira Code Retina")))
(defun nl/after-make-frame (frame)
(nl/set-fonts frame))
(add-hook 'after-make-frame-functions 'nl/after-make-frame t)
(nl/set-fonts nil)
Does not really work when not using Fira Code fonts.
(use-package fira-code-mode
:custom (fira-code-mode-disabled-ligatures '("[]" "#{" "#(" "#_" "#_(" "x")) ;; List of ligatures to turn off
:hook prog-mode) ;; Enables fira-code-mode automatically for programming major modes
Not used since using Googles’ Go fonts. 2021-02-27
Input Font: Install it on Ubuntu as follows:
sudo apt-get install fonts-firacode
And here’s how to tell Emacs to use this font. Copy the following line to your ~/.Xresources
file.
Emacs.font: Input Mono Condensed-9
And then merge the setting to your X server resource database.
xrdb -merge ~/.Xresources
Using Fira Code now. See below.
(set-face-font 'default "Input Mono Condensed-14")
Not used since using Googles’ Go fonts. 2021-02-27
download from here: Symbola font
mv symbola.zip ~/.fonts
cd ~/.fonts
unzip symbola.zip
(set-fontset-font "fontset-default" nil
(font-spec :size 20 :name "Symbola"))
(when (featurep 'ns-win) (set-face-font 'default "Monaco-15"))
(use-package emacs
:hook
;; Make completion buffers disappear after 15 seconds.
(completion-setup . (lambda ()
(run-at-time 15 nil
(lambda ()
(delete-windows-on "*Completions*")))))
;; Remove trailing whitespace
(before-save . delete-trailing-whitespace)
:bind
("C-z" . nil) ;; I never want to suspend the frame
)
Some commands are disabled by default. They are enabled in our config using the following:
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'dired-find-alternate-file 'disabled nil)
(put 'erase-buffer 'disabled nil)
;; Sentences end with a single space.
(setq sentence-end-double-space nil)
;; Set the default major mode to =text-mode=. By default it's =fundamental= mode which is
;; not what we want. Also, use =text-mode= for the scratch buffer.
(setq default-major-mode 'text-mode
initial-major-mode 'text-mode)
;; Don't scroll to middle of the page. Also, scroll line by line, without
;; scrolloff and try to keep point at the same visual place when
;; scrolling by page.
(setq-default scroll-up-aggressively 0.01 scroll-down-aggressively 0.01)
(setq redisplay-dont-pause t
scroll-step 1
scroll-margin 3
scroll-conservatively 10
scroll-preserve-screen-position t)
;; Level of decoration {1 - 3}, t = max.
(setq font-lock-maximum-decoration t)
;; For symlinks, automatically follow the link and visit the real file instead.
(setq vc-follow-symlinks nil)
;; Make searches case insensitive.
(setq-default case-fold-search t)
;; Autosave files are created between saves after a sufficient timeout in
;; the current directory for crash detection, they begin and end with
;; =#=. Change this location to the emacs directory.
(setq auto-save-list-file-prefix "~/.emacs.d/autosave/"
auto-save-file-name-transforms `((".*" "~/.emacs.d/autosave/" t)))
;;Set line wrap at column 100.
(setq fill-column 100)
;; Replace =yes or no= prompt with =y or n= prompt.
(fset 'yes-or-no-p 'y-or-n-p)
;; Use UTF-8 everywhere.
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
;; Use spaces instead of tabs.
(setq-default indent-tabs-mode nil)
;; Delete the region when typing, just like as we expect nowadays.
(delete-selection-mode t)
;; Highlight matches in query-replace mode.
(setq query-replace-highlight t)
;; Use visual line mode to display long lines.
(global-visual-line-mode -1)
;;Revert these files without asking.
(setq revert-without-query '(".*"))
;; Middle-clicking is nice to paste, however it should not adjust point
;; and paste at the then adjusted point.
(setq mouse-yank-at-point t)
;; Save clipboard data of other programs in the kill ring when possible.
(setq save-interprogram-paste-before-kill t)
;; Set environment variable for shells.
(setenv "PAGER" "cat")
;; Configure =next-buffer= and =previous-buffer= to only visit file
;; buffers (has to be called for each frame):
(set-frame-parameter (selected-frame) 'buffer-predicate #'buffer-file-name)
;; These are taken from
;; https://github.com/patrickt/emacs/blob/master/init.el:
(setq
kill-whole-line t ; Lets C-k delete the whole line
;;default-directory "~/src/" ; My code lives here
enable-recursive-minibuffers t ; don't freak out if I use the minibuffer twice
sentence-end-double-space nil ; are you kidding me
confirm-kill-processes nil ; don't when quitting
)
(setq-default
cursor-type 'box
indent-tabs-mode nil
cursor-in-non-selected-windows nil)
;; Cursor Movement
(setq auto-window-vscroll nil)
;; Turn off auto-save.
(setq auto-save-default nil)
;; Don't make any backup files.
(setq make-backup-files nil)
;; Get rid of the menu bar. Tool bar and scroll bars are disabled in
;; ~init.el~..
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
;; Turn off the blinking cursor.
(blink-cursor-mode -1)
;; Don't use dialog boxes
(setq use-dialog-box nil)
;; Don't want an audible bell.
(setq visible-bell t)
;; Display the running program and the selected buffer in the frame title.
(setq frame-title-format
'("" invocation-name ": " (:eval (replace-regexp-in-string
"^ +" "" (buffer-name)))))
;; Don't add new lines past end of file, and indicate unused lines at the
;; end of the window with a small image in the left fringe.
(setq next-line-add-newlines nil)
(setq-default indicate-empty-lines t)
;; Add =\n= to end of file if required.
(setq require-final-newline t)
;; Eshell
(setq eshell-history-size 100000)
;; Follow Buffer
(add-to-list 'auto-mode-alist '("\\.log\\'" . auto-revert-mode))
;; Don’t compact font caches during GC.
(setq inhibit-compacting-font-caches t)
;; Automatically cycle through the highlighting faces listed in
;; ~hi-lock-face-defaults~ instead of bothering the user to pick a face
;; each time.
(setq hi-lock-auto-select-face t)
;; History
(setq history-delete-duplicates t)
;; Use the directory name to make buffer names unique.
(setq uniquify-buffer-name-style 'forward)
http://pragmaticemacs.com/emacs/dont-kill-buffer-kill-this-buffer-instead/
(defun nl/kill-this-buffer ()
"Kill the current buffer."
(interactive)
(kill-buffer (current-buffer)))
;; (defun nl/helm-compile ()
;; "Use Helm to choose a compile command."
;; (interactive)
;; (let ((selected-command
;; (helm-comp-read "Select a compile command: " compile-history :buffer "Helm compile commands")))
;; ;; move this command to the front of the history
;; (setq compile-history (remove selected-command compile-history))
;; (add-to-list 'compile-history selected-command)
;; (compile selected-command)))
;; (defun nl/counsel-git-files ()
;; (interactive)
;; (let ((counsel-fzf-cmd "git ls-files | fzf -f \"%s\""))
;; (counsel-fzf)))
(global-set-key (kbd "M-%") 'query-replace-regexp)
;;(global-set-key "\C-x\C-e" 'compile)
(global-set-key (kbd "C-S-s") 'isearch-forward)
(global-set-key (kbd "C-x C-n") 'next-error)
(global-set-key (kbd "C-x k") 'nl/kill-this-buffer)
(global-set-key (kbd "M-f") 'forward-to-word)
(global-set-key (kbd "M-B") 'backward-to-word)
(global-set-key (kbd "<f1>") 'indent-for-tab-command)
(global-set-key (kbd "S-<f1>") 'indent-region)
(global-set-key (kbd "<f2>") '(lambda () (interactive) (save-some-buffers t)))
(global-set-key (kbd "S-<f2>") '(lambda () (interactive) (revert-buffer t t)))
;;(global-set-key (kbd "S-<f3>") 'helm-projectile-rg)
(global-set-key (kbd "M-S-<f3>") 'counsel-rg)
(global-set-key [f5] 'nl/helm-compile)
(global-set-key (kbd "S-<f5>") 'toggle-truncate-lines)
(global-set-key (kbd "<f8>") 'window-toggle-side-windows)
(global-set-key (kbd "S-<f11>") 'eval-region)
(global-set-key (kbd "C-S-<f11>") 'align-regexp)
;;(global-set-key (kbd "C-c o") 'nl/counsel-git-files)
Recently, line numbering has been really slow. Disabling for now.
(dolist (mode-hook '(text-mode-hook prog-mode-hook))
(add-hook mode-hook 'linum-mode))
Emacs 26 added global-display-line-numbers-mode
:
(dolist (mode-hook '(prog-mode-hook))
(when (version<= "26.0.50" emacs-version)
(add-hook mode-hook 'display-line-numbers-mode)))
Case sensitive tags search:
(set-default 'tags-case-fold-search nil)
Don’t like this: disabling. 2021-02-28
(setq text-mode-hook
'(lambda ()
(turn-on-auto-fill))) ; Enable automatic line wrapping
To reduce the risk of loading outdated byte code files, we set load-prefer-newer and enable auto-compile-on-load-mode as early as possible.
(setq load-prefer-newer t)
(defun nl/indent-whole-buffer ()
(interactive)
(save-excursion
(indent-region (point-min) (point-max))))
(defun nl/beginning-of-line-or-indentation ()
"move to beginning of line, or indentation"
(interactive)
(if (bolp)
(back-to-indentation)
(beginning-of-line)))
(defun nl/common-prog-mode-settings ()
"Enables settings common between programming language modes."
(nl/setup-indent 2) ; indent 2 spaces width
(local-set-key (kbd "<home>") 'nl/beginning-of-line-or-indentation)
(subword-mode 1)
;;
;; Set tab and CR/LF keys to call their corresponding more-general
;; functions. This needs to be here to override the settings of some modes
;; (e.g. c++-mode changes the tab key to do a re-indent).
;;
(local-set-key "\t" 'tab-to-tab-stop)
(local-set-key "\n" 'newline-and-indent)
(local-set-key "\r" 'newline-and-indent)
;;
;; Set paragraph/comment auto-formatting to wrap at column 100.
;;
(set-fill-column 100)
;;
;; Set the comment column to zero so that lisp comment lines will act like
;; C++ comments (i.e. line up with the code), and not automatically indent
;; to column 50.
;;
(setq comment-column 0)
(push '(">=" . ?≥) prettify-symbols-alist)
(push '("<=" . ?≤) prettify-symbols-alist)
(push '("->" . ?→) prettify-symbols-alist)
(smartparens-mode))
(add-hook 'makefile-mode-hook 'nl/common-prog-mode-settings)
(add-hook 'sh-mode-hook 'nl/common-prog-mode-settings)
(add-hook 'prog-mode-hook 'nl/common-prog-mode-settings)
(when (equal system-type 'gnu/linux)
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "/usr/bin/brave-browser"
browse-url-generic-args '("--force-device-scale-factor=1.4")))
(setenv "BROWSER" "google-chrome")
https://www.gnu.org/software/emacs/manual/html_node/elisp/Side-Windows.html#Side-Windows
(defvar nl/side-window-parameters
'(window-parameters . ((no-other-window . nil)
(no-delete-other-windows . t))))
(setq fit-window-to-buffer-horizontally t)
(setq window-resize-pixelwise t)
;; (setq display-buffer-alist '())
;; (defun nl/display-buffer-debug(buf-name action)
;; (message "%s" buf-name)
;; (numberp (string-match "\\(?:\\*\\(?:[Hh]elp\\|grep\\|Warnings\\|Completions\\|xref\\)\\)\\*\\)\\|\\(?:\\(?:HELM.*\\|helm.*\\)\\)" buf-name)))
(add-to-list 'display-buffer-alist
'("\\(?:\\*\\(?:grep\\|Find\\|Warnings\\|xref\\)\\*\\)\\|\\(?:\\(?:HELM.*\\|helm.*\\)\\)"
display-buffer-in-side-window
(window-height . 0.15)
(side . bottom)
(slot . -1) ;; left side
(preserve-size . (nil . t))
,nl/side-window-parameters))
(add-to-list 'display-buffer-alist
'("\\*\\(?:[Hh]elp\\|Backtrace\\|Warnings\\|Completions\\|Compile-Log\\|\\*Flycheck.*\\|shell\\|compilation\\|ng-compile\\|ng-test\\|tide-references\\|sbt\\|coverlay-stats\\)\\*"
display-buffer-in-side-window
(window-height . 0.15)
(side . bottom)
(slot . 1) ;; right side
(preserve-size . (nil . t))
,nl/side-window-parameters))
(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8)
(setq split-height-threshold 160
split-width-threshold nil)
Use spaces instead of \t
character.
(setq-default indent-tabs-mode nil)
A way to set up indentation for all programming modes. Taken from here.
(defun nl/setup-indent (n)
;; java / c / c++ / php
(setq-default c-basic-offset n
javascript-indent-level n ; javascript-mode
js-indent-level n ; js-mode
js2-basic-offset n ; js2-mode, in latest js2-mode, it's alias of js-indent-level
js2-strict-missing-semi-warning nil ;
web-mode-markup-indent-offset n ; web-mode, html tag in html file
web-mode-css-indent-offset n ; web-mode, css in html file
web-mode-code-indent-offset n ; web-mode, js code in html file
css-indent-offset n)) ; css-mode
(setq emacs-lisp-mode-hook 'nl/common-prog-mode-settings)
Revert file buffers updated outside of emacs, unless I’ve made changes to the buffer which I haven’t saved.
(use-package autorevert
:diminish auto-revert-mode
:hook (dired-mode . auto-revert-mode)
:config
(setq global-auto-revert-non-file-buffers t
auto-revert-verbose nil)
(global-auto-revert-mode 1))
(use-package ansi-color
:config
(defun ansi-colorize-current-buffer ()
"Colorize ansi escape sequences in the current buffer."
(interactive)
(ansi-color-apply-on-region (point-min) (point-max))))
Prefer saving this file somewhere other than the default.
(setq bookmark-default-file "~/.emacs.d/etc/bookmarks")
Do not ask me to save files before compiling, or kill a previous compilation. Also scroll to the end of the compilation buffer when it is opened.
Enable ANSI colors for compilation buffers.
(use-package compile
;;:bind (("C-c c" . compile)
;; ("M-O" . show-compilation))
:preface
(defun show-compilation ()
(interactive)
(let ((compile-buf
(catch 'found
(dolist (buf (buffer-list))
(if (string-match "\\*compilation\\*" (buffer-name buf))
(throw 'found buf))))))
(if compile-buf
(switch-to-buffer-other-window compile-buf)
(call-interactively 'compile))))
(defun compilation-ansi-color-process-output ()
(ansi-color-process-output nil)
(set (make-local-variable 'comint-last-output-start)
(point-marker)))
;; (defun colorize-compilation-buffer ()
;; (let ((inhibit-read-only t))
;; (ansi-color-apply-on-region (point-min) (point-max))))
;; (add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
:config
(setq compilation-ask-about-save nil
compilation-always-kill t
compilation-scroll-output t)
:hook (compilation-filter . compilation-ansi-color-process-output))
(use-package cc-mode
:mode (("\\.h\\(h?\\|xx\\|pp\\)\\'" . c++-mode)
("\\.m\\'" . c-mode)
("\\.mm\\'" . c++-mode)
("\\.java\\'" . java-mode))
:preface
(defconst nelson-c-style
'((c-tab-always-indent . t)
(c-set-style "K&R")
(c-offsets-alist . ((statement-block-intro . +)
(substatement-open . 0)
(label . 0)
(case-label . +)
(statement-cont . +)
(innamespace . 0))))
"Nelson programming style.")
;; Customizations for all of c-mode, c++-mode, and objc-mode
(defun nl/c-mode-common-hook ()
;; add my personal style and set it for the current buffer
(c-add-style "NELSON-c-mode" nelson-c-style t)
;; offset customizations not in nelson-c-style
(c-set-offset 'member-init-intro '++)
;; other customizations
;;(c-toggle-auto-state 1) ;; Turn on auto newline
(nl/common-prog-mode-settings)
;; makes the underscore part of a word in C and C++ modes
(modify-syntax-entry ?_ "w" c++-mode-syntax-table)
(modify-syntax-entry ?_ "w" c-mode-syntax-table)
(lambda ()
(when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
(ggtags-mode 1)))
)
(defun nl/java-mode-hook ()
(setq indent-tabs-mode nil)
(setq c-basic-offset 2)
;;(setq zeal-at-point-docset "java")
;;(eclim-mode t)
)
:hook ((c-mode-common . nl/c-mode-common-hook)
(java-mode . nl/java-mode-hook)))
(use-package cperl-mode
:preface
(defun nl/cperl-setup ()
(cperl-set-style "C++")
(nl/common-prog-mode-settings))
:hook (cperl-mode . nl/cperl-setup))
(desktop-save-mode 1)
Make dired show directories first. Dired buffers should auto revert and not give any use feedback (source: Magnars Sveen).
(use-package dired
:ensure nil
:custom
(dired-recursive-copies 'always)
;; Auto refresh Dired, but be quiet about it
(global-auto-revert-non-file-buffers t)
;; Move files to trash when deleting
(delete-by-moving-to-trash t)
(dired-dwim-target t)
(find-file-visit-truename t)
:config
(setq dired-listing-switches "-aBhl --group-directories-first")
;; Reuse same dired buffer, to prevent numerous buffers while navigating in dired
(put 'dired-find-alternate-file 'disabled nil)
:hook ((dired-mode . dired-hide-details-mode)
(dired-mode . hl-line-mode)
(dired-mode . (lambda ()
(local-set-key (kbd "<mouse-2>") #'dired-find-alternate-file)
;;(local-set-key (kbd "RET") #'dired-find-alternate-file)
(local-set-key (kbd "^")
(lambda () (interactive) (find-alternate-file "..")))))))
(use-package ediff
:custom
(ediff-split-window-function 'split-window-horizontally)
(ediff-merge-split-window-function 'split-window-horizontally)
(ediff-window-setup-function 'ediff-setup-windows-plain)
(ediff-diff-options "-w")
:config
(setq-default ediff-ignore-similar-regions t)
(add-hook 'ediff-after-quit-hook-internal 'winner-undo))
(use-package edit-server
:if window-system
:init
(add-hook 'after-init-hook 'server-start t)
(add-hook 'after-init-hook 'edit-server-start t))
(use-package flyspell-correct)
(use-package flyspell
:requires flyspell-popup
:diminish flyspell-mode
:hook ((prog-mode-hook . flyspell-prog-mode)
(text-mode-hook . flyspell-mode))
:bind (:map flyspell-mode-map
("C-;" . flyspell-correct-wrapper))
:config
;; Sets flyspell correction to use two-finger mouse click
(setq ispell-dictionary "en_CA-wo_accents")
(define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word))
Find aspell and hunspell automatically.
Taken from here: http://blog.binchen.org/posts/what-s-the-best-spell-check-set-up-in-emacs.html
;; if (aspell installed) { use aspell}
;; else if (hunspell installed) { use hunspell }
;; whatever spell checker I use, I always use English dictionary
;; I prefer use aspell because:
;; 1. aspell is older
;; 2. looks Kevin Atkinson still get some road map for aspell:
;; @see http://lists.gnu.org/archive/html/aspell-announce/2011-09/msg00000.html
(defun flyspell-detect-ispell-args (&optional run-together)
"if RUN-TOGETHER is true, spell check the CamelCase words."
(let (args)
(cond
((string-match "aspell$" ispell-program-name)
;; Force the English dictionary for aspell
;; Support Camel Case spelling check (tested with aspell 0.6)
(setq args (list "--sug-mode=ultra" "--lang=en_CA"))
(if run-together
(setq args (append args '("--run-together" "--run-together-limit=5" "--run-together-min=2")))))
((string-match "hunspell$" ispell-program-name)
;; Force the English dictionary for hunspell
(setq args "-d en_CA")))
args))
(cond
((executable-find "aspell")
;; you may also need `ispell-extra-args'
(setq ispell-program-name "aspell"
ispell-dictionary "en_CA"
ispell-local-dictionary "en_CA"))
((executable-find "hunspell")
(setq ispell-program-name "hunspell")
;; Please note that `ispell-local-dictionary` itself will be passed to hunspell cli with "-d"
;; it's also used as the key to lookup ispell-local-dictionary-alist
;; if we use different dictionary
(setq ispell-dictionary "en_CA"
ispell-local-dictionary "en_CA"
ispell-local-dictionary-alist
'(("en_CA" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_CA") nil utf-8))))
(t (setq ispell-program-name nil)))
;; ispell-cmd-args is useless, it's the list of *extra* arguments we will append to the ispell process when "ispell-word" is called.
;; ispell-extra-args is the command arguments which will *always* be used when start ispell process
;; Please note when you use hunspell, ispell-extra-args will NOT be used.
;; Hack ispell-local-dictionary-alist instead.
(setq-default ispell-extra-args (flyspell-detect-ispell-args t))
;; (setq ispell-cmd-args (flyspell-detect-ispell-args))
(defadvice ispell-word (around nl/ispell-word activate)
(let ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)
))
(defadvice flyspell-auto-correct-word (around nl/flyspell-auto-correct-word activate)
(let ((old-ispell-extra-args ispell-extra-args))
(ispell-kill-ispell t)
;; use emacs original arguments
(setq ispell-extra-args (flyspell-detect-ispell-args))
ad-do-it
;; restore our own ispell arguments
(setq ispell-extra-args old-ispell-extra-args)
(ispell-kill-ispell t)
))
(defun text-mode-hook-setup ()
;; Turn off RUN-TOGETHER option when spell check text-mode
(setq-local ispell-extra-args (flyspell-detect-ispell-args)))
(add-hook 'text-mode-hook 'text-mode-hook-setup)
ibuffer is the improved version of list-buffers.
(use-package ibuffer
:preface
(setq ibuffer-show-empty-filter-groups nil
ibuffer-saved-filter-groups
'(("home"
("emacs-config" (filename . ".emacs.d"))
("org" (or (mode . org-mode)
(filename . "OrgMode")))
("dired" (mode . dired-mode))
("scala" (mode . scala-mode))
("JS" (mode . js2-mode))
("html" (mode . web-mode))
("php" (mode . php-mode))
("code" (filename . "src"))
("Magit" (name . "\*magit"))
("Helm" (name . "\*helm"))
("Help" (or (name . "\*Help\*")
(name . "\*Apropos\*")
(name . "\*info\*"))))))
(defalias 'list-buffers 'ibuffer)
:hook (ibuffer-mode . (lambda() (ibuffer-switch-to-saved-filter-groups "home"))))
(defun nl/org-mode-setup ()
(org-indent-mode)
(variable-pitch-mode)
(auto-fill-mode 0)
(visual-line-mode)
(diminish org-indent-mode)
(define-key org-mode-map (kbd "C-c l") 'org-store-link)
(define-key org-mode-map (kbd "C-c a") 'org-agenda)
(define-key org-mode-map (kbd "M-<left>") nil)
(define-key org-mode-map (kbd "M-<right>") nil)
(define-key org-mode-map (kbd "M-<down>") nil)
(define-key org-mode-map (kbd "M-<up>") nil)
(smartparens-mode))
;; (nl/org-mode-faces 120)
(defun nl/org-mode-faces (font-height)
(require 'org)
(dolist (face '((org-level-1 . 1.2)
(org-level-2 . 1.1)
(org-level-3 . 1.05)
(org-level-4 . 1.05)
(org-level-5 . 1.05)
(org-level-6 . 1.05)
(org-level-7 . 1.05)
(org-level-8 . 1.05)))
(set-face-attribute (car face) nil :font nl/gui-variable-font-name :weight 'regular :height (cdr face)))
(require 'org-indent)
(require 'org-tempo)
;; Ensure that anything that should be fixed-pitch in Org files appears that way
(set-face-attribute 'org-block nil :font nl/gui-fixed-font-name :height font-height :weight 'semi-bold)
(set-face-attribute 'org-code nil :font nl/gui-fixed-font-name :height font-height :weight 'semi-bold)
(set-face-attribute 'org-indent nil :inherit '(org-hide fixed-pitch) :height font-height)
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch) :height font-height)
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch) :height font-height)
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch) :height font-height)
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch :height font-height)
(set-face-attribute 'org-table nil :inherit 'fixed-pitch :height font-height)
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch :height font-height))
(use-package org
:pin org
:hook (org-mode . nl/org-mode-setup)
:custom-face
(org-table ((t :foreground "#91b831")))
:config
(setq org-ellipsis " ⤵"
org-hide-emphasis-markers t
org-catch-invisible-edits 'error
org-startup-indented t
org-cycle-include-plain-lists 'integrate
org-return-follows-link t
org-M-RET-may-split-line nil
org-src-fontify-natively t
org-src-preserve-indentation t
org-edit-src-content-indentation 0
org-enforce-todo-dependencies t
org-enforce-todo-checkbox-dependencies t
;; org-link-frame-setup '((file . find-file))
org-export-backends '(ascii html icalendar latex md)
org-log-into-drawer t)
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "~/Dropbox/orgfiles/todo.org" "Tasks")
"* TODO %?\n %i\n %a")
("l" "Link" entry (file+headline "~/Dropbox/orgfiles/links.org" "Links")
"* %? %^L %^g \n%T" :prepend t)
("n" "Note" entry (file "~/Dropbox/orgfiles/notes.org")
"* NOTE %?\n%U" :empty-lines 1)
("N" "Note with Clipboard" entry (file "~/Dropbox/orgfiles/notes.org")
"* NOTE %?\n%U\n %c" :empty-lines 1)
("j" "Journal" entry (file+datetree "~/Dropbox/orgfiles/journal.org")
"* %?\nEntered on %U\n %i\n %a")))
(nl/org-mode-faces (* 10 (string-to-number nl/gui-fixed-font-size-normal))))
Learned about this delq
and mapcar
trick from Sacha Chua’s config.
(setq org-agenda-files
(delq nil
(mapcar (lambda (x) (and (file-exists-p x) x))
'("~/Dropbox/orgfiles/todo.org"
"~/Dropbox/orgfiles/cbsr_todo.org"))))
(bind-key "C-c c" 'org-capture)
(setq org-default-notes-file "~/Dropbox/orgfiles/notes.org")
Speed commands are a nice and quick way to perform certain actions while at the beginning of a heading. It’s not activated by default.
(setq org-use-speed-commands t
org-image-actual-width 550)
The default value is -77, which is weird for smaller width windows. I’d rather have the tags align horizontally with the header. 45 is a good column number to do that.
(setq org-tags-column 45)
(with-eval-after-load 'org
(org-babel-do-load-languages
'org-babel-load-languages
'((C . t)
(calc . t)
(emacs-lisp . t)
(latex . t)
(java . t)
(js . t)
(python . t)
(ruby . t)
(shell . t)
(sql . t)
(sqlite . t)))
(defun nl/org-confirm-babel-evaluate (lang body)
"Do not confirm evaluation for these languages."
(not (or (string= lang "C")
(string= lang "emacs-lisp")
(string= lang "java")
(string= lang "python")
(string= lang "sh")
(string= lang "sql")
(string= lang "sqlite"))))
(setq org-confirm-babel-evaluate 'nl/org-confirm-babel-evaluate))
Have source blocks properly syntax highlighted and with the editing popup window staying within the same window so all the windows don’t jump around. Also, having the top and bottom trailing lines in the block is a waste of space, so we can remove them.
Fontification doesn’t work with markdown mode when the block is indented after editing it in the org src buffer—the leading #s for headers don’t get fontified properly because they appear as Org comments.
(setq org-src-window-setup 'current-window
org-src-strip-leading-and-trailing-blank-lines t
org-src-tab-acts-natively t)
(with-eval-after-load 'org
;; This is needed as of Org 9.2
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python")))
(use-package paren
:hook
(prog-mode . (lambda () (show-paren-mode t)))
:custom-face
(show-paren-match ((t (:background "#def" :box nil))))
:custom
(show-paren-style 'parenthesis))
Interactive preview for RE construction.
It’s important to note that there’s three flavours of regular
expressions encountered in Emacs. The read
syntax is most
reminiscent of other RE dialects, but only used in prompts. The
string
syntax is used in code doubles the amount of backslashes as
the RE strings are passed through the reader which removes the
extraneous ones. Finally, there’s the rx
macro one can use for
writing lispy RE.
All listed RE syntaxes are supported by re-builder
. For whatever
reason though the read
syntax is default. I prefer having the
string
syntax as default.
(setq reb-re-syntax 'string)
Recentf is a minor mode that builds a list of recently opened files. This list is is automatically saved across Emacs sessions.
Prefer saving the history of opened files somewhere other than the default.
(use-package recentf
:init (recentf-mode 1)
:custom
(recentf-save-file "~/.emacs.d/etc/recentf")
(recentf-max-saved-items 100))
The history of prompts like M-:
can be saved, but let’s change its
save file and history length first. Also save search entries.
(setq savehist-additional-variables '(search-ring regexp-search-ring)
savehist-file "~/.emacs.d/etc/savehist"
history-length 150)
(savehist-mode 1)
Remember position in a file.
(use-package saveplace
:custom
(save-place-file (locate-user-emacs-file "etc/saveplace" "places"))
(save-place-forget-unreadable-files nil)
(save-place-ignore-files-regexp "\\(?:COMMIT_EDITMSG\\|svn-commit\\.tmp\\|config\\.org\\)$")
;; activate it for all buffers
:init
;;(setq-default save-place t)
(save-place-mode t))
(use-package shell
:bind (("C-x m" . shell)
("C-x M" . ansi-term))
:hook (shell-mode . 'ansi-color-for-comint-mode-on))
(use-package simple
:diminish visual-line-mode
:config
;; Display the column number in the mode line.
(column-number-mode t))
(use-package smerge-mode
:config
(setq smerge-command-prefix "\C-cv"))
This configuration allows me to connect to predefined MySQL servers.
Save command history between sessions (taken from EmacsWiki).
(use-package sql
:commands (nl/sql-connect-server)
:hook
(sql-interactive-mode . nl/sql-save-history-hook)
:preface
(defun nl/sql-save-history-hook ()
(let ((lval 'sql-input-ring-file-name)
(rval 'sql-product))
(if (symbol-value rval)
(let ((filename
(concat "~/.emacs.d/sql/"
(symbol-name (symbol-value rval))
"-history.sql")))
(set (make-local-variable lval) filename))
(error
(format "SQL history will not be saved because %s is nil"
(symbol-name rval))))))
:config
(require 'epa-file)
(epa-file-enable)
(setq sql-connection-alist
'((localhost.dev (sql-product 'mysql)
(sql-port 3306)
(sql-server "localhost")
(sql-user "root")
(sql-database "mysql"))))
(defun nl/sql-connect (product connection)
"Connects to a database server of type PRODUCT using the CONNECTION type."
(require 'nl-passwords (concat user-emacs-directory "nl/password.el.gpg"))
;; update the password to the sql-connection-alist
(let ((connection-info (assoc connection sql-connection-alist))
(sql-password (car (last (assoc connection nl-sql-passwords)))))
(delete sql-password connection-info)
(nconc connection-info `((sql-password ,sql-password)))
(setq sql-connection-alist (assq-delete-all connection sql-connection-alist))
(add-to-list 'sql-connection-alist connection-info))
;; connect to database
(setq sql-product product)
(if current-prefix-arg
(sql-connect connection connection)
(sql-connect connection)))
(defun nl/sql-localhost-dev ()
"Connects to the MySQL server running on machine 'localhost'."
(nl/sql-connect 'mysql 'localhost.dev))
(defun nl/sql-obelix-dev ()
"Connects to the MySQL server running on machine 'obelix'."
(nl/sql-connect 'mysql 'obelix.dev))
(defvar nl/sql-servers-list
'(("localhost dev" nl/sql-localhost-dev)
;;("Obelix Dev" nl/sql-obelix-dev)
)
"A list of server name and the function to connect.")
(defun nl/sql-connect-server (func)
"Connect to the input server using nl/sql-servers-list and FUNC."
(interactive
(helm-comp-read "Select server: " nl/sql-servers-list))
(funcall func)))
(use-package subword
:diminish subword-mode)
(use-package tramp
:init
(setq tramp-ssh-controlmaster-options nil)
:config
(let ((cert-path "~/.ssh/id_dsa")
(ssh-methods '("ssh" "sshx"))))
(setq tramp-terminal-type "dumb"
tramp-shell-prompt-pattern "^[^$>\n]*[#$%>] *\\(\[[0-9;]*[a-zA-Z] *\\)*"
vc-ignore-dir-regexp (format "\\(%s\\)\\|\\(%s\\)" vc-ignore-dir-regexp tramp-file-name-regexp)
tramp-inline-compress-start-size 1000
tramp-copy-size-limit 10000
vc-handled-backends '(Git)
tramp-verbose 1
tramp-default-method "scp"
tramp-use-ssh-controlmaster-options nil
projectile--mode-line "Projectile"
tramp-verbose 1))
/ssh:you@remotehost|sudo:remotehost:/path/to/file
(use-package term
:bind (("C-x M" . ansi-term)))
(use-package vc
:config
(setq vc-find-revision-no-save t))
(use-package vc-git
:ensure nil
:config
(setq vc-git-diff-switches "--patch-with-stat")
(setq vc-git-print-log-follow t))
windmove
provides useful commands for moving window focus by
direction.
(windmove-default-keybindings 'meta)
Window management. C-c left (winner-undo)
undoes the last window
configuration change. Redo the changes using C-c right
(winner-redo)
. Also move from window to window using Meta and the
direction keys.
(use-package winner
:demand t
:config
(winner-mode))
(use-package whitespace
:bind ("S-<f10>" . whitespace-mode))
Using doom themes
(use-package doom-themes
:demand 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-gruvbox t)
;;
(set-face-attribute 'font-lock-comment-face nil :weight 'semi-bold :slant 'italic)
(set-face-background 'region (doom-darken 'blue 0.2))
(set-face-font 'mode-line (nl/gui-variable-font-normal))
(set-face-font 'mode-line-inactive (nl/gui-variable-font-normal))
;; Enable flashing mode-line on errors
(doom-themes-visual-bell-config)
;; or for treemacs users
;;(setq doom-themes-treemacs-theme "doom-colors") ; use the colorful treemacs theme
(doom-themes-treemacs-config)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config)
)
(with-eval-after-load 'markdown-mode
(set-face-foreground 'markdown-code-face (doom-darken 'green 0.2))
(set-face-background 'markdown-code-face (doom-color 'brightblack))
;;(set-face-background 'org-block (doom-color 'brightblack))
(set-face-attribute 'markdown-header-face
nil
:font nl/gui-variable-font-name
:weight 'bold
:height (* 12 (string-to-number nl/gui-current-variable-font-size)))
(set-face-attribute 'markdown-link-face
nil
:font nl/gui-variable-font-name
:weight 'bold
:height (* 10 (string-to-number nl/gui-current-variable-font-size)))
)
Loading themes (https://www.reddit.com/r/emacs/comments/fefwpw/show_your_themes/)
(defun ap/load-doom-theme (theme)
"Disable active themes and load a Doom theme."
(interactive (list (intern (completing-read "Theme: "
(->> (custom-available-themes)
(-map #'symbol-name)
(--select (string-prefix-p "doom-" it)))))))
(ap/switch-theme theme))
(defun ap/switch-theme (theme)
"Disable active themes and load THEME."
(interactive (list (intern (completing-read "Theme: "
(->> (custom-available-themes)
(-map #'symbol-name))))))
(mapc #'disable-theme custom-enabled-themes)
(load-theme theme 'no-confirm))
(use-package dracula-theme
:disabled
:config
(load-theme 'dracula t)
;; default region color is too hard to see on my display
:custom-face
;; (region ((t (:background "#0f3b82"))))
(font-lock-warning-face ((t (:background "#0f3b82"))))
(font-lock-negation-char-face ((nil :foreground "red" :background "#0f3b82")))
(ediff-odd-diff-A ((nil :background "#862b27")))
(ediff-even-diff-A ((nil :background "#1f772c")))
(ediff-current-diff-A ((nil :background "#2b538a")))
(ediff-odd-diff-B ((nil :background "#862b27")))
(ediff-even-diff-B ((nil :background "#1f772c")))
(ediff-current-diff-B ((nil :background "#2b538a")))
(ediff-odd-diff-C ((nil :background "#862b27")))
(ediff-even-diff-C ((nil :background "#1f772c")))
(ediff-current-diff-C ((nil :background "#2b538a"))))
Trying out Bubbleberry theme: 2019-02-25 Switched to Dracula theme: 2019-04-10
(use-package bubbleberry-theme
:custom-face
;; default region color is too hard to see on my display
(region ((t (:background "#0f3b82"))))
(font-lock-warning-face ((t (:background "#0f3b82"))))
(font-lock-negation-char-face ((nil :foreground "red" :background "#0f3b82")))
(ediff-odd-diff-A ((nil :background "#862b27")))
(ediff-even-diff-A ((nil :background "#1f772c")))
(ediff-current-diff-A ((nil :background "#2b538a")))
(ediff-odd-diff-B ((nil :background "#862b27")))
(ediff-even-diff-B ((nil :background "#1f772c")))
(ediff-current-diff-B ((nil :background "#2b538a")))
(ediff-odd-diff-C ((nil :background "#862b27")))
(ediff-even-diff-C ((nil :background "#1f772c")))
(ediff-current-diff-C ((nil :background "#2b538a"))))
:config
(load-theme 'bubbleberry t))
(use-package cyberpunk-theme
:config
(load-theme 'cyberpunk t))
(use-package kaolin-themes
:config
;;(load-theme 'base16-solarized-dark t)
(setq kaolin-wave t
kaolin-hl-line-colored t)
(load-theme 'kaolin-dark))
TextMate like theme.
(use-package monokai-theme
:config
(load-theme 'monokai t)
(setq frame-background-mode `dark)
(setq monokai-use-variable-pitch nil))
(use-package paganini-theme
:config
(load-theme 'paganini t))
(use-package solarized-theme
:config
(load-theme 'solarized-dark t))
Tried out new theme: 2019-08-04
(use-package suscolors-theme
:custom-face
;; '(region ((t (:background "#0f3b82"))))
;; '(font-lock-warning-face ((t (:background "#0f3b82"))))
;; '(font-lock-negation-char-face ((nil :foreground "red" :background "#0f3b82")))
(vterm-color-black ((t (:foreground "#000000" :background "#777777"))))
(ediff-odd-diff-A ((nil :background "#862b27")))
(ediff-even-diff-A ((nil :background "#1f772c")))
(ediff-current-diff-A ((nil :background "#2b538a")))
(ediff-odd-diff-B ((nil :background "#862b27")))
(ediff-even-diff-B ((nil :background "#1f772c")))
(ediff-current-diff-B ((nil :background "#2b538a")))
(ediff-odd-diff-C ((nil :background "#862b27")))
(ediff-even-diff-C ((nil :background "#1f772c")))
(ediff-current-diff-C ((nil :background "#2b538a"))))
:config
(load-theme 'suscolors t))
One tweak to the base16-google-dark theme; the face for the mode line buffer name is too hard to see, set it to white instead.
Tried out 2020-01-20
(use-package base16-theme
:custom-face
;; (region ((t (:background "#0f3b82"))))
;; (font-lock-warning-face ((t (:background "#0f3b82"))))
;; (font-lock-negation-char-face ((nil :foreground "red" :background "#0f3b82")))
(mode-line-buffer-id ((t :foreground "white")))
(vterm-color-black ((t (:foreground "#000000" :background "#777777"))))
(ediff-odd-diff-A ((nil :background "#862b27")))
(ediff-even-diff-A ((nil :background "#1f772c")))
(ediff-current-diff-A ((nil :background "#2b538a")))
(ediff-odd-diff-B ((nil :background "#862b27")))
(ediff-even-diff-B ((nil :background "#1f772c")))
(ediff-current-diff-B ((nil :background "#2b538a")))
(ediff-odd-diff-C ((nil :background "#862b27")))
(ediff-even-diff-C ((nil :background "#1f772c")))
(ediff-current-diff-C ((nil :background "#2b538a")))
:config
(load-theme 'base16-woodland t)
;;(load-theme 'base16-solarized-dark t)
;;(load-theme 'base16-oceanicnext t)
;;(load-theme 'base16-google-dark t)
;;(load-theme 'base16-nord t)
)
(use-package leuven-theme
:config
(load-theme 'leuven-dark t)
:custom-face
(code-block ((nil :foreground "#ffff7f" :background "#25202a")))
(code-inline ((nil :foreground "#ff9bff" :background "#25202a")))
(dired-directory ((nil :background "#25202a")))
(dired-header ((nil :background "#25202a" :foreground "SteelBlue3")))
(flycheck-error ((nil :background "lawn green" :foreground "black")))
(flycheck-warning ((nil :background "yellow" :foreground "black")))
(org-block ((nil :foreground "#ffff7f" :background "#25202a" :extend t)))
(org-block-begin-line ((nil :underline nil :foreground "#ffff7f" :background "#25202a")))
(org-block-end-line ((nil :overline nil :foreground "#ffff7f" :background "#25202a")))
(show-paren-match ((nil :background "#ffad65"))))
These are the packages that are not built into Emacs.
A package that uses the same idea from ace-jump-mode for buffer navigation, but applies it to windows. The default keys are 1-9, but it’s faster to access the keys on the home row, so that’s what I have them set to (with respect to Dvorak, of course).
(use-package ace-window
:config
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))
Use silver surfer to search.
(use-package ag
:commands ag)
(use-package all-the-icons-dired
;; M-x all-the-icons-install-fonts
:hook (dired-mode . all-the-icons-dired-mode))
(use-package anzu
:bind
(([remap query-replace] . anzu-query-replace)
([remap query-replace-regexp] . anzu-query-replace-regexp))
:custom
(anzu-mode-lighter "")
(anzu-deactivate-region t)
(anzu-search-threshold 1000)
(anzu-replace-threshold 50)
(anzu-replace-to-string-separator " => ")
:config
(global-anzu-mode +1)
(set-face-attribute 'anzu-mode-line nil :foreground "yellow" :weight 'bold))
A quick way to jump around text in buffers.
(use-package avy
:bind
(("C-c SPC" . avy-goto-char-timer)
("C-'" . avy-goto-char)))
Never lose your cursor again. Highlights the cursor.
(use-package beacon
:diminish beacon-mode
:init
(setq beacon-push-mark 35)
(setq beacon-color "#666600")
:config
(beacon-mode 1))
(use-package circe
:config (setq circe-default-nick "chucho"
circe-default-user "chucho"
circe-default-realname "chucho"
circe-default-part-message "Bye"
circe-default-quit-message "Bye"
circe-network-options '(("Freenode"
:tls t
:channels ("#emacs")
))))
(use-package clipmon
:commands clipmon-mode-start
:bind ("M-S-<f2>" . clipmon-autoinsert-toggle)
:config
(clipmon-mode-start))
Color Identifiers is a minor mode for Emacs that highlights each source code identifier uniquely based on its name.
Disable for now since it is slow when editing Scala code.
(use-package color-identifiers-mode
:diminish color-identifiers-mode
:config
(add-hook 'after-init-hook 'global-color-identifiers-mode)
(set-face-attribute 'font-lock-comment-delimiter-face nil :slant 'italic)
(set-face-attribute 'font-lock-comment-face nil :slant 'italic))
(use-package column-enforce-mode
:config
(setq column-enforce-column 110)
:hook (progmode-hook . column-enforce-mode))
Complete anything.
(use-package company
:diminish company-mode
:bind (:map company-active-map
("C-n" . company-select-next)
("C-p" . company-select-previous)
("M-/" . company-complete-common))
:init
(global-company-mode t)
:custom
(company-dabbrev-downcase nil "Don't downcase returned candidates.")
(company-show-numbers t "Numbers are helpful.")
(company-abort-manual-when-too-short t "Be less enthusiastic about completion.")
:custom-face
(company-tooltip ((t (:family "IBM Plex Mono Medium" :height 120))))
:config
(setq company-idle-delay 0 ;; no delay no autocomplete
company-minimum-prefix-length 4
company-tooltip-limit 20)
)
Removed due to not displaying properly with IBM Plex Mono
font. 2021-02-16
(use-package company-posframe
:custom-face
(company-posframe-active-backend-name ((t (:family "Fira Code Retina"))))
:custom
(company-posframe-font nl/gui-fixed-font-name)
:config
(company-posframe-mode 1))
(use-package company-tabnine
:after company
:config
(add-to-list 'company-backends #'company-tabnine)
;; Use the tab-and-go frontend.
;; Allows TAB to select and complete at the same time.
(company-tng-configure-default)
(setq company-frontends
'(company-tng-frontend
company-pseudo-tooltip-frontend
company-echo-metadata-frontend)))
(use-package consult
;; Replace bindings. Lazily loaded due by `use-package'.
:bind (;; C-c bindings (mode-specific-map)
("C-c h" . consult-history)
("C-c m" . consult-mode-command)
("C-c b" . consult-bookmark)
("C-c k" . consult-kmacro)
;; C-x bindings (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
;; 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
("<help> a" . consult-apropos) ;; orig. apropos-command
;; M-g bindings (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-project)
;; M-s bindings (search-map)
("M-s f" . consult-find)
("M-s F" . 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 m" . consult-multi-occur)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch)
:map isearch-mode-map
("M-e" . consult-isearch) ;; orig. isearch-edit-string
("M-s e" . consult-isearch) ;; 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
;; Enable automatic preview at point in the *Completions* buffer.
;; This is relevant when you use the default completion UI,
;; and not necessary for Vertico, Selectrum, etc.
: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
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)
;; Optionally replace `completing-read-multiple' with an enhanced version.
(advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)
;; 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 (kbd "M-."))
;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<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-file consult--source-project-file consult--source-bookmark
:preview-key (kbd "M-."))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; (kbd "C-+")
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
;; configure a function which returns the project root directory.
(autoload 'projectile-project-root "projectile")
(setq consult-project-root-function #'projectile-project-root)
)
Keys | Description |
---|---|
b SPC | Narrow to buffers |
f SPC | Narrow to recent files |
m SPC | Narrow to bookmarks |
p SPC | Narrow to project |
(use-package coverlay
:disabled
:load-path "~/src/github/elisp/coverlay.el"
:custom
(coverlay:untested-line-background-color "#862b27")
(coverlay:tested-line-background-color "#1f772c")
(coverlay:mark-tested-lines nil))
(use-package cursor-chg
:load-path "lisp"
:commands change-cursor-mode
:config
(change-cursor-mode 1)
(toggle-cursor-type-when-idle 1))
This package was removed from MELPA since it was only found on Emacs Wiki.
(use-package dap-mode
:after (lsp-mode)
:commands (dap-debug)
:hook ((python-mode . dap-ui-mode)
(python-mode . dap-mode)
(dap-stopped-hook . (lambda (arg) (call-interactively #'dap-hydra)))
)
:config
(dap-mode t)
(dap-ui-mode t)
(require 'dap-node)
(require 'dap-java)
(require 'dap-python)
(require 'dap-lldb))
(use-package dashboard
:demand t
:custom
(dashboard-projects-backend 'projectile)
:config
(setq dashboard-items '((projects . 5)
(recents . 5)
(bookmarks . 5)
(agenda . 5)
(registers . 5)))
(dashboard-setup-startup-hook))
(use-package deadgrep
:bind (("C-c h" . deadgrep)))
(use-package devdocs)
Could not get this package to display changes (2017-10-15).
(use-package diff-hl
:init
(add-hook 'prog-mode-hook #'diff-hl-mode)
(add-hook 'org-mode-hook #'diff-hl-mode)
(add-hook 'dired-mode-hook 'diff-hl-dired-mode)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
:config
(setq diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-type)
(setq diff-hl-margin-side 'left)
(diff-hl-mode t))
Provides a simple UI for customizing dired mode to use different faces and colors.
(use-package diredful
:config (diredful-mode 1))
(use-package dired-narrow
:ensure t
:bind (:map dired-mode-map
("/" . dired-narrow)))
(use-package dired-sidebar
:bind (("C-c C-n" . dired-sidebar-toggle-sidebar))
:commands (dired-sidebar-toggle-sidebar)
:config
(when (eq system-type 'windows-nt)
(setq dired-sidebar-use-all-the-icons nil))
(setq dired-sidebar-use-term-integration t)
(setq dired-sidebar-use-custom-font nil)
(setq dired-sidebar-face
(cond
((eq system-type 'darwin)
'(:family "Helvetica" :height 100))
(:default
'(:family "Arial" :height 90)))))
(use-package docker
:ensure t
:bind ("C-c d" . docker))
(use-package dockerfile-mode
:mode ("Dockerfile\\'" . dockerfile-mode))
(use-package doom-modeline
:hook (after-init . doom-modeline-mode)
:custom-face
(doom-modeline-project-parent-dir ((t (:foreground "#0f3b82"))))
:config
(setq doom-modeline-buffer-file-name-style 'buffer-name
doom-modeline-height 30
doom-modeline-bar-width 3))
Dumb Jump is an Emacs “jump to definition” package with support for multiple programming languages that favors “just working”. This means minimal – and ideally zero – configuration with absolutely no stored indexes (TAGS) or persistent background processes.
(use-package dumb-jump
:bind (("M-g d o" . dumb-jump-go-other-window)
("M-g d j" . dumb-jump-go)
("M-g d x" . dumb-jump-go-prefer-external)
("M-g d z" . dumb-jump-go-prefer-external-other-window))
:config (setq dumb-jump-selector 'ivy
dumb-jump-prefer-searcher 'ag))
(use-package easy-kill
:pin melpa
:config
(global-set-key [remap kill-ring-save] #'easy-kill)
(global-set-key [remap mark-sexp] #'easy-mark))
(use-package editorconfig
:ensure t
:config
(editorconfig-mode 1))
(use-package edwina
:demand t
:config
(setq display-buffer-base-action '(display-buffer-below-selected))
(edwina-setup-dwm-keys)
(edwina-mode 1))
By default keys are prefixed with C-c C-w
.
Binding | Action |
---|---|
r, C-r | Arrange windows |
n, C-n, SPC | Move to next window |
p, C-p | Move to previous window |
N, C-S-n | Swap places with the next window |
P, C-S-p | Swap places with the previous window |
%, {, [ | Decrease the size of the master area |
^, }, ] | Increase the size of the master area |
d, C-d | Decrease number of windows in master |
i | Increase number of windows in master |
k, C-k | Delete window |
RET | Cycle window to/from master area |
c, C-c | Clone current window |
(use-package eglot
:config
(use-package typescript-mode)
(add-hook 'typescript-mode-hook 'eglot-ensure))
(use-package git-gutter
:diminish git-gutter-mode
:hook (prog-mode . git-gutter-mode))
This package adds support for flow to flycheck.
(use-package flycheck-flow
:hook (js2-mode . flycheck-mode))
(when (file-directory-p "~/src/github/elisp/emacs-libvterm")
(use-package vterm
:load-path "~/src/github/elisp/emacs-libvterm"
:bind
(:map vterm-mode-map
("M-<right>" . windmove-right)
("M-<left>" . windmove-left)
("M-<up>" . windmove-up)
("M-<down>" . windmove-down))
:commands vterm vterm-other-window
:config
(setq vterm-max-scrollback 10000)))
https://www.reddit.com/r/emacs/comments/ft84xy/run_shell_command_in_new_vterm/
(defun run-in-vterm-kill (process event)
"A process sentinel. Kills PROCESS's buffer if it is live."
(let ((b (process-buffer process)))
(and (buffer-live-p b)
(kill-buffer b))))
(defun run-in-vterm (command)
"Execute string COMMAND in a new vterm.
Interactively, prompt for COMMAND with the current buffer's file
name supplied. When called from Dired, supply the name of the
file at point.
Like `async-shell-command`, but run in a vterm for full terminal features.
The new vterm buffer is named in the form `*foo bar.baz*`, the
command and its arguments in earmuffs.
When the command terminates, the shell remains open, but when the
shell exits, the buffer is killed."
(interactive
(list
(let* ((f (cond (buffer-file-name)
((eq major-mode 'dired-mode)
(dired-get-filename nil t))))
(filename (concat " " (shell-quote-argument (and f (file-relative-name f))))))
(read-shell-command "Terminal command: "
(cons filename 0)
(cons 'shell-command-history 1)
(list filename)))))
(with-current-buffer (vterm (concat "*" command "*"))
(set-process-sentinel vterm--process #'run-in-vterm-kill)
(vterm-send-string command)
(vterm-send-return)))
(use-package emr
:bind (:map prog-mode-map
("M-RET" . emr-show-refactor-menu))
:config (emr-initialize))
(use-package ycmd
:disabled
:preface
(setq ycmd-startup-timeout 10)
(defun ycmd-setup-completion-at-point-function ()
"Setup `completion-at-point-functions' for `ycmd-mode'."
(add-hook 'completion-at-point-functions
#'ycmd-complete-at-point nil :local))
:config
(set-variable 'ycmd-server-command `("python" ,(file-truename "~/src/github/devtools/ycmd/ycmd")))
;;(set-variable 'ycmd-global-config (expand-file-name "~/path/to/ycmd/ycm_conf.py"))
(use-package company-ycmd
:config
(company-ycmd-setup))
(use-package flycheck-ycmd
:config
(flycheck-ycmd-setup))
(use-package ycmd-eldoc
:hook (ycmd-mode . ycmd-eldoc-setup))
:hook ((js2-mode .ycmd-mode)
( ycmd-mod-hook . ycmd-setup-completion-at-point-function)))
M-x embark-collect-snapshot
- Within an embark session, save results to a buffer
(use-package marginalia
;; Either bind `marginalia-cycle` globally or only in the minibuffer
:bind (("M-A" . marginalia-cycle)
:map minibuffer-local-map
("M-A" . marginalia-cycle))
:init
(marginalia-mode))
(use-package embark
:ensure t
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
: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
:after (embark consult)
:demand t ; only necessary if you have the hook below
;; if you want to have consult previews as you move around an
;; auto-updating embark collect buffer
:hook
(embark-collect-mode . consult-preview-at-point-mode))
Open a buffer with file/lines of exact-match tags shown. Select one by going to a line and pressing return. pop-tag-mark still works with this code.
(use-package etags-select
:config
(global-set-key "\M-?" 'etags-select-find-tag-at-point)
(global-set-key "\M-." 'etags-select-find-tag))
(use-package expand-region
;; :load-path (lambda () (expand-file-name "~/src/github/elisp/expand-region.el"))
:bind ("C-=" . er/expand-region)
:config
(setq expand-region-smart-cursor t
er/enable-subword-mode? nil))
(use-package eyebrowse
:config
(eyebrowse-mode t))
(use-package explain-pause-mode
:load-path "~/src/github/elisp/explain-pause-mode"
:config
(explain-pause-mode t))
Show FIXME/TODO/BUG/KLUDGE in special face only in comments and strings.
(use-package fic-mode
:commands fic-mode
:hook ((c++-mode . fic-mode)
(c-mode . fic-mode)
(java-mode . fic-mode)
(vala-mode . fic-mode)
(python-mode . fic-mode)
(php-mode . fic-mode)
(scala-mode . fic-mode)
(typescript-mode . fic-mode)))
Allow windmove to jump between frames.
(use-package framemove
:defer 0
:load-path "lisp"
:config
(setq framemove-hook-into-windmove t))
(use-package flycheck
:commands global-flycheck-mode
:diminish flycheck-mode
:commands flycheck-define-checker
:init
(global-flycheck-mode)
:config
(setq flycheck-standard-error-navigation nil)
(setq-default flycheck-disabled-checkers
(append flycheck-disabled-checkers
'(javascript-jshint)))
(setq flycheck-checkers (append flycheck-checkers
'(javascript-eslint)))
;; use eslint with web-mode for jsx files
(flycheck-add-mode 'javascript-eslint 'web-mode)
(flycheck-add-mode 'javascript-eslint 'js2-mode)
(flycheck-add-mode 'javascript-eslint 'js-mode))
(use-package flycheck-pos-tip
:after flycheck
:custom-face
;; (popup-face ((t (:inherit default :height 200))))
;; (popup-tip-face ((t (:inherit default :height 200)))))
:config
(flycheck-pos-tip-mode)
(setq flycheck-pos-tip-timeout 10
x-gtk-use-system-tooltips nil
pos-tip-foreground-color "tomato"
pos-tip-background-color "gray20"))
On the fly markdown preview.
(use-package flymd
:commands (flymd-flyit)
:preface
(defun nl/flymd-browser-function (url)
(let ((browse-url-browser-function 'browse-url-firefox))
(browse-url url)))
:config
(setq flymd-browser-open-function 'nl/flymd-browser-function))
(use-package frog-jump-buffer
:load-path "~/src/github/elisp/frog-jump-buffer"
:bind
("C-x C-b" . frog-jump-buffer)
:commands frog-jump-buffer)
This package uses ido-mode which I don’t want to install.
(use-package fzf)
Generate tags on command line with gtags
.
Updte tags on command line with global -u
.
(use-package ggtags
:commands ggtags-mode)
Emacs major mode for OpenGL shading language.
(use-package glsl-mode
:mode "\\.\\(vert\\|frag\\|glsl\\|geom\\)$")
(use-package goto-last-change
:bind
("C-x C-\\" . goto-last-change)
:config
(autoload 'goto-last-change "goto-last-change"
"Set point to the position of the last change." t))
When working with many windows at the same time, each window has a size that is not convenient for editing.
Disable for now, not working the way I prefer.
(use-package golden-ratio
:config
(golden-ratio-mode 1))
Required for gradle build files.
(use-package groovy-mode
(use-package grunt)
Guide the following key bindings automatically and dynamically.
(use-package guide-key
:diminish guide-key-mode
:config
(setq guide-key/guide-key-sequence '("C-x r" "C-c p" "C-h" "C-c h" "C-c l")
guide-key/recursive-key-sequence-flag t)
(guide-key-mode 1))
(use-package headlong)
This minor mode highlights indentation levels via
font-lock
.
(use-package highlight-indent-guides
:config
(setq highlight-indent-guides-method 'character)
(set-face-foreground 'highlight-indent-guides-character-face "gray18")
:hook (prog-mode . highlight-indent-guides-mode))
Not used for now since it breaks ERC font lock.
(use-package hl-anything
:config
(hl-highlight-mode 1)
;; (hl-setup-default-advices nil)
;; (hl-setup-customizable-advices nil)
;; (remove-hook 'kill-emacs-hook 'hl-save-highlights)
)
So that hungry deletion can be used in all modes.
(use-package hungry-delete
:diminish hungry-delete-mode
:init
(global-hungry-delete-mode))
This package can be used to tie related commands into a family of short bindings with a common prefix - a Hydra.
(use-package hydra
:pin melpa
:init
(use-package cl-lib)
(use-package lv)
(use-package key-chord
:init
(setq key-chord-one-key-delay 0.16)
:config
(key-chord-mode 1))
:custom
(hydra-hint-display-type 'posframe)
:config
;;(setq hydra-posframe-show-params (plist-put hydra-posframe-show-params :font "Fira Code Retina"))
(setq hydra-posframe-show-params
(plist-put hydra-posframe-show-params :font nl/gui-fixed-font-name))
(defun nl/pull-window ()
"Pull a window to the window the point is at"
(interactive)
(aw--push-window (selected-window))
(ace-swap-window)
(aw-flip-window))
(defun nl/open-buffer-in-other-window ()
"Open buffer in another window."
(interactive)
(let ((pt (point))
(buf (current-buffer))
(window (ace-select-window)))
(set-window-buffer window buf)
(goto-char pt)
(recenter-top-bottom 'top)))
;; http://oremacs.com/2015/01/29/more-hydra-goodness/
(defun hydra-universal-argument (arg)
(interactive "P")
(setq prefix-arg (if (consp arg)
(list (* 4 (car arg)))
(if (eq arg '-)
(list -4)
'(4)))))
(defhydra hydra-files (:columns 2 :color red)
"Files hydra"
("h" (dired "~/.") "home" :column "System")
("e" (dired "~/.emacs.d") "Emacs")
("c" (dired "~/.config") "Config")
("l" (dired "~/.local") "Local")
("C" (dired "~/home_config") "My config" :column "Mine")
("S" (dired "~/src/nelson/nlscripts") "My scripts")
("O" (dired "~/Dropbox/orgfiles") "Org")
)
(global-set-key (kbd "C-,") 'hydra-files/body)
(defhydra hydra-window (:color red :hint nil)
("h" windmove-left)
("j" windmove-down)
("k" windmove-up)
("l" windmove-right)
("|" (progn (split-window-right) (windmove-right)))
("_" (progn (split-window-below) (windmove-down)))
("v" split-window-right)
("x" split-window-below)
("u" winner-undo)
("r" winner-redo) ;;Fixme, not working?
("a" ace-window :exit t)
("f" new-frame :exit t)
("o" nl/open-buffer-in-other-window :exit t)
("p" nl/pull-window :exit t)
("s" ace-swap-window :exit t)
("da" ace-delete-window)
("dw" delete-window)
("db" kill-this-buffer)
("df" delete-frame :exit t)
("q" nil)
;;("i" ace-maximize-window "ace-one" :color blue)
("m" headlong-bookmark-jump))
(key-chord-define-global "yy" 'hydra-window/body)
(defhydra hydra-buffer (:color blue :columns 3)
("n" next-buffer "next" :color red)
;;("b" helm-mini "switch")
("B" ibuffer "ibuffer")
("p" previous-buffer "prev" :color red)
("C-b" buffer-menu "buffer menu")
("d" kill-this-buffer "delete" :color red)
;; don't come back to previous buffer after delete
("D" (progn (kill-this-buffer) (next-buffer)) "Delete" :color red)
("s" save-buffer "save" :color red))
(key-chord-define-global "zz" 'hydra-buffer/body)
(defhydra hydra-goto-line (goto-map "")
"goto-line"
("f" avy-goto-line "avy goto line")
("g" goto-line "go")
("m" set-mark-command "mark" :bind nil)
("q" nil "quit"))
(global-set-key (kbd "M-g M-g") 'hydra-goto-line/body)
(defhydra hydra-windows-nav (:color red)
("s" shrink-window-horizontally "shrink horizontally" :column "Sizing")
("e" enlarge-window-horizontally "enlarge horizontally")
("S" shrink-window "shrink vertically")
("E" enlarge-window "enlarge vertically")
("b" balance-windows "balance window height")
("m" maximize-window "maximize current window")
("M" minimize-window "minimize current window")
("h" split-window-below "split horizontally" :column "Split management")
("v" split-window-right "split vertically")
("d" delete-window "delete current window")
("x" delete-other-windows "delete-other-windows")
("z" ace-window "ace window" :color blue :column "Navigation")
("h" windmove-left "← window")
("j" windmove-down "↓ window")
("k" windmove-up "↑ window")
("l" windmove-right "→ window")
("r" toggle-window-split "rotate windows") ; Located in utility functions
("q" nil "quit menu" :color blue :column nil))
(global-set-key (kbd "C-c w") 'hydra-windows-nav/body))
impatient-mode is a minor mode that publishes the live buffer through the local simple-httpd server under imp/live/<buffer-name>.
Works slow, so disabling. 2021-02-17
(use-package impatient-mode)
Emacs package that provides visual version of align-regexp command.
Have never used it: disabling. 2021-02-23
(use-package ialign
:bind ("C-x l" . ialign))
(use-package ibuffer-projectile
:after (ibuffer projectile)
:config
(defun nl/ibuffer-customization ()
"My customization for `ibuffer'."
;; ibuffer-projectile setup
(ibuffer-projectile-set-filter-groups)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic) ; first do alphabetic sort
(ibuffer-do-sort-by-major-mode))) ; then do major-mode sort
:hook (ibuffer-mode . nl/ibuffer-customization))
Key | Description | function |
---|---|---|
M-< | selects the first candidate | ivy-beginning-of-buffer |
M-> | selects the last candidate | ivy-end-of-buffer |
C-v | scrolls up by ivy-height lines | ivy-scroll-up-command |
M-v | scrolls down by ivy-height lines | ivy-scroll-down-command |
C-j
(ivy-alt-done
)- When completing file names, selects the
current directory candidate and starts a new completion session
there. Otherwise, it is the same as
ivy-done
. C-M-j
(ivy-immediate-done
)- Exits with the current input instead
of the current candidate (like other commands).
This is useful e.g. when you call find-file to create a new file, but the desired name matches an existing file. In that case, using
C-j
would select that existing file, which isn’t what you want - use this command instead.
C-M-m
(ivy-call
)- Is the non-exiting version of
C-m
(ivy-done
).Instead of closing the minibuffer,
C-M-m
allows selecting another candidate or another action. For example,C-M-m
on functions list invokes describe-function. When combined withC-n
, function descriptions can be invoked quickly in succession. C-M-n
(ivy-next-line-and-call
)- Combines
C-n
andC-M-m
. Applies an action and moves to next line.Comes in handy when opening multiple files from
counsel-find-file
,counsel-git-grep
,counsel-ag
,counsel-rg
, orcounsel-locate
lists. Just holdC-M-n
for rapid-fire default action on each successive element of the list.
C-c C-o
(ivy-occur
)- Saves the current candidates to a new buffer and exits completion.
The new buffer is read-only and has a few useful bindings defined.
C-x C-q
- Make edits to the buffer. After editing, press
C-x C-s
to save changes. RET
orj
(ivy-occur-press
)- Call the current action on the selected candidate.
mouse-1
(ivy-occur-click
)- Call the current action on the selected candidate.
j
(next-line
)- Move to next line.
k
(previous-line
)- Move to previous line.
a
(ivy-occur-read-action
)- Read an action and make it current for this buffer.
o
(ivy-occur-dispatch
)- Read an action and call it on the selected candidate.
q
(quit-window
)- Bury the current buffer.
(use-package ivy
:diminish (ivy-mode . "")
:bind (("C-s" . swiper)
("C-c C-r" . ivy-resume)
("<f6>" . ivy-resume)
:map ivy-mode-map
("C-'" . ivy-avy))
:custom-face
(ivy-current-match ((nil :background "#574a40")))
(ivy-minibuffer-match-face-2 ((nil :background "#574a40")))
(ivy-posframe-cursor ((nil :background "#be6119")))
:config
(ivy-mode 1)
;; add ‘recentf-mode’ and bookmarks to ‘ivy-switch-buffer’.
(setq
ivy-use-virtual-buffers t
ivy-wrap t
;; number of result lines to display
ivy-height 10
;; does not count candidates
ivy-count-format ""
;; no regexp by default
ivy-initial-inputs-alist nil
;; configure regexp engine.
ivy-re-builders-alist ;; allow input not in order
'((t . ivy--regex-ignore-order))))
(use-package ivy-hydra
:after (ivy hydra))
This blog post has a lot of info: Ivy 0.8.0 is out
(use-package swiper
:config
(setq ivy-initial-inputs-alist nil)
(setq ivy-use-virtual-buffers t)
(setq swiper-action-recenter t))
Also, install counsel:
See this article for recentering: Recentre the buffer when leaving Swiper.
(use-package counsel
:bind (;;("C-x C-f" . counsel-find-file)
;;("M-y" . counsel-yank-pop)
("C-h f" . counsel-describe-function)
("C-h v" . counsel-describe-variable)
("C-c s a" . counsel-ag))
:config
(setq counsel-grep-base-command
"rg -i -M 120 --no-heading --line-number --color never '%s' %s"))
When using counsel-ag
:
- use
C-c C-o
(ivy-occur
) to save results to a buffer, - use
C-x C-q
(ivy-wgrep-change-to-wgrep-mode
) to edit the buffer, - use
C-x C-s
to save the changes, or - use
C-c C-k
to abort all changes
(use-package ivy-posframe
:after ivy
:init (ivy-posframe-mode 1)
:custom
(ivy-posframe-font "Fira Code Retina")
:custom-face
;;(ivy-posframe ((t :foreground "#ffffff" :background "#2d2e2e")))
:config
(setq ivy-posframe-display-functions-alist
'((swiper . ivy-posframe-display-at-frame-bottom-window-center)
(complete-symbol . ivy-posframe-display-at-point)
(counsel-fzf . ivy-posframe-display-at-point)
(counsel-M-x . ivy-posframe-display-at-window-bottom-left)
(t . ivy-posframe-display)))
)
Disabled since Jest is being used. 2019-10-11
(use-package karma
:disabled
:commands karma-mode)
(use-package ligature
:demand t
:load-path "~/src/github/elisp/ligature"
:config
;; Enable the "www" ligature in every possible major mode
(ligature-set-ligatures 't '("www"))
;; Enable traditional ligature support in eww-mode, if the
;; `variable-pitch' face supports it
(ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
;; Enable all Cascadia Code ligatures in programming modes
(ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
"\\\\" "://"))
;; Enables ligature checks globally in all buffers. You can also do it
;; per mode with `ligature-mode'.
(global-ligature-mode t))
Add filler lorem ipsum text to Emacs.
(use-package lorem-ipsum)
(use-package lsp-mode
;;:load-path "~/src/github/elisp/lsp-mode"
:pin melpa
:commands (lsp lsp-deferred)
:hook
;;(js-mode . lsp)
(typescript-mode . lsp)
(scala-mode . lsp)
(php-mode . lsp)
(python-mode . lsp)
:custom
(lsp-keymap-prefix "C-c l")
(lsp-ui-flycheck-enable nil)
(lsp-enable-snippet t)
(lsp-enable-file-watchers nil)
(lsp-pyls-plugins-pycodestyle-max-line-length 120)
;;(setq lsp-response-timeout 25)
:config
(setq lsp-prefer-capf t
lsp-idle-delay 0.5
lsp-pyls-plugins-flake8-enabled t)
(setq lsp-clients-angular-language-server-command
'("node"
"/home/nelson/.nvm/versions/node/v14.16.1/lib/node_modules/@angular/language-server"
"--ngProbeLocations"
"/home/nelson/.nvm/versions/node/v14.16.1/lib/node_modules"
"--tsProbeLocations"
"/home/nelson/.nvm/versions/node/v14.16.1/lib/node_modules"
"--stdio"))
(lsp-register-custom-settings
'(("pyls.plugins.pyls_mypy.enabled" t t)
("pyls.plugins.pyls_mypy.live_mode" nil t)
("pyls.plugins.pyls_black.enabled" t t)
("pyls.plugins.pyls_isort.enabled" t t))))
(use-package lsp-ui
;; :load-path "~/src/github/elisp/lsp-ui"
:hook
(lsp-mode . lsp-ui-mode)
:bind (:map lsp-ui-mode-map
([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
([remap xref-find-references] . lsp-ui-peek-find-references)
([f10] . lsp-ui-sideline-toggle-symbols-info))
:custom-face
(lsp-ui-peek-peek ((nil :background "gray30")))
(lsp-ui-peek-highlight ((nil :foreground "gray60" :background "gray20")))
(header-line ((t (:inherit mode-line :background "gray30"))))
:config
(setq lsp-ui-peek-always-show nil)
:custom
(lsp-ui-sideline-enable t)
(lsp-ui-sideline-show-hover nil)
(lsp-ui-doc-enable nil)
(lsp-ui-peek-enable nil)
(flycheck-add-next-checker 'lsp-ui 'typescript-tslint))
Macrostep allows you to see what Elisp macros expand to. Learned about it from the package highlight talk for use-package.
(use-package macrostep)
(use-package markdown-mode
:commands (markdown-mode gfm-mode)
:mode (("README\\.md\\'" . gfm-mode)
("\\.markdown\\'" . markdown-mode)
("\\.md\\'" . markdown-mode))
:hook
(markdown-mode . (lambda () (auto-fill-mode -1)))
(markdown-mode . variable-pitch-mode)
(markdown-mode . flyspell-mode)
:init
(setq markdown-command "pandoc")
:config
(dolist (face '(markdown-inline-code-face markdown-code-face))
(set-face-attribute face nil :inherit 'fixed-pitch)))
(use-package markdown-preview-mode
:config
;;(add-to-list 'markdown-preview-stylesheets
;; "https://raw.githubusercontent.com/richleland/pygments-css/master/emacs.css")
(setq markdown-preview-stylesheets (list
"http://thomasf.github.io/solarized-css/solarized-dark.min.css")))
(use-package meson-mode
:hook ('meson-mode . company-mode))
Quick switching between buffers.
(use-package nswbuff
:bind* (("<C-tab>" . nswbuff-switch-to-next-buffer)
("<C-S-iso-lefttab>" . nswbuff-switch-to-previous-buffer))
:config (setq nswbuff-buffer-list-function #'nswbuff-projectile-buffer-list
nswbuff-display-intermediate-buffers t
nswbuff-exclude-buffer-regexps '("^ .*" "^\\*.*\\*")))
(use-package ob-async
:after org)
(use-package scad-mode
:config
(add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode)))
Show org-mode bullets as UTF-8 characters.
(use-package org-bullets
:hook (org-mode . org-bullets-mode))
(use-package package-utils)
Keys are:
left
/right
keys for movementC-c C-=
for large txtC-c C--
for small textC-c C-q
for quit (which will return you back to vanilla org-mode)C-c <
andC-c >
to jump to first/last slideC-c C-r
set slides read onlyC-c C-w
allow writing on slides
(use-package org-present
:after org)
(pdf-tools-install)
This package provides tagged workspaces.
(use-package perspective
:config (persp-mode))
Project navigation and management library for Emacs.
(use-package projectile
:diminish projectile-mode
:bind-keymap
("C-c p" . projectile-command-map)
:init (projectile-mode +1)
:config
;; tramp-fix: https://github.com/syl20bnr/spacemacs/issues/11381
(defadvice projectile-project-root (around ignore-remote first activate)
(unless (file-remote-p default-directory) ad-do-it))
(setq projectile-indexing-method 'alien
projectile-remember-window-configs nil
projectile-switch-project-action 'projectile-dired
projectile-completion-system 'default
projectile-enable-caching nil
projectile-create-missing-test-files t
projectile-mode-line "Projectile")
(def-projectile-commander-method ?d
"Open project root in dired."
(projectile-dired)))
2019-09-20 This package does not work with Emacs 27
(use-package protobuf-mode
:config
(defconst nl/protobuf-style
'((c-basic-offset . 2)
(indent-tabs-mode . nil)))
:hook (protobuf-mode . (lambda ()
(c-add-style "nl/style" nl/protobuf-style t)
(subword-mode 1))))
(use-package posframe
:pin melpa
:init
(setq x-gtk-resize-child-frames 'resize-mode))
(use-package powerline
:custom-face
(mode-line ((t (:foreground "#030303" :background "#6b6b6b" :box nil))))
(mode-line-inactive ((t (:foreground "#f9f9f9" :background "#6b6b6b" :box nil))))
:config
(setq powerline-arrow-shape 'arrow14)
(setq powerline-default-separator-dir '(right . left))
(setq powerline-color1 "#49483E")
(setq powerline-color2 "#333333")
(powerline-default-theme))
(use-package window-purpose
:commands purpose-mode
:config
(add-to-list 'purpose-user-mode-purposes '(scala-mode . scala))
(add-to-list 'purpose-user-mode-purposes '(sbt-mode . scala))
(purpose-compile-user-configuration))
Highlight brackets according to their depth
(use-package rainbow-delimiters
:commands rainbow-delimiters-mode
:hook (prog-mode . rainbow-delimiters-mode))
Disable for now since causing issues when I use region expand and want to overwrite.
(use-package region-bindings-mode
:config
(region-bindings-mode-enable)
(define-key region-bindings-mode-map "a" 'mc/mark-all-like-this)
(define-key region-bindings-mode-map "p" 'mc/mark-previous-like-this)
(define-key region-bindings-mode-map "n" 'mc/mark-next-like-this)
(define-key region-bindings-mode-map "m" 'mc/mark-more-like-this-extended)
(define-key region-bindings-mode-map "q" 'anzu-query-replace-regexp)
;;(define-key region-bindings-mode-map "w" 'whole-line-or-region-kill-ring-save)
)
(use-package ripgrep)
Convenient package to create *scratch*
buffers that are based on the current buffer’s major mode.
This is more convienent than manually creating a buffer to do some scratch work or reusing the
initial *scratch*
buffer.
(use-package scratch)
(use-package selected
:diminish selected-minor-mode
;; :bind (:map selected-keymap
;; ("M-%" . query-replace-regexp)
;; ("C-[" . align-entire)
;; ("C-f" . fill-region)
;; ("C-U" . unfill-region)
;; ("C-d" . downcase-region)
;; ("C-r" . reverse-region)
;; ("C-s" . sort-lines)
;; ("C-u" . upcase-region))
:init (selected-global-mode 1))
Declarative popup window rules.
(use-package shackle
:config
(setq shackle-rules
'(("*Help*" :align t :ratio 0.4 :select t)
("\\`\\*[Hh]elm.*?\\*\\'" :regexp t :align 'bottom :ratio 0.4)
("\\*sbt\\*.*" :regexp t :other t)
;;(compilation-mode :popup t)
(("*shell*" "*eshell*") :popup t))
shackle-default-rule '(:select t)
shackle-inhibit-window-quit-on-same-windows t)
(shackle-mode))
(use-package smartparens
:diminish smartparens-mode
:config
(require 'smartparens-config)
;; https://github.com/Fuco1/smartparens/issues/783
(setq sp-escape-quotes-after-insert nil)
;; Set up some pairings for org mode markup. These pairings won't
;; activate by default; they'll only apply for wrapping regions.
(sp-local-pair 'org-mode "~" "~" :actions '(wrap))
(sp-local-pair 'org-mode "/" "/" :actions '(wrap))
(sp-local-pair 'org-mode "*" "*" :actions '(wrap))
;; https://emacs.stackexchange.com/questions/26912/smartparens-do-not-insert-parenthesis-pair-when-point-is-at-the-beginning-of-wo
(sp-pair "{" nil :unless '(sp-point-before-word-p))
(sp-pair "(" nil :unless '(sp-point-before-word-p))
(sp-pair "[" nil :unless '(sp-point-before-word-p))
(sp-local-pair 'typescript-mode "\<" "\>"))
Not really using this: disabling. 2021-02-28
Quickly jumps between other symbols found at point in Emacs. http://www.masteringemacs.org/article/smart-scan-jump-symbols-buffer
(use-package smartscan
:init (global-smartscan-mode 1))
(use-package smooth-scrolling
:config (setq smooth-scroll-margin 6))
(use-package spaceline-config
:after spaceline
:init
(require 'spaceline-config)
(setq spaceline-highlight-face-func 'spaceline-highlight-face-modified)
(setq-default powerline-default-separator 'wave
powerline-height 26
spaceline-separator-dir-left '(left . left)
spaceline-separator-dir-right '(right . right))
:config
(spaceline-helm-mode 1)
(spaceline-toggle-version-control-on)
(spaceline-compile
;; left side
'(((projectile-root buffer-modified) :face 'avy-lead-face-1 :priority 100)
((remote-host buffer-id) :face 'avy-lead-face-0 :priority 100)
((line column) :separator ":" :face default-face :priority 100)
(anzu :priority 95)
auto-compile
(process :when active)
(minor-modes :when active
:priority 9)
(org-clock :when active))
;; right side
'(which-function
(selection-info :priority 95)
input-method
(version-control :when active :priority 78)
((flycheck-error flycheck-warning flycheck-info) :when active :priority 89)
(major-mode :priority 79)
(minor-mode :priority 79 :face other-face)
(global :when active)
(buffer-position :priority 99)
(hud :priority 99)))
(setq-default mode-line-format '("%e" (:eval (spaceline-ml-main)))))
super-save auto-saves your buffers, when certain events happen - e.g. you switch between buffers, an Emacs frame loses focus, etc. You can think of it as both something that augments and replaces the standard
auto-save-mode
.
(use-package super-save
:diminish super-save-mode
:config (super-save-mode +1))
(use-package treemacs
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag))
:config
(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 t
treemacs-file-event-delay 5000
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-git-command-pipe ""
treemacs-goto-tag-strategy 'refetch-index
treemacs-indentation 2
treemacs-indentation-string " "
treemacs-is-never-other-window nil
treemacs-max-git-entries 5000
treemacs-missing-project-action 'ask
treemacs-move-forward-on-expand nil
treemacs-no-png-images 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-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-show-cursor nil
treemacs-show-hidden-files t
treemacs-silent-filewatch nil
treemacs-silent-refresh nil
treemacs-sorting 'alphabetic-asc
treemacs-space-between-root-nodes t
treemacs-tag-follow-cleanup t
treemacs-tag-follow-delay 1.5
treemacs-user-mode-line-format nil
treemacs-width 35)
;; 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 t)
(pcase (cons (not (null (executable-find "git")))
(not (null treemacs-python-executable)))
(`(t . t)
(treemacs-git-mode 'deferred))
(`(t . _)
(treemacs-git-mode 'simple)))
)
(use-package treemacs-projectile
:after treemacs projectile)
(use-package treemacs-icons-dired
:after treemacs dired
:config (treemacs-icons-dired-mode))
(use-package treemacs-magit
:after treemacs magit)
(use-package treemacs-persp
:after treemacs persp-mode
:config (treemacs-set-scope-type 'Perspectives))
Allows for transposing window arrangements.
(use-package transpose-frame
:bind ("S-M-t" . transpose-frame))
(use-package undo-tree
:commands global-undo-tree-mode)
(use-package vertico
:init
(vertico-mode)
;; Grow and shrink the Vertico minibuffer
;; (setq vertico-resize t)
;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
;; (setq vertico-cycle t)
)
;; Use the `orderless' completion style.
;; Enable `partial-completion' for file path expansion.
;; You may prefer to use `initials' instead of `partial-completion'.
(use-package orderless
:init
(setq completion-styles '(orderless)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion)))))
;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
:init
(savehist-mode))
;; A few more useful configurations...
(use-package emacs
:init
;; Add prompt indicator to `completing-read-multiple'.
;; Alternatively try `consult-completing-read-multiple'.
(defun crm-indicator (args)
(cons (concat "[CRM] " (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)
;; Emacs 28: Hide commands in M-x which do not work in the current mode.
;; Vertico commands are hidden in normal buffers.
;; (setq read-extended-command-predicate
;; #'command-completion-default-include-p)
;; Enable recursive minibuffers
(setq enable-recursive-minibuffers t))
(use-package vimish-fold
:config (vimish-fold-global-mode 1)
)
Provides visible, buffer local, bookmarks and the ability to jump forward and backward to the next bookmark.
(use-package bm
:bind ("C-<f4>" . bm-toggle)
("A-<f4>" . bm-next)
("S-<f4>" . bm-previous))
visual-regexp for Emacs is like replace-regexp, but with live visual feedback directly in the buffer.
visual-regexp-steroids is an extension to visual-regexp which enables the use of modern regexp engines (no more escaped group parentheses, and other goodies!).
(use-package visual-regexp
:init
(use-package visual-regexp-steroids)
:bind (("C-c r" . vr/replace)
("C-c q" . vr/query-replace)
("C-c m" . vr/mc-mark) ; Need multiple cursors
("C-M-r" . vr/isearch-backward)
("C-M-s" . vr/isearch-forward)))
(defun nl/query-replace-regexp-history-clear ()
"Using visual-regexp functions and query-replace-regexp in
the same session fails if there are invalid history characters in
the history (visual-regexp uses PCRE regexes). This function
clears the history."
(interactive)
(setq query-replace-defaults nil)
(setq query-replace-history nil))
Wand is an extension that allows users to select a piece of text and perform actions based on predefined patterns.
(use-package wand
:bind (("<C-return>" . wand:execute))
:config
(wand:add-rule-by-pattern :match "\\$ "
:capture :after
:action popup-shell-command)
(wand:add-rule-by-pattern :match "https?://"
:capture :whole
:action browse-url))
It takes a few seconds to load and I don’t need them immediately when Emacs starts up, so we can defer loading yasnippet until there’s some idle time.
Large collection of snippets: Andrea Crotti’s collection.
(use-package yasnippet
:diminish yas-minor-mode
:hook (prog-mode . yas-minor-mode)
;;:init
;;(yas-global-mode 1)
:config
(use-package yasnippet-snippets)
(yas-reload-all))
(use-package web-mode
:mode (("\\.html?\\'" . web-mode)
("\\.json\\'" . web-mode))
;;:bind ("C-c s h" . nl/counsel-ag-html)
:hook (web-mode . nl/web-mode-hook)
:preface
(defun html-filename-p (filename)
(string-match "\.html$" filename))
;; (defun nl/counsel-ag-html ()
;; "Perform counsel-ag on the project's HTML files."
;; (interactive)
;; (counsel-ag "" (projectile-project-root) "--html"))
(defun nl/web-mode-hook ()
"Hooks for Web mode."
(setq web-mode-markup-indent-offset 2)
(prettier-js-mode)
(yas-minor-mode))
:config
(setq web-mode-markup-indent-offset 2
web-mode-css-indent-offset 2
web-mode-code-indent-offset 2
web-mode-enable-auto-closing t
web-mode-enable-auto-quoting t
web-mode-ac-sources-alist
'(("css" . (ac-source-css-property))
("html" . (ac-source-words-in-buffer ac-source-abbrev))))
(flycheck-add-mode 'javascript-eslint 'web-mode)
(flycheck-add-mode 'typescript-tslint 'web-mode))
Required by ivy-occur.
(use-package wgrep)
(use-package workgroups)
Disabled since it does not work well with easy-kill (2019-01-31).
(use-package whole-line-or-region
:diminish (whole-line-or-region-local-mode)
:custom
(whole-line-or-region-global-mode t))
(use-package yaml-mode
:config
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)))
Search the word at point with Zeal
Zeal is a simple offline API documentation browser inspired by Dash (OS X app), available for Linux and Windows.
Using DevDocs.io now - 2017-10-19
(use-package zeal-at-point
;;:diminish
:commands zeal-at-point)
(use-package zop-to-char
:bind ("M-z" . zop-up-to-char)
:init
(progn
(setq zop-to-char-kill-keys '(?\C-k))
(setq zop-to-char-quit-at-point-keys '(?\r))))
Ztree is a project dedicated to implementation of several text-tree applications inside GNU Emacs.
(use-package ztree
:commands (ztree-diff ztree-dir))
(use-package zzz-to-char
:bind ("M-z" . zzz-up-to-char))
(use-package move-text
:bind (("C-S-<up>" . move-text-up)
("C-S-<down>" . move-text-down)))
Sometimes you end up with cursors outside of your view. You can scroll
the screen to center on each cursor with C-v
and M-v
.
(use-package multiple-cursors
:after selected
:bind (("C-S-c C-S-c" . mc/edit-lines)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-M->" . mc/unmark-next-like-this)
("C-M-<" . mc/unmark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)
("C-!" . mc/mark-next-symbol-like-this)
("C-x C-m" . mc/mark-all-dwim))
:bind (:map selected-keymap
("C-'" . mc/edit-lines)
("." . mc/mark-next-like-this)
("<" . mc/unmark-next-like-this)
("C->" . mc/skip-to-next-like-this)
("," . mc/mark-previous-like-this)
(">" . mc/unmark-previous-like-this)
("C-<" . mc/skip-to-previous-like-this)
("y" . mc/mark-next-symbol-like-this)
("Y" . mc/mark-previous-symbol-like-this)
("w" . mc/mark-next-word-like-this)
("W" . mc/mark-previous-word-like-this)))
A great interface for git projects. It’s much more pleasant to use than the git interface on the command line. Use an easy keybinding to access magit.
(use-package magit
:bind (("C-x g" . magit-status))
:config
(define-key magit-status-mode-map (kbd "q") 'magit-quit-session)
(setq-default vc-handled-backends '(Git))
(setq magit-push-always-verify nil
;; only use A and B in Ediff
magit-ediff-dwim-show-on-hunks t))
The following code makes magit-status run alone in the frame, and then restores the old window configuration when you quit out of magit.
No more juggling windows after commiting. It’s magit bliss.
;; full screen magit-status
(defadvice magit-status (around magit-fullscreen activate)
(window-configuration-to-register :magit-fullscreen)
ad-do-it
(delete-other-windows))
(defun magit-quit-session ()
"Restores the previous window configuration and kills the magit buffer"
(interactive)
(kill-buffer)
(jump-to-register :magit-fullscreen))
M-x magit-log-buffer-file
(use-package git-timemachine
:commands git-timemachine)
- To grep files use
C-u C-x c M-g s
, select root dir for grep, TAB TAB Enter, enter file type, TAB TAB Enter, enter pattern or pressC-w
to select word at point. - to save the results of the grep use
C-x C-s
in a buffer. - To see minibuffer command history:
M-x helm-complex-command-history
. - To see helm find files history use
C-c h
in the find file buffer. - To see the mark ring us
M-x helm-all-mark-rings
. - For a quick calculator
M-x helm-calcul-expression
. - For a history
M-x helm-eshell-history
. - yank current selection
C-c C-y
. - add the current candidate to the kill ring with
C-c C-k
. - You can insert marked candidates into the current buffer with
C-c C-i
.
- Mark files:
C-SPC
- Delete buffer (or marked buffers) without leaving Helm:
C-c d
- Delete marked buffers and leave Helm:
M-D
- Grep buffers:
M-g s
GNU Global and projectile: use C-c p R
to regenerate tag file.
(use-package helm
;;:load-path "~/src/github/elisp/helm"
:demand t
:pin melpa
:diminish helm-mode
:hook (helm-goto-line-before . helm-save-current-pos-to-mark-ring)
:bind (("M-x" . helm-M-x)
("M-y" . helm-show-kill-ring)
("C-x b" . helm-mini)
("C-x C-f" . helm-find-files)
("C-`" . helm-resume))
:preface (require 'helm-config)
:config
;; must set before helm-config, otherwise helm uses the default
;; prefix "C-x c", which is inconvenient because you can
;; accidentially press "C-x C-c"
(setq ;;helm-M-x-fuzzy-match t
;;helm-bookmark-show-location t
;;helm-buffers-fuzzy-matching t
;;helm-completion-in-region-fuzzy-match t
;;helm-file-cache-fuzzy-match t
;;helm-imenu-fuzzy-match t
;;helm-mode-fuzzy-match t
;;helm-locate-fuzzy-match t
;;helm-quick-update t
;;helm-recentf-fuzzy-match t
;;helm-semantic-fuzzy-match t
;;
helm-split-window-in-side-p t ; open helm buffer inside current window,
;; not occupy whole other window
helm-ff-newfile-prompt-p nil
helm-scroll-amount 4 ; scroll 4 lines other window using
;; M-<next>/M-<prior>
;;helm-quick-update t ; do not display invisible candidates
;;helm-idle-delay 0.01 ; be idle for this many seconds, before
;; updating in delayed sources.
;;helm-input-idle-delay 0.01 ; be idle for this many seconds, before
;; updating candidate buffer
helm-ff-search-library-in-sexp t ; search for library in `require` and
;; `declare-function` sexp.
;;helm-buffers-favorite-modes (append helm-buffers-favorite-modes
;; '(picture-mode artist-mode))
;; limit the number of displayed canidates
;;helm-candidate-number-limit 100
;; show all candidates when set to 0
;;helm-M-x-requires-pattern 0
helm-ff-file-name-history-use-recentf t
;; move to end or beginning of source when reaching top or bottom of source.
helm-move-to-line-cycle-in-source t
;; Needed in helm-buffers-list
;;ido-use-virtual-buffers t
;; fuzzy matching buffer names when non--nil, useful in helm-mini that lists buffers
;;helm-buffers-fuzzy-matching t
;; truncate long lines
;;helm-truncate-lines t
helm-autoresize-min-height 30
helm-autoresize-max-height 30
helm-display-header-line nil
helm-buffer-max-length 45
helm-yas-display-key-on-candidate t
helm-grep-ag-command "rg --color=always --colors 'match:fg:black' --colors 'match:bg:yellow' --smart-case --no-heading --line-number %s %s %s"
helm-grep-ag-pipe-cmd-switches '("--colors 'match:fg:black'" "--colors 'match:bg:yellow'")
helm-mini-default-sources '(helm-source-buffers-list
helm-source-recentf
helm-source-bookmarks
helm-source-buffer-not-found))
;; Save current position to mark ring when jumping to a different place
(helm-autoresize-mode 1)
(helm-mode 1))
(defun nl/helm-eval-expression ()
(interactive)
(let ((selected-expression
(helm-comp-read "Select an eval expression: " read-expression-history :buffer "Helm eval expressions")))
;;(message "selected: %s" selected-expression)
(eval-expression (car (read-from-string selected-expression)))))
(defun nl/helm-async-shell-command ()
(interactive)
(let ((selected-command
(helm-comp-read "Select a shell command: " shell-command-history :buffer "Helm shell commands")))
(async-shell-command selected-command)))
(with-eval-after-load 'helm-files
;; rebind tab to do persistent action
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
;; make TAB works in terminal
(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)
;; list actions using C-z
(define-key helm-map (kbd "C-z") 'helm-select-action)
(define-key helm-grep-mode-map (kbd "<return>") 'helm-grep-mode-jump-other-window)
(define-key helm-grep-mode-map (kbd "n") 'helm-grep-mode-jump-other-window-forward)
(define-key helm-grep-mode-map (kbd "p") 'helm-grep-mode-jump-other-window-backward))
(NOT WORKING) So that helm windows shows at the bottom.
- from http://www.reddit.com/r/emacs/comments/345vtl/make_helm_window_at_the_bottom_without_using_any/
- see also http://www.lunaryorn.com/2015/04/29/the-power-of-display-buffer-alist.html
(with-eval-after-load 'helm
(cond (window-system
(add-to-list 'display-buffer-alist
`("^\\*[Hh]elm"
(display-buffer-in-side-window)
(inhibit-same-window . nil)
(reusable-frames . visible)
(side . bottom)
(slot . -1)
(window-height . 0.15)))
)))
Highlighting of token matches is a tad slow, let’s speed it up.
(with-eval-after-load 'helm
(setq helm-mp-highlight-delay 0.3))
I don’t know why, but helm tries doing window management. Please stop:
(with-eval-after-load 'helm
(setq helm-display-function 'pop-to-buffer))
Define my own function for C-o
key mapping. Uses ace-select-window
instead of find-file-other-window
.
(use-package helm-ag
:pin melpa
:after helm
:commands helm-ag
:bind (:map helm-ag-mode-map
("C-<return>" . nl/jump-other-window))
:preface
(defun nl/ace-find-file (filename)
(setq helm-ag--last-default-directory default-directory)
;; use ace-select-window if there are more than 2 windows in the frame
(let ((path (concat helm-ag--last-default-directory filename)))
(if (> (length (window-list)) 2)
(ace-select-window)
(other-window 1))
(find-file path)))
(defun nl/jump-other-window ()
(interactive)
(let ((line (helm-current-line-contents)))
(helm-ag--find-file-action line 'nl/ace-find-file helm-ag--search-this-file-p)))
:custom
;;(helm-ag-use-temp-buffer nil) ; setting to 't' does not work with js2-mode
(helm-ag-use-temp-buffer nil)
)
(use-package helm-c-yasnippet
:after helm
:commands helm-yas-complete
;;:init (use-package yasnippet)
:bind ("C-c y" . helm-yas-complete))
2020-02-03 Disabled for now since it causes problems with Helm.
(use-package helm-fd
:after helm
:disabled
:custom
(helm-fd-cmd "fdfind")
:bind (:map helm-map
("/" . helm-fd)))
(use-package helm-flx
:after helm
:commands helm-flx-mode
:config
(helm-flx-mode +1)
(setq helm-flx-for-helm-find-files t ;; t by default
helm-flx-for-helm-locate t))
(use-package helm-gtags
:after helm
:commands (helm-gtags-mode)
:bind (("M-." . helm-gtags-find-tag)
("M-," . helm-gtags-find-rtag))
:custom
(helm-gtags-path-style 'relative)
(helm-gtags-ignore-case t)
(helm-gtags-auto-update t))
(use-package helm-lsp
:after helm)
(use-package helm-projectile
:after helm
:init (helm-projectile-on)
;;(setq compilation-read-command t) ; do prompt for a compilation command
)
(use-package helm-rg
:after helm)
(use-package helm-swoop
:after helm
:bind (("M-i" . helm-swoop))
:config
;; When doing isearch, hand the word over to helm-swoop
(define-key isearch-mode-map (kbd "M-i") 'helm-swoop-from-isearch)
;; From helm-swoop to helm-multi-swoop-all
(define-key helm-swoop-map (kbd "M-i") 'helm-multi-swoop-all-from-helm-swoop)
;; Move up and down like isearch
(define-key helm-swoop-map (kbd "C-r") 'helm-previous-line)
(define-key helm-swoop-map (kbd "C-s") 'helm-next-line)
(define-key helm-multi-swoop-map (kbd "C-r") 'helm-previous-line)
(define-key helm-multi-swoop-map (kbd "C-s") 'helm-next-line)
;; Save buffer when helm-multi-swoop-edit complete
(setq helm-multi-swoop-edit-save t
;; If this value is t, split window inside the current window
helm-swoop-split-with-multiple-windows nil
;; Optional face for line numbers
;; Face name is `helm-swoop-line-number-face`
helm-swoop-use-line-number-face t))
No longer using this since most development is now using lsp - 2020-05-29
(use-package helm-xref
:after helm
:init
(require 'helm-xref)
:config
;;(setq xref-show-xrefs-function 'helm-xref-show-xrefs)
)
(use-package string-inflection
:bind
(("C-c i" . string-inflection-cycle)
("C-c C" . string-inflection-camelcase)
("C-c L" . string-inflection-lower-camelcase)
("C-c J" . string-inflection-java-style-cycle)
))
Provides Emacs with some Eclipse features for Java development. Eclim has to be installed first and can be downloaded from here.
2019-03-10 tyring out
(use-package eclim
;; :load-path "~/src/github/elisp/emacs-eclim"
:diminish eclim-mode
:custom-face
;; keep consistent which other auto-complete backend.
(ac-emacs-eclim-candidate-face ((t (:inherit ac-candidate-face))))
(ac-emacs-eclim-selection-face ((t (:inherit ac-selection-face)))))
:preface
(defun nl/restart-eclim (workspace-dir)
"Restarts the eclim server. If it is currently active, the server is stopped first."
(interactive (list (read-directory-name "Workspace directory: "
eclimd-default-workspace nil t eclimd-default-workspace)))
(if (get-buffer "*eclimd*") (stop-eclimd))
(message "workspace dir: %s" workspace-dir)
(cd-absolute workspace-dir)
(eclimd-start workspace-dir)
(switch-to-buffer "*eclimd*"))
(defun nl/gradle-javadoc ()
"Uses gradle to build the Javadoc for the project."
(interactive)
(let* ((current-directory default-directory))
(setq default-directory (locate-dominating-file default-directory "build.gradle"))
(compile "gradle -q --console=plain javadoc")
(setq default-directory current-directory)))
:init (use-package cl)
:config
(use-package company-emacs-eclim
:commands company-emacs-eclim-setup)
(use-package eclimd
;;:load-path "~/src/github/elisp/emacs-eclim"
:preface
;;(setq eclimd-autostart t)
)
(setq eclim-print-debug-messages t)
;;eclim-nailgun-port 9092
;;eclim-eclimrc "~/.eclimrc"
(let ((eclipse-dir (expand-file-name "~/apps/eclipse/java/oxygen/eclipse")))
(if (file-accessible-directory-p eclipse-dir)
(progn
(add-to-list 'eclim-eclipse-dirs eclipse-dir)
(setq eclim-executable (or (concat eclipse-dir "/eclim") (executable-find "eclim"))
eclimd-executable (or (concat eclipse-dir "/eclimd") (executable-find "eclimd"))
))))
(company-emacs-eclim-setup)
(global-company-mode t)
(setq eclim-auto-save t
eclimd-wait-for-process nil
;;eclimd-default-workspace "~/workspace/"
help-at-pt-display-when-idle t
help-at-pt-timer-delay 0.1
)
;; Call the help framework with the settings above & activate eclim-mode
(help-at-pt-set-timer))
(use-package gradle-mode
:disabled
:diminish gradle-mode
:init
(gradle-mode 1))
(use-package lsp-java
;; :hook (java-mode-hook . lsp))
:config (add-hook 'java-mode-hook 'lsp))
(use-package js2-mode
:mode "\\.js\\'"
;;:bind (("C-c s j" . nl/counsel-ag-js))
:preface
(defun js-filename-p (filename)
(string-match "\.js$" filename))
;; (defun nl/counsel-ag-js ()
;; "Perform counsel-ag on the project's JavaScript files."
;; (interactive)
;; (counsel-ag "" (projectile-project-root) "--js"))
;; (defun nl/counsel-ag-js-spec ()
;; "Perform counsel-ag on the project's JavaScript files."
;; (interactive)
;; (counsel-ag "" (projectile-project-root) "-G Spec.js$"))
(defun nl/webpack-find-file ()
"From a webpack failure backtrace, opens the file under the cursor at the line specified."
(interactive)
(let (p1 p2 err-line filename file-with-proj-path)
(save-some-buffers t)
(setq p1 (line-beginning-position) )
(setq p2 (line-end-position) )
(setq err-line (buffer-substring-no-properties p1 p2))
(save-match-data ; is usually a good idea
(and (string-match "^\\(ERROR\\|WARNING\\) in \\.\\/\\([^$]+\\)" err-line)
(setq filename (match-string 2 err-line))))
(message "filename: %s" (expand-file-name filename (projectile-project-root)))
(ace-select-window)
(find-file (expand-file-name filename (projectile-project-root)))
(goto-char (point-min))))
(defun nl/webpack-find-next-error ()
"searches for the next line starting with ERROR and then calls nl/webpack-find-file."
(interactive)
(next-line)
(while (re-search-forward "^ERROR" nil t)
(goto-char (match-beginning 0))
(recenter 0)
(nl/webpack-find-file)))
:init
(setq js2-global-externs '("define"
"jasmine"
"describe"
"fdescribe"
"fail"
"beforeEach"
"afterEach"
"inject"
"expect"
"spyOn"
"it"
"fit"
"xdescribe"
"xit"))
:config
(setq javascript-common-imenu-regex-list
'(("Controller" "[. \t]controller([ \t]*['\"]\\([^'\"]+\\)" 1)
("Controller" "[. \t]controllerAs:[ \t]*['\"]\\([^'\"]+\\)" 1)
("Filter" "[. \t]filter([ \t]*['\"]\\([^'\"]+\\)" 1)
("State" "[. \t]state[(:][ \t]*['\"]\\([^'\"]+\\)" 1)
("Factory" "[. \t]factory([ \t]*['\"]\\([^'\"]+\\)" 1)
("Service" "[. \t]service([ \t]*['\"]\\([^'\"]+\\)" 1)
("Module" "[. \t]module( *['\"]\\([a-zA-Z0-9_.]+\\)['\"], *\\[" 1)
("ngRoute" "[. \t]when(\\(['\"][a-zA-Z0-9_\/]+['\"]\\)" 1)
("Directive" "[. \t]directive([ \t]*['\"]\\([^'\"]+\\)" 1)
("Event" "[. \t]\$on([ \t]*['\"]\\([^'\"]+\\)" 1)
("Config" "[. \t]config([ \t]*function *( *\\([^\)]+\\)" 1)
("Config" "[. \t]config([ \t]*\\[ *['\"]\\([^'\"]+\\)" 1)
("OnChange" "[ \t]*\$(['\"]\\([^'\"]*\\)['\"]).*\.change *( *function" 1)
("OnClick" "[ \t]*\$([ \t]*['\"]\\([^'\"]*\\)['\"]).*\.click *( *function" 1)
("Watch" "[. \t]\$watch( *['\"]\\([^'\"]+\\)" 1)
("Function" "function[ \t]+\\([a-zA-Z0-9_$.]+\\)[ \t]*(" 1)
("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*=[ \t]*function[ \t]*(" 1)
("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)([^)'\"]*)[ \t]*{[ \t]*$" 1)
("Task" "[. \t]task([ \t]*['\"]\\([^'\"]+\\)" 1)
;;("Testcase" "^[ \t]*it(['\"][^']*['\"][ \t]*,[ \t]*function([^)'\"]*)[ \t]*{$" 1)
))
;; js-mode imenu enhancement
;; @see http://stackoverflow.com/questions/20863386/idomenu-not-working-in-javascript-mode
(defun nl-js-imenu-make-index ()
(save-excursion
(imenu--generic-function javascript-common-imenu-regex-list)))
(defun nl/javascript-mode-hook ()
(nl/setup-indent 2) ; indent 2 spaces width
(setq comment-multi-line t
mode-name "JS2")
(define-key js-mode-map [remap indent-new-comment-line]
'c-indent-new-comment-line)
(setq indent-tabs-mode nil)
(setq imenu-create-index-function 'nl-js-imenu-make-index)
(prettier-js-mode)
(flycheck-mode t))
;;(eval-after-load 'js2-mode
;; '(define-key js2-mode-map (kbd "RET") 'js2-line-break))
;;(setq ac-js2-evaluate-calls t)
(setq-default js2-mode-show-parse-errors t)
(setq-default js2-strict-missing-semi-warning t)
(setq-default js2-strict-trailing-comma-warning t)
:custom
(js2-basic-offset 2)
(js2-bounce-indent-p nil)
(js2-highlight-level 3)
:hook ((js2-mode . fic-mode)
;;(js2-mode-hook . ac-js2-mode)
(js2-mode . nl/javascript-mode-hook)
(js2-mode . nl/common-prog-mode-settings)))
(use-package js2-refactor
:after js2-mode
:diminish js2-refactor-mode
:hook (js-mode . js2-refactor-mode)
:config
(js2r-add-keybindings-with-prefix "C-c C-m"))
(use-package prettier-js
:after (typescript-mode web-mode js-mode)
:hook ((typescript-mode . prettier-js-mode)))
(use-package tern
:commands tern-mode
:load-path "~/src/github/elisp/tern/emacs"
:diminish tern-mode
:hook (js2-mode . tern-mode))
(use-package company-tern
:init (add-to-list 'company-backends 'company-tern))
From: https://github.com/jimenezrick/my-emacs.d/blob/master/packages-haskell.el
(use-package haskell-mode
:custom
(haskell-process-type 'cabal-repl)
(haskell-process-load-or-reload-prompt t)
(haskell-process-auto-import-loaded-modules t)
(haskell-process-log t)
(haskell-tags-on-save t)
:config
(defun haskell-mode-setup ()
(haskell-indentation-mode -1)
(interactive-haskell-mode)
(setq-local tab-stop-list '(2 4))
(setq indent-line-function 'indent-relative)
(setq tab-width 2)
(setq-local evil-shift-width 2)
(define-key evil-insert-state-map (kbd "TAB") 'tab-to-tab-stop)
(define-key evil-normal-state-map (kbd "C-]") 'haskell-mode-goto-loc)
(define-key evil-normal-state-map (kbd "C-c C-]") 'haskell-mode-tag-find)
(define-key evil-normal-state-map (kbd "C-c C-t") 'haskell-mode-show-type-at))
(add-hook 'haskell-mode-hook 'haskell-mode-setup)
(add-hook 'haskell-mode-hook 'haskell-decl-scan-mode))
(use-package flycheck-haskell
:config
(setq-default flycheck-disabled-checkers '(haskell-stack-ghc))
(add-hook 'haskell-mode-hook #'flycheck-haskell-setup))
(use-package company-ghci
:after pos-tip
:config
(defun show-hoogle-info-in-popup ()
(pos-tip-show (company-ghci/hoogle-info (symbol-at-point))))
(defun company-ghci-setup ()
(push 'company-ghci company-backends)
(define-key evil-normal-state-map (kbd "C-;") (lambda () (interactive) (show-hoogle-info-in-popup))))
(add-hook 'haskell-interactive-mode-hook 'company-mode)
(add-hook 'haskell-mode-hook 'company-ghci-setup))
(use-package ormolu
:hook (haskell-mode . ormolu-format-on-save-mode)
:bind (:map haskell-mode-map
("C-c r" . ormolu-format-buffer)))
;; (use-package dhall-mode
;; :mode "\\.dhall\\'")
SLIME is the Superior Lisp Interaction Mode for Emacs.
(use-package slime
:config
(setq inferior-lisp-program "/home/nelson/apps/clozureCL/ccl/lx86cl64")
(setq slime-contribs '(slime-fancy)))
(use-package lua-mode
:mode "\\.lua"
:hook
(lua-mode . company-mode)
:config
(setq lua-indent-level 2)
:interpreter ("lua" . lua-mode))
Flycheck configuration taken from here, but had to change the way the nl/php-checker
checker is loaded.
(use-package php-mode
:mode "\\.php[345]?\\'"
:hook (php-mode . nl/php-mode-hook)
:preface
(defun nl/php-mode-hook ()
"My PHP mode configuration."
(flycheck-mode t)
(setq c-basic-offset 2)
(php-set-style "nl/php"))
;; this style is based on the symfony2 style
(c-add-style
"nl/php"
'("php"
(c-basic-offset . 2)
(indent-tabs-mode . nil)
(c-offsets-alist . ((statement-cont . php-lineup-hanging-semicolon)))
(c-indent-comments-syntactically-p . t)
(fill-column . 78)
(require-final-newline . t)))
(flycheck-define-checker nl/php-checker
"A PHP syntax checker using the PHP command line interpreter.
See URL http://php.net/manual/en/features.commandline.php."
:command ("php" "-l" "-d" "error_reporting=E_ALL" "-d" "display_errors=1"
"-d" "log_errors=0" source)
:error-patterns
((error line-start (or "Parse" "Fatal" "syntax") " error" (any ":" ",") " "
(message) " in " (file-name) " on line " line line-end))
:modes (php-mode web-mode))
(eval-after-load 'flycheck
'(add-to-list 'flycheck-checkers 'nl/php-checker))
:custom
(php-mode-coding-style (quote nl/php))
(php-mode-lineup-cascaded-calls t))
(use-package phpunit
:after (php-mode)
:bind (:map php-mode-map
("C-c , t" . phpunit-current-test)
("C-c , c" . phpunit-current-class)
("C-c , p" . phpunit-current-project))
:init
(push `(php-error-regexp
,(rx line-start
(zero-or-more "Trace:" space)
"#" (one-or-more digit)
(zero-or-more space)
(group-n 1 (one-or-more (not (in space "(" "\n"))))
"(" (group-n 2 (one-or-more digit))
(zero-or-more not-newline))
1 2)
compilation-error-regexp-alist-alist)
(push 'php-error-regexp compilation-error-regexp-alist)
:custom
(phpunit-arg "--stderr --debug"))
https://www.mattduck.com/lsp-python-getting-started.html
(use-package python
:config
(require 'dap-node)
(dap-node-setup))
pyright? lsp for python, sure. but which lsp server??
(use-package lsp-pyright
:preface
(defun nl/pyright-hook ()
(require 'lsp-pyright)
(lsp))
:hook (python-mode . nl/pyright-hook))
(use-package company-jedi
:after company
:config
(add-to-list 'company-backends #'company-jedi))
See here
(use-package elpy
:bind
(:map elpy-mode-map
("C-M-n" . elpy-nav-forward-block)
("C-M-p" . elpy-nav-backward-block)
("M-<up>" . nil)
("M-<down>" . nil)
("M-<left>" . nil)
("M-<right>" . nil))
:hook
(elpy-mode . flycheck-mode)
(elpy-mode . (lambda ()
(set (make-local-variable 'company-backends)
'((elpy-company-backend :with company-yasnippet)))))
:config
(setq elpy-rpc-virtualenv-path 'current
;; fix for MacOS, see https://github.com/jorgenschaefer/elpy/issues/1550
elpy-modules (delq 'elpy-module-flymake elpy-modules)
elpy-shell-echo-output nil
elpy-rpc-python-command "python3"
elpy-rpc-timeout 2))
(with-eval-after-load 'python (elpy-enable))
(use-package pyvenv
:after python-mode
:config
(pyvenv-mode 1))
The uncompromising Python code formatter.
(use-package python-black
:after python
:hook (python-mode . python-black-on-save-mode-enable-dwim))
(use-package rust-mode
:mode "\\.rs$"
:hook
(rust-mode . lsp)
(rust-mode . nl/common-prog-mode-settings)
:interpreter ("rust" . rust-mode)
:config
(setq rust-format-on-save t))
(use-package flycheck-rust
:after rust-mode
:hook (flycheck-mode . flycheck-rust-setup))
(use-package lsp-metals)
(use-package scala-mode
;;:load-path "~/src/github/elisp/emacs-scala-mode"
:mode "\\.s\\(cala\\|bt\\)$"
:interpreter ("scala" . scala-mode)
:hook
(scala-mode . nl/scala-mode-hook)
(before-save . nl/scala-before-save)
:custom
;;(prettify-symbols-unprettify-at-point 'right-edge)
(prettify-symbols-unprettify-at-point t)
:preface
(defun nl/scala-mode-hook ()
(yas-minor-mode)
(setq-default indent-tabs-mode nil)
(setq compilation-ask-about-save nil
prettify-symbols-alist scala-prettify-symbols-alist)
(nl/common-prog-mode-settings)
(prettify-symbols-mode))
(defun nl/scala-before-save ()
(when (eq major-mode 'scala-mode)
(lsp-format-buffer)))
(key-chord-define-global "jt" 'hydra-nl-scalatest/body)
;; (defun nl/counsel-ag-scala ()
;; "Perform counsel-ag on the project's Scala files."
;; (interactive)
;; (counsel-ag "" (projectile-project-root) "--scala"))
;; '(global-set-key (kbd "C-c s s") 'nl/counsel-ag-scala)
:config
(setq scala-indent:indent-value-expression t
scala-indent:align-parameters t
scala-indent:align-forms t
scala-indent:default-run-on-strategy '2 ;; scala-indent:reluctant-strategy
scala-indent:use-javadoc-style t)
(push `(scala-error-regexp
,(rx bol
"["
(any "E" "W")
"]"
(zero-or-more space)
(group-n 1 (one-or-more (not (in space ":" "\n"))))
":" (group-n 2 (one-or-more digit))
":" (group-n 3 (one-or-more digit))
":")
1 2 3 2)
compilation-error-regexp-alist-alist)
(push 'scala-error-regexp compilation-error-regexp-alist))
No longer used since Scala Metals is now being used.
(use-package sbt-mode
;;:load-path "~/src/github/elisp/emacs-sbt-mode"
:commands (sbt-start sbt-command)
:preface
(defun nl-sbt-mode-hook ()
;; compilation-skip-threshold tells the compilation minor-mode which type of compiler output can
;; be skipped. 1 = skip info 2 = skip info and warnings.
(setq compilation-skip-threshold 1)
;; Bind C-a to 'comint-bol when in sbt-mode. This will move the cursor to just after prompt.
(local-set-key (kbd "C-a") 'comint-bol)
;; Bind M-RET to 'comint-accumulate. This will allows one to add more than one line to the scala
;; console prompt before sending it for interpretation. It keeps the command history cleaner.
(local-set-key (kbd "M-RET") 'comint-accumulate))
(defun nl-sbt-command ()
(interactive)
(setq completing-read-function 'completing-read-default)
(call-interactively 'sbt-command)
(setq completing-read-function 'ivy-completing-read))
;; ;; Ivy and =sbt-command= do not behave well together right now, define
;; ;; our own wrapper function.
;; ;; --testing--
;; (defun sbt-command-ivy ()
;; "Send a command to the sbt process of the current buffer's sbt project.
;; Prompts for the command to send when in interactive mode. You can
;; use tab completion.
;; This command does the following:
;; - displays the buffer moving focus to it if focus is t
;; - erases the buffer
;; - forgets about compilation errors
;; The command is most usefull for running a compilation command
;; that outputs errors."
;; (interactive)
;; (setq sbt:command-history-temp
;; (ignore-errors (with-current-buffer (sbt:buffer-name) (ring-elements comint-input-ring))))
;; (ivy-read (format "Command to run (default %s): " (sbt:get-previous-command))
;; #'sbt:get-sbt-completions-for-command
;; :action #'sbt:command
;; :history 'sbt:command-history-temp
;; :preselect (sbt:get-previous-command)
;; :dynamic-collection t))
;;; https://github.com/ensime/emacs-sbt-mode/issues/139
(setq sbt:program-options '("-Djline.terminal=auto"))
:hook (sbt-mode . nl-sbt-mode-hook)
:config
;; set this regex so that it knows about Play Framework SBT prompt
(setq sbt:sbt-prompt-regexp "^\\[[^]]+\\]\\s-*\\$\\s-*"
sbt:ansi-support t
sbt:scroll-to-bottom-on-output nil)
(setenv "EMACS" "true"))
(use-package typescript-mode
:mode ("\\.ts\\'" "\\.tsx\\'" "\\.js\\'")
:hook
(typescript-mode . lsp-deferred)
(typescript-mode . column-enforce-mode)
(typescript-mode . rainbow-delimiters-mode)
(typescript-mode . nl/typescript-mode)
:preface
(defun nl/typescript-mode ()
(flycheck-mode +1)
(eldoc-mode +1)
(company-mode +1)
(prettier-js-mode)
(nl/common-prog-mode-settings)
;; need to override the value set in typescript-mode.el
(push '(typescript-tsc-pretty
"^\\(?:\\(Error\\|Warning\\)\\):[[:blank:]]\\([^:]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)"
2 3 4 1)
compilation-error-regexp-alist-alist)
(setq prettify-symbols-alist nl-typescript-prettify-symbols)
(prettify-symbols-mode))
:config
(setq prettify-symbols-unprettify-at-point 'right-edge
company-tooltip-align-annotations t ;; aligns annotation to the right hand side
flycheck-check-syntax-automatically '(save mode-enabled))
(setq-default typescript-indent-level 2)
(defconst nl-typescript-prettify-symbols
'(("=>" . ?⇒)
("<=" . ?≤)
(">=" . ?≥)
("===" . ?≡)
("!" . ?¬)
("!=" . ?≠)
("!==" . ?≢)
("&&" . ?∧)
("||" . ?∨))))
(use-package tide
:after (typescript-mode company flycheck)
:bind (:map tide-mode-map
("C-c C-t f" . tide-fix)
("C-c C-t n" . tide-nav)
("C-c C-t o" . tide-organize-imports)
("C-c C-t r" . tide-rename-symbol)
("C-c C-t x" . tide-references))
:init
(use-package typescript-mode)
:config
(setq tide-sync-request-timeout 5
tide-server-max-response-length 204800)
(flycheck-add-next-checker 'javascript-eslint 'javascript-tide 'append)
(flycheck-add-next-checker 'javascript-eslint 'jsx-tide 'append)
(defun nl-tide-mode-hook ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
(company-mode +1)
(prettier-js-mode)
(nl/common-prog-mode-settings)
(setq prettify-symbols-alist nl-typescript-prettify-symbols-alist
prettify-symbols-unprettify-at-point 'right-edge
company-tooltip-align-annotations t) ;; aligns annotation to the right hand side
(setq-default typescript-indent-level 2))
:hook ((typescript-mode . tide-setup)
(typescript-mode . tide-hl-identifier-mode)
(typescript-mode . nl-tide-mode-hook)
(typescript-mode . column-enforce-mode)
(typescript-mode . rainbow-delimiters-mode)))
Load some computer-specific settings, such as the name and and email address. The way the settings are loaded is based off of Magnar Sveen’s config.
(defvar nl/user-settings-dir nil
"The directory with user-specific Emacs settings for this
user.")
;; Settings for currently logged in user
(require 's)
(let ((user-dir (concat user-emacs-directory "users")))
(when (file-directory-p user-dir)
(setq nl/user-settings-dir
(concat user-dir "/" (s-trim (shell-command-to-string "hostname -s"))))
(add-to-list 'load-path nl/user-settings-dir)))
;; Load settings specific for the current user
(when (file-exists-p nl/user-settings-dir)
(mapc 'load (directory-files nl/user-settings-dir nil "^[^#].*el$")))
Is some cases we need to know what type of OS Emacs is running under.
(defconst ostype-linux
(if (integer-or-marker-p
(string-match "linux" system-configuration)) t nil))
(defconst ostype-windows
(if (integer-or-marker-p
(string-match "pc-mingw32" system-configuration)) t nil))
Align by colons (handy for JavaScript), align by commas, and align by equal signs.
Borrowed from:
http://danconnor.com/post/5028ac91e8891a000000111f/align_and_columnize_key_value_data_in_emacs
(defun align-colons (beg end)
(interactive "r")
(align-regexp beg end ":\\(\\s-*\\)" 1 1 t))
(defun align-commas (beg end)
(interactive "r")
(align-regexp beg end ",\\(\\s-*\\)" 1 1 t))
(defun align-equals (beg end)
(interactive "r")
(align-regexp beg end "\\(\\s-*\\)=" 1 1 t))
(defun align-parameters (beg end)
(interactive "r")
(align-regexp beg end "\\w+\\(\\s-*\\)\\w+,?" 1 1 t))
(defhydra hydra-nl-align (:hint nil)
(":" align-colons "colons" :color blue :column "Align things")
("," align-commas "commas" :color blue)
("=" align-equals "equals" :color blue)
("p" align-parameters "parameters" :color blue))
(key-chord-define-global "aa" 'hydra-nl-align/body)
Using this hydra instead of method below, which is tangled out.
;;
;; Taken from http://doc.rix.si/org/fsem.html
;;
(defhydra hydra-zoom (global-map "C-c z")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out"))
C-c C-+
and C-c C--
are pretty useful, but only resize the current
buffer. Here’s a hack using set-frame-font
and altering the font
size only:
(defun nl/alter-frame-font-size (fn)
(let* ((current-font-name (frame-parameter nil 'font))
(decomposed-font-name (x-decompose-font-name current-font-name))
(font-size (string-to-int (aref decomposed-font-name 5))))
(aset decomposed-font-name 5 (int-to-string (funcall fn font-size)))
(set-frame-font (x-compose-font-name decomposed-font-name))))
(defun nl/inc-frame-font-size ()
(interactive)
(nl/alter-frame-font-size '1+))
(defun nl/dec-frame-font-size ()
(interactive)
(nl/alter-frame-font-size '1-))
(global-set-key (kbd "C-+") 'nl/inc-frame-font-size)
(global-set-key (kbd "C--") 'nl/dec-frame-font-size)
Used for inserting date and time stamps, or date stamps into the current buffer at the current location. I define my own format for these.
(defconst nl/dts-format-string "%Y-%m-%d %H:%M:%S"
"A string specifying the format of the date-time stamp.
Refer to the documentation for 'format-time-string' for an explanation of the
meta characters available for use in this string. Non-meta characters will
be inserted into the buffer without interpretation.")
(defvar nl/ds-format-string "%Y-%m-%d"
"A string specifying the format of the date stamp.
Refer to the documentation for 'format-time-string' for an explanation of the
meta characters available for use in this string. Non-meta characters will
be inserted into the buffer without interpretation.")
(defun nl/insert-dts ()
"Insert the date and time into the current buffer at the current location.
See the documentation for nl/dts-format-string to change the format of the
date-time stamp."
(interactive)
(insert (format-time-string nl/dts-format-string (current-time))))
(defun nl/insert-ds ()
"Insert the date into the current buffer at the current location.
See the documentation for nl/dts-format-string to change the format of the
date-time stamp."
(interactive)
(insert (format-time-string nl/ds-format-string (current-time))))
The following function for occur-dwim
is taken from Oleh Krehel from
his blog post at (or emacs. It takes the current region or the symbol
at point as the default value for occur.
(defun occur-dwim ()
"Call `occur' with a sane default."
(interactive)
(push (if (region-active-p)
(buffer-substring-no-properties
(region-beginning)
(region-end))
(thing-at-point 'symbol))
regexp-history)
(call-interactively 'occur))
Coverts camel case words to uppercase with underscore as delimiters.
(defun nl/camelcase-to-upper ()
(interactive)
(replace-regexp "\\([A-Z]\\)" "_\\1" nil (region-beginning)(region-end))
(upcase-region (region-beginning)(region-end)))
(defun nl/toggle-camelcase-underscores ()
"Toggle between camelcase and underscore notation for the symbol at point."
(interactive)
(save-excursion
(let* ((bounds (bounds-of-thing-at-point 'symbol))
(start (car bounds))
(end (cdr bounds))
(currently-using-underscores-p (progn (goto-char start)
(re-search-forward "_" end t))))
(if currently-using-underscores-p
(progn
(upcase-initials-region start end)
(replace-string "_" "" nil start end)
(downcase-region start (1+ start)))
(replace-regexp "\\([A-Z]\\)" "_\\1" nil (1+ start) end)
(downcase-region start (cdr (bounds-of-thing-at-point 'symbol)))))))
Views the same file side by side:
(defun toggle-window-dedicated ()
"Control whether or not Emacs is allowed to display another
buffer in current window."
(interactive)
(message
(if (let (window (get-buffer-window (current-buffer)))
(set-window-dedicated-p window (not (window-dedicated-p window))))
"%s: Can't touch this!"
"%s is up for grabs.")
(current-buffer)))
;; (global-set-key (kbd "C-c d") 'toggle-window-dedicated)
;; see https://www.reddit.com/r/emacs/comments/80pd2q/anyone_could_help_me_with_window_management/
;; possible values are: display-buffer-same-window, display-buffer-pop-up-window, display-buffer-reuse-window
;;
;; Commented out since it is being configured in the "Side Windows" section now (2019-02-20)
;;
;; (add-to-list 'display-buffer-alist
;; '("\*xref\*" . (display-buffer-same-window)))
(defun nl/frame-grow-horizontally ()
"Set the size and position of the Emacs window."
(interactive)
(let ((frame (selected-frame)))
(set-frame-size frame (* 2 (frame-width)) (frame-height)))
(split-window-right))
(defun nl/frame-shrink-horizontally ()
"Set the size and position of the Emacs window."
(interactive)
(when (> (length (window-list)) 1)
(delete-other-windows))
(let ((frame (selected-frame)))
(set-frame-size frame (/ (frame-width) 2) (frame-height))))
(defun nl-frame-resize ()
"Resizes the frame based on its current width."
(interactive)
(if (<= (frame-width) 120)
(nl/frame-grow-horizontally)
(nl/frame-shrink-horizontally)))
(global-set-key [f9] 'nl-frame-resize)
(defun nl/split-view-same-file ()
(interactive)
(windmove-right)
(delete-window)
(split-window-right)
(windmove-right))
(global-set-key [S-f9] 'nl/split-view-same-file)
(defun nl/-set-transparency (inc)
"Increase or decrease the selected frame transparency"
(let* ((alpha (frame-parameter (selected-frame) 'alpha))
(next-alpha (cond ((not alpha) 100)
((> (- alpha inc) 100) 100)
((< (- alpha inc) 0) 0)
(t (- alpha inc)))))
(set-frame-parameter (selected-frame) 'alpha next-alpha)))
(defhydra hydra-transparency (:columns 2)
"
ALPHA : [ %(frame-parameter nil 'alpha) ]
"
("j" (lambda () (interactive) (nl/-set-transparency +1)) "+ more")
("k" (lambda () (interactive) (nl/-set-transparency -1)) "- less")
("J" (lambda () (interactive) (nl/-set-transparency +10)) "++ more")
("K" (lambda () (interactive) (nl/-set-transparency -10)) "-- less")
("=" (lambda (value) (interactive "nTransparency Value 0 - 100 opaque:")
(set-frame-parameter (selected-frame) 'alpha value)) "Set to ?" :color blue))
(global-set-key (kbd "C-c t") 'hydra-transparency/body)
(when ostype-windows
(set-face-attribute 'default nil :font "InputMonoCondensed Medium-9"))
From Artur Malabarba’s blog:
(defun narrow-or-widen-dwim (p)
"Widen if buffer is narrowed, narrow-dwim otherwise.
Dwim means: region, org-src-block, org-subtree, or defun,
whichever applies first. Narrowing to org-src-block actually
calls `org-edit-src-code'.
With prefix P, don't widen, just narrow even if buffer is
already narrowed."
(interactive "P")
(declare (interactive-only))
(cond ((and (buffer-narrowed-p) (not p)) (widen))
((region-active-p)
(narrow-to-region (region-beginning) (region-end)))
((derived-mode-p 'org-mode)
;; `org-edit-src-code' is not a real narrowing
;; command. Remove this first conditional if you
;; don't want it.
(cond ((ignore-errors (org-edit-src-code))
(delete-other-windows))
((ignore-errors (org-narrow-to-block) t))
(t (org-narrow-to-subtree))))
((derived-mode-p 'latex-mode)
(LaTeX-narrow-to-environment))
(t (narrow-to-defun))))
;;(define-key endless/toggle-map "n" #'narrow-or-widen-dwim)
;; This line actually replaces Emacs' entire narrowing
;; keymap, that's how much I like this command. Only copy it
;; if that's what you want.
(define-key ctl-x-map "n" #'narrow-or-widen-dwim)
(add-hook 'LaTeX-mode-hook
(lambda () (define-key LaTeX-mode-map "\C-xn" nil)))
(eval-after-load 'org-src
'(define-key org-src-mode-map
"\C-x\C-s" #'org-edit-src-exit))
(defun modi/multi-pop-to-mark (orig-fun &rest args)
"Call ORIG-FUN until the cursor moves.
Try the repeated popping up to 10 times."
(let ((p (point)))
(dotimes (i 10)
(when (= p (point))
(apply orig-fun args)))))
(advice-add 'pop-to-mark-command :around
#'modi/multi-pop-to-mark)
From Endless Parentheses blog.
(defun endless/isearch-symbol-with-prefix (p)
"Like isearch, unless prefix argument is provided.
With a prefix argument P, isearch for the symbol at point."
(interactive "P")
(let ((current-prefix-arg nil))
(call-interactively
(if p #'isearch-forward-symbol-at-point
#'isearch-forward))))
(global-set-key [remap isearch-forward]
#'endless/isearch-symbol-with-prefix)
(defun nl/query-replace-regexp-at-point ()
"Runs query-replace-regexp on the word at point"
(interactive)
(let (bounds pos1 pos2 word-at-point replace-with (current-subword-mode-setting subword-mode))
(subword-mode 0)
(setq bounds (bounds-of-thing-at-point 'word)
pos1 (car bounds)
pos2 (cdr bounds)
word-at-point (downcase (buffer-substring-no-properties pos1 pos2)))
(subword-mode current-subword-mode-setting) ;; restore subword-mode to original value
;;(message "%s" word-at-point)
(setq replace-with (read-from-minibuffer (format "Replace \"%s\" with: " word-at-point)))
;; (message "subword-mode-setting: %s, word-at-point: %s, replace-with: %s"
;; subword-mode-setting word-at-point replace-with)
(back-to-indentation) ;; goto beginning of line
(query-replace-regexp word-at-point replace-with)))
(defun nl/strip-html ()
"Remove HTML tags from the current buffer,
(this will affect the whole buffer regardless of the restrictions in effect)."
(interactive "*")
(save-excursion
(save-restriction
(widen)
(goto-char (point-min))
(while (re-search-forward "<[^<]*>" (point-max) t)
(replace-match "\\1"))
(goto-char (point-min))
(replace-string "©" "(c)")
(goto-char (point-min))
(replace-string "&" "&")
(goto-char (point-min))
(replace-string "<" "<")
(goto-char (point-min))
(replace-string ">" ">")
(goto-char (point-min)))))
Taken from: https://old.reddit.com/r/emacs/comments/bz9rxn/weekly_tipstricketc_thread/
(defun user/smarter-backward-kill-word ()
"Deletes the previous word, respecting:
1. If the cursor is at the beginning of line, delete the '\n'.
2. If there is only whitespace, delete only to beginning of line.
3. If there is whitespace, delete whitespace and check 4-5.
4. If there are other characters instead of words, delete one only char.
5. If it's a word at point, delete it."
(interactive)
(if (bolp)
;; 1
(delete-char -1)
(if (string-match-p "^[[:space:]]+$"
(buffer-substring-no-properties
(line-beginning-position) (point)))
;; 2
(delete-horizontal-space)
(when (thing-at-point 'whitespace)
;; 3
(delete-horizontal-space))
(if (thing-at-point 'word)
;; 5
(let ((start (car (bounds-of-thing-at-point 'word)))
(end (point)))
(if (> end start)
(delete-region start end)
(delete-char -1)))
;; 4
(delete-char -1)))))
(global-set-key [remap backward-kill-word] #'user/smarter-backward-kill-word)
From: https://with-emacs.com/posts/tips/quit-current-context/
(defun keyboard-quit-context+ ()
"Quit current context.
This function is a combination of `keyboard-quit' and
`keyboard-escape-quit' with some parts omitted and some custom
behavior added."
(interactive)
(cond ((region-active-p)
;; Avoid adding the region to the window selection.
(setq saved-region-selection nil)
(let (select-active-regions)
(deactivate-mark)))
((eq last-command 'mode-exited) nil)
(current-prefix-arg
nil)
(defining-kbd-macro
(message
(substitute-command-keys
"Quit is ignored during macro defintion, use \\[kmacro-end-macro] if you want to stop macro definition"))
(cancel-kbd-macro-events))
((active-minibuffer-window)
(when (get-buffer-window "*Completions*")
;; hide completions first so point stays in active window when
;; outside the minibuffer
(minibuffer-hide-completions))
(abort-recursive-edit))
(t
(when completion-in-region-mode
(completion-in-region-mode -1))
(let ((debug-on-quit nil))
(signal 'quit nil)))))
(global-set-key [remap keyboard-quit] #'keyboard-quit-context+)
(with-eval-after-load 'ace-window
(require 'helm-treemacs-icons)
(helm-treemacs-icons-enable))
Prot’s config has a lot of nice things.
(use-package emacs
:commands (prot/window-dired-vc-root-left
prot/make-frame-floating-with-current-buffer
prot/display-buffer-at-bottom)
:config
(defun prot/window-dired-vc-root-left ()
"Open root directory of current version-controlled repository
or the present working directory with `dired' and bespoke window
parameters. This is meant as a proof-of-concept function,
illustrating how to leverage window rules to display a buffer,
plus a few concomitant extras."
(interactive)
(let ((dir (if (eq (vc-root-dir) nil)
(dired-noselect default-directory)
(dired-noselect (vc-root-dir)))))
(display-buffer-in-side-window
dir `((side . left)
(slot . -1)
(window-width . 0.16)
(window-parameters . ((no-other-window . t)
(no-delete-other-windows . t)
(mode-line-format . (" "
mode-line-buffer-identification))))))
(with-current-buffer dir
(rename-buffer "*Dired-Side*")
(setq-local window-size-fixed 'width)))
(with-eval-after-load 'ace-window
(when (boundp 'aw-ignored-buffers)
(add-to-list 'aw-ignored-buffers "*Dired-Side*"))))
(defun prot/make-frame-floating-with-current-buffer ()
"Display the current buffer in a new floating frame.
This passes certain parameters to the newly created frame:
- use a different name than the default;
- use a graphical frame;
- do not display the minibuffer.
The name is meant to be used by the external rules of my tiling
window manager (BSPWM) to present the frame in a floating state."
(interactive)
(make-frame '((name . "my_float_window")
(window-system . x)
(minibuffer . nil))))
(defun prot/display-buffer-at-bottom ()
"Move the current buffer to the bottom of the frame. This is
useful to take a buffer out of a side window.
The window parameters of this function are provided mostly for
didactic purposes."
(interactive)
(let ((buffer (current-buffer)))
(with-current-buffer buffer
(delete-window)
(display-buffer-at-bottom
buffer `((window-parameters . ((mode-line-format . (" "
mode-line-buffer-identification))))))))))
(defun to-snake-case (start end)
"Change selected text to snake case format"
(interactive "r")
(if (use-region-p)
(let ((camel-case-str (buffer-substring start end)))
(delete-region start end)
(insert (s-snake-case camel-case-str)))
(message "No region selected")))
(defun play-reminder-sound ()
(interactive)
(start-process "" nil "mpv" "/usr/share/sounds/freedesktop/stereo/suspend-error.oga"))
(defun remind-me ()
"Notify with a sound after certain time"
(interactive)
(let ((time (read-string "Time (min|sec): " "10 min")))
(message "I will remind you after %s" time)
(run-at-time time nil #'play-reminder-sound)))
(defun light-set-value ()
"Set light value directly inside Emacs"
(interactive)
(let* ((current-value (s-trim (shell-command-to-string "light -G")))
(light-value (read-string "Set Value: " current-value)))
(start-process "" nil "light" "-S" light-value)))