specialize a few things depending on which system
(defconst ava/host
(pcase (system-name)
("avat14" 't14)
("avalenovo" 'x220)
("avelazqu01" 'desktop)
(_ 'unknown)))
(use-package modus-themes
:ensure t
:config
(load-theme 'modus-vivendi-tinted t)
(defun ava/toggle-theme ()
(interactive)
(let ((light-theme 'modus-operandi-tinted)
(dark-theme 'modus-vivendi-tinted)
(current-theme (car custom-enabled-themes)))
(mapc #'disable-theme custom-enabled-themes)
(if (eq current-theme dark-theme)
(load-theme light-theme t)
(load-theme dark-theme t)))))
(global-font-lock-mode t)
(setq font-lock-maximum-decoration t)
(set-frame-font
(pcase ava/host
('t14 "Monospace-18")
(_ "Monospace-13")))
(setq display-time-format "%H:%M - %a %b %d"
display-time-24hr-format t
display-time-default-load-average nil)
(column-number-mode t)
(display-battery-mode t)
(display-time-mode 1)
(size-indication-mode t)
(use-package doom-modeline
:ensure t
:custom
(doom-modeline-env-version nil)
(doom-modeline-icon nil)
(doom-modeline-minor-modes t)
(doom-modeline-buffer-encoding nil)
(doom-modeline-modal-icon nil) ; evil specific
:init (doom-modeline-mode 1))
(use-package minions
:ensure t
:custom
(minions-mode-line-lighter "+")
(minions-prominent-modes '(copilot-mode flycheck-mode multiple-cursors-mode view-mode vlf-mode))
:init (minions-mode))
Disable more visuals
(blink-cursor-mode -1)
(transient-mark-mode 1)
Disable audible bell
(setq ring-bell-function 'ignore)
Disable startup messages and text in scratch
(setq initial-major-mode 'fundamental-mode
inhibit-startup-message t
inhibit-startup-echo-area-message t
initial-scratch-message nil)
Disable suspend
(use-package frame :bind ("C-z" . nil))
Mute some warnings out of our control
(setq ad-redefinition-action 'accept)
reduce rendering/line scan work for emacs by not rendering cursors or regions in non-focused windows and left to right rendering only
(setq-default cursor-in-non-selected-windows nil
bidi-display-reordering 'left-to-right
bidi-paragraph-direction 'left-to-right)
Disable common warnings
(put 'set-goal-column 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'erase-buffer 'disabled nil)
(put 'downcase-region 'disabled nil)
(setq large-file-warning-threshold (* 120 1024 1024))
(setq scroll-step 1
scroll-margin 3
scroll-conservatively most-positive-fixnum
scroll-preserve-screen-position t
use-short-answers t
grep-highlight-matches t
shell-file-name "bash"
x-alt-keysym 'meta
kill-ring-max 100
undo-outer-limit 50000000
make-backup-files nil
calendar-mode-line-format nil
set-mark-command-repeat-pop t
load-prefer-newer t
view-read-only t
display-raw-bytes-as-hex t
window-combination-resize t
redisplay-skip-fontification-on-input t
use-dialog-box nil)
(when (version<= "29.1" emacs-version)
(pixel-scroll-precision-mode 1))
(use-package paren
:custom
(show-paren-delay 0)
(show-paren-when-point-inside-paren t)
(show-paren-context-when-offscreen 'overlay)
:config
(show-paren-mode 1))
(setq enable-recursive-minibuffers t)
(minibuffer-depth-indicate-mode)
;too slow otherwise
(unless (eq ava/host 'x220)
(setq completion-styles '(flex)))
(use-package apropos
:custom
(apropos-do-all t))
(use-package delsel
:config (delete-selection-mode t))
(use-package info
:defer t
:config
(let ((texinfo-path "~/.texinfo"))
(when (file-directory-p texinfo-path)
(f-entries texinfo-path
(lambda (path) (add-to-list 'Info-additional-directory-list path)))))
(add-hook 'Info-mode-hook 'variable-pitch-mode))
(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
(use-package saveplace
:config (save-place-mode))
Save some history across sessions. (savehist-mode) on auto-save can be slow so we rely on desktop-save instead
(setq history-length 8000)
(setq history-delete-duplicates t)
(desktop-save-mode -1)
(setq desktop-globals-to-save
(append
'(desktop-missing-file-waning
(shell-command-history 8000)
tags-file-name
tags-table-list
(search-ring . 8000)
(regexp-search-ring . 8000)
(register-alist . 800)
(kill-ring . 8000)
(minibuffer-history . 8000)
(file-name-history . 8000)
(grep-history . 8000)
(extended-command-history . 8000)
(compile-history . 8000)
(read-expression-history . 8000)
query-replace-history
regexp-history)))
(global-hi-lock-mode 1)
(setq hi-lock-auto-select-face t)
(require 'server)
(unless (server-running-p)
(server-start))
kill current buffer no prompt
(defun kill-current-buffer ()
"Kill the current buffer, without confirmation."
(interactive)
(kill-buffer (current-buffer)))
(global-set-key "\C-xk" 'kill-current-buffer)
(setq display-buffer-base-action
'(display-buffer-reuse-mode-window
display-buffer-reuse-window
display-buffer-same-window))
(setq even-window-sizes nil)
(add-to-list 'same-window-buffer-names "*grep*")
(add-to-list 'same-window-buffer-names "*Buffer List*")
(setq world-clock-time-format "%a, %d %b %I:%M %p %Z"
world-clock-list '(("Europe/Berlin" "Berlin")
("America/Chicago" "Chicago")
("Asia/Hong_Kong" "Hong Kong")
("Europe/London" "London")
("America/Mexico_City" "Mexico City")
("Asia/Shanghai" "Shanghai")
("Asia/Singapore" "Singapore")
("Asia/Tokyo" "Tokyo")
("Etc/UTC" "UTC")
("Europe/Zurich" "Zurich")))
(use-package winner
:bind (("M-N" . winner-redo)
("M-P" . winner-undo))
:config
(when (boundp 'winner-boring-buffers-regexp)
(setq winner-boring-buffers-regexp "\\*[hH]elm.*"))
(winner-mode 1))
(global-set-key (kbd "C-x l") 'align-regexp)
(global-set-key [remap eval-last-sexp] 'pp-eval-last-sexp)
(global-set-key "\M-z" 'zap-up-to-char)
(global-set-key "\M-Z" (lambda (char)
(interactive "cZap back to char: ")
(zap-up-to-char -1 char)))
(global-unset-key (kbd "C-x o"))
(use-package isearch
:no-require t
:defer t
:config
(when (version<= "27" emacs-version)
(setq isearch-lazy-count t
isearch-allow-scroll 'unlimited))
(define-key isearch-mode-map [remap isearch-delete-char] #'isearch-del-char))
(use-package proced
:defer t
:custom
(proced-sort 'pmem)
(proced-goal-attribute nil)
(proced-auto-update-flag t)
(proced-auto-update-interval 1)
(proced-enable-color-flag t)
:config
(add-to-list
'proced-format-alist
'(custom user pid pcpu pmem rss thcount start etime time state (args comm)))
(setq-default proced-format 'custom))
(use-package hippie-exp
:custom
(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))
:bind
([remap dabbrev-expand] . hippie-expand))
(use-package eldoc
:diminish
:custom
(eldoc-documentation-strategy 'eldoc-documentation-compose-eagerly)
:hook ((emacs-lisp-mode) . eldoc-mode))
(use-package tramp
:defer t
:custom
(remote-file-name-inhibit-cache nil)
:config
(put 'temporary-file-directory 'standard-value `(,temporary-file-directory))
;; https://www.gnu.org/software/emacs/manual/html_node/tramp/Frequently-Asked-Questions.html
(setq vc-ignore-dir-regexp
(format "\\(%s\\)\\|\\(%s\\)"
vc-ignore-dir-regexp
tramp-file-name-regexp)))
(use-package eww
:custom
(eww-auto-rename-buffer 'title)
:config
(setq browse-url-browser-function 'eww-browse-url))
if need to work in a windows environment talk to it via named pipe
;; (defun ava/on-windows (cmd &rest args)
;; (apply 'start-process "ON-WINDOWS" nil "~/scripts/linux_to_windows.sh"))
;;
;; (defun ava/on-windows-open-url (url &rest args)
;; (interactive "P")
;; (ava/on-windows "start" (or url (url-get-url-at-point))))
;; (setq browse-url-browser-function 'ava/on-windows-open-url)
;;
;; (defun ava/on-windows-serve-dir ()
;; (interactive)
;; (let ((dir-to-serve nil))
;; (if (equal major-mode 'dired-mode)
;; (progn
;; (setq dir-to-serve (dired-get-filename))
;; (when (not (file-directory-p dir-to-serve))
;; (setq dir-to-serve (file-name-directory dir-to-serve))))
;; (setq dir-to-serve (buffer-file-name))
;; (when dir-to-serve
;; (setq dir-to-serve (file-name-directory dir-to-serve))))
;; (cl-assert dir-to-serve t "could not determine directory to serve")
;; (save-excursion
;; (set-buffer (generate-new-buffer (format "httpserve %s" dir-to-serve)))
;; (async-shell-command (format "~/scripts/serve_dir_open_on_windows.sh %s" dir-to-serve) (current-buffer)))))
(setq text-scale-mode-step 1.1
help-enable-symbol-autoload t)
(setq-default tab-width 4
fill-column 80
indent-tabs-mode nil)
(use-package simple
:preface
;; (defun ava/use-interactive-shell-command-switch (orig-fun &rest args)
;; "i flag makes interactive (but not login) so you can see any aliases in bashrc"
;; (let ((shell-command-switch "-ic"))
;; (apply orig-fun args)))
(defun ava/path-slug (dir)
"Returns the initials of `dir`s path, with the last part appended fully
Example: (path-slug \"/foo/bar/hello\") => \"f/b/hello\""
(let* ((path (replace-regexp-in-string "\\." "" dir))
(path (split-string path "/" t))
(path-s (mapconcat (lambda (it) (cl-subseq it 0 1)) (nbutlast (copy-sequence path) 1) "/"))
(path-s (concat path-s "/" (car (last path)))))
path-s))
(defun ava/put-command-in-async-buff-name (orig-fun &rest args)
(let* ((path-s (if default-directory (ava/path-slug default-directory) ""))
(command (car args))
(long-buffname (concat path-s " " command))
(buffname (format "*async-shell %s*" (string-trim (substring long-buffname 0 (min (length long-buffname) 150)))))
(shell-command-buffer-name-async buffname))
(apply orig-fun args)
(let ((buffer (get-buffer buffname)))
(when buffer
(with-current-buffer buffer
(setq-local ava/shell-command command))))))
:custom (async-shell-command-buffer 'new-buffer)
:config
;; (advice-add 'async-shell-command :around #'ava/use-interactive-shell-command-switch)
(advice-add 'shell-command :around #'ava/put-command-in-async-buff-name))
based on https://emacs.stackexchange.com/questions/41256/using-advice-to-run-function-before-tag-symbol-lookup/41277 check if projectile root has a TAGS file and if not generate something
(defun ava/generate-tags ()
"Generate project TAGS"
(interactive)
(cl-assert (projectile-project-root) nil "not in a project")
(let* ((prjd (projectile-project-root))
(tagd (concat prjd ".tagsAndLocate"))
(tagf (concat tagd "/TAGS")))
(make-directory tagd t)
(shell-command
(format "ctags -f %s -e --verbose --totals=yes --links=no \
--kinds-c++=+p --languages=c,c++,lisp --langmap=c++:+.I \
-R %s &> %s/ctags.out" tagf prjd tagd))
(message "generated %s (%s)" tagf
(shell-command-to-string (format "du -sh %s | cut -f1 | tr -d '\n'" tagf)))))
;; TODO only needed if have to locate outside project and no lsp use
(defun ava/generate-locates ()
"Generate project locate.db for helm"
(interactive)
(cl-assert (projectile-project-root) nil "not in a project"))
(defun ava/generate-tags-and-locates ()
"Called interactivel to generate both locate.db and tags for project"
(interactive)
(ava/generate-tags)
(ava/generate-locates))
(defun ava/before-xref-find-defs (&rest _)
(when (projectile-project-root)
(let ((project-tags-file (concat (projectile-project-root) ".tagsAndLocate/TAGS")))
(if (file-exists-p project-tags-file)
(visit-tags-table project-tags-file t)
(ava/generate-tags)))))
(advice-add 'xref-find-definitions :before #'ava/before-xref-find-defs)
indentation related
;;; source: https://www.reddit.com/r/emacs/comments/1bgdw0y/custom_namespace_indentation_in_ctsmode/
(use-package c-ts-mode
:preface
(defun ava/c-ts-indent-style()
"Override the built-in BSD indentation style with some additional rules.
Docs: https://www.gnu.org/software/emacs/manual/html_node/elisp/Parser_002dbased-Indentation.html
Notes: `treesit-explore-mode' can be very useful to see where you're at in the tree-sitter tree,
especially paired with `(setq treesit--indent-verbose t)' to debug what rules is being
applied at a given point."
`(;; do not indent namespace children
((n-p-gp nil nil "namespace_definition") grand-parent 0)
;; append to bsd style
,@(alist-get 'bsd (c-ts-mode--indent-styles 'cpp))))
:config
(setq c-ts-mode-indent-offset 4)
(setq c-ts-mode-indent-style #'ava/c-ts-indent-style))
toggle between implementation and header
(setq cc-search-directories '("."))
(setq cc-other-file-alist
'(("\\.cpp$" (".h" ".hpp"))
("\\.h$" (".cpp" ".c"))
("\\.hpp$" (".cpp" ".c"))
("\\.C$" (".H"))
("\\.H$" (".C"))))
(add-hook 'c-mode-common-hook (lambda() (global-set-key (kbd "C-c o") 'ff-find-other-file)))
(use-package compile
:custom
(compile-command "make")
(compilation-always-kill t)
(compilation-scroll-output 'first-error)
(compilation-read-command nil)
(compilation-ask-about-save nil)
(compilation-skip-threshold 2)
(next-error-message-highlight t)
:hook (compilation-filter . ava/colorize-compilation-buffer)
:config
(progn
;; http://stackoverflow.com/questions/13397737
(defun ava/colorize-compilation-buffer ()
(require 'ansi-color)
(let ((inhibit-read-only t))
(ansi-color-apply-on-region compilation-filter-start (point))))))
(use-package diff-mode
:defer t
:bind (:map diff-mode-map ("M-o" . nil)))
(use-package ediff
:custom
(ediff-highlight-all-diffs nil)
(ediff-window-setup-function #'ediff-setup-windows-plain)
(ediff-split-window-function #'split-window-horizontally)
(ediff-grab-mouse nil)
(ediff-keep-variants nil)
(ediff-diff-options "-w")
:bind (("C-c = b" . ediff-buffers)
("C-c = B" . ediff-buffers3)
("C-c = c" . compare-windows)
("C-c = f" . ediff-files)
("C-c = F" . ediff-files3)
("C-c = m" . count-matches)
("C-c = r" . ediff-revision)
("C-c = p" . ediff-patch-file)
("C-c = P" . ediff-patch-buffer)
("C-c = l" . ediff-regions-linewise)
("C-c = w" . ediff-regions-wordwise))
:config
(add-hook 'ediff-prepare-buffer-hook #'outline-show-all))
bridge re-builder with query regexp replace (from https://karthinks.com/software/bridging-islands-in-emacs-1/)
(use-package re-builder
:config
(setq reb-re-syntax 'string)
(defvar ava/re-builder-positions nil
"Store point and region bounds before calling re-builder")
(advice-add 're-builder
:before
(defun ava/re-builder-save-state (&rest _)
"Save into `ava/re-builder-positions' the point and region
positions before calling `re-builder'."
(setq ava/re-builder-positions
(cons (point)
(when (region-active-p)
(list (region-beginning)
(region-end)))))))
(defun ava/reb-replace-regexp (&optional delimited)
"Run `query-replace-regexp' with the contents of re-builder. With
non-nil optional argument DELIMITED, only replace matches
surrounded by word boundaries."
(interactive "P")
(reb-update-regexp)
(let* ((re (reb-target-binding reb-regexp))
(replacement (query-replace-read-to
re
(concat "Query replace"
(if current-prefix-arg
(if (eq current-prefix-arg '-) " backward" " word")
"")
" regexp"
(if (with-selected-window reb-target-window
(region-active-p)) " in region" ""))
t))
(pnt (car ava/re-builder-positions))
(beg (cadr ava/re-builder-positions))
(end (caddr ava/re-builder-positions)))
(with-selected-window reb-target-window
(goto-char pnt) ; replace with (goto-char (match-beginning 0)) if you want
; to control where in the buffer the replacement starts
; with re-builder
(setq ava/re-builder-positions nil)
(reb-quit)
(query-replace-regexp re replacement delimited beg end))))
(define-key reb-mode-map (kbd "RET") #'ava/reb-replace-regexp)
(define-key reb-lisp-mode-map (kbd "RET") #'ava/reb-replace-regexp)
(global-set-key (kbd "C-M-%") #'re-builder))
(use-package ace-window
:ensure t
:bind (("M-o" . ace-window))
:custom
(aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
(aw-background nil))
;:config (set-face-attribute
; 'aw-leading-char-face nil :height 3.0))
(use-package ace-link
:ensure t
:config (ace-link-setup-default)
(add-hook 'ess-r-help-mode-hook #'(lambda () (bind-key "o" #'ace-link-help ess-r-help-mode-map))))
(use-package tex
:ensure auctex
:defer t
:custom
(TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
:hook
(LaTeX-mode . (lambda ()
(turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
(reftex-isearch-minor-mode)
(setq TeX-source-correlate-start-server t))))
(use-package company-auctex
:after tex
:ensure t
:commands (company-auctex
company-auctext-labels
company-auctest-bibs
company-auctex-macros
company-auctext-symbols
company-auctext-environments)
:hook
(tex-mode . (lambda ()
(setq-local company-backends '((company-auctex-labels
company-auctex-bibs
company-auctex-macros
company-auctex-environments
company-auctex-symbols
company-capf))))))
from karthink
(use-package avy
:ensure t
:bind (("M-j" . avy-goto-char-timer)
("M-g M-g" . avy-goto-line)
)
:custom
(avy-timeout-seconds 0.3)
(avy-keys '(?q ?e ?r ?u ?o ?p ?a ?s ?d ?f ?g ?h ?j ?k ?l ?x ?c ?v ?b ?n ?,))
:init
(bind-key "M-j" 'avy-isearch isearch-mode-map)
:config
(when (display-graphic-p)
(setq avy-background t))
(progn ;kill text
(defun avy-action-kill-whole-line (pt)
(save-excursion
(goto-char pt)
(kill-whole-line))
(select-window (cdr (ring-ref avy-ring 0))) t)
(setf (alist-get ?k avy-dispatch-alist) 'avy-action-kill-stay
(alist-get ?K avy-dispatch-alist) 'avy-action-kill-whole-line))
(progn ;copy text
(defun avy-action-copy-whole-line (pt)
(save-excursion
(goto-char pt)
(cl-destructuring-bind (start . end)
(bounds-of-thing-at-point 'line)
(copy-region-as-kill start end)))
(select-window (cdr (ring-ref avy-ring 0))) t)
(setf (alist-get ?w avy-dispatch-alist) 'avy-action-copy
(alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line))
(progn ;yank text
(defun avy-action-yank-whole-line (pt)
(avy-action-copy-whole-line pt)
(save-excursion (yank)) t)
(setf (alist-get ?y avy-dispatch-alist) 'avy-action-yank
(alist-get ?Y avy-dispatch-alist) 'avy-action-yank-whole-line))
(progn ;transpose text
(defun avy-action-teleport-whole-line (pt)
(avy-action-kill-whole-line pt)
(save-excursion (yank)) t)
(setf (alist-get ?t avy-dispatch-alist) 'avy-action-teleport
(alist-get ?T avy-dispatch-alist) 'avy-action-teleport-whole-line))
(progn ;helpful
(defun avy-action-helpful (pt)
(save-excursion
(goto-char pt)
(helpful-at-point))
(select-window (cdr (ring-ref avy-ring 0))) t)
(setf (alist-get ?H avy-dispatch-alist) 'avy-action-helpful))
(progn ;dash
(defun avy-action-dash (pt)
(save-excursion
(goto-char pt)
(helm-dash-at-point))
(select-window (cdr (ring-ref avy-ring 0))) t)
(setf (alist-get ?D avy-dispatch-alist) 'avy-action-dash))
(progn ;man
(defun avy-action-man (pt)
(save-excursion
(goto-char pt)
(helm-man-woman nil))
(select-window (cdr (ring-ref avy-ring 0))) t)
(setf (alist-get ?M avy-dispatch-alist) 'avy-action-man)))
(use-package bookmark
:custom
(bookmark-save-flag 1))
(use-package clang-format
:ensure t
:commands clang-format-buffer clang-format-region)
(use-package cc-mode
:defer t
:config
(bind-key "C-c b" #'clang-format-buffer c-mode-base-map))
(use-package c-ts-mode
:defer t
:config
(bind-key "C-c b" #'clang-format-buffer c++-ts-mode-map))
(use-package company
:ensure t
:custom
(company-dabbrev-downcase nil)
(company-dabbrev-other-buffers t)
(company-idle-delay 0.1)
(company-minimum-prefix-length 1)
(company-require-match nil)
(company-show-numbers t)
(company-tooltip-limit 20)
(company-tooltip-align-annotations t)
(company-selection-wrap-around t)
(company-global-modes '(not compilation-mode magit-status-mode reb-mode))
(company-backends '(company-clang company-capf company-files
(company-dabbrev-code company-gtags company-etags company-keywords)
company-dabbrev))
:config
(define-key company-mode-map (kbd "C-:") 'company-complete-common)
(define-key company-active-map (kbd "<tab>") 'smarter-yas-expand-next-field-complete)
(global-company-mode 1)
(defun smarter-yas-expand-next-field-complete ()
"Try to `yas-expand' and `yas-next-field' at current cursor position.
If failed try to complete the common part with `company-complete-common'"
(interactive)
(if yas-minor-mode
(let ((old-point (point))
(old-tick (buffer-chars-modified-tick)))
(yas-expand)
(when (and (eq old-point (point))
(eq old-tick (buffer-chars-modified-tick)))
(ignore-errors (yas-next-field))
(when (and (eq old-point (point))
(eq old-tick (buffer-chars-modified-tick)))
(company-complete-common))))
(company-complete-common))))
A much nicer frame for completion candidates
(use-package company-posframe
:ensure t
:config
(company-posframe-mode 1))
(use-package helm-company
:ensure t
:config
(define-key company-mode-map (kbd "C-:") 'helm-company))
clone via git clone https://github.com/zerolfx/copilot.el.git copilot
in emacs user dir lisp
subdir
use M-x copilot-login
to authenticate. copilot-mode
to turn it on automatically blending in with company (use C-n
and C-p
to control company when they overlap).
can also use M-C-<return>
to summon it manually instead
(use-package editorconfig :ensure t)
(use-package copilot
:if (file-directory-p "~/.emacs.d/lisp/copilot")
:load-path "~/.emacs.d/lisp/copilot"
:preface
(defun ava/copilot-quit ()
(when copilot--overlay
(copilot-clear-overlay)))
(defun ava/copilot-complete-or-accept ()
"Either trigger a completion or accept one if available."
(interactive)
(if (copilot--overlay-visible)
(progn
(copilot-accept-completion)
(open-line 1)
(next-line))
(copilot-complete)))
:bind (("M-C-<return>" . #'ava/copilot-complete-or-accept)
(:map copilot-completion-map
("M-n" . #'copilot-next-completion)
("M-p" . #'copilot-previous-completion)
("M-<return>" . #'copilot-accept-completion)))
:config
;; (add-to-list 'copilot-disable-predicates #'company--active-p)
;; (add-to-list 'copilot-disable-display-predicates #'company--active-p)
(advice-add 'keyboard-quit :before #'ava/copilot-quit))
uses rg for fast grep
(use-package deadgrep
:ensure t
:commands deadgrep
:init
(defun ava/deadgrep--include-args (rg-args)
"https://github.com/Wilfred/deadgrep/issues/24#issuecomment-942290197"
(push "--hidden" rg-args))
:bind (("M-s g" . deadgrep)
(:map deadgrep-mode-map ("C-c C-w" . #'deadgrep-edit-mode)))
:config
(advice-add 'deadgrep--arguments :filter-return #'ava/deadgrep--include-args))
(use-package devdocs-browser :ensure t)
(with-eval-after-load 'dired
(require 'dired-x)
(setq
dired-recursive-copies 'always
dired-recursive-deletes 'always
dired-dwim-target t
dired-auto-revert-buffer 'dired-directory-changed-p
dired-listing-switches "-Al --si --time-style long-iso --group-directories-first"
dired-hide-details-hide-symlink-targets nil
dired-kill-when-opening-new-dired-buffer t
dired-mouse-drag-files t
; dired-guess-shell-alist-user (list '("\\.foobar$" "some command")) ;; suggestions for ! and & in Dired
wdired-allow-to-change-permissions t)
(add-hook 'dired-mode-hook (lambda () (interactive) (dired-hide-details-mode 1))))
a much nicer dired (can in-place expand subdirectory contents)
(use-package dired-subtree
:ensure t
:after dired
:bind (:map dired-mode-map
("i" . dired-subtree-insert)
(";" . dired-subtree-remove)
("<tab>" . dired-subtree-cycle)))
replaces list-directory with recentf for dirs
(use-package dired-recent
:ensure t
:config (dired-recent-mode 1))
add rsync option to dired
(use-package dired-rsync-transient
:ensure t
:bind (:map dired-mode-map ("r" . dired-rsync-transient))
:custom (dired-rsync-unmark-on-completion nil)
:hook (dired-rsync-failed . dired-rsync--pop-to-rsync-failed-buf))
(use-package dumb-jump
:ensure t
:custom
(dumb-jump-selector 'helm)
(dumb-jump-confirm-jump-to-modified-file nil)
:bind
(:map prog-mode-map
(("C-c C-j" . dumb-jump-go))))
Use M-w
and modifiers to more efficiently save things to kill ring
(use-package easy-kill
:ensure t
:config
(global-set-key [remap kill-ring-save] #'easy-kill)
(global-set-key [remap mark-sexp] #'easy-mark)
(defun ava/easy-kill-on-buffer-file-name-with-line-number (n)
"Get `buffer-file-name' or `default-directory' with line number if N is 2.
If N is zero, remove the directory part; -, remove the file name
part; +, full path; 9, name with line number.; 8 full name with line number"
(if (easy-kill-get mark)
(easy-kill-echo "Not supported in `easy-mark'")
(pcase (or buffer-file-name default-directory)
(`nil (easy-kill-echo "No `buffer-file-name'"))
(file (let* ((file (directory-file-name file))
(text (pcase n
(`- (file-name-directory file))
(`0 (file-name-nondirectory file))
(`8 (concat file ":" (number-to-string (line-number-at-pos))))
(`9 (concat (file-name-nondirectory file) ":" (number-to-string (line-number-at-pos))))
(_ file))))
(easy-kill-adjust-candidate 'buffer-file-name text))))))
(advice-add 'easy-kill-on-buffer-file-name :override #'ava/easy-kill-on-buffer-file-name-with-line-number))
(use-package eglot
:commands eglot
:init
;(defun ava/eglot-disable-flymake () (flymake-mode -1))
;(add-hook 'eglot-managed-mode-hook #'ava/eglot-disable-flymake)
;; (defvar ava/eglot-enabled-projects '("foo" "bar")) ;; <- if want to auto enable in some projects
;; (defun ava/eglot-ensure ()
;; (when (and (derived-mode-p 'c++-mode 'c++-ts-mode)
;; (member (projectile-project-name) ava/eglot-enabled-projects))
;; (eglot-ensure)))
;; (add-hook 'eglot-managed-mode-hook #'ava/eglot-ensure)
(defun ava/eglot-enable-eager-eldoc () (setq eldoc-documentation-strategy 'eldoc-documentation-compose-eagerly))
(add-hook 'eglot-managed-mode-hook #'ava/eglot-enable-eager-eldoc)
:bind (:map eglot-mode-map
("C-h ." . eldoc)
("C-c e a" . eglot-code-actions)
("C-c e r" . eglot-rename)
("C-c e q" . eglot-code-action-quickfix)
("C-c e e" . eglot-code-action-extract)
("C-c e i" . eglot-code-action-inline)
("C-c e n" . flymake-goto-next-error)
("C-c e p" . flymake-goto-prev-error))
:custom
(eglot-events-buffer-size 0)
(eglot-extend-to-xref t)
(eldoc-echo-area-use-multiline-p nil)
(eglot-ignored-server-capabilities '(:documentHighlightProvider))
:config
(let ((clangd-options (list "clangd"
"--malloc-trim"
"--log=info"
"--background-index"
"--clang-tidy"
"--completion-style=detailed"
"--header-insertion=never"
"--header-insertion-decorators=0"))
(clangd-modes (list 'c++-mode 'c++-ts-mode 'c-mode 'c-ts-mode)))
(let ((entry (assoc clangd-modes eglot-server-programs)))
(if entry
(setcdr entry clangd-options)
(push (cons clangd-modes clangd-options) eglot-server-programs)))))
(use-package elfeed
:ensure t
:commands elfeed
:custom
(elfeed-search-filter "@1-week-ago ")
(elfeed-feeds
'(("https://www.archlinux.org/feeds/news/" arch)
("https://matklad.github.io/feed.xml" programming)
("http://www.reddit.com/r/emacs/.rss" emacs reddit)
("http://sachachua.com/blog/category/emacs-news/feed" emacs)
("http://www.masteringemacs.org/feed/" emacs)
("http://emacsredux.com/atom.xml" emacs)
("https://emacs.tv/videos.rss" emacs))))
(use-package ess
:ensure t
:init (require 'ess-site)
:custom
(inferior-R-program-name "/usr/bin/R")
(inferior-R-args "--no-save --no-restore-data --quiet")
(ess-eval-visibly-p nil)
(ess-directory "~/")
(ess-use-flymake nil)
(ess-indent-with-fancy-comments nil)
(ess-ask-for-ess-directory nil)
:config
(setf (alist-get 'ess-indent-with-fancy-comments ess-style-alist)
'(nil nil nil))
(define-key ess-r-mode-map "_" #'ess-insert-assign)
(define-key inferior-ess-r-mode-map "_" #'ess-insert-assign))
(use-package flycheck :ensure t)
; (use-package flycheck-clang-tidy
; :ensure t
; :after flycheck
; :hook (flycheck-mode . flycheck-clang-tidy-setup))
(use-package git-gutter
:ensure t
:init
(global-git-gutter-mode +1))
(use-package git-timemachine
:ensure t
:bind ("C-x v t" . git-timemachine-toggle))
https://github.com/karthink/gptel
(use-package gptel
:ensure t
:preface
(defun ava/init-gptel-mode ()
(visual-line-mode)
(setq-local gptel-expert-commands t)
(setq-local gptel--system-message (alist-get 'default gptel-directives)))
:hook (gptel-mode . ava/init-gptel-mode)
:custom
(gptel-model 'gpt-4o)
(gptel-default-mode 'org-mode)
(gptel-track-media t)
(gptel-directives '((default . "You are a helpful assistant living inside Emacs. The user is a computer programmer. Your responses are always concise, succinct, and to the point. You never apologize for confusions as that wastes time. If you generate blocks using three backticks inspect your response and add the appropriate programming language after the opening backticks. Do not use the asterisk character followed by whitespace for bullet points in your responses as this can interfere with org-mode rendering (you can use a hyphen instead)")
(programmer . "You are a careful programmer. Provide code and only code as output without any additional text, prompt, or note. Do NOT use markdown backticks (```) to format your response.")
(emacser . "You are an emacs maven. Reply with the most appropriate built-in Emacs command for the task I specify. Do NOT generate any additional description or explanation.")
(cliwhiz . "You are a command line helper. Generate command line commands that do what is requested, without any additional description or explanation. Generate ONLY the command, without any markdown code fences.")
(explainer . "You are a computer programmer's assistant. Explain what this code does")
(differ . "You are a computer programmer's assistant. Explain what this code diff hunk is doing, is it trying to fix something? Is it just a refactor? What is your understanding of the diff")))
:config
(setf (alist-get 'org-mode gptel-prompt-prefix-alist) "*Prompt*: "
(alist-get 'org-mode gptel-response-prefix-alist) "*Response*:\n")
(with-eval-after-load 'gptel-org
(setq-default gptel-org-branching-context t))
(gptel-make-anthropic "claude" :key gptel-api-key :stream t))
(use-package helm
:ensure t
:diminish helm-mode
:init (helm-mode 1)
:bind (
("C-h a" . helm-apropos)
("C-x b" . helm-mini)
("M-y" . helm-show-kill-ring)
("M-x" . helm-M-x)
("C-x C-f" . helm-find-files)
("C-c h o" . helm-occur)
("C-c h b" . helm-resume)
("C-c h i" . helm-semantic-or-imenu)
("C-c h m" . helm-man-woman)
("C-c h I" . helm-imenu-in-all-buffers)
("C-c h l" . helm-locate)
("C-c h g s" . helm-google-suggest)
("C-c h t" . helm-top)
("C-c h x" . helm-shell-history)
("C-c h <SPC>" . helm-all-mark-rings))
:config
(setq helm-candidate-number-limit 100
helm-idle-delay 0.0
helm-input-idle-delay 0.01
helm-yas-display-key-on-candidate t
helm-quick-update t
helm-M-x-requires-pattern nil
helm-command-prefix-key "C-c h"
helm-autoresize-min-height 25
helm-autoresize-max-height 25
helm-split-window-inside-p t
helm-move-to-line-cycle-in-source t
helm-ff-search-library-in-sexp t
helm-scroll-amount 8
helm-ff-file-name-history-use-recentf t
helm-buffer-max-length nil
helm-buffer-skip-remote-checking t
helm-window-prefer-horizontal-split 'decide)
;;locate %s -d FOO -e --regex %s where FOO is : delimited from cmd updatedb -l 0 -o i.db -U path_i for all paths
;;(defvar my-locate-db-command (with-temp-buffer (insert-file-contents "path/to/cmd.txt") (buffer-string)))
;;(setq helm-locate-command my-locae-db-command)
(helm-autoresize-mode 1)
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-z") 'helm-select-action)
(defun ava/around-helm-buffers-sort-transformer (candidates source)
candidates)
(advice-add 'helm-buffers-sort-transformer
:override #'ava/around-helm-buffers-sort-transformer)
(defun ava/reset-helm-buffer-max-length (&rest ignore) (setq helm-buffer-max-length nil))
(advice-add 'helm-mini :before #'ava/reset-helm-buffer-max-length))
(use-package helm-swoop
:ensure t
:bind (("C-c h s" . helm-multi-swoop))
:custom (helm-swoop-speed-or-color t)
:init
(bind-key "M-i" 'helm-swoop-from-isearch isearch-mode-map)
:config
(define-key helm-swoop-map (kbd "M-i") 'helm-multi-swoop-current-mode-from-helm-swoop))
(use-package helm-rg
:ensure t
:bind
(("C-c h r g" . helm-rg)))
(use-package helm-ag
:ensure t
:bind
(("C-c h a" . helm-ag))
:custom
(helm-ag-use-agignore t)
(helm-ag-insert-at-point 'symbol))
(use-package helm-git-grep
:ensure t
:bind
(("C-c h g g" . helm-git-grep-at-point)))
remap term-previous-matching-input
to a helm frontend
(use-package helm-shell-history
:load-path "~/.emacs.d/lisp/helm-shell-history"
:after term vterm
:config
(setq helm-shell-history-file "~/.bash_eternal_history")
(setq helm-shell-history-fuzzy-match t)
(setq helm-shell-history-fast-parser "~/development/helm-shell-history/src/parse_history")
(define-key term-mode-map (kbd "M-r") 'helm-shell-history)
(define-key vterm-mode-map (kbd "M-r") 'helm-shell-history))
(use-package helm-descbinds
:ensure t
:custom
(helm-descbinds-disable-which-key nil)
:init
(helm-descbinds-mode))
(use-package helm-dash
:ensure t
:bind (("C-c h d" . helm-dash-at-point))
:custom
(dash-docs-enable-debugging nil)
(dash-docs-browser-func #'eww)
:config
(require 'dash-docs)
(setq dash-docs-common-docsets '("Emacs Lisp", "Python 3" "NumPy" "Pandas")))
(use-package helm-org-rifle
:ensure t
:bind
("C-c h r r" . helm-org-rifle)
("C-c h r b" . helm-org-rifle-current-buffer)
("C-c h r a" . helm-org-rifle-agenda-files)
("C-c h r o" . helm-org-rifle-org-directory))
(use-package helpful
:ensure t
:bind
(("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)
("C-c C-d" . helpful-at-point)
("C-h F" . helpful-funtion)
("C-h C" . helpful-command)))
(use-package hydra
:ensure hydra
:init
(global-set-key
(kbd "C-c g")
(defhydra hydra-git-gutter (:body-pre (git-gutter-mode 1) :hint nil)
"
Up^^ Down^^ Miscellaneous
------------------------------------------------------------------
[_p_] Prev [_n_] Next [_<SPC>_] Show [_r_] Revert [_q_] Quit
[_h_] First [_l_] Last [_s_] Stage [_d_] Digest [_b_] Set Base Revision"
("n" git-gutter:next-hunk)
("p" git-gutter:previous-hunk)
("h" (progn (goto-char (point-min)) (git-gutter:next-hunk 1)))
("l" (progn (goto-char (point-min)) (git-gutter:previous-hunk 1)))
("<SPC>" git-gutter:popup-hunk)
("s" git-gutter:stage-hunk)
("r" git-gutter:revert-hunk)
("r" git-gutter:revert-hunk)
("d" git-gutter:statistic)
("b" git-gutter:set-start-revision)
("q" nil)))
(with-eval-after-load 'paredit
(defhydra hydra-paredit (:hint nil)
"
Forward^^ Backward^^ Miscellaneous
------------------------------------------------------------------
[_n_] Next [_p_] Next [_r_] Raise [_q_] Quit
[_s_] Slurp [_M-s_] Slurp [_l_] Splice
[_b_] Barf [_M-b_] Barf [_u_] Undo"
("n" paredit-forward)
("s" paredit-forward-slurp-sexp)
("b" paredit-forward-barf-sexp)
("p" paredit-backward)
("M-s" paredit-backward-slurp-sexp)
("M-b" paredit-backward-barf-sexp)
("r" paredit-raise-sexp)
("l" paredit-splice-sexp)
("u" undo-only)
("q" nil))
(add-hook 'paredit-mode-hook #'(lambda () (bind-key "C-c e" #'hydra-paredit/body paredit-mode-map))))
(global-set-key
(kbd "C-c w")
(defhydra hydra-windows (:hint nil)
("r" rotate-frame-clockwise "clockwise")
("\\" rotate-frame-clockwise "anticlockwise")
("v" flip-frame "flip")
("f" flop-frame "flop")
("j" (shrink-window -10) "down")
("k" (shrink-window 10) "up")
("h" (shrink-window 10 t) "shrink")
("l" (shrink-window -10 t) "widen")
("0" (balance-windows) "balance")
("q" nil "quit")))
(with-eval-after-load 'smerge-mode
(defhydra hydra-smerge
(:color pink :hint nil :post (smerge-auto-leave))
"
^Move^ ^Keep^ ^Diff^ ^Other^
^^-----------^^-------------------^^---------------------^^-------
_n_ext _b_ase _<_: upper/base _C_ombine
_p_rev _u_pper _=_: upper/lower _r_esolve
^^ _l_ower _>_: base/lower _k_ill current
^^ _a_ll _R_efine
^^ _RET_: current _E_diff
"
("n" smerge-next)
("p" smerge-prev)
("b" smerge-keep-base)
("u" smerge-keep-upper)
("l" smerge-keep-lower)
("a" smerge-keep-all)
("RET" smerge-keep-current)
("\C-m" smerge-keep-current)
("<" smerge-diff-base-upper)
("=" smerge-diff-upper-lower)
(">" smerge-diff-base-lower)
("R" smerge-refine)
("E" smerge-ediff)
("C" smerge-combine-with-next)
("r" smerge-resolve)
("k" smerge-kill-current)
("ZZ" (lambda ()
(interactive)
(save-buffer)
(bury-buffer))
"Save and bury buffer" :color blue)
("q" nil "cancel" :color blue))
(add-hook 'smerge-mode-hook (lambda () (bind-key "C-c ^ h" #'hydra-smerge/body smerge-mode-map)))))
(use-package ibuffer
:bind ("C-x C-b" . ibuffer)
:config (define-key ibuffer-mode-map (kbd "M-o") nil))
(use-package ibuffer-vc
:ensure t
:bind (:map ibuffer-mode-map
("/ V" . ibuffer-vc-set-filter-groups-by-vc-root)))
(use-package jq-mode
:ensure t
:mode "\\.jq\\'")
(with-eval-after-load 'json-ts-mode
(require 'json)
(require 'jq-mode)
(add-hook 'json-ts-mode-hook (lambda () (flycheck-mode)))
(setq json-ts-mode-indent-offset 4)
(setq json-encoding-pretty-print t)
(setq json-encoding-default-indentation " ")
(let ((map json-ts-mode-map))
(define-key map (kbd "C-c C-i") #'jq-interactively)
(define-key map (kbd "C-c C-f") #'json-pretty-print-buffer)))
(can use magit-toggle-verbose-refresh
to profile status buffer)
(use-package magit
:ensure t
:preface
(defun ava/format-staged ()
(interactive)
(dolist (name (magit-staged-files))
(let ((fname (expand-file-name name (magit-toplevel))))
(when (file-exists-p fname)
(pcase (file-name-extension name)
("py"
(shell-command (format "dos2unix -q %s" fname)))
((or "C" "H" "I" "c" "h" "cpp" "hpp")
(shell-command (format "dos2unix -q %s && clang-format --style=file -i %s" fname fname))))))))
:custom
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
(magit-log-section-commit-count 25)
(magit-diff-refine-hunk 'all)
(magit-no-confirm '(stage-all-changes unstage-all-changes set-and-push))
;; (magit-refresh-status-buffer nil) ;set to nil as last resort for perf
:bind
("C-x g" . magit-status)
("C-c m" . magit-file-dispatch))
;;; if too slow remove some headers like this
;:config (remove-hook 'magit-status-section-hook 'magit-insert-tags-header)
(use-package forge
:ensure t
:after magit
:config
(remove-hook 'magit-status-sections-hook 'forge-insert-issues))
addresses the issues with variable-pitch-mode
in modes like org (tables/code-blocks)
(use-package mixed-pitch
:ensure t
:defer t
:config
(dolist (face '(org-date org-priority org-tag org-special-keyword))
(add-to-list 'mixed-pitch-fixed-pitch-faces face)))
meta up and down to move text or region
(use-package move-text :ensure t :config (move-text-default-bindings))
- power hydra here
- ivanmalison hydra example here
- github issue on setting run once to avoid exp behavior here
- pull in phi-search as well to get incremental search while in mc
- protip: easy-kill ==C-SPC== will turn selection into region
(use-package multiple-cursors
:ensure t
:config (progn
(use-package phi-search-mc
:ensure t
:config
(phi-search-mc/setup-keys)))
(defhydra ava/multiple-cursors-hydra (:hint nil)
"
Up^^ Down^^ Miscellaneous % 2(mc/num-cursors) cursor%s(if (> (mc/num-cursors) 1) \"s\" \"\")
------------------------------------------------------------------
[_p_] Next [_n_] Next [_l_] Edit lines [_d_] Mark sym defun [_|_] Vertical align
[_P_] Skip [_N_] Skip [_a_] Mark all [_r_] Mark all regex [_q_] Quit
[_M-p_] Unmark [_M-n_] Unmark [_s_] Mark sym [_0_] Insert numbers"
("n" mc/mark-next-like-this)
("N" mc/skip-to-next-like-this)
("M-n" mc/unmark-next-like-this)
("p" mc/mark-previous-like-this)
("P" mc/skip-to-previous-like-this)
("M-p" mc/unmark-previous-like-this)
("|" mc/vertical-align)
("0" mc/insert-numbers)
("l" mc/edit-beginnings-of-lines)
("a" mc/mark-all-like-this :exit t)
("s" mc/mark-all-symbols-like-this :exit t)
("d" mc/mark-all-symbols-like-this-in-defun :exit t)
("r" mc/mark-all-in-region-regexp :exit t)
("q" nil))
:bind (("C-c i" . ava/multiple-cursors-hydra/body)
:map mc/keymap ("C-s" . phi-search)))
(use-package org
:custom
(org-ellipsis " ▾")
(org-use-speed-commands 1)
(org-return-follows-link t)
(org-blank-before-new-entry nil)
(org-catch-invisible-edits 'smart)
(org-enforce-todo-dependencies t)
(org-hide-emphasis-markers t)
(org-list-description-max-indent 5)
(org-export-html-postamble nil)
(org-log-done 'time)
(org-cycle-separator-lines 0)
(org-deadline-warning-days 7)
(org-imenu-depth 10)
(org-startup-folded t)
(org-goto-auto-isearch nil)
(org-refile-targets '((nil :maxlevel . 5) (org-agenda-files :maxlevel . 5)))
(org-refile-use-outline-path 'file)
(org-outline-path-complete-in-steps nil)
(org-src-window-setup 'current-window)
(org-log-into-drawer t)
(org-todo-keywords '((sequence "TODO(t)" "WAIT(w@/!)" "|" "DONE(d)")))
(org-highlight-latex-and-related '(native script entities))
(org-format-latex-options (plist-put org-format-latex-options :scale 1.5))
(org-latex-create-formula-image-program 'dvisvgm)
(org-confirm-babel-evaluate nil)
(org-clock-history-length 20)
(org-clock-out-remove-zero-time-clocks t)
(org-link-elisp-confirm-function nil)
(org-edit-src-content-indentation 0)
(org-fontify-quote-and-verse-blocks t)
:hook
(org-mode . org-indent-mode)
(org-mode . mixed-pitch-mode)
:config
(add-to-list 'org-speed-commands '("i" . (progn (outline-show-subtree) (org-end-of-subtree))))
(add-to-list 'org-speed-commands '("b" . (unless (org-goto-sibling t) (while (org-goto-sibling)))))
(add-to-list 'org-speed-commands '("f" . (unless (org-goto-sibling) (while (org-goto-sibling t)))))
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(R . t)
(python . t)
(dot . t)
(plantuml . t)))
(setq org-capture-bookmark nil
org-capture-templates
'(("n" "note" entry (file "notes.org") "* %? \n%U\n%i")
("t" "tasks")
("tt" "whenever" entry (file "todo.org") "* TODO %^{title}\n%?")
("ts" "schedule" entry (file "todo.org") "* TODO %^{title}\nSCHEDULED: %^t\n%?")
("td" "deadline" entry (file "todo.org") "* TODO %^{title}\nDEADLINE: %^t\n%?")
("ta" "sch&dead" entry (file "todo.org") "* TODO %^{title}\nSCHEDULED: %^t DEADLINE: %^t\n%?")))
(define-key global-map (kbd "C-c l") 'org-store-link)
(define-key global-map (kbd "C-c c") 'org-capture)
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src bash"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(add-to-list 'org-structure-template-alist '("R" . "src R"))
(add-to-list 'org-structure-template-alist '("cpp" . "src C"))
(add-to-list 'org-structure-template-alist '("conf" . "src conf"))
(add-to-list 'org-structure-template-alist '("xml" . "src nxml"))
(dolist (face '((org-level-1 . 1.20) (org-level-2 . 1.10) (org-level-3 . 1.05)))
(set-face-attribute (car face) nil :weight 'regular :height (cdr face))))
hide emphasis markers the nice way
(use-package org-appear
:ensure t
:commands (org-appear-mode)
:hook (org-mode . org-appear-mode)
:custom
(org-appear-delay 0.5)
(org-appear-autolinks t)
(org-appear-autoemphasis t)
(org-appear-autokeywords t))
(use-package org-modern
:ensure t
:hook ((org-mode . org-modern-mode)
(org-agenda-finalize . org-modern-agenda))
:custom
(org-modern-star '("◉" "○" "●" "○" "●" "○" "●"))
(org-modern-table-vertical 1)
(org-modern-progress nil)
(org-modern-block-fringe nil))
(use-package org-mime
:ensure t
:config
(setq mail-host-address (getenv "HOST")
org-mime-export-options '(:section-numbers nil
:with-author nil
:with-toc nil
:with-latex imagemagick))
(add-hook 'message-mode-hook
(lambda ()
(local-set-key (kbd "C-c M-o") 'org-mime-htmlize)))
(add-hook 'org-mode-hook
(lambda ()
(local-set-key (kbd "C-c M-o") 'org-mime-org-subtree-htmlize))))
(use-package orgit :ensure t)
(use-package org-agenda
:after org
:custom
(org-agenda-files '("todo.org" "projects.org"))
(org-agenda-span 'day)
(org-agenda-window-setup 'current-window)
(org-agenda-restore-windows-after-quit t)
(org-agenda-todo-ignore-scheduled 'future)
(org-agenda-skip-deadline-if-done t)
(org-agenda-skip-scheduled-if-done t)
(org-agenda-skip-deadline-prewarning-if-scheduled t)
:init
(global-set-key (kbd "C-c a") 'org-agenda))
(use-package org-noter
:ensure t
:custom
(org-noter-always-create-frame nil))
use paredit
in lisp modes (animated paredit guide)
(use-package paredit
:ensure t
:bind (
:map paredit-mode-map
("M-s" . nil) ; used for isearch
("RET" . nil) ; used during M-: to evaluate the input
("C-j" . paredit-newline) ; replacement for RET
("M-I" . paredit-splice-sexp))
:hook ((emacs-lisp-mode
lisp-mode
lisp-interaction-mode
eval-expression-minibuffer-setup
ielm-mode
lisp-data-mode) . enable-paredit-mode))
(use-package pdf-tools
:ensure t
:custom
(pdf-view-display-size 'fit-page)
(pdf-view-continuous nil)
(pdf-view-use-scaling t)
:config
(pdf-tools-install)
(setq pdf-view-resize-factor 1.1)
(add-hook 'pdf-tools-enabled-hook 'pdf-view-midnight-minor-mode))
(use-package projectile
:ensure t
:diminish projectile-mode
:custom
(projectile-project-root-files-bottom-up '(".git" ".projectile"))
;; (projectile-project-root-files '("WORKSPACE"))
:init
(setq projectile-enable-caching t
projectile-project-search-path '("~/development"))
(when (executable-find "rg")
(setq projectile-generic-command "rg -0 --hidden --files --color never"))
:config
(projectile-mode t)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(define-key projectile-mode-map (kbd "C-c p t") 'projectile-run-vterm)
(define-key projectile-mode-map (kbd "C-c p S") 'helm-multi-swoop-projectile)
(define-key projectile-mode-map (kbd "C-c p R") 'ava/generate-tags)
(use-package helm-projectile
:ensure t
:init
(helm-projectile-on)
(setq projectile-switch-project-action #'helm-projectile)
(setq projectile-completion-system 'helm)))
make sure imenu does not override dumb-jump in python mode
(use-package python
:defer t
:config
(bind-key "C-c C-j" #'dumb-jump-go python-mode-map))
To use a venv set a pyvenv-activate directory local or file local variable to the venv path
(if one gets “exited abnormally with code 1” errors run M-x elpy-rpc-reinstall-virtualenv
as per jorgenschaefer/elpy#1729)
(use-package elpy
:ensure t
:commands elpy-enable
:custom
;; (elpy-rpc-virtualenv-path 'system)
(elpy-get-info-from-shell t)
:preface
;; https://elpy.readthedocs.io/en/latest/customization_tips.html
(defun ava/elpy-goto-definition-or-rgrep ()
"Go to the definition of the symbol at point, if found. Otherwise, run `elpy-rgrep-symbol'."
(interactive)
(xref-push-marker-stack)
(condition-case nil (elpy-goto-definition)
(error (elpy-rgrep-symbol
(concat "\\(def\\|class\\)\s" (thing-at-point 'symbol) "(")))))
(defun ava/elpy-enable-inferior-eldoc ()
(when (and (version< "28.0.0" emacs-version)
(boundp 'eldoc-documentation-functions))
(add-hook 'eldoc-documentation-functions 'elpy-eldoc-documentation t nil)))
:init
(progn
(elpy-enable)
(setq elpy-modules
'(elpy-module-sane-defaults
elpy-module-company
elpy-module-eldoc
elpy-module-highlight-indentation
elpy-module-pyvenv
elpy-module-yasnippet
elpy-module-folding))
(eval-after-load "elpy"
'(cl-dolist (key '("C-<return>" "C-<up>" "C-<down>" "C-<left>" "C-<right>"))
(define-key elpy-mode-map (kbd key) nil))))
:bind
(:map inferior-python-mode-map
("C-c C-d" . elpy-doc)
("M-." . elpy-goto-definition))
:config
(setq python-shell-interpreter-args "-i")
(setq elpy-rpc-timeout 10)
(setq python-shell-prompt-detect-failure-warning nil)
(define-key elpy-mode-map (kbd "M-.") 'ava/elpy-goto-definition-or-rgrep)
(add-to-list 'python-shell-completion-native-disabled-interpreters "jupyter")
(add-to-list 'process-coding-system-alist '("python" . (utf-8 . utf-8)))
(add-hook 'elpy-mode-hook (lambda () (elpy-shell-toggle-dedicated-shell 1)))
(add-hook 'inferior-python-mode-hook #'ava/elpy-enable-inferior-eldoc))
(use-package python-black
:ensure t
:after (python)
:config
(setq python-black-command "/usr/bin/black")
(define-key python-mode-map "\C-cb" 'python-black-buffer)
(define-key python-mode-map "\C-cb" 'python-black-region))
(use-package recentf
:custom
(recentf-max-saved-items 500)
(recentf-auto-cleanup "05:00am")
(recentf-exclude '(file-remote-p))
:config
(defun ava/recentf-cleanup-silent (fun)
"Call `recentf-cleanup' suppressing messages."
(let (message-log-max (inhibit-message t)) (funcall fun)))
(advice-add 'recentf-cleanup :around #'ava/recentf-cleanup-silent)
(recentf-mode t))
(use-package smart-comment
:ensure t
:bind ("M-;" . smart-comment))
(use-package transpose-frame
:ensure t
:bind (("C-x |" . rotate-frame-clockwise)
("C-x \\" . rotate-frame-anticlockwise)))
(use-package treesit
:if (version<= "29" emacs-version)
:ensure nil
:custom
(treesit-font-lock-level 4))
(use-package treesit-auto
:if (version<= "29" emacs-version)
:ensure t
:custom
(treesit-auto-install 'prompt)
:config
(setq treesit-auto-langs (delete 'python treesit-auto-langs))
(treesit-auto-add-to-auto-mode-alist 'all)
(setq c-ts-base-mode-hook c-mode-common-hook)
(global-treesit-auto-mode))
(use-package undo-tree
:ensure t
:diminish undo-tree-mode
:custom
(undo-tree-auto-save-history nil)
(undo-tree-enable-undo-in-region nil)
(undo-tree-visualizer-diff t)
(undo-tree-visualizer-timestamps t)
(undo-tree-incompatible-major-modes '(term-mode vterm-mode))
:config
(global-undo-tree-mode))
use for opening files larger than large-file-warning-threshold
(use-package vlf
:ensure t
:custom
(vlf-save-in-place t)
:config
(require 'vlf-setup))
(use-package vterm
:ensure t
:config
(setq vterm-max-scrollback 100000)
(define-key vterm-mode-map (kbd "C-c C-j") 'vterm-copy-mode))
start a remote vterm
(defun ava/rvterm (hos)
"Start a dir-tracking vterm on hos (or host at point if host is nil)"
(interactive "P")
(let* ((host (or hos (thing-at-point 'sexp)))
(user (getenv "USER"))
(bname (format "*vterm %s*" host)))
(vterm bname)
(switch-to-buffer bname)
(let* ((inhibit-read-only t)
(sshcmd (format "ssh -Y %s@%s" user host))
(fn1cmd "function vterm_printf() { \n printf \"\\e]%s\\e\\\\\" \"$1\" \n}")
(fn2cmd "function vterm_prompt_end() { \n vterm_printf \"51;A$(whoami)@$(hostname):$(pwd)\" \n }")
(ps1cmd "PS1=$PS1\'\\[$(vterm_promt_end)\\]\'")
(bigcmd (format "%s\n%s\n%s\n%s\n" sshcmd fn1cmd fn2cmd ps1cmd)))
(vterm-send-string bigcmd t))))
start a few common vterms
(defun ava/start-vterms ()
"Start a few common vterms"
(interactive)
(let ((vterm-start-helper (lambda (name cmd)
(let ((bname (format "*vterm %s*" name)))
(if (eq nil (get-buffer bname))
(progn
(vterm bname)
(with-current-buffer bname
(let ((inhibit-read-only t))
(vterm-send-string (format "%s\n" cmd) t)))))))))
(save-window-excursion
(funcall vterm-start-helper "rand2" "")
(funcall vterm-start-helper "rand1" "")
(funcall vterm-start-helper "rand0" ""))))
(use-package webjump
:bind (("C-c j" . webjump))
:config
(setq webjump-sites '(("Emacs Wiki" . [simple-query "www.emacswiki.org" "www.emacswiki.org/cgi-bin/wiki/" ""])
("DuckDuckGo" . [simple-query "duckduckgo.com" "duckduckgo.com/?q=" ""])
("Google" . [simple-query "www.google.com" "www.google.com/search?q=" ""])
("Google Maps" . [simple-query "www.google.com/maps" "www.google.com/maps/search/" ""])
("Wikipedia" . [simple-query "wikipedia.org" "wikipedia.org/wiki/" ""])
("AUR" . [simple-query "https://aur.archlinux.org" "https://aur.archlinux.org/packages/?O=0&K=" ""]))))
- Execute one of the search commands like
projectile-ag
- Use
C-x C-s
to make permanent your search results to a buffer - Use
C-c C-p
within that result buffer to executewgrep-change-to-wgrep-mode
and now you can make edits to any lines you please (including regular emacs search-and-replace commands) - Use
C-c C-c
to save you changes, which will be promulgated to all files you’ve chosen to edit
(use-package wgrep
:ensure t
:custom
(wgrep-auto-save-buffer t)
:config
(use-package wgrep-helm :ensure t)
(use-package wgrep-deadgrep
:ensure t
:config
(add-hook 'deadgrep-finished-hook 'wgrep-deadgrep-setup)))
show options for bindings in realtime
(use-package which-key
:ensure t
:init
(which-key-mode))
magit uses this but can also use it to make crontab editing work from a running emacs
(use-package with-editor
:ensure t
:config
(defun ava/crontab ()
"Run `crontab -e` from an emacs buffer"
(interactive)
(with-editor-async-shell-command "crontab -e")))
automatically encloses double quotes or parens
(use-package wrap-region
:ensure t
:config
(wrap-region-global-mode t)
:diminish wrap-region-mode)
advantage over (add-hook 'before-save-hook #'delete-trailing-whitespace)
is that it does mess with others whitespace
(use-package ws-butler
:ensure t
:hook
(prog-mode . ws-butler-mode)
(text-mode . ws-butler-mode))
(use-package yasnippet
:ensure t
:diminish yas-minor-mode
:hook (prog-mode . yas-minor-mode))
(use-package yasnippet-snippets
:ensure t
:after yasnippet)
nice directory level diffing
(use-package ztree
:ensure t
:commands ztree-diff
:bind (:map ztree-mode-map
("j" . ztree-jump-side)))
;; (use-package auto-package-update
;; :ensure t
;; :if (not (daemonp))
;; :custom
;; (auto-package-update-interval 90)
;; (auto-package-update-prompt-before-update t)
;; (auto-package-update-delete-old-versions t)
;; (auto-package-update-hide-results t)
;; :config
;; (auto-package-update-maybe))
; (use-package clojure-mode
; :ensure t
; :mode
; (("\\.clj.*$" . clojure-mode)
; ("\\.edn.*$" . clojure-mode))
; :init
; (add-hook 'clojure-mode-hook #'yas-minor-mode)
; (add-hook 'clojure-mode-hook #'paredit-mode)
; (add-hook 'clojure-mode-hook #'eldoc-mode))
;
; ;pulls cider
; (use-package clj-refactor
; :ensure t
; :defer t
; :diminish clj-refactor-mode
; :config
; (setq cljr-warn-on-eval nil)
; (cljr-add-keybindings-with-prefix "C-c C-m"))
;
; (use-package cider
; :ensure t
; :defer t
; :init
; (add-hook 'cider-mode-hook #'clj-refactor-mode)
; (add-hook 'cider-repl-mode-hook #'paredit-mode)
; :config
; (setq cider-repl-use-clojure-font-lock t
; cider-overlays-use-font-lock t
; cider-repl-display-help-banner nil
; cider-repl-pop-to-buffer-on-connect nil
; ;nrepl-log-messages t
; ;cider-preferred-build-tool "boot" ;(if no lein)
; ;cider-prompt-save-file-on-load 'always-save
; ;cider-font-lock-dynamically '(macro core function var)
; ;nrepl-hide-special-buffers t
; )
; (cider-repl-toggle-pretty-printing))
;; (use-package discover-my-major
;; :ensure t
;; :bind (("C-h C-m" . discover-my-major)
;; ("C-h C-d" . discover-my-mode)))
to launch applications from exwm
;;(use-package dmenu
;; :ensure t
;; :bind
;; ("s-SPC" . dmenu))
Disabled as not snappy enough emacs-eaf AUR github
; (use-package eaf
; :load-path "/usr/share/emacs/site-lisp/eaf"
; :custom
; (eaf-find-alternate-file-in-dired t)
; (browse-url-browser-function 'eaf-open-browser)
; :config
; (eaf-setq eaf-pdf-default-zoom 1.25)
; (eaf-setq eaf-browser-enable-adblocker "true")
; (eaf-bind-key nil "SPC" eaf-browser-keybinding)
; (eaf-bind-key nil "p" eaf-browser-keybinding)
; (defun adviser-find-file (orig-fn file &rest args)
; (let ((fn (if (commandp 'eaf-open) 'eaf-open orig-fn)))
; (pcase (file-name-extension file)
; ("pdf" (apply fn file nil))
; ("epub" (apply fn file nil))
; (_ (apply orig-fn file args)))))
; (advice-add #'find-file :around #'adviser-find-file))
;; (use-package ement
;; :ensure t
;; :custom
;; (ement-save-sessions t))
use M-x erc-tls
to start
;; (use-package erc
;; :ensure t
;; :preface
;; (defun ava/erc-quit ()
;; "Kill ERC buffers and terminate its child process."
;; (interactive)
;; (let ((kill-buffer-query-functions nil)
;; (erc-buffers (erc-buffer-list)))
;; (dolist (buffer erc-buffers) (kill-buffer buffer)))
;; (erc-buffer-list))
;; :init
;; (require 'erc-autoaway)
;; :custom
;; (erc-lurker-hide-list '("PART" "QUIT" "JOIN"))
;; (erc-server "irc.libera.chat")
;; (erc-nick "hooxen")
;; (erc-join-buffer 'buffer)
;; (erc-interpret-mirc-color t)
;; (erc-server-reconnect-timeout 10)
;; (erc-autoaway-idle-seconds 600)
;; :config
;; (add-hook 'erc-text-matched-hook #'(lambda (match-type nickuserhost msg)
;; (shell-command-to-string (format "notify-send erc '%s'" msg))))
;; (use-package erc-colorize
;; :ensure t
;; :config (erc-colorize-mode 1)))
;; (use-package expand-region
;; :ensure t
;; :bind
;; (("C-=" . er/expand-region)
;; :map mode-specific-map
;; :prefix-map region-prefix-map
;; :prefix "r"
;; ("(" . er/mark-inside-pairs)
;; (")" . er/mark-outside-pairs)
;; ("'" . er/mark-inside-quotes)
;; ([34] . er/mark-outside-quotes) ; "
;; ("o" . er/mark-org-parent)
;; ("u" . er/mark-url)
;; ("b" . er/mark-org-code-block)
;; ("." . er/mark-method-call)
;; ("w" . er/mark-word)
;; ("d" . er/mark-defun)
;; ("s" . er/mark-symbol)
;; (";" . er/mark-comment)
;; ("S" . er/mark-sentence)
;; ("P" . er/mark-paragraph)))
;;(use-package exwm :ensure t
;; :init
;; :config
;; (setq exwm-workspace-number 4)
;; (defun exwm-rename-buffer-to-title () (exwm-workspace-rename-buffer exwm-title))
;; (add-hook 'exwm-update-title-hook 'exwm-rename-buffer-to-title)
;; (exwm-input-set-key (kbd "s-r") #'exwm-reset)
;; (exwm-input-set-key (kbd "s-w") #'exwm-workspace-switch)
;; (dotimes (i 10)
;; (exwm-input-set-key (kbd (format "s-%d" i))
;; `(lambda ()
;; (interactive)
;; (exwm-workspace-switch-create ,i))))
;; (exwm-input-set-key (kbd "s-&")
;; (lambda (command)
;; (interactive (list (read-shell-command "$ ")))
;; (start-process-shell-command command nil command)))
;; (setq exwm-input-simulation-keys
;; '(([?\C-b] . [left])
;; ([?\C-f] . [right])
;; ([?\C-p] . [up])
;; ([?\C-n] . [down])
;; ([?\C-a] . [home])
;; ([?\C-e] . [end])
;; ([?\M-v] . [prior])
;; ([?\C-v] . [next])
;; ([?\C-d] . [delete])
;; ([?\C-k] . [S-end delete])
;; ([?\C-s] . [?\C-f])
;; ([?\C-t] . [?\C-n])))
;; (exwm-enable)
;; )
replaces default narrow (slow so not in use)
; (use-package fancy-narrow
; :ensure t
; :init
; (fancy-narrow-mode)
; :diminish fancy-narrow-mode)
; (use-package iedit
; :ensure t
; :bind ("C-;" . iedit-mode)
; :config
; (setq iedit-toggle-key-default nil)
; (define-key iedit-mode-occurrence-keymap (kbd "RET") 'iedit-mode)
; :diminish)
Also run M-x irony-install-server
which just needs cmake, libclang, and llvm libs (using eglot instead)
; (use-package irony
; :disabled
; :ensure t
; :init
; (add-hook 'c++-mode-hook 'irony-mode)
; (add-hook 'c-mode-hook 'irony-mode)
; (add-hook 'objc-mode-hook 'irony-mode)
; (setq-default irony-cdb-compilation-databases '(irony-cdb-libclang
; irony-cdb-json
; irony-cdb-clang-complete))
; :bind (:map irony-mode-map
; ("C-c t" . irony-get-type))
; :config
; (defun ava/irony-mode-hook ()
; (define-key irony-mode-map [remap completion-at-point]
; 'irony-completion-at-point-async)
; (define-key irony-mode-map [remap complete-symbol]
; 'irony-completion-at-point-async))
; (add-hook 'irony-mode-hook 'ava/irony-mode-hook)
; (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
; (add-hook 'irony-mode-hook 'company-irony-setup-begin-commands)
; (add-hook 'irony-mode-hook #'irony-eldoc)
; (use-package irony-eldoc
; :ensure t))
on MELPA from here leetcode
; (use-package leetcode
; :disabled
; :ensure t
; :config
; (setq leetcode-prefer-language "cpp")
; (setq leetcode-prefer-sql "mysql"))
Some references here: ccls + lsp example A example B and B2 example C goodies lsp-ui goodies lsp-ui more goodies how-to-turn-off example D
Only use lsp with flycheck (rather than hook, manual enable via ==M-x lsp==)
;; (use-package lsp-mode
;; :ensure t
;; :after flycheck
;; :commands lsp
;; :bind
;; (:map lsp-mode-map
;; ([remap xref-find-references] . lsp-find-references)
;; ([remap xref-find-definitions] . lsp-find-definition))
;; :custom
;; (lsp-keymap-prefix "C-c u")
;; (lsp-auto-configure t)
;; (lsp-eldoc-hook nil)
;; (lsp-eldoc-enable-hover t)
;; (lsp-diagnostics-provider :none)
;; (lsp-enable-symbol-highlighting nil)
;; (lsp-headerline-breadcrumb-enable nil)
;; (lsp-lens-enable t)
;; (lsp-modeline-code-actions-enable t)
;; (lsp-modeline-diagnostics-enable nil)
;; (lsp-signature-render-documentation t)
;; (lsp-completion-show-kind t)
;; (lsp-completion-show-detail t)
;; (lsp-enable-file-watchers t)
;; (lsp-file-watch-threshold nil)
;; (lsp-enable-xref t)
;; (lsp-enable-imenu t)
;; (lsp-enable-folding nil)
;; (lsp-enable-links nil)
;; (read-process-output-max (* 1024 1024))
;; ;:config
;; ;(define-key lsp-mode-map (kbd "C-c u") 'lsp-describe-thing-at-point)
;; )
;; (use-package lsp-ui
;; :ensure t
;; :after lsp-mode flycheck
;; :diminish
;; :commands lsp-ui-mode
;; :bind
;; (:map lsp-ui-mode-map
;; ;("C-c u" . lsp-ui-imenu)
;; ;("C-c C-d" . lsp-ui-doc-glance)
;; ("C-c d" . lsp-ui-doc-show)
;; ("M-i" . lsp-ui-doc-focus-frame))
;; :custom
;; (lsp-ui-peek-enable t)
;; (lsp-ui-doc-enable t)
;; (lsp-ui-doc-alignment 'window)
;; (lsp-ui-doc-header t)
;; (lsp-ui-doc-max-height 45)
;; (lsp-ui-doc-position 'at-point)
;; (lsp-ui-doc-show-with-mouse nil)
;; (lsp-ui-doc-show-with-cursor nil)
;; (lsp-ui-doc-include-signature t)
;; (lsp-ui-doc-border (face-foreground 'default))
;; (lsp-ui-sideline-enable t)
;; (lsp-ui-sideline-ignore-duplicate t)
;; (lsp-ui-sideline-show-code-actions nil)
;; (lsp-ui-sideline-show-diagnostics nil)
;; (lsp-ui-sideline-show-hover nil))
;;(use-package company-lsp
;; :ensure t
;; :custom (company-lsp-cache-candidates 'auto))
The smtp portion will require app specific password and will store it in ~/.authinfo after first use
;; (use-package mu4e
;; :load-path "/usr/share/emacs/site-lisp/mu4e"
;; :config
;; (setq mu4e-maildir (expand-file-name "~/mbsync"))
;; (setq mu4e-sent-folder "/sent")
;; (setq mu4e-drafts-folder "/drafts")
;; (setq mu4e-trash-folder "/trash")
;; ;;GMail/IMAP takes care of this
;; (setq mu4e-sent-messages-behavior 'delete)
;; (setq mu4e-get-mail-command "mbsync -q gmail")
;; (setq mu4e-update-interval 3600)
;; (setq mu4e-maildir-shortcuts
;; '(("/INBOX" . ?i)
;; ("/sent" . ?s)))
;; (setq mu4e-view-show-images t)
;; (setq mu4e-use-fancy-chars t)
;; (setq mu4e-view-show-addresses t)
;; (setq mu4e-headers-show-threads nil)
;; )
;; (require 'smtpmail)
;; (setq message-send-mail-function 'smtpmail-send-it
;; user-mail-address "[email protected]"
;; smtpmail-smtp-user "email_username"
;; smtpmail-local-domain "gmail.com"
;; smtpmail-default-smtp-server "smtp.gmail.com"
;; smtpmail-smtp-server "smtp.gmail.com"
;; smtpmail-smtp-service 587)
a second reference setup (works with outlook)
;; (use-package mu4e
;; :load-path "path/to/mu4e/lisp"
;; :bind (("C-c 2" . mu4e))
;; :custom
;; (mu4e-mu-home "/path/to/mu/index/if/not/homedir")
;; (mu4e-mu-binary "path/to/mu/binary/if/not/in/path")
;; (mu4e-sent-folder "/sent")
;; (mu4e-drafts-folder "/drafts")
;; (mu4e-trash-folder "/trash")
;; (mu4e-get-mail-command "mbsync -q work")
;; (mu4e-update-interval 180)
;; (mu4e-sent-messages-behavior 'delete)
;; (mu4e-maildir-shortcuts '(("/Inbox" . ?i) ("/sent" . ?s)))
;; :config
;; (setq mu4e-headers-show-threads nil)
;; (setq mail-user-agent 'mu4e-user-agent) ;C-x m uses mu4e
;; (progn ; SMTP
;; (require 'smtpmail)
;; (setq message-send-mail-function 'smtpmail-send-it
;; smtpmail-default-smtp-server "foo.com"
;; smtpmail-smtp-server "foo.com"))
;; (progn ; Calendar
;; (require 'mu4e-icalendar)
;; (mu4e-icalendar-setup)
;; (setq gnus-icalendar-org-capture-file "~/calendar.org"
;; gnus-icalendar-org-capture-headline '("calendar"))
;; (gnus-icalendar-org-setup)))
;; (use-package org-projectile
;; :ensure t
;; :after org
;; :custom
;; (org-projectile-capture-template "* TODO %^{title}\n%?")
;; :config
;; (add-to-list 'org-capture-templates (org-projectile-project-todo-entry :capture-heading "project todo")))
;; (use-package helm-org :ensure t)
;; (use-package org-projectile-helm
;; :ensure t
;; :after (org-projectile helm-org))
; (use-package rmsbolt
; :disabled
; :ensure t)
; (use-package speed-type
; :ensure t
; :disabled
; :commands (speed-type-text))
;; (use-package stan-mode
;; :ensure t)
;; (use-package company-stan
;; :ensure t
;; :hook (stan-mode . company-stan-setup))
;; (use-package eldoc-stan
;; :ensure t
;; :hook (stan-mode . eldoc-stan-setup))
;; (use-package switch-window
;; :ensure t
;; :bind (("C-x o" . switch-window))
;; :config
;; (setq switch-window-shortcut-style 'qwerty)
;; (setq switch-window-qwerty-shortcuts '("a" "s" "d" "f" "j" "k" "l" "w" "e" "i" "o"))
; (setq switch-window-minibuffer-shortcut ?z))
Telegram support from emacs (needs visual-fill-column)
; (use-package visual-fill-column :ensure t)
; (require 'notifications)
; (use-package telega
; :disabled
; :load-path "~/3rdParty/telega/"
; :commands (telega)
; :config
; (setq telega-use-notifications t)
; (add-hook 'telega-chat-mode-hook (lambda ()
; (setq company-backends '(telega-company-emoji))
; (company-mode 1)))
; :defer t)
make line-mode the default for terms and allow bigger buffer size
; (setq term-buffer-maximum-size 262144)
; (defun ava/default-term-line-mode (&ret ignore) (term-line-mode))
; (advice-add 'ansi-term :after #'ava/default-term-line-mode)
ansi-term defaults to bash
;(defvar my-term-shell "/bin/bash")
;(defadvice ansi-term (before force-bash)
; (interactive (list my-term-shell)))
;(ad-activate 'ansi-term)
start a remote term https://www.emacswiki.org/emacs/AnsiTermHints#toc4
; (defun ava/raterm ()
; (interactive)
; (setq user (read-string "User: "))
; (setq host (read-string "Host: "))
; (setq term-ansi-buffer-name (concat "term " host))
; (setq term-ansi-buffer-name (generate-new-buffer-name term-ansi-buffer-name))
; (setq term-ansi-buffer-name (apply 'make-term term-ansi-buffer-name "ssh" nil (list (concat user "@" host))))
; (set-buffer term-ansi-buffer-name)
; (term-mode)
; (term-line-mode)
; (term-set-escape-char ?\C-x)
; (switch-to-buffer term-ansi-buffer-name)
; (insert "function set-eterm-dir { \n echo -e \"\\033AnSiTu\" \"$LOGNAME\" \n echo -e \"\\033AnSiTc\" \"$(pwd)\" \n echo -e \"\\033AnSiTh\" \"$(hostname -f)\" \n history -a \n }")
; (insert "\nPROMPT_COMMAND=set-eterm-dir\n")
; (term-send-input))
start a few common terms
; (defun ava/start-ansi-terms ()
; "Start a few common ansi terms"
; (interactive)
; (let ((term-start-helper (lambda (name cmd)
; (ansi-term "/bin/bash" (format "bash.%s" name))
; (with-current-buffer (format "*bash.%s*" name)
; (insert (format "%s\n" cmd))
; (term-send-input)))))
; (save-window-excursion
; ;only shells for now
; (funcall term-start-helper "rand0" "")
; (funcall term-start-helper "rand1" "")
; (funcall term-start-helper "rand2" ""))))
(this is built in as treesit
after emacs 29)
https://emacs-tree-sitter.github.io/installation/
;; (use-package tree-sitter-langs :ensure t)
;; (use-package tree-sitter
;; :ensure t
;; :after tree-sitter-langs
;; :config
;; (global-tree-sitter-mode)
;; (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
reference: visual-fill-column (to center code in wide monitors)
; (defun ava/visual-fill-column-and-center ()
; (setq visual-fill-column-center-text t
; visual-fill-column-width 134)
; (visual-fill-column-mode 1))
;
; (use-package visual-fill-column
; :hook (prog-mode . ava/visual-fill-column-and-center))