(setq user-full-name "Ian Fernandez"
user-mail-address "[email protected]")
(global-set-key (kbd "<menu>")
(lambda () (interactive) (find-file "~/.emacs.d/README.org")))
(defalias 'yes-or-no-p 'y-or-n-p)
(fset 'yes-or-no-p 'y-or-n-p)
;(eval-when-compile
; (setq use-package-expand-minimally byte-compile-current-file))
;; ;;-----------------
(defvar current-user
(getenv
(if (equal system-type 'windows-nt) "USERNAME" "USER")))
(message "Let the coding begin! Be patient, %s!" current-user)
;; Always load newest byte code
(setq load-prefer-newer t)
;; (use-package gcmh
;; :ensure t
;; :delight gcmh-mode
;; :init
;; (setq gcmh-verbose t)
;; :config
;; (setq gc-cons-threshold #x40000000)
;; (gcmh-mode 1))
(defvar read-process-output-max (* 1024 2048)) ; 1 megabyte
(setq inhibit-compacting-font-caches t)
;;;; Packaging
(setq package-enable-at-startup nil)
(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
;;("marmalade" . "https://marmalade-repo.org/packages/")
;;("melpa-stable" . "https://stable.melpa.org/packages/")
("jcs-elpa" . "https://jcs-emacs.github.io/jcs-elpa/packages/")
("tromey" . "http://tromey.com/elpa/")
("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")))
(package-initialize)
;;;; use-package
(eval-and-compile
(setq use-package-always-ensure t))
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package)
(eval-and-compile
(setq use-package-always-ensure t)))
(eval-when-compile (require 'use-package))
(setq use-package-always-ensure t)
(defvar straight-use-package-by-default)
(setq straight-use-package-by-default t)
;; auto-package-update
(use-package auto-package-update
:config
(auto-package-update-maybe))
(unless (file-exists-p (concat user-emacs-directory "custom/custom.el"))
(make-directory (concat user-emacs-directory "custom"))
(make-empty-file (concat user-emacs-directory "custom/custom.el")))
(setq custom-file (expand-file-name (concat user-emacs-directory "custom/custom.el")))
(load custom-file)
(use-package async
:ensure t
:defer t
:init
(dired-async-mode 1)
(async-bytecomp-package-mode 1)
:custom
(async-bytecomp-allowed-packages '(all)))
(defun paste-from-osx ()
(shell-command-to-string "pbpaste"))
(defun copy-to-osx (text &optional push)
(let ((process-connection-type nil))
(let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
(process-send-string proc text)
(process-send-eof proc))))
;; Check the system
(when (eq system-type 'darwin)
(setq ;; interprogram-cut-function 'copy-to-osx
;; interprogram-paste-function 'paste-from-osx
mac-emulate-three-button-mouse nil
mac-option-modifier 'command
mac-command-modifier 'meta
mac-right-command-modifier 'meta
mac-right-option-modifier 'control
;;mac-option-key-is-control t
))
Allow pasting selection outside of Emacs
(setq x-select-enable-clipboard t)
Say you copied a link from your web browser, then switched to Emacs to paste it somewhere. Before you do that, you notice something you want to kill. Doing that will place the last kill to the clipboard, thus overriding the thing you copied earlier. We can have a kill ring solution:
(setq save-interprogram-paste-before-kill t)
(use-package exec-path-from-shell
:config
(exec-path-from-shell-initialize))
(setenv "PATH" (concat "/usr/local/bin" path-separator (getenv "PATH")))
(when (eq system-type 'darwin)
(setenv "PATH" (concat (getenv "PATH") ":/usr/local/bin:/opt/homebrew/bin"))
(setq exec-path (append exec-path '("/usr/local/bin"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (setenv "NODE_VERSION" ;;
;; (concat "/home/ianffcs/.nvm/versions/node/" ;;
;; (substring (shell-command-to-string "/usr/bin/node --version") 0 -1) "/bin")) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (setq exec-path ;;
;; (nconc exec-path (getenv "NODE_VERSION"))) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;(setq exec-path
;; (append exec-path '("/home/ianffcs/.nvm/versions/node/v12.11.1/bin")))
(set-charset-priority 'unicode)
(set-terminal-coding-system 'utf-8) ; pretty
(set-keyboard-coding-system 'utf-8) ; pretty
(set-selection-coding-system 'utf-8) ; please
(prefer-coding-system 'utf-8) ; with sugar on top
(setq default-process-coding-system '(utf-8-unix . utf-8-unix)
locale-coding-system 'utf-8)
(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8)
Find out what face something at point have.
(defun what-face (pos)
(interactive "d")
(let ((face (or (get-char-property (point) 'read-face-name)
(get-char-property (point) 'face))))
(if face (message "Face: %s" face) (message "No face at %d" pos))))
(defconst my-frame-alist
`((scroll-bar . -1)
(height . 60)
(width . 95)
(alpha . 95)
(vertical-scroll-bars . nil)))
(setq default-frame-alist my-frame-alist)
(use-package all-the-icons
:ensure t)
(use-package doom-themes
:init (setq doom-themes-enable-bold t doom-themes-enable-italic t)
:config
(doom-themes-org-config))
(use-package zenburn-theme
:defer t)
(use-package solarized-theme
:defer t)
(use-package organic-green-theme
:defer t)
(use-package django-theme
:defer t)
(load-theme 'doom-acario-light t)
invasive graphical elements.
(add-hook 'window-setup-hook 'toggle-frame-maximized t)
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(add-to-list 'initial-frame-alist '(fullscreen . maximized))
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
Emacs convention is to show help and other inline documentation in the message area. Show help there instead of OS tooltip.
(when
(display-graphic-p)
(tooltip-mode -1))
Let’s remove some crunchy messages at startup time.
(setq inhibit-startup-screen t
inhibit-splash-screen t
inhibit-startup-echo-area-message t)
(setq line-number-mode 0
column-number-mode +1
show-paren-mode 1
show-paren-delay 0
transient-mark-mode 1
scroll-bar-mode -1
browser-url-browse-function 'browse-url-firefox
linum-format "%5d"
tab-width 4
global-hl-line-mode t
indent-tabs-mode nil
truncate-partial-width-windows 1
fill-column 80
truncate-lines 1
confirm-kill-processes nil
create-lockfiles nil
make-backup-files nil)
(use-package which-key
:ensure t
:config (which-key-mode))
(global-display-fill-column-indicator-mode)
(blink-cursor-mode 0)
Beacon, never lose your cursor
(use-package beacon
:ensure t
:config
(setq beacon-push-mark 35
beacon-color "#666600")
(beacon-mode 1))
Change the highlight color for selection text.
(set-face-attribute 'region nil :background "#666" :foreground "#ffffff")
Make cursor the width of the character it is under.
(setq x-stretch-cursor t)
Smooth mouse scrolling
(setq transentient-mark-mode t
mouse-wheel-follow-mouse t
scroll-step 1
scroll-conservatively 101
mouse-wheel-scroll-amount '(1)
mouse-wheel-progressive-speed nil)
(use-package smooth-scrolling
:config (smooth-scrolling-mode 1))
(defun custom-set-frame-size ()
(add-to-list 'default-frame-alist '(height . 50))
(add-to-list 'default-frame-alist '(width . 178)))
(custom-set-frame-size)
(add-hook 'before-make-frame-hook 'custom-set-frame-size)
(defun set-frame-alpha (value)
"Set the transparency of the frame. 0 = transparent/100 = opaque"
(interactive "Alpha value (0-100): ")
(set-frame-parameter (selected-frame) 'alpha value))
(set-frame-alpha 90)
This package implements a menu that lists all enabled minor modes. Emacs mode line can become pretty long, so this can be handy, and perhaps I don’t need to use :diminish everywhere anymore.
(use-package minions
:commands minions-mode
:init (minions-mode 1))
(use-package time
:ensure nil
:init
(setq display-time-default-load-average nil
display-time-format "%Hh%M "
display-time-day-and-date t)
:config
(display-time-mode t))
Control the fringe around the frame.
(fringe-mode '(10 . 1))
Preview line numbers when prompting for line number.
(define-advice goto-line (:before (&rest _) preview-line-number)
"Preview line number when prompting for goto-line."
(interactive
(lambda (spec)
(if (and (boundp 'display-line-numbers)
(not display-line-numbers))
(unwind-protect
(progn (display-line-numbers-mode)
(advice-eval-interactive-spec spec))
(display-line-numbers-mode -1))
(advice-eval-interactive-spec spec)))))
(use-package mode-icons
:config (mode-icons-mode))
(use-package nyan-mode
:ensure t
:init
(setq nyan-animate-nyancat t
nyan-wavy-trail t
mode-line-format
(list '(:eval (list (nyan-create)))))
(nyan-mode t))
(use-package parrot
:config
(global-set-key (kbd "C-c p") 'parrot-rotate-prev-word-at-point)
(global-set-key (kbd "C-c n") 'parrot-rotate-next-word-at-point)
(parrot-set-parrot-type 'emacs)
(parrot-mode)
(add-hook 'before-save-hook 'parrot-start-animation))
(use-package emojify)
;; HIGHLIGHT WHEN ;; TODO
(use-package hl-todo
:config
(global-hl-todo-mode 1))
;; Show current key-sequence in minibuffer, like vim does. Any feedback
;; after typing is better UX than no feedback at all
(setq echo-keystrokes 0.2)
(setq backup-by-copying 1 ; don't clobber symlinks
;; store all backup and autosave files in the tmp dir
backup-directory-alist `((".*" . ,temporary-file-directory))
auto-save-file-name-transforms `((".*" ,temporary-file-directory t))
; use versioned backups
delete-old-versions 1
kept-new-versions 6
kept-old-versions 2
version-control 1)
(use-package savehist
:config
(setq savehist-additional-variables
;; search entries
'(search-ring regexp-search-ring)
;; save every minute
savehist-autosave-interval 60
;; keep the home clean
savehist-mode +1))
(setq proced-auto-update-flag t
proced-auto-update-interval 1
proced-descend t)
(use-package ivy
:diminish (ivy-mode)
:bind (("C-x b" . ivy-switch-buffer)
("C-c C-r" . ivy-resume))
:config
(ivy-mode 1)
(setq ivy-use-virtual-buffers t)
(setq ivy-count-format "%d/%d ")
(setq ivy-display-style 'fancy))
(use-package swiper
:bind (("C-s" . swiper-isearch))
:config
(ivy-mode 1))
(use-package anzu
:config
(global-anzu-mode)
(global-set-key (kbd "M-%") 'anzu-query-replace)
(global-set-key (kbd "C-M-%") 'anzu-query-replace-regexp))
(use-package counsel
:bind
(("M-x" . counsel-M-x)
("M-y" . counsel-yank-pop)
:map ivy-minibuffer-map
("M-y" . ivy-next-line))
:config
(define-key read-expression-map (kbd "C-r") 'counsel-expression-history)
(global-set-key (kbd "C-x C-f") 'counsel-find-file))
It is also interesting to use ivy-rich
for a… richer… Ivy
experience.
;; Function for buffer icons
(defun ivy-rich-switch-buffer-icon (candidate)
(with-current-buffer
(get-buffer candidate)
(let ((icon (all-the-icons-icon-for-mode major-mode)))
(if (symbolp icon)
(all-the-icons-icon-for-mode 'fundamental-mode)
icon))))
(use-package ivy-rich
:config (progn
(ivy-rich-mode 1)
(setcdr (assq t ivy-format-functions-alist)
#'ivy-format-function-line)
(setq ivy-rich-display-transformers-list
'(ivy-switch-buffer
(:columns
(;; Buffer icon
(ivy-rich-switch-buffer-icon (:width 2))
;; return the candidate itself
(ivy-rich-candidate (:width 30))
;; return the buffer size
;;(ivy-rich-switch-buffer-size (:width 7))
;; return the buffer indicators
(ivy-rich-switch-buffer-indicators
(:width 4 :face error :align right))
;; return the major mode info
(ivy-rich-switch-buffer-major-mode
(:width 12 :face warning))
;; return project name using `projectile'
;; (ivy-rich-switch-buffer-project
;; (:width 15 :face success))
;; return file path relative to project root
;; or `default-directory' if project is nil
(ivy-rich-switch-buffer-path
(:width (lambda (x)
(ivy-rich-switch-buffer-shorten-path
x
(ivy-rich-minibuffer-width 0.3))))))
:predicate
(lambda (cand) (get-buffer cand)))
counsel-M-x
;; (:columns
;; ;; the original transformer
;; ((counsel-M-x-transformer (:width 40))
;; (ivy-rich-counsel-function-docstring
;; ;; return the docstring of the command
;; (:face font-lock-doc-face))))
;; Two-column mode
(:columns
((counsel-M-x-transformer (:width 40))
(ivy-rich-counsel-function-docstring
(:face font-lock-doc-face))))
counsel-describe-function
(:columns
;; the original transformer
((counsel-describe-function-transformer (:width 40))
;; return the docstring of the function
(ivy-rich-counsel-function-docstring
(:face font-lock-doc-face))))
counsel-describe-variable
(:columns
;; the original transformer
((counsel-describe-variable-transformer (:width 40))
(ivy-rich-counsel-variable-docstring
;; return the docstring of the variable
(:face font-lock-doc-face))))
counsel-recentf
(:columns
;; return the candidate itself
((ivy-rich-candidate (:width 0.8))
(ivy-rich-file-last-modified-time
;; return the last modified time of the file
(:face font-lock-comment-face))))))))
Floaty stuff is floaty. But floaty stuff can only be floaty when EXWM is not being used.
;; (use-package ivy-posframe
;; :config (progn
;; (setq ivy-posframe-display-functions-alist
;; '((t . ivy-posframe-display-at-frame-center))
;; ivy-posframe-parameters
;; '((left-fringe . 8)
;; (right-fringe . 8)))
;; (ivy-posframe-mode 1)))
This queries YouTube stuff from Emacs and plays it on the browser.
(use-package ivy-youtube
:bind (("C-c y" . ivy-youtube)))
(setq ring-bell-function 'ignore)
(setq-default indent-tabs-mode nil ;; don't use tabs to indent
tab-width 4 ;; but maintain correct appearance
fill-column 80)
;; revert buffers automatically when underlying files are changed externally
(use-package autorevert
:ensure nil
:config
(global-auto-revert-mode +1)
(setq auto-revert-interval 2
auto-revert-check-vc-info t
global-auto-revert-non-file-buffers t
auto-revert-verbose nil))
;; Newline at end of file
(setq require-final-newline t)
;; Word wrapping
(setq-default word-wrap t
truncate-lines t
truncate-partial-width-windows nil
sentence-end-double-space nil
delete-trailing-lines nil
require-final-newline t
tabify-regexp "^\t* [ \t]+")
;; Favor hard-wrapping in text modes
;; (defun auto-fill ()
;; "My autofill setup for text buffers."
;; (auto-fill-mode t)
;; (delight 'auto-fill-mode))
;; (add-hook 'text-mode-hook #'auto-fill)
(setq shift-select-mode nil)
;; clean up obsolete buffers automatically
(use-package midnight)
(defmacro with-region-or-buffer (func)
"When called with no active region, call FUNC on current buffer."
`(defadvice ,func (before with-region-or-buffer activate compile)
(interactive
(if mark-active
(list (region-beginning) (region-end))
(list (point-min) (point-max))))))
(with-region-or-buffer indent-region)
(with-region-or-buffer untabify)
This is a built-in mode that keeps track of the files you have
opened allowing you go back to them faster. It can also integrate
with a completion framework to populate a virtual buffers
list.
(use-package recentf
:ensure nil
:init
(setq recentf-max-saved-items 50
recentf-max-menu-items 15
recentf-show-file-shortcuts-flag nil
recentf-auto-cleanup 'never)
:config
(add-to-list 'recentf-exclude "\\.gpg\\")
(recentf-mode t))
Emacs registers are compartments where you can save text, rectangles, positions, and other things for later use. Once you save text or a rectangle in a register, you can copy it into the buffer once or many times; once you save a position in a register, you can jump back to that position once or many times.
For more information: `C-h r’ and then letter i to search for registers and the amazing video from Protesilaos.
The prefix to all commands of registers is C-x r
command | description |
---|---|
M-x view-register R | see what register R contains |
C-x r s | save region to register |
C-x r i | insert text from a register |
C-x r n | record a number defaults to 0 |
C-x r + | increment a number from register |
C-x r SPC | record a position into register |
C-x r j | jump to positions or windows config |
C-x r w | save a window configuration |
C-x r f | save a frame configuration |
Important note: the data saved into the register is persistent as long as you don’t override it.
The way to specify a number, is to use an universal argument e.g. C-u <number> C-x n
Clean all the registers you saved.
(defun clear-registers ()
"Remove all saved registers."
(interactive)
(setq register-alist nil))
(set-register ?e '(file . "~/.emacs.d/README.org"))
(set-register ?t '(file . "~/org/todo.org"))
(set-register ?c '(file . "~/.emacs.d/docs/cheatsheet.org"))
ibuffer-expert | Stop asking for confirmation after every action in Ibuffer |
ibuffer-auto-mode | Keeps the buffer list up to date |
(use-package ibuffer
:ensure nil
:init
(setq ibuffer-expert t)
(setq ibuffer-show-empty-filter-groups t)
(setq ibuffer-saved-filter-groups
'(("Main"
("Directories" (mode . dired-mode))
("Rest" (mode . restclient-mode))
("Docker" (or
(mode . docker-compose-mode)
(mode . dockerfile-mode)))
("Programming" (or
(mode . clojure-mode)
(mode . emacs-lisp-mode)
(mode . python-mode)))
("Browser" (or
(name . "qutebrowser:\*")
(name . "Firefox:\*")))
("Org" (mode . org-mode))
("Markdown" (or
(mode . markdown-mode)
(mode . gfm-mode)))
("Git" (or
(mode . magit-blame-mode)
(mode . magit-cherry-mode)
(mode . magit-diff-mode)
(mode . magit-log-mode)
(mode . magit-process-mode)
(mode . magit-status-mode)))
("Emacs" (or
(name . "^\\*Help\\*$")
(name . "^\\*Custom.*")
(name . "^\\*Org Agenda\\*$")
(name . "^\\*info\\*$")
(name . "^\\*ielm\\*$")
(name . "^\\*scratch\\*$")
(name . "^\\*Backtrace\\*$")
(name . "^\\*Messages\\*$"))))))
:config
(add-hook 'ibuffer-mode-hook
(lambda ()
(ibuffer-auto-mode 1)
(ibuffer-switch-to-saved-filter-groups "Main"))))
(global-set-key (kbd "C-x C-b") 'ibuffer)
;; Package =ibuffer-vc= let you filter the Ibuffer by projects
;; definitions (in my case, every folder that has a =.git= folder
;; inside is considered a project).
(use-package ibuffer-vc
:ensure t
:after ibuffer)
;; Increasing the width of each column in ibuffer. Some buffers names
;; are very large in EXWM.
(setq ibuffer-formats
'((mark modified read-only " "
(name 60 60 :left :elide) ; change: 60s were originally 18s
" "
(size 9 -1 :right)
" "
(mode 16 16 :left :elide)
" " filename-and-process)
(mark " "
(name 16 -1)
" " filename)))
(use-package ibuffer-tramp)
(use-package ibuffer-projectile)
(use-package ibuffer-sidebar
:commands (ibuffer-sidebar-toggle-sidebar)
:config
(setq ibuffer-sidebar-use-custom-font t)
(setq ibuffer-sidebar-face `(:family "Helvetica" :height 140)))
(setq kill-buffer-query-functions
(delq 'process-kill-buffer-query-function kill-buffer-query-functions))
(defun close-all-buffers ()
"Kill all buffers without regard for their origin."
(interactive)
(mapc 'kill-buffer (buffer-list)))
(global-set-key (kbd "C-M-s-k") 'close-all-buffers)
Auth Source is a generic interface for common backends such as your operating sysetm’s keychain and your local ~/.authinfo file. Auth Source solves the problem of mapping passwords and usernames to hosts.
(use-package keepass-mode)
(setq auth-sources
'((:source "~/.authinfo.gpg")
(:source "~/.netrc")))
(setq auth-source-debug t)
Is good to know how to ask for help in Emacs
(use-package helpful
:bind
(("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)
("C-h ," . helpful-at-point)))
See also bidi-paragraph-direction
; setting that non-nil might speed up
redisplay.
(setq bidi-paragraph-direction 'left-to-right)
Since I am using EXWM, I might open very large files, there is a package to help Emacs handle this kind of files.
(use-package vlf
:defer t)
I found a good paper about log files
in Emacs where they mention
vlf
package. This
paper
is very worth reading nevertheless.
Emacs leaves a trail of breadcrumbs (the mark ring) through which we can navigate to hop around to places you’ve been in the buffer. A nice alternative is to move round through points at which you made edits in a buffer.
(use-package goto-chg
:ensure t
:config
(global-set-key (kbd "C-c b ,") 'goto-last-change)
(global-set-key (kbd "C-c b .") 'goto-last-change-reverse))
Now we can use C-c b ,
and C-c b .
to go back and forth
through the edit points in your buffer. It takes you through your
undo history without undoing anything.
Visual feedback on some operations like yank, kill, undo. An example is that if you paste the next key. This is just a small tweak, but gives a nice bit of visual feedback.
(use-package volatile-highlights
:ensure t
:delight volatile-highlights-mode
:defer t
:config
(volatile-highlights-mode t))
Very often is useful to highlight some symbols.
(use-package highlight-symbol
:ensure t
:delight highlight-symbol-mode
:hook
((highlight-symbol-mode . highlight-symbol-nav-mode)
(prog-mode . highlight-symbol-mode))
:custom
(highlight-symbol-highlight-single-occurrence nil)
(highlight-symbol-idle-delay 0.25)
(highlight-symbol-on-navigation-p t))
Multiple cursors is a very nice package that lets you create several cursors that all do the same thing as you type.
(use-package multiple-cursors
:bind
(("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-S-<mouse-1>" . mc/add-cursor-on-click)
("C-c m c" . mc/edit-lines)))
To use mc/edit-lines
you need to highlight the lines on which you
wish to have cursors and use C-c m c
. Now you can edit away and
press enter when you are done to exit multiple cursors.
There is this amazing video from magnars showing off multiple cursors features.
However, occasionally the best way to get the cursors where you
want them is with the mouse. With the following code, C-S-<left
mouse click>
adds a new cursor.
Very nice default.
;; `C-a' first takes you to the first non-whitespace char as
;; `back-to-indentation' on a line, and if pressed again takes you to
;; the actual beginning of the line.
(defun smarter-move-beginning-of-line (arg)
"Move depending on ARG to beginning of visible line or not.
From https://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/."
(interactive "^p")
(setq arg (or arg 1))
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
(global-set-key [remap move-beginning-of-line] 'smarter-move-beginning-of-line)
(defun duplicate-current-line-or-region (arg)
"Duplicates the current line or region ARG times.
If there's no region, the current line will be duplicated."
(interactive "p")
(save-excursion
(if (region-active-p)
(duplicate-region arg)
(duplicate-current-line arg))))
(defun duplicate-region (num &optional start end)
"Duplicates the region bounded by START and END NUM times.
If no START and END is provided, the current region-beginning
region-end is used."
(interactive "p")
(let* ((start (or start (region-beginning)))
(end (or end (region-end)))
(region (buffer-substring start end)))
(goto-char start)
(dotimes (i num)
(insert region))))
(defun duplicate-current-line (num)
"Duplicate the current line NUM times."
(interactive "p")
(when (eq (point-at-eol) (point-max))
(goto-char (point-max))
(newline)
(forward-char -1))
(duplicate-region num (point-at-bol) (1+ (point-at-eol))))
Let’s bind the top level function to a sensible key.
(global-set-key (kbd "C-c 2") 'duplicate-current-line-or-region)
; deletes all the whitespace when you hit backspace or delete
;; (use-package hungry-delete
;; :ensure t
;; :config
;; (global-hungry-delete-mode))
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
(defun unfill-region (beg end)
"Unfill the region, joining text paragraphs into a single
logical line. This is useful, e.g., for use with `visual-line-mode'."
(interactive "*r")
(let ((fill-column (point-max)))
(fill-region beg end)))
;; before save clears whitespace
(add-hook 'before-save-hook 'whitespace-cleanup)
(global-set-key (kbd "<f5>") 'revert-buffer)
(global-set-key (kbd "C-c i") 'string-inflection-all-cycle)
(use-package flyspell
:config
(setq flyspell-mode +1)
(setq ispell-program-name "aspell" ; use aspell instead of ispell
ispell-extra-args '("--sug-mode=ultra")))
;; dired - reuse current buffer by pressing 'a'
(put 'dired-find-alternate-file 'disabled nil)
;; always delete and copy recursively
(setq dired-recursive-deletes 'always)
(setq dired-recursive-copies 'always)
;; if there is a dired buffer displayed in the next window, use its
;; current subdir, instead of the current subdir of this dired buffer
(setq dired-dwim-target t)
(use-package dired-sidebar
:bind (("C-x C-n" . dired-sidebar-toggle-sidebar))
:ensure t
:commands (dired-sidebar-toggle-sidebar)
:init
(add-hook 'dired-sidebar-mode-hook
(lambda ()
(unless (file-remote-p default-directory)
(auto-revert-mode))))
:config
(push 'toggle-window-split dired-sidebar-toggle-hidden-commands)
(push 'rotate-windows dired-sidebar-toggle-hidden-commands)
(setq dired-sidebar-subtree-line-prefix "__"
dired-sidebar-use-term-integration t
dired-sidebar-use-custom-font t)
;; (setq dired-sidebar-theme 'vscode)
)
(defun sidebar-toggle ()
"Toggle both `dired-sidebar' and `ibuffer-sidebar'."
(interactive)
(dired-sidebar-toggle-sidebar)
(ibuffer-sidebar-toggle-sidebar))
(global-set-key (kbd "C-x <menu>") 'sidebar-toggle)
Some custom functions for Dired.
(require 'dired-x)
(defun dired-xdg-open ()
"Open the file at point with xdg-open."
(interactive)
(let ((file (dired-get-filename nil t)))
(message "Opening %s..." file)
(call-process "xdg-open" nil 0 nil file)
(message "Opening %s done" file)))
(eval-after-load 'dired
'(define-key dired-mode-map (kbd "O") 'dired-xdg-open))
(defun dired-directories-first ()
"Sort dired listings with directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2)
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))
(set-buffer-modified-p nil)))
(advice-add 'dired-readin :after #'dired-directories-first)
M-up is nicer in dired if it moves to the third line - straight to the “..”, which M-down is nicer if it moves to the last file and finally C-a moving back to start of files.
(defun dired-back-to-top ()
(interactive)
(beginning-of-buffer)
(next-line 2)
(dired-back-to-start-of-files))
(defun dired-back-to-bottom ()
(interactive)
(end-of-buffer)
(next-line -1)
(dired-back-to-start-of-files))
(defun dired-back-to-start-of-files ()
(interactive)
(backward-char (- (current-column) 2)))
Let’s bind the functions defined above so it can take effect in dired.
(eval-after-load 'dired
'(progn
(define-key dired-mode-map (kbd "M-p") 'dired-back-to-top)
(define-key dired-mode-map (kbd "M-n") 'dired-back-to-bottom)
(define-key dired-mode-map (kbd "C-a") 'dired-back-to-start-of-files)))
(use-package eshell-bookmark
:ensure t
:config
(add-hook 'eshell-mode-hook 'eshell-bookmark-setup))
(setenv "PAGER" "cat")
(defun eshell-clear-buffer ()
"Clear the terminal buffer."
(interactive)
(let ((inhibit-read-only t))
(erase-buffer)
(eshell-send-input)))
(add-hook 'eshell-mode-hook (lambda ()
(local-set-key (kbd "C-l") 'eshell-clear-buffer)))
(require 'em-alias)
(add-hook 'eshell-mode-hook
(lambda ()
(eshell/alias "e" "find-file $1")
(eshell/alias "ee" "find-file-other-window $1")))
This is very useful if you want to keep some default windows around while you edit in your main programming environment. For example, to keep a eshell and dired buffer around.
(use-package emacs
:custom
(display-buffer-alist
'(("\\*e?shell\\*"
(display-buffer-in-side-window)
(window-height . 0.30)
(side . bottom)
(slot . -1))))
:bind
("<f8>" . window-toggle-side-windows))
(use-package smartparens
:diminish
:init
(define-key smartparens-mode-map (kbd "M-(") 'sp-wrap-round)
(define-key smartparens-mode-map (kbd "M-[") 'sp-wrap-square)
(define-key smartparens-mode-map (kbd "M-{") 'sp-wrap-curly)
(define-key smartparens-mode-map (kbd "C-c (") 'sp-splice-sexp)
:config
(require 'smartparens-config)
(setq sp-base-key-bindings 'paredit)
(setq sp-autoskip-closing-pair 'always)
(setq sp-hybrid-kill-entire-symbol nil)
(sp-use-paredit-bindings)
(show-smartparens-global-mode +1)
(sp-local-pair '(emacs-lisp-mode) "'" "'" :actions nil)
(sp-local-pair '(common-lisp-mode) "'" "'" :actions nil)
(sp-local-pair '(clojure-mode) "'" "'" :actions nil)
(sp-local-pair '(cider-repl-mode) "'" "'" :actions nil)
(sp-local-pair '(scheme-mode) "'" "'" :actions nil)
(sp-local-pair '(lisp-mode) "'" "'" :actions nil)
(setq smartparens-global-strict-mode 1))
(use-package highlight-parentheses)
(use-package highlight-sexp)
(use-package switch-window
:ensure t
:config
(setq switch-window-input-style 'minibuffer)
(setq switch-window-increase 4)
(setq switch-window-threshold 2)
(setq switch-window-shortcut-style 'qwerty)
(setq switch-window-qwerty-shortcuts
'("a" "s" "d" "f" "j" "k" "l" "i" "o"))
:bind
([remap other-window] . switch-window))
(defun split-and-follow-horizontally ()
(interactive)
(split-window-below)
(balance-windows)
(other-window 1))
(global-set-key (kbd "C-x 2") 'split-and-follow-horizontally)
(defun split-and-follow-vertically ()
(interactive)
(split-window-right)
(balance-windows)
(other-window 1))
(global-set-key (kbd "C-x 3") 'split-and-follow-vertically)
(use-package windmove
:config
(windmove-default-keybindings))
;; avy allows us to effectively navigate to visible things
(use-package avy
:bind (("M-s a" . avy-goto-char))
:config
(setq avy-background t
avy-style 'at-full))
(use-package ace-window
:ensure t
:init
(setq aw-keys '(?h ?j ?k ?l ?y ?u ?i ?o ?p)
aw-background nil
aw-scope 'frame
aw-dispatch-alist
'((?s aw-swap-window "swap window")
(?2 aw-split-window-vert "split window vertically")
(?3 aw-split-window-horz "split window horizontally")
(?? aw-show-dispatch-help)))
:config
(ace-window-display-mode -1)
(global-set-key (kbd "C-x o") 'ace-window))
;; Don't popup certain buffers
(add-to-list 'display-buffer-alist
(cons "\\*Async Shell Command\\*.*"
(cons #'display-buffer-no-window nil)))
I can barely contain my joy. This extension allows you to quickly mark the next occurence of a region and edit them all at once. Wow!
(use-package mark-multiple
:ensure t
:bind ("C-c q" . 'mark-next-like-this))
Why on earth does a function called kill-word
not .. kill a word.
It instead deletes characters from your cursors position to the end of the word,
let’s make a quick fix and bind it properly.
(defun kill-inner-word ()
"Kills the entire word your cursor is in. Equivalent to 'ciw' in vim."
(interactive)
(forward-char 1)
(backward-word)
(kill-word 1))
(global-set-key (kbd "C-c w k") 'kill-inner-word)
And again, the same as above but we make sure to not delete the source word.
(defun copy-whole-word ()
(interactive)
(save-excursion
(forward-char 1)
(backward-word)
(kill-word 1)
(yank)))
(global-set-key (kbd "C-c w c") 'copy-whole-word)
Regardless of where your cursor is, this quickly copies a line.
(defun copy-whole-line ()
"Copies a line without regard for cursor position."
(interactive)
(save-excursion
(kill-new
(buffer-substring
(point-at-bol)
(point-at-eol)))))
(global-set-key (kbd "C-c l c") 'copy-whole-line)
And this quickly deletes a line.
(global-set-key (kbd "C-c l k") 'kill-whole-line)
While changing buffers or workspaces, the first thing you do is look for your cursor. Unless you know its position, you can not move it efficiently. Every time you change buffers, the current position of your cursor will be briefly highlighted now.
(use-package beacon
:ensure t
:config
(beacon-mode 1))
A nifty little package that kills all text between your cursor and a selected character.
A lot more useful than you might think. If you wish to include the selected character in the killed region,
change zzz-up-to-char
into zzz-to-char
.
(use-package zzz-to-char
:ensure t
:bind ("M-z" . zzz-up-to-char))
https://www.reddit.com/r/emacs/comments/7au3hj/how_do_you_manage_your_emacs_windows_and_stay_sane/ https://github.com/Alexander-Miller/dotfiles/blob/master/.config/spacemacs/user-config.org#shackle
Gives you the means to put an end to popped up buffers not behaving the way you’d like them to. By setting up simple rules you can for instance make Emacs always select help buffers for you or make everything reuse your currently selected window.
(use-package shackle
:ensure t
:config
(setq shackle-rules '(("*Ledger Report*" :same t)))
(add-hook 'after-init-hook 'shackle-mode))
Winner is a built-in tool that keeps a record of buffer and window layout changes. It then allows us to move back and forth in the history of said changes. The mnemonic is related to Emacs default commands to operating on windows (C-x 4) and the undo operations with [uU] letter.
There are some buffers that winner will not restore, I list them in the winner-boring-buffers.
(use-package winner
:ensure nil
:hook ((after-init . winner-mode))
:init
(setq winner-dont-bind-my-keys t)
(setq winner-boring-buffers
'("*Completions*"
"*Compile-Log*"
"*inferior-lisp*"
"*Fuzzy Completions*"
"*Apropos*"
"*Help*"
"*cvs*"
"*Buffer List*"
"*Ibuffer*"
"*esh command on file*"))
:bind (("C-x 4 u" . winner-undo)
("C-x 4 U" . winner-redo)))
(use-package restart-emacs
:ensure t)
There is a lot of customization to the kill ring, and while I have not used it much before, I decided that it was time to change that.
The default is 60, I personally need more sometimes.
(setq kill-ring-max 100)
Out of all the packages I tried out, this one, being the simplest, appealed to me most. With a simple M-y you can now browse your kill-ring like browsing autocompletion items. C-n and C-p totally work for this.
(use-package popup-kill-ring
:ensure t
:bind ("M-y" . popup-kill-ring))
(use-package auto-complete
:init
(progn
(ac-config-default)
(global-auto-complete-mode t)))
(use-package projectile
:config
(projectile-mode t))
(use-package yasnippet
:ensure t
:init
(yas-global-mode 1))
(use-package auto-yasnippet
:ensure t)
(use-package yasnippet-snippets
:after (yas-global-mode))
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(use-package rainbow-delimiters
:ensure t
:hook ((cider-mode . rainbow-delimiters-mode)
(cider-repl-mode-hook . rainbow-delimiters-mode)
(emacs-lisp-mode . rainbow-delimiters-mode)
(common-lisp-mode . rainbow-delimiters-mode)
(scheme-mode . rainbow-delimiters-mode)
(lisp-mode . rainbow-delimiters-mode)))
(use-package smartparens
:config
(progn
(setq sp-base-key-bindings 'paredit
sp-autoskip-closing-pair 'always
sp-hybrid-kill-entire-symbol nil)
(sp-use-paredit-bindings)))
(use-package aggressive-indent)
(use-package eldoc
:init
(setq eldoc-idle-delay 0.1
eldoc-echo-area-use-multiline-p nil))
(use-package smart-shift
:ensure t
:config
(global-smart-shift-mode t))
Enable hide definitions functions
(use-package hideshow
:defer t
:commands (hs-toggle-hiding)
:delight hs-minor-mode
:config
(add-hook 'prog-mode-hook 'hs-minor-mode)
(global-set-key (kbd "C-c h") 'hs-toggle-hiding))
(use-package expand-region)
(use-package highlight-numbers
:config (add-hook 'prog-mode-hook 'highlight-numbers-mode))
(require 'semantic)
;; (global-semanticdb-minor-mode 1)
;; (global-semantic-idle-scheduler-mode 1)
;; (global-semantic-stickyfunc-mode 0)
;; (semantic-mode 1)
Org and Mu4e’s compose buffer use auto-fill-mode
. I like to wrap on
column 80.
(setq fill-column 80)
(use-package highlight-numbers
:config (add-hook 'prog-mode-hook 'highlight-numbers-mode))
(use-package flycheck
:config (progn
(add-hook 'after-init-hook #'global-flycheck-mode)
;; Disable JSHint and json-jsonlist
(setq-default flycheck-disabled-checkers
(append flycheck-disabled-checkers
'(javascript-jshint
json-jsonlist)))))
(use-package flycheck-clj-kondo
:after flycheck)
(require 'semantic)
(global-semanticdb-minor-mode 1)
(global-semantic-idle-scheduler-mode 1)
(global-semantic-stickyfunc-mode 0)
(semantic-mode 1)
(use-package company-tabnine
:ensure t
:after company)
(use-package company
:delight company-mode
:init
(setq company-show-numbers t
company-dabbrev-downcase nil
company-dabbrev-ignore-case t
company-tooltip-limit 10
company-minimum-prefix-length 2
company-require-match 'never
company-tooltip-align-annotations t
company-transformers '(company-sort-by-occurrence)
company-idle-delay 0.5
company-tooltip-align-annotations t
company-tooltip-flip-when-above t)
:config
(setq company-idle-delay 0
company-minimum-prefix-length 3)
(global-company-mode))
(defun ora-company-number ()
"Choose the candidate based on his number at candidate list."
(interactive)
(let* ((k (this-command-keys))
(re (concat "^" company-prefix k)))
(if (cl-find-if (lambda (s) (string-match re s)) company-candidates)
(self-insert-command)
(company-complete-number (string-to-number k)))))
(defun ora-activate-number ()
"Activate the number-based choices in company."
(interactive)
(let ((map company-active-map))
(mapc
(lambda (x)
(define-key map (format "%d" x) 'ora-company-number))
(number-sequence 0 9))
;; (define-key map " " (lambda ()
;; (interactive)
;; (company-abort)
;; (self-insert-command 1)))
(define-key map (kbd "<return>") nil)))
(eval-after-load 'company
'(ora-activate-number))
Hippie Expand is a more feature complete completion engine than the
default dabbrev engine. The main feature I use over dabbrev
is
that is supports a wide range of backends for finding completions -
dabbrev
only looks at currently open buffers.
(setq hippie-expand-try-functions-list
'(try-expand-dabbrev
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-complete-file-name-partially
try-complete-file-name
try-expand-all-abbrevs
try-expand-list
try-expand-line
try-complete-lisp-symbol-partially
try-complete-lisp-symbol))
Then we override dabbrev-expand
’s keybinding to use
hippie-expand
instead.
(define-key (current-global-map) [remap dabbrev-expand] 'hippie-expand)
;;(use-package aggressive-indent)
(use-package nvm)
(use-package lsp-mode
:ensure t
:hook ((clojure-mode . lsp)
(clojurec-mode . lsp)
(clojurescript-mode . lsp)
(dart-mode . lsp)
(docker-mode . lsp)
(haskell-mode . lsp)
(elixir-mode . lsp)
(python-mode . lsp)
(go-mode . lsp)
(c++-mode . lsp)
(c-mode . lsp)
(terraform-mode . lsp))
;; :custom ((lsp-clojure-server-command '("java" "-jar" "/home/ianffcs/clj-kondo-lsp-server-2020.07.29-standalone.jar")))
:config
(progn
(dolist (m '(clojure-mode
clojurec-mode
clojurescript-mode
clojurex-mode))
(add-to-list 'lsp-language-id-configuration `(,m . "clojure")))
(setq lsp-clojure-server-command (cond ((eq system-type 'darwin) '("/opt/homebrew/bin/clojure-lsp"))
((eq system-type 'gnu/linux) '("/usr/bin/clojure-lsp")))
lsp-enable-indentation nil)
(defvar lsp-elixir--config-options (make-hash-table))
(setq lsp-haskell-process-path-hie "ghcide")
(setq lsp-haskell-process-args-hie '())
(setq lsp-lens-enable t)
(add-hook
'lsp-after-initialize-hook
(lambda ()
(lsp--set-configuration `(:elixirLS, lsp-elixir--config-options))))
(add-to-list 'exec-path "/home/ianffcs/elixir-ls/release/"))
:commands lsp)
;; (use-package lsp-jedi
;; :ensure t
;; :config
;; (with-eval-after-load "lsp-mode"
;; (add-to-list 'lsp-disabled-clients 'pyls)
;; (add-to-list 'lsp-enabled-clients 'jedi)))
;; (use-package lsp-python-ms
;; :ensure t
;; :init (setq lsp-python-ms-auto-install-server t)
;; :hook (python-mode . (lambda ()
;; (require 'lsp-python-ms)
;; (lsp))))
(use-package lsp-ui
:config
(setq lsp-headerline-breadcrumb-enable nil)
:commands lsp-ui-mode)
(use-package company-lsp
:ensure t
:commands company-lsp)
(use-package eglot
:config
(add-to-list 'eglot-server-programs '(haskell-mode . ("ghcide" "--lsp"))
(add-to-list 'eglot-server-programs `(elixir-mode "/home/ianffcs/elixir-ls/release/language_server.sh"))))
(use-package dap-mode
:after lsp-mode
:config
(dap-mode 1)
(dap-ui-mode 1)
(dap-tooltip-mode 1)
(tooltip-mode 1)
(dap-ui-controls-mode 1))
(add-hook 'shell-mode-hook 'yas-minor-mode)
(add-hook 'shell-mode-hook 'flycheck-mode)
(add-hook 'shell-mode-hook 'company-mode)
(defun shell-mode-company-init ()
(setq-local company-backends '((company-shell
company-shell-env
company-etags
company-dabbrev-code))))
(use-package company-shell
:ensure t
:config
(require 'company)
(add-hook 'shell-mode-hook 'shell-mode-company-init))
(use-package vterm
:ensure t)
(require 'cc-mode)
(defun my-c-mode-hook ()
(local-set-key (kbd "C-c c") 'compile)
;(setq c-basic-offset 4
; c-default-style "k&r"
; indent-tabs-mode nil)
(c-set-offset 'substatement-open 0))
(add-hook 'c++-mode-hook #'my-c-mode-hook)
(add-hook 'c-mode-hook #'my-c-mode-hook)
(use-package company-irony
:ensure t
:config
(add-to-list 'company-backends 'company-irony))
(use-package irony
:ensure t
:config
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'c-mode-hook 'irony-mode)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options))
(use-package irony-eldoc
:ensure t
:config
(add-hook 'irony-mode-hook #'irony-eldoc))
(use-package slime-company
:after slime-mode)
;; (load (expand-file-name "~/.roswell/helper.el"))
;; (add-hook 'slime-mode-hook #'smartparens-strict-mode)
;; (add-hook 'slime-repl-mode-hook #'smartparens-strict-mode)
;; (add-hook 'slime-mode-hook #'rainbow-delimiters-mode)
;; (add-hook 'slime-repl-mode-hook #'rainbow-delimiters-mode)
;; (add-hook 'slime-mode-hook #'highlight-parentheses-mode)
;; (add-hook 'slime-repl-mode-hook #'highlight-parentheses-mode)
(use-package slime
:hook ((slime-mode . lisp-mode)
(slime-mode . smartparens-strict-mode)
(slime-mode . rainbow-delimiters-mode)
(slime-mode . highlight-parentheses-mode)
(slime-repl-mode . smartparens-strict-mode)
(slime-repl-mode . rainbow-delimiters-mode)
(slime-repl-mode . highlight-parentheses-mode))
:bind (:map slime-mode
("M-TAB" . company-complete)
("C-c M-j" . slime)
("C-c C-d C-s" . slime-describe-symbol)
("C-c C-d C-f" . slime-describe-function)
("C-c C-s" . slime-selector)
("C-x C-e" . slime-eval-last-expression)
("C-c C-p" . slime-eval-print-last-expression)
("C-c C-c" . slime-eval-last-expression-in-repl))
:mode
("\\.lisp$" . slime-mode)
:config
(progn (lambda ()
(use-package slime-repl-ansi-color)
(load (expand-file-name "~/quicklisp/slime-helper.el"))
(whitespace-mode -1)))
(setq slime-contribs '(slime-repl slime-autodoc slime-banner slime-repl-ansi-color)
inferior-lisp-program "ros run"
slime-net-coding-system 'utf-8-unix
slime-lisp-implementations '((ccl ("ccl"))
(clisp ("clisp" "-q"))
(cmucl ("cmucl" "-quiet"))
(sbcl ("sbcl" "--noinform") :coding-system utf-8-unix))
slime-default-lisp 'sbcl
slime-contribs '(slime-fancy slime-company slime-cl-indent)
slime-complete-symbol-function 'slime-fuzzy-complete-symbol
slime-fuzzy-completion-in-place t
slime-enable-evaluate-in-emacs t
slime-autodoc-use-multiline-p t
common-lisp-hyperspec-root "/opt/homebrew/share/doc/hyperspec/HyperSpec/"
common-lisp-hyperspec-symbol-table (concat common-lisp-hyperspec-root "Data/Map_Sym.txt")
common-lisp-hyperspec-issuex-table (concat common-lisp-hyperspec-root "Data/Map_IssX.txt")))
(defun slime-description-fontify ()
(with-current-buffer "*slime-description*"
(slime-company-doc-mode)))
(defadvice slime-show-description (after slime-description-fontify activate)
"Fontify sections of SLIME Description."
(slime-description-fontify))
(add-hook 'emacs-lisp-mode-hook #'smartparens-strict-mode)
(add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode)
(add-hook 'emacs-lisp-mode-hook #'highlight-parentheses-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'smartparens-strict-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'rainbow-delimiters-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'highlight-parentheses-mode)
(add-hook 'ielm-mode-hook #'smartparens-strict-mode)
(add-hook 'ielm-mode-hook #'rainbow-delimiters-mode)
(add-hook 'ielm-mode-hook #'highlight-parentheses-mode)
(add-hook 'lisp-mode-hook #'smartparens-strict-mode)
(add-hook 'lisp-mode-hook #'rainbow-delimiters-mode)
(add-hook 'lisp-mode-hook #'highlight-parentheses-mode)
(add-hook 'lisp-interaction-mode-hook #'smartparens-strict-mode)
(add-hook 'lisp-interaction-mode-hook #'rainbow-delimiters-mode)
(add-hook 'lisp-interaction-mode-hook #'highlight-parentheses-mode)
(add-hook 'scheme-mode-hook #'smartparens-strict-mode)
(add-hook 'scheme-mode-hook #'rainbow-delimiters-mode)
(add-hook 'scheme-mode-hook #'highlight-parentheses-mode)
;;(add-hook 'emacs-lisp-mode-hook #'highlight-sexp-mode)
;; eldoc-mode shows documentation in the minibuffer when writing code
;; http://www.emacswiki.org/emacs/ElDoc
(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
(add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode)
(add-hook 'ielm-mode-hook 'turn-on-eldoc-mode)
(defun ielm-auto-complete ()
"Enables `auto-complete' support in \\[ielm]."
(setq ac-sources '(ac-source-functions
ac-source-variables
ac-source-features
ac-source-symbols
ac-source-words-in-same-mode-buffers))
(auto-complete-mode 1))
(defun ielm/clear-repl ()
"Clear current REPL buffer."
(interactive)
(let ((inhibit-read-only t))
(erase-buffer)
(ielm-send-input)))
(use-package eval-sexp-fu)
;;(require 'auto-complete-config)
(use-package ac-cider)
(use-package clojure-mode-extra-font-locking)
(defalias 'cquit 'cider-quit)
(use-package parinfer-rust-mode
:hook emacs-lisp-mode)
(use-package cider
:hook ((cider-repl-mode . subword-mode)
(cider-repl-mode . company-mode)
(cider-repl-mode . smartparens-strict-mode)
(cider-repl-mode . rainbow-delimiters-mode)
(cider-repl-mode . set-auto-complete-as-completion-at-point-function)
(cider-repl-mode . eldoc-mode)
;;(cider-repl-mode . prettify-some-chars)
(cider-mode . subword-mode)
(cider-mode . company-mode)
(cider-mode . eldoc-mode)
(cider-mode . smartparens-strict-mode)
(cider-mode . rainbow-delimiters-mode)
(cider-mode . set-auto-complete-as-completion-at-point-function)
(cider-mode . highlight-parentheses-mode))
:bind (:map
cider-mode-map
("C-c C-d" . cider-debug-defun-at-point)
:map
cider-repl-mode-map
("C-c M-o" . cider-repl-clear-buffer))
:config
(progn
(add-hook 'cider-repl-mode-hook #'cider-company-enable-fuzzy-completion)
(add-hook 'cider-mode-hook #'cider-company-enable-fuzzy-completion)
(setq cider-repl-pop-to-buffer-on-connect nil
cider-repl-use-clojure-font-lock nil
cider-annotate-completion-candidates t
cider-prompt-for-symbol nil
cider-repl-use-pretty-printing t
cider-repl-wrap-history t
cider-repl-pop-to-buffer-on-connect nil
cider-repl-prompt-function 'cider-repl-prompt-custom
cider-jdk-src-paths '("~/projects/java/clojure-1.10.2-sources"
"~/projects/java/openjdk-11/src")
;;cider-repl-result-prefix ";; =>"
cider-repl-require-ns-on-set t
cider-repl-display-in-current-window t
cider-repl-wrap-history t
cider-repl-use-pretty-printing 't
cider-pprint-fn 'puget
cider-print-options '(("print-color" "true"))
cider-repl-use-clojure-font-lock t
cider-auto-select-error-buffer nil
org-babel-clojure-backend 'cider
cider-eldoc-display-context-dependent-info t
cider-save-file-on-load t
cider-jump-to-pop-to-buffer-actions '((display-buffer-same-window))
cider-eldoc-display-for-symbol-at-point nil
nrepl-use-ssh-fallback-for-remote-hosts t
;; lsp-enable-completion-at-point nil
;; emidje-load-facts-on-eval t
)
(when window-system
(setq pretty-mode t))
)
;; (eval-after-load 'cider #'emidje-enable-nrepl-middleware)
)
(use-package cider-eval-sexp-fu)
;; (use-package nrepl-eval-sexp-fu)
;; (defun prettify-some-chars ()
;; (dolist (x '((true т)
;; (false ғ)
;; (:keys ӄ)
;; (:strs ş)
;; (nil Ø)
;; (partial Ƥ)
;; (with-redefs я)
;; (defn ƒ)
;; (comp º)
;; (apply ζ)
;; (a-fn1 α)
;; (a-fn2 β)
;; (a-fn3 γ)
;; (no-op ε)))
;; (font-lock-add-keywords
;; nil `((,(concat "[\[({[:space:]]"
;; "\\(" (symbol-name (first x)) "\\)"
;; "[\])}[:space:]]")
;; (0 (progn (compose-region (match-beginning 1)
;; (match-end 1) ,(symbol-name (second x)))
;; nil)))))
;; (font-lock-add-keywords
;; nil `((,(concat "^"
;; "\\(" (symbol-name (first x)) "\\)"
;; "[\])}[:space:]]")
;; (0 (progn (compose-region (match-beginning 1)
;; (match-end 1) ,(symbol-name (second x)))
;; nil)))))
;; (font-lock-add-keywords
;; nil `((,(concat "[\[({[:space:]]"
;; "\\(" (symbol-name (first x)) "\\)"
;; "$")
;; (0 (progn (compose-region (match-beginning 1)
;; (match-end 1) ,(symbol-name (second x)))
;; nil)))))
;; ;; prettify set
;; (font-lock-add-keywords
;; nil `(("\\(#\\){"
;; (0 (progn (compose-region (match-beginning 1) (match-end 1)
;; "∈")
;; nil)))))
;; ;; prettify fn's
;; (font-lock-add-keywords
;; nil `(("\\(#\\)("
;; (0 (progn (compose-region (match-beginning 1) (match-end 1)
;; ,(make-char 'greek-iso8859-7 107))
;; nil)))))))
(use-package clojure-mode
:hook ( ;;(clojure-mode . aggressive-indent-mode)
(clojure-mode . smartparens-strict-mode)
(clojure-mode . subword-mode)
(clojure-mode . cider-mode)
(clojure-mode . clj-refactor-mode)
(clojure-mode . company-mode)
(clojure-mode . eldoc-mode)
(clojure-mode . rainbow-delimiters-mode)
;;(clojure-mode . highlight-sexp-mode)
(clojure-mode . highlight-parentheses-mode)
;; (clojure-mode . prettify-some-chars)
)
:mode (("\\.clj$" . clojure-mode)
("\\.cljs$" . clojurescript-mode)
("\\.edn$" . clojure-mode)
("\\.boot$" . clojure-mode))
:config
(progn
(eval-after-load 'clojure-mode
'(define-clojure-indent
(train-n 3)
(for-all 1)
(fdef 1)
(defresolver 1)
(mlet 1)
(alet 1)
;;(async 1)
(defapi '(2 nil nil (1)))
(server 2)
(sniptest 1)
(reg-event-db 1)
(reg-sub 1)
(reg-sub-raw 1)
(reg-event-fx 1)
(reg-fx 1)
(reg-cofx 1)
(at-media 1)
(GET 2)
(not-join 1)
(recursive-path 2)
(wcar 1)
(implement '(1 (1)))
(letfn '(1 ((:defn)) nil))
(proxy '(2 nil nil (1)))
(reify '(:defn (1)))
(deftype '(2 nil nil (1)))
(defrecord '(2 nil nil (1)))
(specify '(1 (1)))))
(hack-local-variables)
(define-key clojure-mode-map (kbd "C-t") 'cider-test-rerun-test)
(setq clojure-thread-all-but-last t
clojure-align-forms-automatically t
cider-ns-refresh-show-log-buffer t
cider-show-error-buffer t;'only-in-repl
cider-font-lock-dynamically '(macro core function var deprecated)
yas-minor-mode 1)))
(use-package html-to-hiccup
:ensure t
:config
(define-key clojure-mode-map (kbd "H-h") 'html-to-hiccup-convert-region))
(defun cider-repl-prompt-custom (namespace)
"Return a prompt string that mentions NAMESPACE."
(format "λ %s\n" namespace))
(use-package clj-refactor
:config
(progn
(setq cljr-warn-on-eval nil
cljr-eagerly-build-asts-on-startup nil
;;cljr-clojure-test-declaration "[midje.sweet :refer :all]"
clj-refactor-mode 1
cljr-magic-require-namespaces
'(("s" . "schema.core")
("th" . "common-core.test-helpers")
("gen" . "common-test.generators")
("d-pro" . "common-datomic.protocols.datomic")
("ex" . "common-core.exceptions")
("dth" . "common-datomic.test-helpers")
("t-money" . "common-core.types.money")
("t-time" . "common-core.types.time")
("d" . "datomic.api")
("m" . "matcher-combinators.matchers")
("pp" . "clojure.pprint")
("init" . "postman-aux.init")))
(add-hook 'clojure-mode-hook
(lambda () (clj-refactor-mode 1)
(yas-minor-mode 1)
(cljr-add-keybindings-with-prefix "C-c C-m")))))
(use-package flycheck-joker
:after clojure-mode
:ensure t)
(use-package flycheck-clj-kondo
:ensure t
:after clojure-mode
:config
(dolist (checker
'(clj-kondo-clj clj-kondo-cljs clj-kondo-cljc clj-kondo-edn))
(setq flycheck-checkers
(cons checker (delq checker flycheck-checkers))))
(dolist (checkers '((clj-kondo-clj . clojure-joker)
(clj-kondo-cljs . clojurescript-joker)
(clj-kondo-cljc . clojure-joker)
(clj-kondo-edn . edn-joker)))
(flycheck-add-next-checker (car checkers) (cons 'error (cdr checkers)))))
(defun set-auto-complete-as-completion-at-point-function ()
(setq completion-at-point-functions '(auto-complete)))
(use-package clojure-snippets
:ensure t
:defer t)
(use-package dart-mode
:config
(define-key dart-mode-map (kbd "C-c C-o") 'dart-format-buffer)
(with-eval-after-load "projectile"
(add-to-list 'projectile-project-root-files-bottom-up "pubspec.yaml")
(add-to-list 'projectile-project-root-files-bottom-up "BUILD"))
(setq lsp-auto-guess-root t))
(use-package dart-server)
(use-package lsp-dart
:ensure t
:hook (dart-mode . lsp)
:init
;; TODO fix here after
;; (dap-register-debug-template "Flutter :: Custom debug"
;; (list :flutterPlatform "x86_64"
;; :program "lib/main_debug.dart"
;; :args '("--flavor" "customer_a")))
)
(use-package alchemist)
(use-package elixir-mode
:hook ((elixir-mode . aggressive-indent-mode)
(elixir-mode . smartparens-strict-mode)
(elixir-mode . subword-mode)
(elixir-mode . rainbow-delimiters-mode)
(elixir-mode . highlight-parentheses-mode)
(elixir-mode . alchemist-mode))
:mode (("\\.ex'" . elixir-mode)
("\\.exs\\'" . elixir-mode)
("\\.lex\\'" . elixir-mode))
:init (add-hook 'elixir-mode-hook
(lambda () (add-hook 'before-save-hook 'elixir-format nil t))))
(use-package exunit)
(use-package forth-mode
:config (progn
(define-key forth-mode-map (kbd "C-x C-e") #'forth-eval-last-expression)
(define-key forth-mode-map (kbd "C-c C-c") #'forth-eval-region)))
(use-package kotlin-mode)
(use-package flycheck-kotlin)
(use-package ob-kotlin)
(use-package dockerfile-mode
:mode ("\\Dockerfile$" . dockerfile-mode))
(use-package docker-compose-mode)
(defun format-elixir-buffer ()
"Format elixir buffer."
(add-hook 'before-save-hook 'elixir-format nil t))
(use-package elixir-mode
:hook ((elixir-mode . format-elixir-buffer)
(elixir-mode . flycheck-mix-setup))
:mode (("\\.ex$" . elixir-mode)
("\\.exs$" . elixir-mode)))
(use-package alchemist
:hook ((elixir-mode . alchemist-mode)))
(use-package flycheck-mix)
(use-package exunit)
We install Java support and setup LSP for Java mode.
(use-package lsp-java)
After first run, lsp-java will detect and download Eclipse JDT Language Server automatically.
(use-package nginx-mode)
(use-package python
:mode ("\\.py" . python-mode)
:hook ((python-mode . jedi:setup))
:config (setq python-shell-interpreter "ipython"
python-shell-interpreter-args "-i"
py-python-command "python3"))
(use-package jedi
:config (setq jedi:complete-on-dot t))
(use-package company-jedi
:ensure t
:config
(add-to-list 'company-backends 'company-jedi))
(use-package elpy
:hook ((python-mode . elpy-mode)
(python-mode . elpy-enable))
:custom
(elpy-rpc-backend "jedi")
:bind (:map elpy-mode-map
("M-." . elpy-goto-definition)
("M-," . pop-tag-mark)
("<M-S-left>" . elpy-nav-indent-shift-left)
("<M-S-right>" . elpy-nav-indent-shift-right)
("C-c i" . elpy-autopep8-fix-code)
("C-c C-d" . elpy-doc)))
(use-package pip-requirements
:hook ((pip-requirements-mode . #'pip-requirements-auto-complete-setup)))
(use-package py-autopep8
:hook ((elpy-mode . py-autopep8-mode)))
(use-package virtualenvwrapper
:ensure t
:config
(venv-initialize-interactive-shells)
(venv-initialize-eshell))
(use-package pipenv
:hook (python-mode . pipenv-mode)
:init
(setq pipenv-projectile-after-switch-function
#'pipenv-projectile-after-switch-extended))
(use-package ein)
(use-package hy-mode)
(use-package rustic)
(use-package lsp-haskell
:ensure t
:config
(setq lsp-haskell-process-path-hie "ghcide"
lsp-haskell-process-args-hie '())
;; Comment/uncomment this line to see interactions between lsp client/server.
;; (setq lsp-log-io t)
)
(use-package haskell-mode
:ensure t
:hook (haskell-mode . interactive-haskell-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (use-package intero ;;
;; :ensure t :config ;;
;; (progn ;;
;; (add-hook 'haskell-mode-hook 'intero-mode))) ;;
;; ;;
;; (setq flycheck-check-syntax-automatically '(save new-line)) ;;
;; (flycheck-add-next-checker 'intero '(warning . haskell-hlint)) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package web-mode
:ensure t
:config
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.vue?\\'" . web-mode))
(setq web-mode-engines-alist
'(("django" . "\\.html\\'")))
(setq web-mode-ac-sources-alist
'(("css" . (ac-source-css-property))
("vue" . (ac-source-words-in-buffer ac-source-abbrev))
("html" . (ac-source-words-in-buffer ac-source-abbrev))))
(setq web-mode-enable-auto-closing t))
(setq web-mode-enable-auto-quoting t) ; this fixes the quote problem I mentioned
(use-package js2-mode
:ensure t
:ensure ac-js2
:init
(progn
(add-hook 'js-mode-hook 'js2-minor-mode)
(add-hook 'js2-mode-hook 'ac-js2-mode)))
(use-package js2-refactor
:ensure t
:config
(progn
(js2r-add-keybindings-with-prefix "C-c C-m")
;; eg. extract function with `C-c C-m ef`.
(add-hook 'js2-mode-hook #'js2-refactor-mode)))
(use-package tern
:ensure tern
:ensure tern-auto-complete
:config
(progn
(add-hook 'js-mode-hook (lambda () (tern-mode t)))
(add-hook 'js2-mode-hook (lambda () (tern-mode t)))
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
;;(tern-ac-setup)
))
;;(use-package jade
;;:ensure t
;;)
;; use web-mode for .jsx files
(add-to-list 'auto-mode-alist '("\\.jsx$" . web-mode))
;; turn on flychecking globally
(add-hook 'after-init-hook #'global-flycheck-mode)
;; disable jshint since we prefer eslint checking
(setq-default flycheck-disabled-checkers
(append flycheck-disabled-checkers
'(javascript-jshint)))
;; use eslint with web-mode for jsx files
(flycheck-add-mode 'javascript-eslint 'web-mode)
;; customize flycheck temp file prefix
(setq-default flycheck-temp-prefix ".flycheck")
;; disable json-jsonlist checking for json files
(setq-default flycheck-disabled-checkers
(append flycheck-disabled-checkers
'(json-jsonlist)))
;; adjust indents for web-mode to 2 spaces
(defun my-web-mode-hook ()
"Hooks for Web mode. Adjust indents"
;;; http://web-mode.org/
(setq web-mode-markup-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-code-indent-offset 2))
(add-hook 'web-mode-hook 'my-web-mode-hook)
(use-package company-web
:after web-mode)
(use-package rjsx-mode
:mode ("\\.jsx$" . rjsx-mode)
:magic ("%React" . rjsx-mode))
(use-package vue-mode
:mode
("\\.vue$" . vue-mode))
(use-package indium
:after js2-mode
:hook ((js2-mode . indium-interaction-mode))
:bind (:map indium-interaction-mode-map
("C-x C-e" . indium-eval-last-node)
("C-<f6>" . vs/stop-indium-debug)
("S-<f6>" . indium-connect)
("<f6>" . indium-launch))
:config (delight indium-interaction-mode))
(use-package mocha
:init (setq mocha-reporter "spec")
:bind (:map js2-mode-map
(("C-c t" . mocha-test-project))))
(use-package json-mode
:mode
("\\.json$" . json-mode))
(use-package tide
:ensure t
:after (typescript-mode company flycheck)
:hook ((typescript-mode . tide-setup)
(typescript-mode . tide-hl-identifier-mode)
(before-save . tide-format-before-save)))
(use-package markdown-mode
:hook ((markdown-mode . visual-line-mode)))
(use-package markdown-mode+)
(use-package markdownfmt
:config
(add-hook 'markdown-mode-hook #'markdownfmt-enable-on-save))
(custom-set-variables
'(markdown-command "/usr/local/bin/pandoc"))
(use-package markdown-preview-mode)
;; (use-package tex
;; :ensure t)
;; (use-package cdlatex
;; :ensure t)
;; ;;
;(use-package auctex
;; :ensure t
;; :config (setq TeX-auto-save t)
;; (setq TeX-parse-self t)
;; (setq TeX-close-quote "")
;; (setq TeX-open-quote ""))
;; (defcustom
;; prelude-latex-fast-math-entry 'LaTeX-math-mode
;; "Method used for fast math symbol entry in LaTeX."
;; :link '(function-link :tag "AUCTeX Math Mode" LaTeX-math-mode)
;; :link '(emacs-commentary-link :tag "CDLaTeX" "cdlatex.el")
;; :group 'prelude
;; :type '(choice (const :tag "None" nil)
;; (const :tag "AUCTeX Math Mode" LaTeX-math-mode)
;; (const :tag "CDLaTeX" cdlatex)))
;; (defun tex-view ()
;; (interactive)
;; (tex-send-command "evince" (tex-append tex-print-file ".pdf")))
;; (require 'latex-pretty-symbols)
;; (add-hook 'markdown-mode-hook 'pandoc-mode)
;; (add-hook 'markdown-mode-hook 'latex-unicode-simplified)
;; (setq markdown-enable-math 1)
;; (add-hook 'org-mode-hook 'latex-unicode-simplified)
;; (eval-after-load "tex"
;; '(add-to-list 'TeX-command-list '("latexmk" "latexmk -synctex=1 -shell-escape -pdf %s" TeX-run-TeX nil t :help "Process file with latexmk")))
;; (eval-after-load "tex"
;; '(add-to-list 'TeX-command-list '("xelatexmk" "latexmk -synctex=1 -shell-escape -xelatex %s" TeX-run-TeX nil t :help "Process file with xelatexmk")))
;; (add-hook 'TeX-mode-hook '(lambda () (setq TeX-command-default "latexmk")))
(use-package geiser
:ensure t
:hook ((geiser-repl-mode . subword-mode)
(geiser-repl-mode . company-mode)
(geiser-repl-mode . smartparens-strict-mode)
(geiser-repl-mode . rainbow-delimiters-mode)
(geiser-repl-mode . highlight-parentheses-mode)
(geiser-mode . smartparens-strict-mode)
(geiser-mode . rainbow-delimiters-mode)
(geiser-mode . highlight-parentheses-mode))
:config (setq geiser-mode-start-repl-p t
geiser-active-implementations '(guile racket)))
I used to use latex-preview-pane for comfortable editing, but not anymore…
;; (use-package latex-preview-pane
;; :config
;; (when (display-graphic-p)
;; (latex-preview-pane-enable)))
To compile the current file, we resort to Rubber, an external tool.
(defun rubber-compile-file ()
(interactive)
(shell-command
(concat "rubber -d " buffer-file-name))
(message "Finished LaTeX compilation."))
It is also interesting to have pretty symbols for our LaTeX files.
(use-package latex-pretty-symbols)
(use-package ess
:ensure t)
(use-package scad-mode)
(use-package csv-mode
:ensure t
:config
(setq csv-separators '("," ";" "|" " " )))
(use-package plantuml-mode
:mode ("\\.plantuml\\'" . plantuml-mode)
:config
(let ((plantuml-directory (concat user-emacs-directory "private/"))
(plantuml-link "http://sourceforge.net/projects/plantuml/files/plantuml.jar/download"))
(let ((plantuml-target (concat plantuml-directory "plantuml.jar")))
(if (not (file-exists-p plantuml-target))
(progn (message "Downloading plantuml.jar")
(shell-command
(mapconcat 'identity (list "wget" plantuml-link "-O" plantuml-target) " "))
(kill-buffer "*Shell Command Output*")))
(setq org-plantuml-jar-path plantuml-target
plantuml-jar-path plantuml-target
plantuml-default-exec-mode 'jar
plantuml-output-type "svg"))))
;;(use-package flycheck-plantuml
;; :config (flycheck-plantuml-setup))
(use-package go-mode
:hook ((go-mode . smartparens-strict-mode)
(go-mode . rainbow-delimiters-mode)
(before-save-hook . gofmt-before-save))
:init (add-hook 'go-mode-hook
(lambda ()
;;(setq gofmt-command "goimports")
(add-hook 'before-save-hook 'lsp-organize-imports nil t)
(setq truncate-lines t
indent-tabs-mode t
tab-width 4
;; lsp-ui-sideline-enable nil
;; lsp-ui-doc-enable nil
lsp-gopls-staticcheck t
lsp-eldoc-render-all t
lsp-gopls-complete-unimported t
company-tooltip-limit 20
company-idle-delay .3
company-echo-delay 0
company-begin-commands '(self-insert-command))
(defun go-run-save-file ()
(interactive)
(save-buffer)
(go-run))
(local-set-key (kbd "C-c C-c") 'go-run-save-file)
(local-set-key (kbd "M-.") 'godef-jump)
(local-set-key (kbd "M-b") 'pop-tag-mark)
(local-set-key (kbd "C-c r w") 'lsp-workspace-restart)
(local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)
(local-set-key (kbd "C-c C-a") 'go-import-add)
(local-set-key (kbd "C-c C-g") 'go-goto-imports)
(local-set-key (kbd "C-c C-f") 'gofmt)
(local-set-key (kbd "C-c r .") 'lsp-find-definition)
(local-set-key (kbd "C-c r ,") 'lsp-find-references)
(local-set-key (kbd "C-c r i") 'lsp-find-implementation)
(local-set-key (kbd "C-c r j") 'go-guru-definition)
(local-set-key (kbd "C-c r d") 'go-guru-describe)
(local-set-key (kbd "C-c o i") 'lsp-organize-imports)
(local-set-key (kbd "C-c s f") 'gofmt-before-save)
(local-set-key (kbd "C-c r r") 'lsp-rename)
(local-set-key (kbd "C-c t f") 'go-test-current-test)
(local-set-key (kbd "C-c t a") 'go-test-current-file)
(lsp)
(gofmt-before-save)
(go-guru-hl-identifier-mode)
(set (make-local-variable 'company-backends) '(company-go))
(company-mode)))
:config
(progn
(add-to-list 'auto-mode-alist (cons "\\.go\\'" 'go-mode))))
(use-package go-guru)
(use-package go-eldoc
:init (lambda ()
(set-face-attribute 'eldoc-highlight-function-argument nil
:underline t :foreground "green"
:weight 'bold))
:config
(add-hook 'go-mode-hook 'go-eldoc-setup))
(use-package go-complete
:ensure t
:config
(add-hook 'completion-at-point 'go-complete-at-point))
(use-package gorepl-mode
:hook ((go-mode . flycheck-golangci-lint-setup)))
(use-package go-tag)
(use-package go-gen-test)
(use-package company-go)
(use-package flycheck-golangci-lint)
(use-package go-dlv
:ensure t)
(use-package gotest
:ensure t)
(use-package hcl-mode)
(use-package terraform-mode)
(use-package terraform-doc)
(use-package company-terraform)
(use-package kubel
:after (vterm)
:config (kubel-vterm-setup))
(use-package desktop
:if window-system
:straight nil
:hook ((after-init . desktop-restore)
(desktop-after-read . desktop-remove))
:custom
(desktop-path `(,user-emacs-directory))
(desktop-dirname user-emacs-directory)
(desktop-base-file-name "desktop")
(desktop-base-lock-name "desktop.lock")
(desktop-save t)
(desktop-load-locked-desktop t)
:init
(defun desktop-remove ()
(let ((desktop desktop-dirname))
(desktop-remove)
(setq desktop-dirname desktop)))
(defun saved-desktop-p ()
"Check if desktop exists."
(file-exists-p (concat desktop-dirname "/" desktop-base-file-name)))
(defun desktop-restore ()
"Restore a saved emacs session."
(interactive)
(desktop-save-mode t)
(if (saved-desktop-p)
(desktop-read)
(message "No desktop found."))))
(defconst private-dir (expand-file-name "private" user-emacs-directory))
(defconst temp-dir (format "%s/cache" private-dir))
(unless (file-exists-p private-dir)
(make-directory private-dir :parents))
(unless (file-exists-p temp-dir)
(make-directory temp-dir :parents))
(use-package alert
:config
(setq alert-default-style 'libnotify
alert-log-messages t))
(add-to-list 'alert-user-configuration
'(((:category . "telega"))
log nil))
(add-to-list
'alert-user-configuration
'(((:message . "@ianffcs\\|Ian")
(:category . "telega"))
libnotify nil))
Sane config for ediff
which is basically removing noisy
highlights, avoiding crazy multi-frames setup, ignoring some
whitespaces and windows should be side-by-side.
(use-package ediff
:init
(setq ediff-highlight-all-diffs nil)
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-diff-options "-w")
(setq ediff-split-window-function 'split-window-horizontally))
(setq project-switch-commands t)
(use-package magit
:ensure t
:defer t
:bind ("C-x g" . magit-status)
:init
(setq magit-diff-options (quote ("--word-diff"))
magit-diff-refine-hunk 'all
;;magit-completing-read-function 'magit-ido-completing-read
;;highlight individual word and letter changes when hunk diff displays
magit-diff-refine-hunk t
;; don't tell me when magit reverts buffers
magit-revert-buffers 'silent
;; always show the verbose diff in commit windows
magit-commit-arguments '("--verbose")
;; timeout when magit takes a while to call out to git
magit-process-popup-time 10)
:config
(add-to-list 'magit-no-confirm 'stage-all-changes)
)
(use-package git-gutter
:ensure t
:init
(global-git-gutter-mode +1))
(use-package browse-at-remote :ensure t)
(use-package gitignore-templates :ensure t)
(use-package org
:straight nil
:init (org-crypt-use-before-save-magic)
:hook ((org-mode . toggle-word-wrap)
(org-mode . org-indent-mode)
(org-mode . turn-on-visual-line-mode)
(org-mode . (lambda () (display-line-numbers-mode -1)))
(org-mode . auto-revert-mode))
:bind (("C-c l" . org-store-link)
("C-c a" . org-agenda)
("C-c d" . org-decrypt-entry))
:mode (("\\.org$" . org-mode))
:config
(setq
org-default-notes-files "~/sync/orgfiles/notes.org.gpg"
org-catch-invisible-edits 'smart ;; or show
org-export-html-postamble nil
org-hide-leading-stars t
org-startup-indented t
org-display-inline-images t
org-redisplay-inline-images t
org-startup-with-inline-images "inlineimages"
;org-agenda-files (list "~/sync/orgfiles/life.org.gpg" "~/sync/orgfiles/personal_cal.org.gpg" "~/sync/orgfiles/work_cal.org.gpg")
org-todo-keywords '((sequence "TODO(t)" "PENDING(p!)" "WAIT(w@)" "VERIFY(v)" "|" "DONE(d!)" "CANCELED(c@)")
(sequence "REPORT(r@)" "BUG(b@)" "KNOWNCAUSE(k@)" "|" "FIXED(f!)"))
org-edit-src-content-indentation 0
org-src-tab-acts-natively t
org-src-fontify-natively t
org-confirm-babel-evaluate nil
org-support-shift-select 'always
org-hide-emphasis-markers t
org-edit-src-content-indentation 0
org-src-tab-acts-natively t
org-src-fontify-natively t
org-src-preserve-indentation t
org-file-apps '((auto-mode . emacs)
("\\.mm\\'" . default)
("\\.x?html?\\'" . "/usr/bin/firefox %s")
;;("\\.pdf\\'" . "/usr/bin/zathura %s")
)
org-display-inline-images t
org-redisplay-inline-images t
org-startup-with-inline-images "inlineimages"
org-confirm-elisp-link-function nil
org-hide-emphasis-markers t
org-babel-clojure-nrepl-timeout nil
org-export-allow-bind-keywords t
org-confirm-babel-evaluate t
org-tags-exclude-from-inheritance (quote ("crypt"))
org-crypt-key "A6A63F72F3FA0BE546769D9013C0FCE929207C95"
auto-save-default nil)
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images 'append)
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images)
(defun do-org-show-all-inline-images ()
(interactive)
(org-display-inline-images t t))
(global-set-key (kbd "C-c C-x C v")
'do-org-show-all-inline-images)
(use-package ob-restclient)
(use-package ob-hy)
(use-package ob-prolog)
(use-package ob-async
:init (setq ob-async-no-async-languages-alist '("ipython")))
(use-package ox-reveal)
(org-defkey org-mode-map "\C-x\C-e" 'cider-eval-last-sexp)
(org-defkey org-mode-map "\C-c\C-d" 'cider-doc))
(use-package toc-org
:after org
:hook (org-mode . toc-org-enable))
(defun my/org-clock-query-out ()
"Ask the user before clocking out.
This is a useful function for adding to `kill-emacs-query-functions'."
(if (and
(featurep 'org-clock)
(funcall 'org-clocking-p)
(y-or-n-p "You are currently clocking time, clock out? "))
(org-clock-out)
t)) ;; only fails on keyboard quit or error
;; timeclock.el puts this on the wrong hook!
(add-hook 'kill-emacs-query-functions 'my/org-clock-query-out)
;; organize journal confs after
;;(use-package org-web-tools :ensure t)
(require 'org-agenda)
(use-package calendar
:ensure nil
:hook (calendar-today-visible . calendar-mark-today)
:config
(setq calendar-latitude -23.5475
calendar-longitude -46.63611
calendar-location-name "Sao_Paulo, Brazil")
(setq calendar-holiday-marker t))
;;(load (expand-file-name (concat user-emacs-directory "elisp/brazil-holidays.el")))
;;(setq calendar-holidays holiday-brazil-all)
(when (file-exists-p (concat user-emacs-directory "sensitive/agenda.el"))
(load (expand-file-name (concat user-emacs-directory "sensitive/agenda.el"))))
(add-hook 'org-mode-hook 'auto-revert-mode)
(use-package org-superstar
:config (progn (add-hook 'org-mode-hook (lambda () (org-superstar-mode 1)))))
(use-package fill-column-indicator
:config (progn
(add-hook 'org-mode-hook
(lambda ()
(setq fci-rule-width 1)
(setq fci-rule-color "darkblue")))
(add-hook 'org-mode-hook 'turn-on-auto-fill)))
(use-package org-alert
:config (progn
(setq alert-default-style 'libnotify
org-alert-notification-title "*org-mode*"
org-alert-interval 21600)
(org-alert-enable)))
Let’s begin by setting up a few things for Babel.
(setq org-export-allow-bind-keywords t)
(use-package ob-go)
(use-package ess) ;; package for languages such as Julia, R
(org-babel-do-load-languages 'org-babel-load-languages
'((lisp . t)
(go . t)
(shell . t)
(dot . t)
(js . t)
;;(julia . t)
(C . t)
(scheme . t)
(prolog . t)
(python . t)
;;(ein . t)
(emacs-lisp . t)
(clojure . t)
(hy . y)
(restclient . t)
(plantuml . t)
(sql . t)))
(mapc (lambda (x)
(add-to-list 'org-babel-tangle-lang-exts x))
'(("js" . "js")
("gnu-apl" . "apl")))
Configure Htmlize to preferred defaults.
(use-package htmlize
:config (setq htmlize-output-type 'css))
(require 'ox-latex)
(unless (boundp 'org-latex-classes)
(setq org-latex-classes nil))
(add-to-list 'org-latex-classes
'("abntex2"
"\\documentclass{abntex2}
[NO-DEFAULT-PACKAGES]
[EXTRA]"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")
("\\maketitle" . "\\imprimircapa")))
(add-to-list 'org-latex-classes
'("standalone"
"\\documentclass{standalone}
[NO-DEFAULT-PACKAGES]"))
I also like to use the plain PDF export.
(setq org-latex-pdf-process '("latexmk -shell-escape -bibtex -f -pdfxe -8bit %f"))
Also, for buffer images to scale and look good, we use this:
;;(plist-put org-format-latex-options :scale 1.2)
When using the minted
package for source code, make sure that Common
Lisp uses highlighting:
(setq org-latex-listings 'minted)
(add-to-list 'org-latex-minted-langs
'(lisp "common-lisp"))
(add-to-list 'org-latex-packages-alist '("" "minted"))
inputenc
configuration for Unicode characters.
(setq org-latex-inputenc-alist '(("utf8" . "utf8x")))
Using mathletters
from ucs
also helps a lot.
(add-to-list 'org-latex-default-packages-alist
'("mathletters" "ucs" nil))
Export Org filex to Epub format.
(use-package ox-epub)
(use-package org-ref
:config
(setq reftex-default-bibliography "~/sync/bibliography.bib"
org-ref-bibliography-notes "~/sync/bibliography/notes.org"
org-ref-default-bibliography '("~/sync/bibliography/references.bib")
org-ref-pdf-directory "~/sync/bibliography/bibtex-pdfs/"))
;; (setq org-reveal-mathjax t
;; org-reveal-root "https://cdn.jsdelivr.net/npm/[email protected]/js/reveal.min.js"
;; org-re-reveal-root "~/reveal")
(use-package org-re-reveal
:config (setq org-ref-default-bibliography '("references.bib")
org-ref-bibliography-entry-format
'(("article" . "%a, %t, <i>%j %v(%n)</i>, %p (%y). <a href=\"%U\">%U</a>")
("book" . "%a, %t, %u, %y. <a href=\"%U\">%U</a>")
("inproceedings" . "%a, %t, %b, %y. <a href=\"%U\">%U</a>")
("incollection" . "%a, %t, %b, %u, %y. <a href=\"%U\">%U</a>")
("misc" . "%a, %t, %i, %y. <a href=\"%U\">%U</a>")
("phdthesis" . "%a, %t, %s, %y. <a href=\"%U\">%U</a>")
("techreport" . "%a, %t, %i, %u (%y).")
("proceedings" . "%e, %t in %S, %u (%y)."))))
(use-package org-ref
:after org-re-reveal)
(use-package org-re-reveal-ref
:after org-re-reveal)
(let ((emacs-reveal-path "~/.emacs.d/elpa/emacs-reveal"))
(when (file-directory-p emacs-reveal-path)
(add-to-list 'load-path emacs-reveal-path)
(require 'emacs-reveal)))
;; (require 'oer-reveal-publish)
;; (oer-reveal-setup-submodules t)
;; (oer-reveal-generate-include-files t)
;; (oer-reveal-publish-setq-defaults)
I use Epresentation which makes Emacs fullscreen in org.
(use-package epresent)
Org-noter is a tool for writing notes in Org for PDFs, EPUB, DVI, PS, etc. See the documentation here.
(use-package pdf-tools)
(use-package nov)
(use-package djvu)
(use-package org-noter)
(use-package org-roam
:pin melpa
:ensure t
:custom
(org-roam-directory "~/org-roam/")
:bind (:map org-roam-mode-map
(("C-c n l" . org-roam)
("C-c n f" . org-roam-find-file)
("C-c n g" . org-roam-graph))
:map org-mode-map
(("C-c n i" . org-roam-insert))
(("C-c n I" . org-roam-insert-immediate))))
(use-package deft
:after org-roam
:custom
(deft-recursive t)
(deft-use-filter-string-for-filename t)
(deft-default-extension "org")
(deft-directory org-roam-directory))
;;(load-sensible-file "journal.el")
(defvar org-journal-loaded nil)
(use-package org-journal
:after org
:bind (("C-c T" . org-journal-new-entry)
("C-c Y" . journal-file-yesterday))
:init
(defun org-journal-load-files ()
(interactive)
(when (not org-journal-loaded)
(setq org-agenda-file-regexp "\\`[^.].*\\.org'\\|[0-9]$")
(add-to-list 'org-agenda-files org-journal-dir)
(setq org-journal-loaded t)))
:config
(setq org-journal-date-format "%e %b %Y (%A)"
org-journal-dir "~/sync/orgfiles"
org-journal-enable-encryption t
org-journal-file-format "%Y%m%d"
org-journal-time-format ""))
;; whisper, everything below this point is only needed if you want speech input
(defun rk/get-ffmpeg-device ()
"Gets the list of devices available to ffmpeg.
The output of the ffmpeg command is pretty messy, e.g.
[AVFoundation indev @ 0x7f867f004580] AVFoundation video devices:
[AVFoundation indev @ 0x7f867f004580] [0] FaceTime HD Camera (Built-in)
[AVFoundation indev @ 0x7f867f004580] AVFoundation audio devices:
[AVFoundation indev @ 0x7f867f004580] [0] Cam Link 4K
[AVFoundation indev @ 0x7f867f004580] [1] MacBook Pro Microphone
so we need to parse it to get the list of devices.
The return value contains two lists, one for video devices and one for audio devices.
Each list contains a list of cons cells, where the car is the device number and the cdr is the device name."
(unless (string-equal system-type "darwin")
(error "This function is currently only supported on macOS"))
(let ((lines (string-split (shell-command-to-string "ffmpeg -list_devices true -f avfoundation -i dummy || true") "\n")))
(cl-loop with at-video-devices = nil
with at-audio-devices = nil
with video-devices = nil
with audio-devices = nil
for line in lines
when (string-match "AVFoundation video devices:" line)
do (setq at-video-devices t
at-audio-devices nil)
when (string-match "AVFoundation audio devices:" line)
do (setq at-audio-devices t
at-video-devices nil)
when (and at-video-devices
(string-match "\\[\\([0-9]+\\)\\] \\(.+\\)" line))
do (push (cons (string-to-number (match-string 1 line)) (match-string 2 line)) video-devices)
when (and at-audio-devices
(string-match "\\[\\([0-9]+\\)\\] \\(.+\\)" line))
do (push (cons (string-to-number (match-string 1 line)) (match-string 2 line)) audio-devices)
finally return (list (nreverse video-devices) (nreverse audio-devices)))))
(defun rk/find-device-matching (string type)
"Get the devices from `rk/get-ffmpeg-device' and look for a device
matching `STRING'. `TYPE' can be :video or :audio."
(let* ((devices (rk/get-ffmpeg-device))
(device-list (if (eq type :video)
(car devices)
(cadr devices))))
(cl-loop for device in device-list
when (string-match-p string (cdr device))
return (car device))))
(defcustom rk/default-audio-device nil
"The default audio device to use for whisper.el and outher audio processes."
:type 'string)
(defun rk/select-default-audio-device (&optional device-name)
"Interactively select an audio device to use for whisper.el and other audio processes.
If `DEVICE-NAME' is provided, it will be used instead of prompting the user."
(interactive)
(let* ((audio-devices (cadr (rk/get-ffmpeg-device)))
(indexes (mapcar #'car audio-devices))
(names (mapcar #'cdr audio-devices))
(name (or device-name (completing-read "Select audio device: " names nil t))))
(setq rk/default-audio-device (rk/find-device-matching name :audio))
(when (boundp 'whisper--ffmpeg-input-device)
(setq whisper--ffmpeg-input-device (format ":%s" rk/default-audio-device)))))
;; example usage:
;; (rk/find-device-matching "FaceTime" :video)
;; (rk/find-device-matching "Macbook Pro Microphone" :audio)
;; (rk/select-default-audio-device)
(use-package org-ai
:ensure t
:commands (org-ai-mode
org-ai-global-mode)
:init
(add-hook 'org-mode-hook #'org-ai-mode) ; enable org-ai in org-mode
(org-ai-global-mode) ; installs global keybindings on C-c M-a
:config
(setq org-ai-default-chat-model "gpt-4-32k-0314") ; if you are on the gpt-4 beta:
(org-ai-install-yasnippets)) ; if you are using yasnippet and want `ai` snippets
(use-package whisper
:straight `(whisper :type git :host github :repo "natrys/whisper.el")
:config
(setq whisper-model "base"
whisper-language "pt"
whisper-translate nil
whisper-install-directory "/tmp/")
(when (eq system-type 'darwin)
(rk/select-default-audio-device "Microfone (MacBook Pro)")
(when rk/default-audio-device)
(setq whisper--ffmpeg-input-device (format ":%s" rk/default-audio-device))))
(use-package greader :ensure)
(require 'whisper)
(require 'org-ai-talk)
;; macOS speech settings, optional
(setq org-ai-talk-say-words-per-minute 210)
(setq org-ai-talk-say-voice "Karen")
(use-package dashboard
:ensure t
:config
(dashboard-setup-startup-hook)
(progn
(setq initial-buffer-choice (lambda ()
(get-buffer "*dashboard*"))
dashboard-center-content t
dashboard-startup-banner 'logo
dashboard-set-init-info t
dashboard-set-navigator t
dashboard-items '((recents . 5)
(bookmarks . 5)
(projects . 10)
(agenda . 5)
(registers . 5)))))
(use-package sudo-edit
:ensure t
:bind("s-e" . sudo-edit))
(use-package counsel-tramp
:config (setq tramp-default-method "ssh"))
(setq tramp-backup-directory-alist backup-directory-alist)
; mark and edit all copies of the marked region simultaniously.
(use-package iedit
:ensure t)
; if you're windened, narrow to the region, if you're narrowed, widen
; bound to C-x n
(defun narrow-or-widen-dwim (p)
"If the buffer is narrowed, it widens. Otherwise, it narrows intelligently.
Intelligently 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))
((org-at-block-p)
(org-narrow-to-block))
(t (org-narrow-to-subtree))))
(t (narrow-to-defun))))
- Try is a package that allows you to try out Emacs packages without installing them. If you pass a URL to a plain text .el-file it evaluates the content, without storing the file.
(use-package try
:ensure t)
(use-package which-key
:config
(which-key-mode))
(use-package keyfreq
:ensure t
:config
(require 'keyfreq)
(keyfreq-mode 1)
(keyfreq-autosave-mode 1))
(use-package wgrep
:ensure t)
(use-package projectile-ripgrep)
(use-package rg
:ensure t
:config
(rg-define-search search-git-root-or-dir
:query ask
:format regexp
:files "everything"
:dir (let ((vc (vc-root-dir)))
(if vc
vc
default-directory))
:confirm prefix
:flags ("--hidden -g !.git"))
;; :bind ("M-s g" . bk/search-git-root-or-DIR)
)
Let’s use an occur
snippet from (or emacs. It will offer as the
default candidate:
- the current region, if it’s active
- the current symbol, otherwise
(defun occur-dwim ()
"Call `occur' with a sane default."
(interactive)
(push (if (region-active-p)
(buffer-substring-no-properties
(region-beginning)
(region-end))
(let ((sym (thing-at-point 'symbol)))
(when (stringp sym)
(regexp-quote sym))))
regexp-history)
(call-interactively 'occur))
(global-set-key (kbd "M-s o") 'occur-dwim)
Artur Malabarba has a nice package called google-this
which
provides a set of functions for querying google from emacs.
(use-package google-this
:delight google-this-mode
:config
(google-this-mode 1))
This package provides a set of functions under the prefix C-c /
.
The simplest is C-c / RET
which prompts you for a search in the
minibuffer, with a default search based on the text around the
point.
Keys | Function |
---|---|
C-c / SPC | google-this-region |
C-c / a | google-this-ray |
C-c / c | google-this-translate-query-or-region |
C-c / e | google-this-error |
C-c / f | google-this-forecast |
C-c / g | google-this-lucky-search |
C-c / i | google-this-lucky-and-insert-url |
C-c / m | google-maps |
C-c / n | google-this-noconfirm |
C-c / r | google-this-cpp-reference |
C-c / s | google-this-symbol |
C-c / t | google-this |
C-c / w | google-this-word |
C-c / <return> | google-this-search |
(when (not (eq system-type 'darwin))
(use-package pdf-tools
:config (progn (pdf-tools-install)
;;(add-hook 'pdf-view-mode-hook 'pdf-view-midnight-minor-mode)
(setq pdf-annot-activate-created-annotations t)
(define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)
;; turn off cua so copy works
(add-hook 'pdf-view-mode-hook (lambda () (cua-mode 0)))
;; more fine-grained zooming
(setq pdf-view-resize-factor 1.1)
;; keyboard shortcuts
(define-key pdf-view-mode-map (kbd "h") 'pdf-annot-add-highlight-markup-annotation)
(define-key pdf-view-mode-map (kbd "t") 'pdf-annot-add-text-annotation)
(define-key pdf-view-mode-map (kbd "D") 'pdf-annot-delete)
(add-hook 'pdf-view-mode-hook 'pdf-view-fit-height-to-window)
(add-hook 'pdf-view-mode-hook 'auto-revert-mode)))
;; initialise
;; open pdfs scaled to fit page
;; automatically annotate highlights
;; use normal isearch
)
(use-package pcre2el
:ensure t
:config (pcre-mode))
(use-package telega
:load-path "~/telega.el"
:commands (telega)
:defer t
:config (progn
(telega-notifications-mode 1) ; DBus notifications
(setq telega-use-images t))
:hook ((telega-chat-mode-hook
.
(lambda () ; completions
(set (make-local-variable 'company-backends)
(append '(telega-company-emoji
telega-company-username
telega-company-hashtag)
(when (telega-chat-bot-p telega-chatbuf--chat)
'(telega-company-botcmd))))
(company-mode 1)))))
Nov.el is good for reading EPUB files on Emacs.
Oh, and I also use Olivetti for centering and making it look good.
(use-package nov
:config (progn
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
(add-hook 'nov-mode-hook
(lambda ()
(face-remap-add-relative 'variable-pitch
:family "Liberation Serif"
:height 1.0)))
(setq nov-text-width t
visual-fill-column-center-text t)
(add-hook 'nov-mode-hook 'visual-line-mode)
(add-hook 'nov-mode-hook 'visual-fill-column-mode)))
(use-package paradox
:config (paradox-enable))
(use-package circe
:commands circe
:preface
(defun my/circe-count-nicks ()
"Display the number of users connected on the current channel."
(interactive)
(when (eq major-mode 'circe-channel-mode)
(message "%i users are online on %s."
(length (circe-channel-nicks)) (buffer-name))))
(defun my/circe-fetch-password (&rest params)
"Fetch the NickServ password for an username."
(require 'auth-source)
(let ((match (car (apply 'auth-source-search params))))
(if match
(let ((secret (plist-get match :secret)))
(if (functionp secret)
(funcall secret)
secret))
(error "[✗] Password not found for %S" params))))
(defun my/circe-nickserv-password (server)
"Fetch the NickServ password for the Libera Chat."
(my/circe-fetch-password :login "ietcd" :machine "irc.libera.chat"))
:custom
(circe-default-part-message nil)
(circe-default-quit-message nil)
(circe-format-say (format "{nick:+%ss}: {body}" 8))
(circe-network-options
'(("Libera Chat"
:host "irc.libera.chat"
:nick "ietcd"
:tls t
:port 6697
:server-buffer-name "⇄ Libera Chat"
:channels (:after-auth "#archlinux" "#bash" "#emacs" "#linux" "#clojure")
:nickserv-password my/circe-nickserv-password
)
("Hackint Chat"
:host "irc.hackint.org"
:nick "ietcd"
:tls t
:port 6697
:server-buffer-name "⇄ Hackint"
:channels (:after-auth "#milliways"))
("Autistici"
:host "irc.autistici.org"
:nick "ietcd"
:tls t
:port 6697
:server-buffer-name "⇄ Autistici"
:channels (:after-auth "#hackit99" "#ai"))
))
(circe-reduce-lurker-spam t)
(circe-use-cycle-completion t)
(lui-flyspell-p t)
:config
(circe-lagmon-mode)
(enable-circe-color-nicks)
(enable-circe-display-images))
(use-package circe-notifications
:after circe
:hook (circe-server-connected . enable-circe-notifications))
(setq gnus-select-method '(nnnil nil))
(setq gnus-secondary-select-methods
'((nnimap "Autistici"
(nnimap-address "mail.autistici.org")
(nnimap-server-port 143)
(nnimap-list-pattern ("INBOX" "*"))
(nnimap-stream ssl)
(nnir-search-engine imap)
(nnmail-expiry-target "nnimap+home:[Example]/Trash")
(nnmail-expiry-wait 'immediate)
(nnimap-authenticator login)
(nnimap-authinfo-file "~/.authinfo.gpg")
(nnimap-expunge-on-close always))
;; (nnimap "Gmail"
;; (nnimap-address "imap.gmail.com")
;; (nnimap-server-port 143)
;; (nnimap-server-port 143)
;; (nnimap-list-pattern ("INBOX" "*"))
;; (nnimap-stream ssl)
;; (nnir-search-engine imap)
;; (nnmail-expiry-target "nnimap+home:[Example]/Trash")
;; (nnmail-expiry-wait 'immediate)
;; (nnimap-authenticator login)
;; (nnimap-authinfo-file "~/.authinfo.gpg")
;; (nnimap-expunge-on-close always))
))
(setq gnus-asynchronous t
gnus-use-cache t
gnus-use-header-prefetch t)
(setq gnus-posting-styles
'(("ietcd"
(address "[email protected]")
(signature "i etc daemon.")
("X-Message-SMTP-Method" "smtp smtp.autistici.org 587 [email protected]"))))