This file re-organises the old init files
Backup existing ~/.emacs.d
, and then follow by
git clone https://github.com/yang-l/emacs.d.git ~/.emacs.d
Path to non ELPA included lisp files
(add-to-list 'load-path "~/.emacs.d/lisp/")
Path to personal/credential info in ~/.emacs.d/private.el
(defvar default-directory ; default folder
(concat (getenv "HOME") "/"))
(defvar my-win-default-directory default-directory)
(defvar my-lin-default-directory default-directory)
(defvar my-erc-nick "") ; ERC
(defvar my-erc-user-full-name "")
(defvar my-erc-email-userid "")
(defvar my-op/repository-directory "") ; org-page
(defvar my-op/site-domain "")
(defvar my-op/personal-github-link "")
;; override
(when (file-exists-p (concat user-emacs-directory "private.el"))
(load (expand-file-name "private.el" user-emacs-directory) 'no-error))
straight.el
defined in init.el
Call pp-macroexpand-last-sexp
to check the expanded macro done by use-package
use-package
related delay-hook
stuffs
;; https://github.com/jwiegley/use-package/issues/889
;; https://github.com/Ergus/EmacsConfig/blob/master/early-init.el
(defvar lo/gc-cons-default (* 1024 1024 32))
(defvar lo/gc-cons-lsp (* 1024 1024 128))
(defsubst lo/unset-gc ()
"Defer garbage collection"
(setq gc-cons-threshold most-positive-fixnum))
(use-package gcmh
:defer 3
:diminish
:demand t
:config (gcmh-mode 1))
;; benchmarking emacs boot sequence
(use-package benchmark-init
:disabled ; by default
:config
;; To disable collection of benchmark data after init is done.
(add-hook 'after-init-hook 'benchmark-init/deactivate))
Configuration for use-package
. The packages below should be loaded first before any use-package
has been invoked
(defvar backup-directory ; backup and autosave directory
(if (eq system-type 'windows-nt) ; Windows
(concat "C:/tmp/emacs/" (user-login-name) "/")
(expand-file-name
(concat "~/emacs/" (user-login-name) "/")) ; Linux & Mac
))
(if (not (file-exists-p backup-directory))
(make-directory backup-directory t))
(use-package no-littering ; keep `litter` files in one location
:init
(setq no-littering-var-directory (expand-file-name (convert-standard-filename "cache/var/") backup-directory)
no-littering-etc-directory (expand-file-name (convert-standard-filename "cache/etc/") backup-directory))
)
(use-package diminish) ; shorten mode-line
(prefer-coding-system 'utf-8-unix) ; UTF-8 on everything
(unless (eq system-type 'windows-nt)
(set-selection-coding-system 'utf-8))
(setq x-select-request-type ; pasting
'(UTF8_STRING COMPOUND_TEXT TEXT STRING))
(setq-default
ad-redefinition-action 'accept ; silence functions getting redefined messages
column-number-mode t ; show cursor position
custom-file ; save customisations into a sibling file
(no-littering-expand-etc-file-name "custom.el")
default-major-mode 'text-mode ; set new buffers as text files
enable-recursive-minibuffers t ; enable minibuffer recursive
fill-column 80 ; column space
frame-title-format "emacs@%b" ; show on title
indent-tabs-mode nil ; space instead of tab
kill-ring-max 1000 ; kill ring size
mouse-wheel-scroll-amount '(1 ((shift) .1)) ; scroll one line at a time
frame-resize-pixelwise t
read-buffer-completion-ignore-case t ; ignore case-sensitivity
read-file-name-completion-ignore-case t
require-final-newline t ; always add a new line at the end of a file
save-interprogram-paste-before-kill t ; put clipboard into killring
scroll-margin 3 ; auto scrolling
scroll-step 1 ; line-by-line scrolling
scroll-conservatively 10000 ; do not jump to centre point in the window
scroll-preserve-screen-position t ; make the cursor steady when scrolling
tab-width 2 ; 2 space indentation
visible-bell 1 ; no bell in windows
window-combination-resize t ; split windows equally
x-stretch-cursor t ; stretch cursor to cover wide characters
vc-follow-symlinks t ; visiting a symbolic link to a file under version control
)
(fset 'yes-or-no-p 'y-or-n-p) ; fast confirmation
;; tuning for very long line
(setq-default bidi-display-reordering nil)
(setq bidi-inhibit-bpa t
long-line-threshold 1000
large-hscroll-threshold 1000
syntax-wholeline-max 1000)
(use-package exec-path-from-shell
:defer 0.1
:custom (exec-path-from-shell-arguments '("-l"))
:config
(when (eq system-type 'darwin) ; only apply to under OSX graphic and console UI
(setq exec-path-from-shell-arguments nil
exec-path-from-shell-check-startup-files nil)
(exec-path-from-shell-initialize))
(exec-path-from-shell-copy-env "SSH_AGENT_PID") ; inherent ssh-agent from system
(exec-path-from-shell-copy-env "SSH_AUTH_SOCK")
(setenv "PATH"
(concat
(getenv "PATH")
))
)
Run Emacs as a daemon, and edit via emacsclient
. emacsclient -t
for terminal / emacsclient -c
for graphic
(use-package server
:disabled
:defer 1
:config
(unless (and (fboundp 'server-running-p)
(server-running-p))
(server-start)))
Use the stock key bindings when possible.
(global-unset-key (kbd "C-SPC")) ; set-mark-command
(global-unset-key (kbd "C-x f")) ; set-fill-column
(global-unset-key (kbd "C-z")) ; suspend-frame
passing tmux keystrokes within emacs terminal
(defadvice terminal-init-screen
;; The advice is named `tmux', and is run before `terminal-init-screen' runs.
(before tmux activate)
;; Docstring. This describes the advice and is made available inside emacs;
;; for example when doing C-h f terminal-init-screen RET
"Apply xterm keymap, allowing use of keys passed through tmux."
;; This is the elisp code that is run before `terminal-init-screen'.
(if (getenv "TMUX")
(let ((map (copy-keymap xterm-function-map)))
(set-keymap-parent map (keymap-parent input-decode-map))
(set-keymap-parent input-decode-map map))))
OSX-only key bindings
(when (eq system-type 'darwin) ; mac only settings
(setq mac-option-modifier 'meta
mac-right-option-modifier 'alt)) ; only work under gui
(defvar browser-path
(cond
((executable-find "firefox")
"firefox")
((executable-find "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")))
(setq browse-url-browser-function 'browse-url-generic ; default browser
browse-url-generic-program browser-path)
(add-hook 'window-setup-hook
#'(lambda () (progn
(mouse-avoidance-mode 'animate) ; mouse avoidance
(when (fboundp ; windmove
'windmove-default-keybindings)
(windmove-default-keybindings)
(with-eval-after-load `switch-window
(advice-add #'windmove-do-window-select
:after
#'(lambda (&rest args)
"Auto-reszie the window size"
(switch-window--auto-resize-window)))))
(setq eval-expression-print-length nil ; do not truncate output in the echo area
message-log-max 10000 ; increase number of lines in *Messages*
use-dialog-box nil) ; disable usage of dialog box, and in echo area instead
)))
(dolist
(hook
(list
'term-exec-hook
))
(add-hook hook #'redraw-display)) ; force redraw
(add-hook 'window-setup-hook
#'(lambda ()
(toggle-frame-fullscreen) ; fullscreen
(toggle-frame-maximized)) ; maximised
t)
(when (daemonp) ; when calling "emacsclient -c -n" under daemon
(add-hook 'after-make-frame-functions
#'(lambda (frame)
(when (display-graphic-p frame)
(toggle-frame-fullscreen) ; fullscreen
(toggle-frame-maximized) ; maximised
))
))
; https://blog.d46.us/advanced-emacs-startup/
(add-hook 'emacs-startup-hook
#'(lambda ()
(message "Emacs ready in %s with %d garbage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done)))
(run-with-idle-timer 2 nil #'(lambda () (with-eval-after-load `gcmh (setq gcmh-high-cons-threshold lo/gc-cons-default)))) ; https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/
; https://emacs.stackexchange.com/questions/32150/how-to-add-a-timestamp-to-each-entry-in-emacs-messages-buffer
(advice-add 'message :before ; add timestamp in *Messages* buffer
#'(lambda (FORMAT-STRING &rest args)
"Advice to run before `message' that prepends a timestamp to each message."
(if message-log-max
(let ((deactivate-mark nil)
(inhibit-read-only t))
(with-current-buffer "*Messages*"
(goto-char (point-max))
(if (not (bolp))
(newline))
(insert (format-time-string "[%F %T.%3N %:z] ")))))
))
(unless (display-graphic-p) (mouse-wheel-mode 0)) ; disable 'mouse-wheel-mode' under character-based terminal
(setq default-directory
(if (eq system-type 'windows-nt)
my-win-default-directory ; Win
my-lin-default-directory ; Linux/Mac
))
(setq backup-directory-alist `((".*" . ,backup-directory))
auto-save-list-file-prefix backup-directory
auto-save-file-name-transforms `((".*" ,backup-directory t)))
(setq make-backup-files t ; backup of a file the first time it is saved.
backup-by-copying t ; don't clobber symlinks
version-control t ; version numbers for backup files
delete-old-versions t ; delete excess backup files silently
kept-old-versions 5 ; oldest versions to keep when a new numbered backup is made (default: 2)
kept-new-versions 15 ; newest versions to keep when a new numbered backup is made (default: 2)
auto-save-default t ; auto-save every buffer that visits a file
auto-save-timeout 10 ; number of seconds idle time before auto-save (default: 30)
auto-save-interval 200 ; number of keystrokes between auto-saves (default: 300)
vc-make-backup-files t ; backup versioned files
)
; ignore file backups @ http://stackoverflow.com/questions/482256/
(defvar my-backup-ignore-regexps (list "\\.vcf$" "\\.gpg$")
"*List of filename regexps to not backup")
(defun my-backup-enable-p (name)
"Filter certain file backups"
(when (normal-backup-enable-predicate name)
(let ((backup t))
(mapc (lambda (re)
(setq backup (and backup (not (string-match re name)))))
my-backup-ignore-regexps)
backup)))
(setq backup-enable-predicate 'my-backup-enable-p)
Note - the .#foo
files are file locks, and #foo#
files are cached for auto-save (info)
savehist - save the minibuffer histories
(use-package savehist
:defer 0.5
:hook (window-setup . (lambda () (savehist-mode 1)))
:config
(setq-default savehist-additional-variables '(kill-ring search-ring regexp-search-ring extended-command-history)
savehist-autosave-interval 60
history-length 10000))
(defun create-non-existent-directory ()
(let ((parent-directory (file-name-directory buffer-file-name)))
(when (and (not (file-exists-p parent-directory))
(y-or-n-p (format "Directory `%s' does not exist! Create it?" parent-directory)))
(make-directory parent-directory t))))
(add-to-list 'find-file-not-found-functions #'create-non-existent-directory)
(use-package abbrev
:bind (("M-/" . dabbrev-completion)
("C-M-/" . dabbrev-expand))
:diminish
:straight (:type built-in)
:custom
(save-abbrevs 'silently)
(dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'"))
:config (if (file-exists-p abbrev-file-name) (quietly-read-abbrev-file)))
Open compressed files on the fly
(use-package jka-cmpr-hook
:hook (window-setup . auto-compression-mode)
:straight (:type built-in))
(cl-loop for fn in '(downcase-region ; enable commands
upcase-region
erase-buffer)
do (put fn 'disabled nil))
Command interpreter
(use-package comint
:disabled
:hook (comint-mode . (lambda () (setq comint-scroll-show-maximum-output nil)))
:straight (:type built-in))
(use-package dired
:disabled
:straight (:type built-in)
:config
(load "dired-x")
;; http://emacswiki.org/emacs/DiredOmitMode
(setq-default dired-omit-files-p t)
(setq dired-omit-files
(concat dired-omit-files "\\|^\\..+$"))
(when (string= system-type "darwin")
(setq dired-use-ls-dired nil))
;; http://ann77.emacser.com/Emacs/EmacsDiredExt.html
;; 排序功能
(make-local-variable 'dired-sort-map)
(setq dired-sort-map (make-sparse-keymap))
(define-key dired-mode-map "s" dired-sort-map)
(define-key dired-sort-map "s"
'(lambda () "sort by Size"
(interactive) (dired-sort-other (concat dired-listing-switches "S"))))
(define-key dired-sort-map "x"
'(lambda () "sort by eXtension"
(interactive) (dired-sort-other (concat dired-listing-switches "X"))))
(define-key dired-sort-map "t"
'(lambda () "sort by Time"
(interactive) (dired-sort-other (concat dired-listing-switches "t"))))
(define-key dired-sort-map "n"
'(lambda () "sort by Name"
(interactive) (dired-sort-other (concat dired-listing-switches ""))))
;; http://www.emacswiki.org/emacs/DiredSortDirectoriesFirst
(defun mydired-sort ()
"Sort dired listings with directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2) ;; beyond dir. header
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))
(set-buffer-modified-p nil)))
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort))
;; single buffer
(put 'dired-find-alternate-file 'disabled nil)
;; http://www.emacswiki.org/emacs/DiredReuseDirectoryBuffer
(define-key dired-mode-map (kbd "^")
(lambda () (interactive) (find-alternate-file "..")))
;; http://ergoemacs.org/emacs/emacs_dired_tips.html
(define-key dired-mode-map (kbd "<return>")
'dired-find-alternate-file)
;; copy split windows
;; C-o / C-0 o to paste the original filename
;; https://appsmth.appspot.com/smth/subject/Emacs/94609
(setq dired-dwim-target t)
(setq dired-recursive-deletes 'top ; recursive delection
dired-recursive-copies 'always) ; recursive copy
(defadvice shell-command ; allow running multiple async commands simultaneously
(after shell-in-new-buffer
(command &optional output-buffer error-buffer))
(when (get-buffer "*Async Shell Command*")
(with-current-buffer "*Async Shell Command*"
(rename-uniquely))))
(ad-activate 'shell-command)
)
Call ediff
or ediff3
in Emace for file comparisons
(use-package ediff
:commands (ediff ediff3)
:hook (ediff-before-setup . (lambda () (setq ediff-saved-window-configuration (current-window-configuration))))
:custom
;; horizontal window split
(ediff-split-window-function 'split-window-horizontally)
(ediff-merge-split-window-function 'split-window-vertically)
(ediff-window-setup-function 'ediff-setup-windows-plain)
:init
(let ((restore-window-configuration
(lambda ()
(set-window-configuration ediff-saved-window-configuration))))
(add-hook 'ediff-quit-hook restore-window-configuration 'append)
(add-hook 'ediff-suspend-hook restore-window-configuration 'append))
)
(use-package gnutls
:disabled
:config
(setq-default gnutls-verify-error t) ; check tls/ssl
(cond
((string-equal system-type "darwin") ; Mac OS X
(progn
(add-to-list 'gnutls-trustfiles "/private/etc/ssl/cert.pem")
)))
)
Code folding
(use-package hideshow
:disabled
:diminish hs-minor-mode
:hook ((prog-mode) . hs-minor-mode))
Highlight the current line
(use-package hl-line
:hook (window-setup . global-hl-line-mode)
:init
(custom-set-faces
'(hl-line ((nil (:background "gray22"))))))
(use-package imenu
:disabled
:config
(set-default 'imenu-auto-rescan t)) ; automatic buffer rescan
new line number mode since Emacs 26
(use-package display-line-numbers
:hook ((prog-mode org-mode text-mode) . display-line-numbers-mode)
:custom
(display-line-numbers-type 'relative)
(display-line-numbers-width-start t)
:config
(set-face-foreground 'line-number "#5c5c5c")
(set-face-background 'line-number-current-line "#000000")
(set-face-foreground 'line-number-current-line "#ababab"))
build automation
(use-package make-mode
:mode (("\\Makefile\\'" . makefile-mode)
("\\.mk\\'" . makefile-mode)))
Markup language often for readme
(use-package markdown-mode
:commands (markdown-mode gfm-mode)
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:init (setq markdown-command "multimarkdown")
:custom
(markdown-fontify-code-blocks-natively t)
)
(cl-loop for fn in '(narrow-to-defun ; enable commands
narrow-to-page
narrow-to-region)
do (put fn 'disabled nil))
(with-eval-after-load `shell (setq-default shell-dirtrackp nil)); disable global 'shell-dirtrack-mode'
Terminal emulator inside Emacs
(use-package vterm :disabled)
(use-package vterm-toggle
:disabled
:custom
(vterm-toggle-scope 'project)
(vterm-toggle-hide-method 'reset-window-configration)
:hook
(vterm-toggle-show . meow-insert-mode))
(use-package saveplace
:defer 0.5
:init (setq save-place-file (expand-file-name "saveplace" no-littering-var-directory))
:hook (after-init . save-place-mode))
(use-package simple
:defer 1
:diminish visual-line-mode
:hook ((window-setup . visual-line-mode) ; soft line warpping
(window-setup . size-indication-mode)) ; show total buffer size
:straight (:type built-in))
M-x tramp-cleanup-all-connections
- flush remote connections
(use-package tramp
:init (autoload #'tramp-register-crypt-file-name-handler "tramp-crypt")
:config
(setq tramp-default-method "ssh" ; faster than the default scp
tramp-use-connection-share nil)
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
(tramp-set-completion-function
"ssh"
'((tramp-parse-sconfig "~/.ssh/config")
))
(add-to-list 'backup-directory-alist ; local backup directory for remote files
(cons tramp-file-name-regexp (expand-file-name backup-directory)))
)
(use-package uniquify
:defer 2
:straight (:type built-in)
:custom
(uniquify-buffer-name-style 'post-forward)
)
Buffer readonly mode
(use-package view
:bind([remap read-only-mode] . view-mode)) ; C-x C-q
(use-package which-func
:hook ((prog-mode) .
(lambda ()
(run-with-idle-timer
5 nil
#'(lambda ()
(unless (bound-and-true-p lsp-mode)
(which-function-mode))))))
:custom (which-func-unknown "⊥"))
Undo Emacs window changes
(use-package winner
:defer 2
:config (winner-mode))
(use-package misc
:commands zap-up-to-char
:bind ([remap zap-to-char] . zap-up-to-char) ; M-z
:straight (:type built-in))
Emacs GUI font settings - https://emacs-china.org/t/emacs/15676
(when (display-graphic-p)
(add-hook
'window-setup-hook
#'(lambda ()
(cond
((eq system-type 'windows-nt) ; Win
(set-face-attribute 'default nil :font "Consolas:antialias=natural" :height 100))
((eq system-type 'gnu/linux) ; Linux
(cond
((find-font (font-spec :name "Terminus"))
(set-face-attribute 'default nil :font "Terminus" :height 120))
((find-font (font-spec :maker "misc"
:family "fixed"
:widthtype "normal"
:pixels "14"
:height "130"
:horiz "75"
:vert "75"
)) ; fallback to "7x14" bitmap
; 7x14 / -misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1
(set-face-attribute 'default nil :font "7x14"))
)
(when (member "WenQuanYi Zen Hei Sharp" (font-family-list))
(set-fontset-font "fontset-default" ; 中文字体
'han '("WenQuanYi Zen Hei Sharp" . "unicode-bmp"))))
((eq system-type 'darwin) ; macOS
(set-face-attribute 'default nil :font "Monaco" :height 120))
(t ; default
(when (member "Inconsolata" (font-family-list))
(set-face-attribute 'default nil :font "Inconsolata" :height 120)))
)
)))
(when (daemonp) ; for emacsclient -c
(add-hook 'after-make-frame-functions
#'(lambda (frame)
(select-frame frame)
(cond
((eq system-type 'darwin) ; macOS
(set-face-attribute 'default nil :font "Monaco" :height 120))
(t ; default
(when (member "Inconsolata" (font-family-list))
(set-face-attribute 'default nil :font "Inconsolata" :height 120)))
)
)))
Spacemacs dark theme
(add-hook
'window-setup-hook
#'(lambda ()
;; when failed in use-package, remove `README.el*` and reopen this file again
(use-package spacemacs-theme
:defer t
:init
(custom-set-variables
'(spacemacs-theme-custom-colors
'((border . "#4f4f4f"))))
(load-theme 'spacemacs-dark t))
(when (eq system-type 'darwin) ; mac only
(when (display-graphic-p) ; gui only
(let ((win-sys (window-system)))
(when (eq win-sys 'ns) ; emacs ns port
(setq
x-colors (ns-list-colors) ; fix macports emacs-app port bug
ns-use-thin-smoothing t
)
)))
(when (daemonp) ; for emacsclient -c
(add-hook 'after-make-frame-functions
#'(lambda (frame)
(select-frame frame)
(when (display-graphic-p frame)
(let ((win-sys (window-system)))
(when (eq win-sys 'ns) ; emacs ns port
(setq
x-colors (ns-list-colors) ; fix macports emacs-app port bug
ns-use-thin-smoothing t
)
))))
))
)
))
(set-frame-parameter
(selected-frame) 'alpha '(98 98))
(defun modes/prog-mode ()
"prog-mode hook"
(setq
compilation-ask-about-save nil ; save before compiling
compilation-always-kill t ; always kill old compile processes before
; starting the new one
compilation-scroll-output 'first-error ; Automatically scroll to first error
)
(goto-address-prog-mode) ; highlight URL
(push '(">=" . ?≥) prettify-symbols-alist) ; prettify symbols
(push '("<=" . ?≤) prettify-symbols-alist)
(push '("delta" . ?Δ) prettify-symbols-alist)
(prettify-symbols-mode)
(local-set-key (kbd "RET") 'newline-and-indent)
; (defconst intellij-java-style ; coding style
; '((c-basic-offset . 4)
; (c-comment-only-line-offset . (0 . 0))
; (c-offsets-alist
; .
; ((inline-open . 0)
; (topmost-intro-cont . +)
; (statement-block-intro . +)
; (knr-argdecl-intro . +)
; (substatement-open . +)
; (substatement-label . +)
; (case-label . +)
; (label . +)
; (statement-case-open . +)
; (statement-cont . ++)
; (arglist-intro . 0)
; (arglist-cont-nonempty . ++)
; (arglist-close . --)
; (inexpr-class . 0)
; (access-label . 0)
; (inher-intro . ++)
; (inher-cont . ++)
; (brace-list-intro . +)
; (func-decl-cont . ++))))
; "Elasticsearch's Intellij Java Programming Style")
; (c-add-style "intellij" intellij-java-style)
)
(add-hook 'prog-mode-hook 'modes/prog-mode)
(add-hook 'before-save-hook #'delete-trailing-whitespace) ; remove trailing whitespace
(use-package quickrun :commands (quickrun quickrun-region quickrun-shell))
Respect to the .editorconfig
file in a project
(use-package editorconfig :diminish editorconfig-mode :hook (prog-mode . (lambda () (editorconfig-mode 1))))
(use-package apheleia :disabled :diminish apheleia-mode :hook (prog-mode . apheleia-mode))
(use-package separedit
:bind (:map prog-mode-map
("C-c \"" . separedit))
:custom
(separedit-buffer-creation-hook #'auto-fill-mode)
(separedit-continue-fill-column t)
(separedit-default-mode 'markdown-mode)
(separedit-preserve-string-indentation t)
(separedit-remove-trailing-spaces-in-comment t)
(separedit-write-file-when-execute-save t))
Code highlighting (for now)
(use-package tree-sitter
:diminish tree-sitter-mode
:hook (((enh-ruby-mode
go-mode
json-mode
sh-mode
typescript-mode) . tree-sitter-mode)
(tree-sitter-after-on . tree-sitter-hl-mode))
:config
(with-eval-after-load `enh-ruby-mode
(add-to-list 'tree-sitter-major-mode-language-alist '(enh-ruby-mode . ruby)))
)
(use-package tree-sitter-langs :after tree-sitter)
(use-package turbo-log
:after (:any go-mode typescript-mode)
:straight '(turbo-log :host github
:branch "master"
:repo "artawower/turbo-log.el")
:custom
(turbo-log-allow-insert-without-tree-sitter-p t)
(turbo-log-msg-format-template "\"%s\""))
(use-package git-gutter
:diminish git-gutter-mode
:hook ((prog-mode org-mode) . git-gutter-mode)
:custom
(git-gutter:update-interval 0.02)
:config
(custom-set-variables ; backend
'(git-gutter:handled-backends
(quote (git))))
)
(use-package magit
:bind (("C-x g" . magit-status))
:config
(setq magit-completing-read-function
(quote magit-builtin-completing-read)
magit-diff-refine-hunk t ; highlight changes
)
;; full screen magit-status
(defadvice magit-status (around magit-fullscreen activate)
(window-configuration-to-register :magit-fullscreen)
ad-do-it
(delete-other-windows))
)
(use-package autorevert :diminish auto-revert-mode)
web-mode
(use-package web-mode
:mode ("\\.html\\'" . web-mode)
:custom (web-mode-enable-css-colorization t))
(add-hook 'after-save-hook ; make shell script executable on save
'executable-make-buffer-file-executable-if-script-p)
(use-package eldoc
:diminish eldoc-mode
:hook ((eval-expression-minibuffer-setup prog-mode) . eldoc-mode) ; show eldoc for 'Eval:'
:init
(global-eldoc-mode -1) ; ignore eldoc globally
:config
(setq eldoc-idle-delay 0.2))
(use-package groovy-mode :mode "\\.groovy\\'\\|\\.gradle\\'")
(use-package ansible :disabled :diminish ansible :hook (yaml-mode . ansible))
(use-package es-mode :config (setq es-always-pretty-print t))
(use-package jinja2-mode :disabled)
(use-package json-mode :mode ("\\.json.erb\\'" . json-mode))
(use-package nix-mode)
(use-package puppet-mode :disabled)
Explore and test HTTP REST webservices
(use-package restclient
:mode ("\\.\\(http\\|https\\|rest\\)$" . restclient-mode)
:config
(defun restclient-ignore-ssl ()
"Ignore SSL verification. Identical to \=curl -k\="
(interactive)
(custom-reevaluate-setting 'gnutls-verify-error)
(make-local-variable 'gnutls-verify-error)
(setq gnutls-verify-error nil)
)
)
(use-package yaml-mode
:mode (("\\.ya?ml$" . yaml-mode)
("\\.ya?ml.erb\\'" . yaml-mode)))
(add-hook 'sql-interactive-mode-hook
(lambda ()
(toggle-truncate-lines t))) ; no line wrap when working on DB
;(defun modes/c-mode ()
; "c/c++ mode hook"
; (progn
; (setq gdb-many-windows t) ; gdb
; (local-set-key (kbd "C-c -") ; fold tag
; 'senator-fold-tag)
; (local-set-key (kbd "C-c +")
; 'senator-unfold-tag)
; (add-to-list (make-local-variable 'company-backends)
; '(company-gtags company-semantic))
; ))
;(dolist
; (hook
; (list
; 'c-mode-hook
; 'c++-mode-hook
; ))
; (add-hook hook #'modes/c-mode))
Helper function to create a Python virtualenv used for LSP servers
;(dolist
; (mode-hook
; '(python-mode-hook))
; (add-hook mode-hook
; #'(lambda ()
; (defun create-virtualenv (virtualenv-folder setup-cmd python-version requirement-file &optional version install-packages)
; "Create a python pip based virtualenv and install packages based on the supplied requirement file"
; (use-package pyvenv
; :commands pyvenv-activate
; :init
; (defvar python-virtualenv-directory (concat backup-directory virtualenv-folder))
; (if (not (file-exists-p python-virtualenv-directory))
; (progn
; (make-directory python-virtualenv-directory t)
; (shell-command
; (concat
; "bash" " "
; (expand-file-name (concat user-emacs-directory setup-cmd)) " "
; (expand-file-name (concat python-virtualenv-directory)) " "
; python-version " "
; (expand-file-name (concat user-emacs-directory requirement-file))
; (when version (concat " " version))
; (when install-packages (concat " " install-packages))
; ))
; ))
; (pyvenv-activate python-virtualenv-directory)
; (pyvenv-tracking-mode t)
; ))
; )))
Language Server Protocol
(use-package lsp-mode
:commands (lsp lsp-deferred)
:hook ((lsp-mode . (lambda ()
(let ((lsp-keymap-prefix "C-c l"))
#'lsp-enable-which-key-integration)
(advice-add 'lsp-completion--enable :after
#'(lambda ()
(setq-local completion-at-point-functions
(list
(cape-capf-buster
(cape-capf-super
#'tabnine-completion-at-point
#'lsp-completion-at-point)
'equal)))))))
(lsp-completion-mode . (lambda ()
(setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
'(orderless))))
(lsp-managed-mode . lsp-modeline-diagnostics-mode)
(dockerfile-mode . lsp-deferred)
(enh-ruby-mode . lsp-deferred)
(go-mode . lsp-deferred)
(js2-mode . lsp-deferred)
(json-mode . lsp-deferred)
(python-mode . lsp-deferred)
(sh-mode . lsp-deferred)
(terraform-mode . lsp-deferred)
(typescript-mode . lsp-deferred)
(yaml-mode . lsp-deferred))
:custom
(lsp-auto-guess-root t)
(lsp-client-packages '(lsp-bash
lsp-dockerfile
lsp-go
lsp-javascript
lsp-json
lsp-pyright
lsp-solargraph
lsp-terraform ; 'terraform' is managed by 'asdf'
; Nix installed lsp server won't do lookups properly
; require to manually install as =~/.config/local/bin/terraform-ls=
lsp-yaml))
(lsp-clients-typescript-server-args '("--stdio"))
(lsp-completion-provider :none) ; handled by corfu
(lsp-idle-delay 0.3)
(lsp-log-io nil)
(lsp-prefer-flymake nil)
(lsp-response-timeout 3)
(lsp-yaml-schema-store-local-db (expand-file-name (convert-standard-filename "lsp/lsp-yaml-schemas.json") no-littering-var-directory)) ; lsp-yaml
:config
(define-key lsp-mode-map (kbd "C-c l") lsp-command-map)
(with-eval-after-load `lsp-mode
(run-with-idle-timer
5 nil #'(lambda ()
(with-eval-after-load `gcmh
(setq gcmh-high-cons-threshold lo/gc-cons-lsp)) ; performance tuning @ https://emacs-lsp.github.io/lsp-mode/page/performance/
(setq read-process-output-max (* 1024 1024 4)))))
(when (derived-mode-p 'enh-ruby-mode)
(with-eval-after-load `lsp-solargraph
; load libraries
(add-to-list 'lsp-solargraph-library-directories (expand-file-name "~/.asdf/installs/ruby/"))
(add-to-list 'lsp-solargraph-library-directories
(concat (expand-file-name (shell-command-to-string "( git rev-parse --show-toplevel 2> /dev/null || echo $(pwd) ) | tr -d $'\n'")) "/vendor/bundle/"))
))
;; Use lsp servers from PATH installed by Nix
(with-eval-after-load 'lsp-json (lsp-dependency 'vscode-json-languageserver `(:system ,(executable-find "vscode-json-languageserver"))))
;; ignore directories on lsp file watcher
(with-eval-after-load 'lsp-mode
(let* ((proj-root (lsp-workspace-root))
(ignore-folders (list ".terragrunt-cache")))
(when proj-root
(dolist (folder ignore-folders)
(dolist (f (directory-files-recursively proj-root folder t))
(add-to-list 'lsp-file-watch-ignored-directories f)))))
(add-to-list 'lsp-file-watch-ignored-directories (expand-file-name "~/.asdf")))
)
(use-package lsp-pyright
:after lsp-mode
:config (when (executable-find "python3") (setq lsp-pyright-python-executable-cmd "python3")))
(use-package lsp-diagnostics :after lsp-mode :straight lsp-mode)
(use-package lsp-headerline :after lsp-mode :straight lsp-mode)
(use-package lsp-lens
:after lsp-mode
:straight lsp-mode
:custom
(lsp-lens-debounce-interval 0.5)
(lsp-lens-enable t))
(use-package lsp-modeline
:after lsp-mode
:straight lsp-mode
:custom
(lsp-modeline-code-actions-segments '(count icon name)))
(use-package lsp-ui
:after (lsp-mode yasnippet)
:bind-keymap ("C-c l" . lsp-command-map)
:bind ((:map lsp-ui-mode-map
([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
([remap xref-find-references] . lsp-ui-peek-find-references))
(:map lsp-command-map
("d f" . lsp-ui-doc-focus-frame) ; keyboard scrolling in the lsp-ui-doc popup frame, and graphic display only
("d u" . lsp-ui-doc-unfocus-frame)))
:commands lsp-ui-mode
:hook ((lsp-mode . lsp-ui-mode)
(lsp-ui-mode . yas-minor-mode))
:custom
(lsp-modeline-code-actions-enable nil)
(lsp-ui-doc-enable nil)
(lsp-ui-sideline-ignore-duplicate t)
(lsp-ui-sideline-show-code-actions t)
(lsp-ui-flycheck-list-position 'right)
:config
;; https://www.reddit.com/r/emacs/comments/x1nwxi/how_to_customize_lspuisideline/
(defun lsp-ui-sideline--compute-height nil '(height unspecified)))
(use-package lsp-ui-flycheck :after lsp-ui :defer 2 :straight lsp-ui)
(use-package lsp-ui-imenu :after lsp-ui :defer 2 :straight lsp-ui)
(use-package consult-lsp
:after lsp-mode
:bind (:map lsp-mode-map
([remap xref-find-apropos] . consult-lsp-symbols)))
(use-package lsp-treemacs
:after lsp-mode
:commands lsp-treemacs-errors-list
:custom
(lsp-treemacs-sync-mode t)
)
(use-package dap-mode
:after (lsp-mode lsp-modeline)
:hook (python typescript-mode)
:init
(unless (display-graphic-p)
(custom-set-faces
'(dap-ui-marker-face ((t (:background "color-166"))))
'(dap-ui-pending-breakpoint-face ((t (:background "blue" :underline "dim gray"))))
'(dap-ui-verified-breakpoint-face ((t (:background "green" :underline "green")))))
))
(use-package sh-script
:mode (("\\.*bashrc$" . sh-mode)
("\\.*bash_profile" . sh-mode))
:custom
(sh-indent-comment t)
:config
; Fixing OSX/node "Operation not permitted" - add 'node' under "Security & Privacy"
;; -> http://osxdaily.com/2018/10/09/fix-operation-not-permitted-terminal-error-macos/
(run-with-idle-timer
0.1 nil
#'(lambda ()
(when (derived-mode-p 'sh-mode)
(when (eq 1 (point-max)) ; new file template
(insert
"#!/usr/bin/env bash\n"
"\n"
"set -Eeuxo pipefail\n"
"\n"
"err() {\n"
" echo \"errexit with status [$?] at line $(caller)\" >&2\n"
" awk 'NR>L-5 && NR<L+3 { printf \"%-5d%3s%s\\n\",NR,(NR==L?\">> \":\"\"),$0 }' L=$1 $0\n"
"}\n"
"trap 'err $LINENO' ERR\n"
"\n\n\n\n"
"main() {\n"
" return\n"
"}\n"
"main \"$@\"\n"
))
)))
)
(use-package dockerfile-mode
:mode (("\\.dockerfile\\'" . dockerfile-mode)
("/Dockerfile\\(?:\\.[^/\\]*\\)?\\'" . dockerfile-mode)))
(use-package go-mode
:if (executable-find "go")
:hook
((go-mode . (lambda ()
(add-hook 'before-save-hook #'(lambda ()
(lsp-format-buffer)
(lsp-organize-imports)))
(unless (file-exists-p (concat (expand-file-name (shell-command-to-string "( git rev-parse --show-toplevel 2> /dev/null || echo $(pwd) ) | tr -d $'\n'")) "/go.mod"))
(setenv "GO111MODULE" "off"))))) ; turn off for one-off file
:config
(run-with-idle-timer
0.1 nil
#'(lambda ()
(when (derived-mode-p 'go-mode)
(when (eq 1 (point-max)) ; new file template
(insert
"package main\n\n"
"import (\n"
"\t\"bufio\"\n"
"\t\"fmt\"\n"
"\t\"os/exec\"\n"
"\t\"strings\"\n"
"\t)\n\n"
"func main() {\n"
"\tcmdName := `sh -c \"ls\"`\n"
"\tcmdArgs := strings.Fields(cmdName)\n"
"\tcmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)\n\n"
"\tstdout, err := cmd.StdoutPipe()\n"
"\tif err != nil {\n"
"\t\tfmt.Println(err)\n"
"\t}\n\n"
"\tif err = cmd.Start(); err != nil {\n"
"\t\tfmt.Println(err)\n"
"\t}\n\n"
"\tscanner := bufio.NewScanner(stdout)\n"
"\tfor scanner.Scan() {\n"
"\t\tmsg := scanner.Text()\n"
"\t\tfmt.Println(msg)\n"
"\t}\n\n"
"\tif err = cmd.Wait(); err != nil {\n"
"\t\tfmt.Println(err)\n"
"\t}\n"
"}\n"))
))))
(use-package gotest
:after go-mode
:bind (:map go-mode-map
("C-x x f" . go-test-current-file)
("C-x x t" . go-test-current-test)
("C-x x x" . go-run))
:commands (go-test-current-file go-test-current-test go-run))
;(defun modes/java-mode ()
; "java mode hook"
; (progn
; (c-set-style "intellij" t) ; code style
; (setq c-basic-offset 2)
;
; (use-package lsp-java) ; Java LSP
; ; check on github on how to install the server
; ; set workspace
; (setq lsp-java-workspace-dir (expand-file-name (concat backup-directory "jdt-workspace/"))
; lsp-java-workspace-cache-dir (expand-file-name (concat lsp-java-workspace-dir ".cache/"))
; lsp-java--workspace-folders
; (list
; ((lambda ()
; (let ((root_dir (locate-dominating-file (expand-file-name (file-name-directory buffer-file-name)) "pom.xml")))
; (if root_dir
; (expand-file-name root_dir)
; (expand-file-name (file-name-directory buffer-file-name))))
; ))
; ))
;
; (setq lsp-inhibit-message t
; lsp-ui-sideline-update-mode 'point)
;
; (lsp-java-enable) ; make this one the last step
; ))
;(add-hook 'java-mode-hook #'modes/java-mode t)
(use-package js2-mode
:interpreter "node"
:mode (("\\.js\\'" . js2-mode))
:custom
(js2-basic-offset 2)
(js2-bounce-indent-p t)
(js2-strict-missing-semi-warning nil)
(js2-concat-multiline-strings nil)
(js2-include-node-externs t)
(js2-skip-preprocessor-directives t)
(js2-strict-inconsistent-return-warning nil))
;(use-package powershell
; :config
; (use-package lsp-pwsh
; :after lsp-mode
; :if (executable-find "pwsh")
; :init
; (setq
; lsp-pwsh-ext-path (expand-file-name "lsp-pwsh/.cache/lsp/pwsh" no-littering-var-directory)
; lsp-pwsh-dir (expand-file-name "PowerShellEditorServices" lsp-pwsh-ext-path)
; lsp-pwsh-exe (executable-find "pwsh"))
; :config
; (lsp)
; )
; )
(use-package python
:if (executable-find "python3")
:interpreter ("python" . python-mode)
:mode ("\\.wsgi$" . python-mode)
:custom
(python-indent-guess-indent-offset t)
(python-indent-guess-indent-offset-verbose nil)
:config
(setenv "PYTHONPATH" (shell-command-to-string "$SHELL --login -c 'echo -n $PYTHONPATH'"))
(when (eq 1 (point-max)) ; new file template
(insert
"#!/usr/bin/env python3\n"
"\n\n"
"def main():\n"
" pass\n"
"\n\n"
"if __name__ == \"__main__\":\n"
" main()\n"
))
(defun python-lsp-organise-imports ()
"pyright does not provide source.organizeImports code action,
so using Autoflake to implement the same function"
(interactive)
(save-buffer) ; work on file only, and need to save the file first
(shell-command (format "autoflake --remove-all-unused-imports -i %s"
(shell-quote-argument (buffer-file-name))))
(revert-buffer t t t))
(defun python-lsp-document-formatting ()
"pyright does not provide document formatting code action,
so using Black to implement the same function"
(interactive)
(save-buffer) ; work on file only, and need to save the file first
(shell-command (format "python -m black -q %s"
(shell-quote-argument (buffer-file-name))))
(revert-buffer t t t))
)
(use-package dap-python ; lsp debugger
:after (python dap-mode)
:custom (dap-python-debugger 'debugpy)
:defer 2
:demand t
:straight dap-mode)
(use-package enh-ruby-mode
:mode
(("\\.rb\\'" . enh-ruby-mode)
("\\.rake\\'" . enh-ruby-mode)
("Rakefile\\'" . enh-ruby-mode)
("\\.gemspec\\'" . enh-ruby-mode)
("\\.ru\\'" . enh-ruby-mode)
("Gemfile\\'" . enh-ruby-mode)
("Cheffile\\'" . enh-ruby-mode)
("Vagrantfile\\'" . enh-ruby-mode))
:custom
(enh-ruby-add-encoding-comment-on-save nil)
(rspec-compilation-buffer-name "*rspec-compilation*")
(rspec-use-opts-file-when-available nil)
(rspec-use-rake-when-possible nil)
(ruby-insert-encoding-magic-comment nil)
:init
(setenv "RUBYOPT" "--jit")
:config
(add-to-list 'exec-path
(concat (expand-file-name "~/.asdf/installs/ruby/") (shell-command-to-string (concat "grep ruby " (expand-file-name "~/.tool-versions") " 2>/dev/null | cut -d' ' -f2 | tr -d $'\n'" )) "/bin"))
(setenv "PATH" (concat (getenv "PATH") ":" (expand-file-name "~/.asdf/installs/ruby/") (shell-command-to-string (concat "grep ruby " (expand-file-name "~/.tool-versions") " 2>/dev/null | cut -d' ' -f2 | tr -d $'\n'" )) "/bin"))
)
(use-package inf-ruby
:after enh-ruby-mode
:hook (compilation-filter . inf-ruby-auto-enter)
)
(use-package rspec-mode
:after enh-ruby-mode
:diminish rspec-mode
:hook (enh-ruby-mode . rspec-mode)
)
(use-package terraform-mode
:mode "\\.tf\\(vars\\)?\\'"
:custom (terraform-indent-level 2))
(use-package terraform-doc :after terraform-mode)
(use-package typescript-mode
:interpreter "node"
:hook (typescript-mode . js2-minor-mode)
:mode ("\\.tsx\\'" . typescript-mode)
:custom
(typescript-indent-level 2))
(use-package dap-node
:after (typescript-mode dap-mode)
:defer 2
:straight dap-mode
:config
(dap-register-debug-template "node::launch::debug_current_file"
(list :type "node"
:request "launch"
:smartStep t
:cwd "${workspaceFolder}"
:outFiles ["${workspaceFolder}/**/*.js"]
:skipFiles ["<node_internals>/**"]
:program "${file}"
;; Or
;; :program "${workspaceFolder}//APP.ts" ; replace with the filename & path to debug
;; :args (list "") ; uncomment & replace with the arguments to program
))
(dap-register-debug-template "node::launch::npm"
(list :type "node"
:request "launch"
:smartStep t
:cwd "${workspaceFolder}"
:outFiles ["${workspaceFolder}/**/*.js"]
:skipFiles ["<node_internals>/**"]
:runtimeExecutable "npm"
:runtimeArgs ["run-script", "test"]
))
(dap-register-debug-template "node::launch::yarn"
(list :type "node"
:request "launch"
:smartStep t
:cwd "${workspaceFolder}"
:outFiles ["${workspaceFolder}/**/*.js"]
:skipFiles ["<node_internals>/**"]
:runtimeExecutable "yarn"
:runtimeArgs ["test"]
)))
(use-package copilot
:straight (:host github :repo "copilot-emacs/copilot.el" :files ("*.el"))
:requires editorconfig
:init
(use-package jsonrpc :defer t))
Char-based jumping
(use-package avy
:bind ([remap goto-char] . avy-goto-char-2) ; M-g c
:commands avy-goto-char-2)
Visible bookmarks
(use-package bm
:init
(setq bm-restore-repository-on-load t) ; restore on load
:config
(setq bm-cycle-all-buffers t) ; cycle through bookmarks in all open buffers
(setq-default bm-buffer-persistence t) ; save/load/restore bookmarks
(add-hook' after-init-hook #'bm-repository-load)
(add-hook 'find-file-hook #'bm-buffer-restore)
(add-hook 'kill-buffer-hook #'bm-buffer-save)
(add-hook 'kill-emacs-hook #'(lambda nil
(bm-buffer-save-all)
(bm-repository-save)))
(add-hook 'after-save-hook #'bm-buffer-save)
(add-hook 'find-file-hook #'bm-buffer-restore)
(add-hook 'after-revert-hook #'bm-buffer-restore)
)
moving word/line/region around
(use-package drag-stuff
:diminish drag-stuff-mode
:hook ((prog-mode org-mode text-mode) . drag-stuff-mode)
:config
(setq drag-stuff-modifier 'alt) ; alt-up/down/left/rigth key bindings
(drag-stuff-define-keys)
)
simple implementation of jumping to definition/source
(use-package dumb-jump
:diminish dumb-jump-mode
:hook (prog-mode . (lambda () (add-hook 'xref-backend-functions #'dumb-jump-xref-activate t)))
:custom
(dumb-jump-prefer-searcher 'rg))
(autoload 'define-erc-response-handler "erc-backend" nil t)
(with-eval-after-load `erc
(progn
(setq erc-server "irc.freenode.net" ; default to freenode.net
erc-port "6697"
erc-nick my-erc-nick
erc-user-full-name my-erc-user-full-name
erc-email-userid my-erc-email-userid
erc-hide-list ; hide unwanted messages
'("JOIN" "PART" "QUIT")
erc-interpret-mirc-color t ; color highlighting
erc-rename-buffers t ; Rename buffers to the current network name instead of SERVER:PORT
erc-server-coding-system ; always utf-8
'(utf-8 . utf-8)
erc-log-mode t ; enable logging
erc-generate-log-file-name-function
(quote erc-generate-log-file-name-with-date)
erc-hide-timestamps t ; hide logging timestamp when chatting
erc-log-channels-directory ; directory
(concat backup-directory "erc.logs/")
erc-log-insert-log-on-open nil ; ignore previous messages
erc-log-file-coding-system 'utf-8-unix
erc-button-url-regexp ; Button URL
"\\([-a-zA-Z0-9_=!?#$@~`%&*+\\/:;,]+\\.\\)+[-a-zA-Z0-9_=!?#$@~`%&*+\\/:;,]*[-a-zA-Z0-9\\/]"
erc-prompt (lambda () (concat "[" (buffer-name) "]"))
erc-auto-discard-away t ; autoaway
erc-autoaway-idle-seconds 600
erc-autoaway-use-emacs-idle t
erc-query-display 'buffer ; open query in the current window
)
(erc-log-mode)
(erc-truncate-mode +1) ; truncate long irc buffers
(require 'erc-sasl) ; sasl
(add-to-list 'erc-sasl-server-regexp-list "irc\\.freenode\\.net")
;; for erc-sasl
(defun erc-login ()
"Perform user authentication at the IRC server."
(erc-log (format "login: nick: %s, user: %s %s %s :%s"
(erc-current-nick)
(user-login-name)
(or erc-system-name (system-name))
erc-session-server
erc-session-user-full-name))
(if erc-session-password
(erc-server-send (format "PASS %s" erc-session-password))
(message "Logging in without password"))
(when (and (featurep 'erc-sasl) (erc-sasl-use-sasl-p))
(erc-server-send "CAP REQ :sasl"))
(erc-server-send (format "NICK %s" (erc-current-nick)))
(erc-server-send
(format "USER %s %s %s :%s"
(if erc-anonymous-login erc-email-userid (user-login-name))
"0" "*"
erc-session-user-full-name))
(erc-update-mode-line))
))
Comment code block
(use-package evil-nerd-commenter
:bind ([remap comment-dwim] . evilnc-comment-or-uncomment-lines) ; M-;
:config (evilnc-default-hotkeys t t)) ; disable default key bindings
(use-package elfeed
:disabled
:bind ("C-x w" . elfeed)
:init (setf url-queue-timeout 30)
:config
(setq my-elfeed-timer ; 1hr update timer
(run-at-time t (* 60 60) #'elfeed-update)
elfeed-feeds
'(("http://www.reddit.com/r/devops/.rss" devops reddit)
("http://feeds.dzone.com/devops" devops dzone)
("https://www.infoq.com/feed/devops/news" devops infoq)
("http://www.reddit.com/r/emacs/.rss" emacs reddit)
)
)
)
(use-package flycheck
:diminish flycheck-mode
:hook (prog-mode . (lambda () (run-with-idle-timer 1 nil #'(lambda () (flycheck-mode)))))
:init
(custom-set-faces
'(flycheck-error ((nil (:background "red"))))
'(flycheck-warning ((nil (:background "yellow")))))
:config
(setq flycheck-buffer-switch-check-intermediate-buffers t
flycheck-check-syntax-automatically '(new-line idle-change save)
flycheck-idle-change-delay (if flycheck-current-errors 0.5 15.0)
flycheck-python-pylint-executable "pyright")
(flymake-mode -1) ; disable flymake
)
(use-package flyspell
:diminish flyspell-mode
:hook ((after-change-major-mode find-file)
. (lambda ()
(run-with-idle-timer
1 nil
#'(lambda ()
(if (not (symbol-value flyspell-mode))
(cond
((derived-mode-p 'prog-mode)
(progn
(message "Flyspell on (code)")
(flyspell-prog-mode)))
((derived-mode-p 'text-mode)
(progn
(message "Flyspell on (text)")
(flyspell-mode 1))))
)))))
:custom
(flyspell-issue-message-flag nil)
(flyspell-issue-welcome-flag nil)
(ispell-list-command "--list")
(ispell-program-name "aspell")
(ispell-extra-args '("--sug-mode=ultra" "--run-together" "--run-together-limit=8"))
:config
(advice-add 'message :around
#'(lambda (old-fun format &rest args)
"Supress \"Starting \"look\" process\" message from \=ispell-lookup-words\="
(if (string= format "Starting \"%s\" process...")
(ignore)
(apply old-fun format args))))
:init
(setq flyspell-use-meta-tab nil)) ; do not bundle to M-Tab
(use-package flyspell-correct :after flyspell) ; C-u/C-u C-u/C-u C-u C-u M-x flyspell-correct-wrapper
(use-package indent-guide
:disabled
:diminish indent-guide-mode
:hook ((prog-mode org-mode) . indent-guide-mode)
:custom
(indent-guide-delay 0.3)
:config (set-face-foreground 'indent-guide-face "dimgray"))
Indent at yank/paste
(use-package indent-yank
:disabled
:defer 5
:hook (window-setup . indent-yank-mode)
:straight '(indent-yank :host github
:branch "master"
:repo "HuangBoHong/indent-yank"))
Show the key pressed on the modeline
(use-package keycast
:defer 2
:init
(custom-set-faces
'(keycast-key ((nil (:height 1 :background "gray30" :foreground "gray70")))))
:custom
(keycast-remove-tail-elements nil)
(keycast-separator-width 2)
(keycast-mode-line-insert-after 'mode-line-misc-info)
(keycast-mode-line-format "%10s%k%c%r%5s")
:config
(keycast-mode-line-mode)
)
(use-package meow
:defer 0.2
:config
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
(meow-leader-define-key
'("e" . "C-x C-e") ; eval-last-sexp
'("," . xref-pop-marker-stack)
'("." . xref-find-definitions)
;; Use SPC (0-9) for digit arguments.
'("1" . meow-digit-argument)
'("2" . meow-digit-argument)
'("3" . meow-digit-argument)
'("4" . meow-digit-argument)
'("5" . meow-digit-argument)
'("6" . meow-digit-argument)
'("7" . meow-digit-argument)
'("8" . meow-digit-argument)
'("9" . meow-digit-argument)
'("0" . meow-digit-argument)
'("/" . meow-keypad-describe-key)
'("?" . meow-cheatsheet))
(meow-normal-define-key
'("0" . meow-expand-0)
'("9" . meow-expand-9)
'("8" . meow-expand-8)
'("7" . meow-expand-7)
'("6" . meow-expand-6)
'("5" . meow-expand-5)
'("4" . meow-expand-4)
'("3" . meow-expand-3)
'("2" . meow-expand-2)
'("1" . meow-expand-1)
'("-" . negative-argument)
'(";" . meow-reverse)
'("," . meow-inner-of-thing)
'("." . meow-bounds-of-thing)
'("[" . meow-beginning-of-thing)
'("]" . meow-end-of-thing)
'("a" . meow-append)
'("A" . meow-open-below)
'("b" . meow-back-word)
'("B" . meow-back-symbol)
'("c" . meow-change)
'("d" . meow-delete)
'("D" . meow-backward-delete)
'("e" . meow-next-word)
'("E" . meow-next-symbol)
'("f" . meow-find)
'("g" . meow-cancel-selection)
'("G" . meow-grab)
'("h" . meow-left)
'("H" . meow-left-expand)
'("i" . meow-insert)
'("I" . meow-open-above)
'("j" . meow-next)
'("J" . meow-next-expand)
'("k" . meow-prev)
'("K" . meow-prev-expand)
'("l" . meow-right)
'("L" . meow-right-expand)
'("m" . meow-join)
'("n" . meow-search)
'("o" . meow-block)
'("O" . meow-to-block)
'("p" . meow-yank)
'("q" . meow-quit)
'("Q" . meow-goto-line)
'("r" . meow-replace)
'("R" . meow-swap-grab)
'("s" . meow-kill)
'("t" . meow-till)
'("u" . meow-undo)
'("U" . meow-undo-in-selection)
'("v" . meow-visit)
'("w" . meow-mark-word)
'("W" . meow-mark-symbol)
'("x" . meow-line)
'("X" . meow-goto-line)
'("y" . meow-save)
'("Y" . meow-sync-grab)
'("z" . meow-pop-selection)
'("'" . repeat)
'("<escape>" . ignore))
(setq meow-expand-hint-remove-delay 5
meow-keypad-describe-delay 3
meow-use-cursor-position-hack t
meow-use-enhanced-selection-effect t)
(meow-setup-line-number)
(meow-global-mode 1)
(defun exit-meow-insert-mode ()
"Reset back to box cursor on terminal"
(unless (display-graphic-p)
(when (bound-and-true-p meow-insert-mode)
(meow-insert-exit))))
(advice-add #'save-buffers-kill-terminal
:before
(lambda (func &rest args)
(exit-meow-insert-mode))))
move where I mean
(use-package mwim
:bind (("C-a" . mwim-beginning-of-code-or-line-or-comment)
("C-e" . mwim-end-of-code-or-line))
:commands (mwim-beginning-of-code-or-line-or-comment mwim-end-of-code-or-line))
Grouping buffers
(use-package perspective
:defer 1
:custom
(persp-mode-prefix-key (kbd "C-c p z"))
:init
(unless (equal persp-mode t)
(persp-mode)))
C-c DEL
to delete active region
(use-package puni
:init
(puni-global-mode)
(dolist (hook '(vterm-toggle-show-hook)) (add-hook hook #'puni-disable-puni-mode)))
(use-package elec-pair :hook (after-init . electric-pair-mode))
(use-package paren
:custom
(show-paren-delay 0.03)
(show-paren-style 'mixed)
(show-paren-when-point-inside-paren t)
:hook (after-init . show-paren-mode)
:init
(custom-set-faces
'(show-paren-match ((nil (:background "#767676" :foreground "#00cd00" :weight extra-bold))))))
(use-package treemacs
:bind (("M-0" . treemacs-select-window)
("C-c p t 1" . treemacs-delete-other-windows)
("C-c p t t" . treemacs)
("C-c p t B" . treemacs-bookmark)
("C-c p t C-t" . treemacs-find-file)
("C-c p t M-t" . treemacs-find-tag))
:init (defvar treemacs-no-load-time-warnings t))
(use-package treemacs-magit :after (treemacs magit))
(use-package treemacs-perspective
:after (treemacs perspective)
:config (treemacs-set-scope-type 'Perspectives))
(use-package treemacs-projectile
:after (treemacs projectile)
:bind ("C-c p t p" . treemacs-projectile))
(use-package scratch-pop
:defer 0.1
:init
(setq scratch-pop-backup-directory (expand-file-name (convert-standard-filename "scratch-pop/") no-littering-var-directory))
(add-hook 'kill-emacs-hook #'scratch-pop-backup-scratches)
)
(use-package so-long :hook (after-init-hook . global-so-long-mode))
navigate into CamelCaseWords
(use-package subword
:diminish subword-mode
:hook ((prog-mode org-mode) . subword-mode))
auto-save buffers
(use-package super-save
:defer 3
:diminish super-save-mode
:config
(super-save-mode +1)
(setq super-save-auto-save-when-idle t))
(use-package switch-window
:bind (([remap other-window] . switch-window)
([remap delete-other-windows] . switch-window-then-maximize)
([remap split-window-below] . switch-window-then-split-below)
([remap split-window-right] . switch-window-then-split-right)
([remap delete-window] . switch-window-then-delete)
([remap dired-other-window] . switch-window-then-dired)
([remap find-file-other-window] . switch-window-then-find-file)
([remap compose-mail-other-window] . switch-window-then-compose-mail)
([remap find-file-read-only-other-window] . switch-window-then-find-file-read-only)
([remap find-file-other-window] . switch-window-then-find-file)
([remap display-buffer] . switch-window-then-display-buffer)
([remap kill-buffer-and-window] . switch-window-then-kill-buffer))
:custom
(switch-window-auto-resize-window (lambda () (if (ignore-errors (dap--cur-session-or-die)) nil t))) ; do not resizing under dap-mode debug session
(switch-window-default-window-size '(0.618 . 0.618))
(switch-window-minibuffer-shortcut ?z)
(switch-window-shortcut-appearance 'asciiart)
(switch-window-shortcut-style 'qwerty))
(use-package symbol-overlay
:commands (symbol-overlay-put
symbol-overlay-jump-prev
symbol-overlay-jump-next
symbol-overlay-switch-backward
symbol-overlay-switch-forward
symbol-overlay-remove-all)
:custom (symbol-overlay-idle-time 0.1)
:custom-face (symbol-overlay-default-face ((t (:inherit (region bold)))))
:diminish
:hook ((prog-mode org-mode) . symbol-overlay-mode))
(use-package undo-tree
:commands undo-tree-visualize
:diminish undo-tree-mode
:config
(add-to-list 'undo-tree-history-directory-alist
(cons "." (concat backup-directory "/undo-tree")))
(global-undo-tree-mode)
(setq undo-tree-visualizer-diff t
undo-tree-visualizer-timestamps t
undo-tree-auto-save-history t)
)
vim-like text folding
(use-package vimish-fold :commands (vimish-fold vimish-fold-delete vimish-fold-toggle))
Display the key bindings in a popup.
(use-package which-key
:defer 2
:diminish which-key-mode
:custom
(which-key-idle-delay 0.5) ; popup delay
(which-key-compute-remaps t)
(which-key-allow-multiple-replacements t)
:config
(which-key-mode)
(which-key-setup-side-window-right-bottom)
)
(use-package yasnippet
:commands yas-minor-mode
:diminish yas-minor-mode
:custom (yas-keymap-disable-hook t)
:config (yas-reload-all))
(use-package yasnippet-snippets :after yasnippet)
Diff between directories
(use-package ztree :config (setq ztree-draw-unicode-lines t))
(use-package projectile
:bind(:map projectile-mode-map
("C-c p p" . projectile-command-map))
:custom
(projectile-enable-caching t) ; enable caching unconditionally
(projectile-file-exists-remote-cache-expire nil) ; disable remote file exists cache
(projectile-remember-window-configs t)
(projectile-switch-project-action #'consult-projectile-find-file)
(projectile-sort-order 'modification-time)
:config
(setq projectile-globally-ignored-directories (append
'(".metadata" "node_modules" "vendor") projectile-globally-ignored-directories)
projectile-globally-ignored-files (append
'(".DS_Store") projectile-globally-ignored-files))
(setq-default projectile-mode-line
'(:eval
(if (file-remote-p default-directory)
" Pr"
(format " Proj[%s]" (projectile-project-name)))))
(cond
((executable-find "ag")
(setq projectile-generic-command
(concat "ag -0 -l --nocolor"
; https://github.com/ggreer/the_silver_searcher/issues/1060
(mapconcat #'identity (cons "" projectile-globally-ignored-directories) " --ignore /")
(mapconcat #'identity (cons "" projectile-globally-ignored-directories) " --ignore /**/"))))
((executable-find "rg")
(setq projectile-generic-command
(let ((rg-cmd ""))
(dolist (dir projectile-globally-ignored-directories)
(setq rg-cmd (format "%s --glob '!%s'" rg-cmd dir)))
(concat "rg -0 --files --color=never --hidden" rg-cmd)))))
(if (eq system-type 'windows-nt) ; external indexing under windows
(setq projectile-indexing-method 'alien))
)
(use-package consult-projectile
:bind (:map prog-mode-map
("C-c p SPC" . consult-projectile))
:config
(unless (equal projectile-mode t)
(projectile-mode)))
(use-package rg :bind ("C-c p R" . rg-menu))
(use-package vertico
:bind (("C-c p v r" . vertico-repeat)
:map vertico-map
("C-j" . vertico-directory-enter)
("C-l" . vertico-directory-up)
("C-q" . vertico-quick-exit)
("M-q" . vertico-quick-insert))
:config
(minibuffer-depth-indicate-mode)
:custom
(enable-recursive-minibuffers t)
(vertico-cycle t)
(vertico-resize t)
:hook ((after-init . vertico-mode)
(minibuffer-setup . vertico-repeat-save)
(rfn-eshadow-update-overlay . vertico-directory-tidy))
:straight (vertico :files (:defaults "extensions/vertico-*.el")
:includes (vertico-directory vertico-quick vertico-repeat)))
(use-package orderless
:custom
(completion-category-defaults nil)
(completion-category-overrides '((file (styles basic partial-completion))))
(completion-styles '(orderless basic))
(orderless-component-separator #'orderless-escapable-split-on-space))
(use-package marginalia
:after vertico
:init (marginalia-mode))
(use-package embark
:bind (("C-c p v ." . embark-act)
("C-c p v ;" . embark-dwim))
:commands (embark-act embark-dwim)
:config
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none))))
:custom
(embark-quit-after-action nil)
(embark-cycle-key ".")
(embark-help-key "?"))
(use-package embark-consult
:after (embark consult)
:demand t
:hook (embark-collect-mode . consult-preview-at-point-mode))
(use-package consult
:bind
(("C-c p G" . consult-git-grep)
("C-c p g" . consult-grep)
("C-c p r" . consult-ripgrep)
([remap describe-bindings] . local/consult-descbinds) ; C-h b
([remap goto-line] . consult-goto-line) ; M-g g
([remap isearch-forward] . consult-line) ; C-s
([remap isearch-backward] . consult-line) ; C-r
([remap switch-to-buffer] . consult-buffer) ; C-x b
)
:config
(with-eval-after-load `perspective
(consult-customize consult--source-buffer :hidden t :default nil)
(defvar consult--source-perspective
(list :name "Perspective"
:narrow ?s
:category 'buffer
:state #'consult--buffer-state
:default t
:items #'persp-get-buffer-names))
(push consult--source-perspective consult-buffer-sources))
:custom
(consult-narrow-key "<")
(xref-show-xrefs-function #'consult-xref)
(xref-show-definitions-function #'consult-xref)
:init
;; https://github.com/WorldsEndless/emacs-clojure/blob/master/emacs.el
(defun local/consult-descbinds ()
(interactive)
(describe-bindings)
(other-window 1)
(call-interactively #'consult-focus-lines)))
(use-package corfu
:bind (:map corfu-map
("M-d" . corfu-info-documentation)
("M-l" . corfu-info-location)
("TAB" . corfu-next)
([tab] . corfu-next)
("S-TAB" . corfu-previous)
([backtab] . corfu-previous)
("M-q" . corfu-quick-insert))
:config
(corfu-history-mode 1)
(add-to-list 'savehist-additional-variables 'corfu-history)
:custom
(corfu-auto t)
(corfu-bar-width 0) ; hide popup right scroll bar
(corfu-cycle t)
(corfu-min-width 30)
(corfu-preselect-first nil)
(corfu-right-margin-width 0) ; hide popup right scroll bar
:hook ((prog-mode
terraform-mode
text-mode) . (lambda ()
(let ((frame (selected-frame)))
(run-with-idle-timer
1 nil
#'(lambda ()
(when (active-minibuffer-window)
"Sometime, the minibuffer window is focused during the initialisation, and this function switches back to the orinal frame"
(select-frame frame))
(unless (bound-and-true-p corfu-mode)
(corfu-mode) ; corfu
(unless (display-graphic-p) ; corfu-terminal
(corfu-terminal-mode 1))
(add-to-list ; kind-icon
'corfu-margin-formatters #'kind-icon-margin-formatter)))))))
:init
(setq completion-cycle-threshold 3)
:straight (corfu :files (:defaults "extensions/*")
:includes (corfu-history corfu-info corfu-quick)))
(use-package popon
:after corfu
:straight (popon :type git :repo "https://codeberg.org/akib/emacs-popon.git")
:unless (display-graphic-p))
(use-package corfu-terminal
:after (corfu popon)
:straight (corfu-terminal :type git :repo "https://codeberg.org/akib/emacs-corfu-terminal.git")
:unless (display-graphic-p))
(use-package kind-icon
:after corfu
:config
(add-to-list 'kind-icon-mapping '(tabnine "ai" :icon "cloud" :face shadow) t)
:custom
(kind-icon-default-face 'corfu-default)
(kind-icon-blend-background nil)
(kind-icon-blend-frac 0.08)
(svg-lib-icons-dir (no-littering-expand-var-file-name "svg-lib/cache/")))
(use-package cape
:after corfu
:init
(add-to-list 'completion-at-point-functions
(cape-capf-buster
(cape-capf-super
#'tabnine-completion-at-point
#'cape-dabbrev
#'cape-dict
#'cape-keyword)
'equal)
t)
(add-to-list 'completion-at-point-functions #'cape-file t))
(use-package tabnine-capf
:after cape
:commands (tabnine-completion-at-point)
:hook (kill-emacs . tabnine-capf-kill-process)
:straight (:host github :repo "50ways2sayhard/tabnine-capf" :files ("*.el" "*.sh")))
(use-package org
:bind ("C-c o b" . org-switchb)
:straight (:type built-in)
:config
(setq truncate-lines nil ; line wrap
org-edit-src-content-indentation 0 ; no indentation in SRC block
org-export-with-smart-quotes t
org-log-done 'time
org-html-doctype "html5"
org-pretty-entities t ; show symbols without math delimiters
org-src-preserve-indentation t
org-src-fontify-natively t ; native fontification
org-src-tab-acts-natively t ; mative tab in SRC block
org-use-speed-commands t ; speed keys
org-startup-indented t
org-hide-leading-stars t)
(org-indent-mode t) ; list-oriented
(diminish 'org-indent-mode)
(add-hook 'org-shiftup-final-hook 'windmove-up) ; active windmove
(add-hook 'org-shiftleft-final-hook 'windmove-left)
(add-hook 'org-shiftdown-final-hook 'windmove-down)
(add-hook 'org-shiftright-final-hook 'windmove-right)
;; recompile README.org/.el/.elc
(add-hook 'after-save-hook
#'(lambda ()
"Load and compile README.org"
(when (equal (buffer-file-name) (expand-file-name (concat user-emacs-directory "README.org")))
(org-babel-tangle nil (expand-file-name (concat user-emacs-directory "README.el")) "emacs-lisp")
(byte-compile-file (expand-file-name (concat user-emacs-directory "README.el")))
(when (fboundp 'native-compile)
(native-compile (expand-file-name (concat user-emacs-directory "README.el"))))
)))
)
Static site generator in org-mode
Two stpes to write a blog
- op/new-post
- op/do-publication
To configure the org-page site variables, put the below settings into ~/.emacs.d/private.el
(setq my-op/repository-directory "~/repos/public/yang-l.github.io" my-op/site-domain "http://yang-l.github.io/" my-op/personal-github-link "https://github.com/yang-l")
(use-package org-page
:disabled
:commands (op/new-repository op/new-post op/do-publication)
:config
(setq op/repository-directory my-op/repository-directory
op/site-domain my-op/site-domain
op/personal-github-link my-op/personal-github-link
op/site-main-title "@Home"
op/site-sub-title "")
)
;; (when (locate-library "auctex") (progn
;; (defun modes/auctex-mode ()
;; "auctex-mode hook"
;; ;; set latexmk the default LaTeX compiler
;; (push
;; '("Latexmk" "latexmk -outdir=/tmp/emacs/latex -bibtex -pdf -pv %s" TeX-run-command nil t
;; :help "Run Latexmk on file")
;; TeX-command-list)
;; (setq TeX-command-default "Latexmk")
;; ;; auto directory for auto-generated info
;; (setq TeX-auto-local "/tmp/emacs/latex/auctex-auto/")
;; (setq TeX-parse-self t) ; enable parse on load
;; (setq TeX-auto-save t) ; enable parse on save
;; (setq-default TeX-master nil)
;; (setq TeX-save-query nil) ; autosave before compiling
;; (TeX-fold-mode 1) ; enable code folding
;; (TeX-fold-buffer)
;; ;; smart quotes
;; (setq TeX-open-quote "<<")
;; (setq TeX-close-quote ">>")
;; ;; detect master files
;; (defun guess-TeX-master (filename)
;; "Guess the master file for FILENAME from currently open .tex files."
;; (let ((candidate nil)
;; (filename (file-name-nondirectory filename)))
;; (save-excursion
;; (dolist (buffer (buffer-list))
;; (with-current-buffer buffer
;; (let ((name (buffer-name))
;; (file buffer-file-name))
;; (if (and file (string-match "\\.tex$" file))
;; (progn
;; (goto-char (point-min))
;; (if (re-search-forward (concat "\\\\input{" filename "}") nil t)
;; (setq candidate file))
;; (if (re-search-forward (concat "\\\\include{" (file-name-sans-extension filename) "}") nil t)
;; (setq candidate file))))))))
;; (if candidate
;; (message "TeX master document: %s" (file-name-nondirectory candidate)))
;; candidate))
;; (setq TeX-master (guess-TeX-master (buffer-file-name))))
;; (add-hook 'LaTeX-mode-hook 'modes/auctex-mode)
;; ;; activate the Ref mode
;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
;; (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode) ; auctex LaTeX math mode
;; (add-hook 'LaTeX-mode-hook 'visual-line-mode) ; with AUCTeX LaTeX mode
;; ;; enable flyspell-mode
;; (add-hook 'LaTeX-mode-hook 'flyspell-mode)
;; ;; activate syntax highlighting - font-lock-mode
;; (add-hook 'LaTeX-mode-hook 'turn-on-font-lock)
;; ;; AUCTEX / EMACS / EVINCE - Forward & Inverse Search
;; (add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
;; (setq TeX-source-correlate-method 'synctex)
;; (setq TeX-source-correlate-start-server t)
;; ;; evince(pdf) -> emacs(latex) search - inverse search
;; ;; ctrl + mouse right button in evince
;; ;;(defun un-urlify (fname-or-url)
;; ;; "A trivial function that replaces a prefix of file:/// with just /."
;; ;; (if (string= (substring fname-or-url 0 8) "file:///")
;; ;; (substring fname-or-url 7)
;; ;; fname-or-url))
;; (defun th-evince-sync (file linecol &rest ignored)
;; (let* ((fname (un-urlify file))
;; (buf (find-file fname))
;; (line (car linecol))
;; (col (cadr linecol)))
;; (if (null buf)
;; (message "[Synctex]: %s is not opened..." fname)
;; (switch-to-buffer buf)
;; (with-no-warnings
;; (goto-line (car linecol)))
;; (unless (= col -1)
;; (move-to-column col)))))
;; (defvar *dbus-evince-signal* nil)
;; (defun enable-evince-sync ()
;; (eval-when-compile (require 'dbus))
;; (when (and
;; (eq window-system 'x)
;; (fboundp 'dbus-register-signal))
;; (unless *dbus-evince-signal*
;; (setf *dbus-evince-signal*
;; (dbus-register-signal
;; :session nil "/org/gnome/evince/Window/0"
;; "org.gnome.evince.Window" "SyncSource"
;; 'th-evince-sync)))))
;; (add-hook 'LaTeX-mode-hook 'enable-evince-sync)
;; ;; emacs(latex) -> evince(pdf) - forward search
;; ;; c-c c-c -> View -> pdf-forward-search in emacs
;; (add-hook 'LaTeX-mode-hook 'TeX-PDF-mode)
;; (add-hook 'LaTeX-mode-hook (lambda()
;; ;; https://github.com/MassimoLauria/dotemacs/blob/42fd1978da3780df725198862fa9f28c0ac4218c/init-latex.le
;; ;; https://gist.github.com/2297447
;; ;; http://tex.stackexchange.com/a/78051
;; ;; un-urlify and urlify-escape-only should be improved to handle all special characters, not only spaces.
;; ;; The fix for spaces is based on the first comment on http://emacswiki.org/emacs/AUCTeX#toc20
;; (defun un-urlify (fname-or-url)
;; "Transform file:///absolute/path from Gnome into /absolute/path with very limited support for special characters"
;; (if (string= (substring fname-or-url 0 8) "file:///")
;; (url-unhex-string (substring fname-or-url 7))
;; fname-or-url))
;; (defun urlify-escape-only (path)
;; "Handle special characters for urlify"
;; (replace-regexp-in-string " " "%20" path))
;; (defun urlify (absolute-path)
;; "Transform /absolute/path to file:///absolute/path for Gnome with very limited support for special characters"
;; (if (string= (substring absolute-path 0 1) "/")
;; (concat "file://" (urlify-escape-only absolute-path))
;; absolute-path))
;; ;; universal time, need by evince
;; (defun utime ()
;; (let ((high (nth 0 (current-time)))
;; (low (nth 1 (current-time))))
;; (+ (* high (lsh 1 16) ) low)))
;; ;; Forward search.
;; ;; Adapted from http://dud.inf.tu-dresden.de/~ben/evince_synctex.tar.gz
;; (defun auctex-evince-forward-sync (pdffile texfile line)
;; (let ((dbus-name
;; (dbus-call-method :session
;; "org.gnome.evince.Daemon" ; service
;; "/org/gnome/evince/Daemon" ; path
;; "org.gnome.evince.Daemon" ; interface
;; "FindDocument"
;; (urlify pdffile)
;; t ; Open a new window if the file is not opened.
;; )))
;; (dbus-call-method :session
;; dbus-name
;; "/org/gnome/evince/Window/0"
;; "org.gnome.evince.Window"
;; "SyncView"
;; (urlify-escape-only texfile)
;; (list :struct :int32 line :int32 1)
;; (utime))))
;; (defun pdf-forward-search ()
;; (let (
;; (pdf (concat "/tmp/emacs/latex/" (TeX-master-file (TeX-output-extension))))
;; (tex (buffer-file-name))
;; (line (line-number-at-pos)))
;; (auctex-evince-forward-sync pdf tex line)))
;; ;; PDF forward search : emacs -> dbus -> evince
;; (setq TeX-view-program-list '())
;; (add-to-list 'TeX-view-program-list
;; '("EvinceForward" pdf-forward-search))
;; (setq TeX-view-program-selection '())
;; (add-to-list 'TeX-view-program-selection
;; '(output-pdf "EvinceForward"))
;; ))))
;; (when (locate-library "maxima")
;; (autoload 'maxima-mode "maxima" nil t)
;; (setq auto-mode-alist (cons '("\\.ma?[cx]" . maxima-mode) auto-mode-alist))
;; )
;; (autoload 'octave-mode "octave-mod" nil t)
;; (setq auto-mode-alist (append '(("\\.m$" . octave-mode)) auto-mode-alist))
;; (with-eval-after-load 'octave-mod
;; '(progn
;; (abbrev-mode 1)
;; (auto-fill-mode 1)
;; (if (eq window-system 'x)
;; (font-lock-mode 1))
;; (run-octave)
;; (add-hook 'inferior-octave-mode-hook
;; (lambda ()
;; (turn-on-font-lock)
;; (define-key inferior-octave-mode-map [up]
;; 'comint-previous-input)
;; (define-key inferior-octave-mode-map [down]
;; 'comint-next-input)))
;; ))
(defun indent-whole-buffer () ; indentation
"indent whole buffer"
(interactive)
(delete-trailing-whitespace)
(indent-region (point-min) (point-max) nil)
(untabify (point-min) (point-max)))
(defun indent-current-paragraph () ; code cleanup
"indent current paragraph"
(interactive)
(save-excursion
(delete-trailing-whitespace)
(mark-paragraph)
(indent-region (region-beginning) (region-end) nil)))
(defun indent-text (distance)
(if (use-region-p)
(let ((mark (mark)))
(save-excursion
(indent-rigidly (region-beginning)
(region-end)
distance)
(push-mark mark t t)
(setq deactivate-mark nil)))
(indent-rigidly (line-beginning-position)
(line-end-position)
distance)))
(defun inc-line-indent (count)
(interactive "p")
(indent-text count))
(defun dec-line-indent (count)
(interactive "p")
(indent-text (- count)))
;(global-set-key (kbd "C-c > >") #'(lambda () (interactive) (inc-line-indent 4)))
;(global-set-key (kbd "C-c < <") #'(lambda () (interactive) (dec-line-indent 4)))
(defun dos2unix () ; EoL conversion
"dos2unix on current buffer."
(interactive)
(set-buffer-file-coding-system 'unix))
(defun unix2dos ()
"unix2dos on current buffer."
(interactive)
(set-buffer-file-coding-system 'dos))
Selective copy and paste
;; require xsel
(defun copy-to-clipboard ()
(interactive)
(if (display-graphic-p)
(progn
(message "Yanked region to x-clipboard!")
(call-interactively 'clipboard-kill-ring-save)
)
(if (region-active-p)
(progn
(shell-command-on-region (region-beginning) (region-end) "xsel -i -b")
(message "Yanked region to clipboard!")
(deactivate-mark))
(message "No region active; can't yank to clipboard!")))
)
(defun paste-from-clipboard ()
(interactive)
(if (display-graphic-p)
(progn
(clipboard-yank)
(message "graphics active")
)
(insert (shell-command-to-string "xsel -o -b"))
)
)
File manager
(defun dired-open-home ()
(interactive)
(dired "~/")
)
(defun json-format ()
(interactive)
(save-excursion
(shell-command-on-region (mark) (point) "python3 -m json.tool" (buffer-name) t)
)
)
(defun urldecode ()
(interactive)
(save-excursion
(shell-command-on-region (mark) (point) "python3 -c \"import sys; from urllib.parse import unquote_plus; print(unquote_plus(sys.stdin.read()));\" " (buffer-name) t)
)
)
(defun urlencode ()
(interactive)
(save-excursion
(shell-command-on-region (mark) (point) "python3 -c \"import sys; from urllib.parse import quote_plus; print(quote_plus(sys.stdin.read()));\"" (buffer-name) t)
)
)
keybindings | alternative | mode | description |
---|---|---|---|
C-u 4 C-x Tab / C-4 C-x Tab | C-c > > | buildin | indent the region by 4 spaces |
C-u -4 C-x Tab / C--4 C-x Tab | C-c < < | buildin | un-indent the region by 4 spaces |
C-x SPC | buildin | rectangular selection | |
C-x r t | buildin | replace rectangule content | |
C-c ' | org | edit SRC block in separate buffer | |
S-<arrow> | C-x o | buildin | move point between windows |
M-<num> | window-number | jump to window by number | |
C-S-Backspace | C-a C-k | buildin | delete a whole line |
C-x z | buildin | repeat last command | |
z | buildin | repeat last command again | |
M-< | buildin | top of buffer | |
M-> | buildin | end of buffer | |
C-NUM C-x $ | hideshow | buildin | hide lines indented more NUM colums |
C-x $ | hideshow | buildin | show all lines |
C-x = | buildin | show current cursor position | |
M-z CHAR | buildin | del up to CHAR (but not included) | |
C-x r b | buildin | create bookmark | |
C-x r m | buildin | jump to bookmark | |
C-x r l | buildin | list bookmark |
;; Local Variables:
;; byte-compile-warnings: (not free-vars unresolved)
;; End: