I can use C-c I
to open this config file and use C-c R
to reload it.
By the way, I can use C-c i
to open system config file.
(defun find-config ()
"Edit config.org"
(interactive)
(find-file "~/.emacs.d/config.org"))
(defun find-dotfiles ()
"Edit dotfiles.org"
(interactive)
(find-file "~/.emacs.d/dotfiles.org"))
(defun reload-config()
"Reload config.org"
(interactive)
(delete-file "~/.emacs.d/config.el")
(org-babel-load-file (expand-file-name "~/.emacs.d/config.org")))
(global-set-key (kbd "C-c i") 'find-dotfiles)
(global-set-key (kbd "C-c I") 'find-config)
(global-set-key (kbd "C-c R") 'reload-config)
(setq user-full-name "Teddy Ma"
user-mail-address "[email protected]")
straight.el
is a good tool to manage packages, but it is slow when pull all the packages,
so I can use the command line : (async-shell-command "emacs -batch -l ~/.emacs.d/init.el -f straight-pull-all")
when something wrong with ‘can not find package xxx’, try to delete the local repo of package and restart emacs
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name
"straight/repos/straight.el/bootstrap.el"
user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
;;; Integration with use-package
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
(setq straight-vc-git-default-clone-depth 1)
Set up the customize file to its own separate file, instead of saving customize settings in init.el. Try your best to make custom config clean.
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file)
The default is 800 kilobytes. Measured in bytes.
(setq gc-cons-threshold 80000000)
(setq read-process-output-max (* 1024 1024))
(use-package esup
:straight t)
(setq-default use-short-answers t)
(setq native-comp-async-report-warnings-errors nil)
Only macOS needs this config
(use-package exec-path-from-shell
:straight t
:if (memq window-system '(mac ns))
:config
(setq exec-path-from-shell-arguments '("-l"))
(exec-path-from-shell-initialize)
(exec-path-from-shell-copy-envs
'("GOPATH" "GO111MODULE" "GOPROXY"
"NPMBIN" "LC_ALL" "LANG" "LC_TYPE"
"SSH_AGENT_PID" "SSH_AUTH_SOCK" "SHELL"
"JAVA_HOME")))
(setq vc-follow-symlinks t)
(setq visible-bell nil)
(global-hl-line-mode 1)
(use-package beacon
:straight t
:init
(beacon-mode 1))
(blink-cursor-mode -1)
(setq make-backup-file nil)
(setq auto-save-default nil)
(setq backup-inhibited t)
(setq backup-directory-alist `(("." . "~/.saves")))
(setq-default delete-by-moving-to-trash t)
(global-auto-revert-mode t)
(setq utf-translate-cjk-mode nil) ; disable CJK coding/encoding (Chinese/Japanese/Korean characters)
(set-language-environment 'utf-8)
(set locale-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-selection-coding-system
(if (eq system-type 'windows-nt)
'utf-16-le ;; https://rufflewind.com/2014-07-20/pasting-unicode-in-emacs-on-windows
'utf-8))
(prefer-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-clipboard-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-buffer-file-coding-system 'utf-8)
(setq-default pathname-coding-system 'utf-8)
(set-file-name-coding-system 'utf-8)
Will automated download images for the first time
(use-package emojify
:straight t
:hook (after-init . global-emojify-mode))
Run M-x all-the-icons-install-fonts
to install fonts (only once)
;; Emoji: 😄, 🤦, 🏴
(use-package all-the-icons
:straight t
:config
(set-fontset-font t 'symbol "Apple Color Emoji")
(set-fontset-font t 'symbol "Noto Color Emoji" nil 'append)
(set-fontset-font t 'symbol "Segoe UI Emoji" nil 'append)
(set-fontset-font t 'symbol "Symbola" nil 'append))
(column-number-mode t)
(global-visual-line-mode 1)
(use-package winner-mode
:straight nil
:hook (after-init . winner-mode))
(use-package package-loading-notifier
:straight t
:config
(package-loading-notifier-mode 1))
Suggest next keys to me based on currently entered key combination.
(use-package which-key
:straight t
:init
(which-key-mode 1)
:config
(which-key-setup-side-window-right-bottom)
(setq which-key-sort-order 'which-key-key-order-alpha
which-key-side-window-max-width 0.33
which-key-idle-delay 2
which-key-show-early-on-C-h t
which-key-idle-secondary-delay 0.05)
:diminish
which-key-mode)
(use-package uniquify
:straight nil
:config
(setq uniquify-buffer-name-style 'reverse)
(setq uniquify-separator " • ")
(setq uniquify-after-kill-buffer-p t)
(setq uniquify-ignore-buffers-re "^\\*"))
(when (eq system-type 'darwin)
(setq mac-command-modifier 'meta
mac-option-modifier 'meta))
;; (when (eq system-type 'gnu/linux)
;; (setq x-meta-keysym 'super
;; x-super-keysym 'meta))
(global-unset-key (kbd "M-c"))
(use-package vertico
:straight t
:init
(vertico-mode))
(use-package savehist
:config
(setq history-length 25)
(savehist-mode 1))
(use-package marginalia
:after vertico
:straight t
:custom
(marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
:init
(marginalia-mode))
(defun teddy-ma/clean-exit ()
"Exit Emacs cleanly.
If there are unsaved buffer, pop up a list for them to be saved
before existing. Replaces ‘save-buffers-kill-terminal’."
(interactive)
(if (frame-parameter nil 'client)
(server-save-buffers-kill-terminal arg)
(if-let ((buf-list (seq-filter (lambda (buf)
(and (buffer-modified-p buf)
(buffer-file-name buf)))
(buffer-list))))
(progn
(pop-to-buffer (list-buffers-noselect t buf-list))
(message "s to save, C-k to kill, x to execute"))
(save-buffers-kill-emacs))))
(use-package power-mode
:straight '(power-mode :host github
:branch "main"
:repo "elizagamedev/power-mode.el"))
;; Vertical Scroll
(setq scroll-step 1)
(setq scroll-margin 1)
(setq scroll-conservatively 101)
(setq scroll-up-aggressively 0.01)
(setq scroll-down-aggressively 0.01)
(setq auto-window-vscroll nil)
(setq fast-but-imprecise-scrolling nil)
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(setq mouse-wheel-progressive-speed nil)
;; Horizontal Scroll
(setq hscroll-step 1)
(setq hscroll-margin 1)
(setq-default create-lockfiles nil)
(use-package crux
:straight t
:bind (
("C-a" . crux-move-beginning-of-line)
))
(use-package consult
:straight t
:bind
(("M-g g" . consult-goto-line)))
M + <
# beginning of buffer
M + >
# end of buffer
M-s
to search with key words
(use-package orderless
:straight t
:custom
(completion-styles '(orderless)))
(use-package consult
:straight t
:bind
(("M-s" . consult-line)))
anzu-query-replace
command, y
to replace and n
to skip
(use-package anzu
:straight t
:config
(global-anzu-mode +1))
C-x b
can select buffers with preview (including bookmarks and files)
(use-package consult
:straight t
:bind
(("C-x b" . consult-buffer)))
C-c r
to rename file and buffer
C-c D
to delte file and buffer
(use-package crux
:straight t
:bind (
;;("C-c r" . crux-rename-file-and-buffer) ;; conflic with rails keybinding
("C-c D" . crux-delete-file-and-buffer)
))
enchance default backspace and C-d
(use-package smart-hungry-delete
:straight t
:bind (("<backspace>" . smart-hungry-delete-backward-char)
("C-d" . smart-hungry-delete-forward-char))
:defer nil ;; dont defer so we can add our functions to hooks
:config (smart-hungry-delete-add-default-hooks))
(add-hook 'before-save-hook 'delete-trailing-whitespace)
expand-region
expands the region around the cursor semantically depending on mode.
Hard to describe but a killer feature.
(use-package expand-region
:straight t
:bind ("C-=" . er/expand-region))
C-x C-=
Zoom in
C-x C--
Zoom out
C-x 0
Reset
(use-package iedit
:straight t)
(use-package multiple-cursors
:straight t
:config
(global-unset-key (kbd "M-<down-mouse-1>"))
(global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this))
(defun toggle-quotes ()
"Toggle single quoted string to double or vice versa, and
flip the internal quotes as well. Best to run on the first
character of the string."
(interactive)
(save-excursion
(re-search-backward "[\"']")
(let* ((start (point))
(old-c (char-after start))
new-c)
(setq new-c
(case old-c
(?\" "'")
(?\' "\"")))
(setq old-c (char-to-string old-c))
(delete-char 1)
(insert new-c)
(re-search-forward old-c)
(backward-char 1)
(let ((end (point)))
(delete-char 1)
(insert new-c)
(replace-string new-c old-c nil (1+ start) end)))))
M-<up> M-<down> to move line up and down
(use-package drag-stuff
:straight t
:diminish drag-stuff-mode
:config
(drag-stuff-global-mode t)
(drag-stuff-define-keys)
(add-to-list 'drag-stuff-except-modes 'org-mode))
C-S-d
if marked region, dumplicate region else current line
(use-package crux
:straight t
:bind (
("C-S-d" . crux-duplicate-current-line-or-region)
))
(use-package caps-lock
:straight t)
(delete-selection-mode t)
calling avy-goto-word-1 then press one key char and then press n
, and select target word
(global-set-key (kbd “M-t”) ‘avy-goto-word-1) and a word that starts with a “w” and is select-able with “a”. Here’s what you can do now:
M-t w a to jump there M-t w x a - avy-action-kill-move: kill the word and move there, M-t w X a - avy-action-kill-stay: kill the word without moving the point, M-t w i a - avy-action-ispell: use ispell/flyspell to correct the word, M-t w y a - avy-action-yank: yank the word at point, M-t w t a - avy-action-teleport: kill the word and yank it at point, M-t w z a - avy-action-zap-to-char: kill from point up to selected point.
Vundo (visual undo) displays the undo history as a tree and lets you move in the tree to go back to previous buffer states. To use vundo, type M-x vundo RET in the buffer you want to undo. An undo tree buffer should pop up. To move around, type:
f to go forward b to go backward
n to go to the node below when you at a branching point p to go to the node above
a to go back to the last branching point e to go forward to the end/tip of the branch
q to quit, you can also type C-g
(use-package vundo
:straight '(vundo :host github
:branch "master"
:repo "casouri/vundo"))
(defun magnifying-current-line ()
(setq magnifying-overlay (make-overlay (line-beginning-position) (line-end-position)))
(overlay-put magnifying-overlay 'font-lock-face '(:height 2.5)))
(defun magnifying-restore-line ()
(dolist (o (overlays-in (line-beginning-position) (line-end-position)))
(delete-overlay o)))
(define-minor-mode magnifying-mode
"Toggles global magnifying-mode."
nil ; Initial value, nil for disabled
:global t
:group 'magnifying
:lighter " magnifying"
:keymap
(list
(cons (kbd "C-c t") (lambda ()
(interactive)
(magnifying-current-line)))
(cons (kbd "C-c m") (lambda ()
(interactive)
(magnifying-restore-line)))
)
(if magnifying-mode
(message "magnifying-mode activated!")
(message "magnifying-mode deactivated!")))
(add-hook 'magnifying-mode-hook (lambda () (message "magnifying hook was executed!")))
(add-hook 'magnifying-mode-on-hook (lambda () (message "magnifying turned on!")))
(add-hook 'magnifying-mode-off-hook (lambda () (message "magnifying turned off!")))
(use-package redacted
:straight t)
use consult-grep
to get global search result, C-S-a (embark-act) and E to export and C-c C-p to use wgrep to edit,
after saved, use wgrep-save-all-buffers
to confirm change
(use-package embark
:straight t
:bind
(("C-S-a" . embark-act) ;; pick some comfortable binding
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:straight t
:after (embark consult)
:demand t ; only necessary if you have the hook below
;; if you want to have consult previews as you move around an
;; auto-updating embark collect buffer
:hook
(embark-collect-mode . consult-preview-at-point-mode))
;; wgrep allows you to edit a grep buffer and apply those changes to the file buffer like sed interactively.
;; No need to learn sed script, just learn Emacs.
(use-package wgrep
:straight t)
(use-package consult
:straight t
:config
(setq consult-project-root-function
(lambda ()
(when-let (project (project-current))
(car (project-roots project)))))
)
M-o
if more than two windows, a leader key is needed
(use-package ace-window
:straight t
:config
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
(custom-set-faces
'(aw-leading-char-face
((t (:inherit ace-jump-face-foreground :height 5.0)))))
:bind
("M-o" . ace-window))
(use-package transpose-frame :straight t)
ace-swap-window
will lose after emacs restart
window-configuration-to-register
C-x { | (shrink-window-horizontally) |
C-x } | (enlarge-window-horizontally) |
---|
enable flow-mode and create new window (C-x 3)
press x
when calling ace-window and select window
many other actions https://github.com/abo-abo/ace-window#change-the-action-midway
no tool bar, no scroll bar, no menu bar, very clear
(tool-bar-mode -1)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(when (eq system-type 'darwin)
(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))
(setq ns-use-proxy-icon nil)
(setq frame-title-format nil)
;;(setq-default frame-title-format '("M-EMACS - " user-login-name "@" system-name " - %b"))
(setq frame-resize-pixelwise t))
(setq inhibit-startup-screen t)
Font on windows with 4k minitor is too small
(when (eq system-type 'windows-nt) (set-face-attribute 'default nil :height 100))
(when (not (eq system-type 'windows-nt))
(setq emacs-banner "~/Dropbox/Photos/emacs-banner.png")
(use-package dashboard
:straight t
:config
(dashboard-setup-startup-hook)
(if (file-exists-p emacs-banner)
(setq dashboard-startup-banner emacs-banner))
(setq dashboard-items '((recents . 5)
;;(bookmarks . 5)
(projects . 5)
(agenda . 5))))
)
It works fine with windows and org table in Chinese
(when (display-graphic-p)
(when (eq system-type 'darwin)
(setq fonts '("Monaco" "STKaiti"))
(set-face-attribute 'default nil :font
(format "%s:pixelsize=%d" (car fonts) 15))
(setq face-font-rescale-alist '(("STKaiti". 1.2))))
(when (eq system-type 'windows-nt)
(setq fonts '("Inconsolata" "华文楷体"))
(set-face-attribute 'default nil :font
(format "%s:pixelsize=%d" (car fonts) 20))
(setq face-font-rescale-alist '(("华文楷体". 1.0))))
(when (eq system-type 'gnu/linux)
(setq fonts '("Sarasa Mono SC Nerd" "STKaiti"))
(set-face-attribute 'default nil :font
(format "%s:pixelsize=%d" (car fonts) 18))
(setq face-font-rescale-alist '(("STKaiti". 1.0))))
(dolist (charset '(kana han symbol cjk-misc bopomofo))
(set-fontset-font (frame-parameter nil 'font) charset
(font-spec :family (car (cdr fonts)))))
)
(use-package diminish
:straight t)
(use-package hide-mode-line
:straight t)
(use-package nyan-mode
:straight t
:init
(setq nyan-animate-nyancat t)
(setq nyan-wavy-trail t)
(setq nyan-minimum-window-width 80)
(setq nyan-bar-length 20)
(nyan-mode))
Custom mode line unitlity functions (align) https://gist.github.com/fhdhsni/990cba7794b4b6918afea94af0b30d66
(setq teddy-ma/current-mode-line-index 1)
(setq teddy-ma/mode-line-options `(""
(eval `mode-line-modes)
(teddy-ma/render-cyan)))
(setq teddy-ma/mode-line-content "")
(defun teddy-ma/toggle-mode-line-left-display()
(interactive)
(let ((idx (% teddy-ma/current-mode-line-index (length teddy-ma/mode-line-options))))
(setq teddy-ma/mode-line-content (eval (nth idx teddy-ma/mode-line-options))))
(setq teddy-ma/current-mode-line-index (+ teddy-ma/current-mode-line-index 1))
(teddy-ma/refresh-mode-line))
(defun teddy-ma/render-mode-line-modes()
teddy-ma/mode-line-content)
(defun mode-line-fill-right (face reserve)
"Return empty space using FACE and leaving RESERVE space on the right."
(unless reserve
(setq reserve 20))
(when (and window-system (eq 'right (get-scroll-bar-mode)))
(setq reserve (- reserve 3)))
(propertize " "
'display `((space :align-to (- (+ right right-fringe right-margin) ,reserve)))
'face face))
(defun mode-line-fill-center (face reserve)
"Return empty space using FACE to the center of remaining space leaving RESERVE space on the right."
(unless reserve
(setq reserve 20))
(when (and window-system (eq 'right (get-scroll-bar-mode)))
(setq reserve (- reserve 3)))
(propertize " "
'display `((space :align-to (- (+ center (.5 . right-margin)) ,reserve
(.5 . left-margin))))
'face face))
(defconst RIGHT_PADDING 1)
(defun reserve-left/middle ()
(/ (length (format-mode-line mode-line-align-middle)) 2))
(defun reserve-middle/right ()
(+ RIGHT_PADDING (length (format-mode-line mode-line-align-right))))
(defun teddy-ma/refresh-middle-mode-line ()
(setq mode-line-align-middle ;; git status, modified status
'(""
(vc-mode vc-mode)
"%3 "
(:eval
(when (eql (buffer-modified-p) t)
;; propertize adds metadata to text, so you can add colours and formatting, amongst other things
(propertize "" 'face '(:foreground "black"))))
" "
(:eval
(when (eql buffer-read-only t)
(propertize "" 'face '(:foreground "pink"))))
"")))
(defun teddy-ma/refresh-right-mode-line ()
(setq mode-line-align-right ;; line number and point location
'(""
mode-line-misc-info
"%2 "
(:eval (format "%%l/%d : %%c " (line-number-at-pos (point-max))))))
)
(defun teddy-ma/refresh-left-mode-line ()
(setq mode-line-align-left ;; buffer name
'(
""
"%2 "
(:propertize "%b" face mode-line-buffer-id) ;; buffer name
"%2 "
;;mode-line-modes
)))
(defun teddy-ma/render-cyan()
'(:eval (list (nyan-create))))
(defun teddy-ma/refresh-mode-line ()
(teddy-ma/refresh-left-mode-line)
(teddy-ma/refresh-middle-mode-line)
(teddy-ma/refresh-right-mode-line)
(setq-default mode-line-format
(list
(teddy-ma/render-mode-line-modes)
mode-line-align-left '(:eval (mode-line-fill-center 'mode-line (reserve-left/middle)))
mode-line-align-middle '(:eval (mode-line-fill-right 'mode-line (reserve-middle/right)))
mode-line-align-right
))
)
(teddy-ma/refresh-mode-line)
(use-package kaolin-themes
:straight t)
(setq-default custom-enabled-themes '(kaolin-light))
(defun reapply-themes ()
"Forcibly load the themes listed in `custom-enabled-themes'."
(dolist (theme custom-enabled-themes)
(unless (custom-theme-p theme)
(disable-theme theme)
(load-theme theme)))
(custom-set-variables `(custom-enabled-themes (quote ,custom-enabled-themes))))
(add-hook 'after-init-hook 'reapply-themes)
(defun theme-light ()
"Activate a light color theme."
(interactive)
(setq custom-enabled-themes '(kaolin-light))
(reapply-themes))
(defun theme-dark ()
"Activate a dark color theme."
(interactive)
(setq custom-enabled-themes '(kaolin-dark))
(reapply-themes))
(defun theme-day ()
"Activate a light day color theme."
(interactive)
(color-theme-sanityinc-tomorrow-day))
load-theme without annoying confirmation
;; (advice-add 'load-theme
;; :around
;; (lambda (fn theme &optional no-confirm no-enable)
;; (funcall fn theme t)))
custom hl-line and mode-line bg color if necessary
;; (set-face-background 'hl-line "midnight blue")
;; (set-face-background hl-line-face "gray13")
;; (set-face-background 'mode-line "color-28")
Only works on windowed emacs on macOS
(defun increase-transparency ()
"Increase Transparency"
(interactive)
(seethru-relative 10))
(defun decrease-transparency ()
"Decrease Transparency"
(interactive)
(seethru-relative -10))
(use-package seethru
:straight t
:bind
(("C-c 9" . increase-transparency)
("C-c 8" . decrease-transparency))
:config
(seethru 95))
Solaire YYDS!
(use-package solaire-mode
:straight t
:hook (after-init . solaire-global-mode))
(defun align-non-space (BEG END)
"Align non-space columns in region BEG END."
(interactive "r")
(align-regexp BEG END "\\(\\s-*\\)\\S-+" 1 1 t))
(setq-default indent-tabs-mode nil)
(setq-default indicate-empty-lines nil)
Just one space is needed.
(setq sentence-end-double-space nil)
(use-package rainbow-delimiters
:straight t
:config
(add-hook 'prog-mode-hook 'rainbow-delimiters-mode))
(use-package smartparens
:straight t
:diminish
smartparens-mode
:hook
(prog-mode . smartparens-mode))
I only want this in programming modes, and I don’t want colour names to be highlighted (x-colors
).
(use-package rainbow-mode
:straight t
:config
(setq rainbow-x-colors nil)
:hook
(prog-mode . rainbow-mode))
(use-package aggressive-indent
:straight t)
(use-package editorconfig
:straight t
:diminish editorconfig-mode
:config
(editorconfig-mode 1))
(use-package format-all
:straight t
:hook
(prog-mode . format-all-mode))
(use-package quickrun
:straight t)
(when (not (eq system-type 'windows-nt))
(use-package tree-sitter
:straight t
:config
(global-tree-sitter-mode)
;; you can easily see the difference tree-sitter-hl-mode makes for python, ts or tsx
;; by switching on and off
(add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
(use-package tree-sitter-langs
:straight t
:after tree-sitter))
(use-package turbo-log
:straight '(turbo-log :host github
:branch "master"
:repo "artawower/turbo-log.el")
:bind (("C-s-l" . turbo-log-print)
("C-s-i" . turbo-log-print-immediately)
("C-s-h" . turbo-log-comment-all-logs)
("C-s-s" . turbo-log-uncomment-all-logs)
("C-s-[" . turbo-log-paste-as-logger)
("C-s-]" . turbo-log-paste-as-logger-immediately)
("C-s-d" . turbo-log-delete-all-logs))
:config
(setq turbo-log-msg-format-template "\"🚀: %s\"")
(setq turbo-log-allow-insert-without-tree-sitter-p t))
(use-package devdocs
:straight t)
(defun my-string-inflection-cycle-auto ()
"switching by major-mode"
(interactive)
(cond
((eq major-mode 'emacs-lisp-mode)
(string-inflection-all-cycle))
((eq major-mode 'java-mode)
(string-inflection-java-style-cycle))
((eq major-mode 'ruby-mode)
(string-inflection-ruby-style-cycle))
(t
(string-inflection-all-cycle))))
(use-package string-inflection
:straight t
:config
(global-set-key (kbd "C-M-j") 'my-string-inflection-cycle-auto))
(use-package projectile
:straight t
:config
(projectile-mode +1)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(setq projectile-enable-caching t)
(projectile-mode))
(use-package neotree
:straight t
:config
(defun neotree-project-tree-open ()
(interactive)
(let ((project-dir (ignore-errors (projectile-project-root)))
(file-name (buffer-file-name)))
(if project-dir
(progn
(neotree-dir project-dir)
(neotree-find file-name))
(neotree-find)))
(neo-global--select-window))
(defun neotree-project-tree-toggle ()
(interactive)
(if (neo-global--window-exists-p)
(neotree-hide)
(neotree-project-tree-open)))
(global-set-key (kbd "C-<tab>") 'neotree-project-tree-toggle)
(setq neo-show-hidden-files t)
(setq neo-theme 'arrow)
(setq neo-window-width 35)
(defun custom-neotree-enter-hide ()
(interactive)
(neotree-enter)
(let ((current (neo-buffer--get-filename-current-line)))
(if (not (and current (file-accessible-directory-p current)))
(neotree-hide))))
(defun custom-neotree-peek ()
(interactive)
(let ((neo-window (neo-global--get-window)))
(neotree-enter)
(select-window neo-window)))
(add-hook
'neotree-mode-hook
(lambda ()
(define-key neotree-mode-map (kbd "RET") 'custom-neotree-enter-hide)))
(add-hook
'neotree-mode-hook
(lambda ()
(define-key neotree-mode-map (kbd "TAB") 'custom-neotree-peek))))
(use-package consult-projectile
:straight (consult-projectile
:type git
:host gitlab
:repo "OlMon/consult-projectile"
:branch "master"))
fzf
is a fuzzy file finder which is very quick.
(use-package fzf
:straight t)
You can now edit files directly from results buffers with M-x deadgrep-edit-mode.
(use-package deadgrep
:straight t)
Open files and goto lines like we see from g++ etc. i.e. Gemfile:12
(defadvice find-file (around find-file-line-number
(filename &optional wildcards)
activate)
"Turn files like file.cpp:14 into file.cpp and going to the 14-th line."
(save-match-data
(let* ((matched (string-match "^\\(.*\\):\\([0-9]+\\):?$" filename))
(line-number (and matched
(match-string 2 filename)
(string-to-number (match-string 2 filename))))
(filename (if matched (match-string 1 filename) filename)))
ad-do-it
(when line-number
;; goto-line is for interactive use
(goto-char (point-min))
(forward-line (1- line-number))))))
Individual language packages often support IDE features like jump to source, but dumb-jump
attempts to support many languages by simple searching.
It’s quite effective even with dynamic libraries like JS and Python.
(use-package dumb-jump
:straight t
:diminish dumb-jump-mode
:bind (("C-M-g" . dumb-jump-go)
("C-M-p" . dumb-jump-back)
("C-M-q" . dumb-jump-quick-look)))
(use-package magit
:straight t
:commands (magit-status magit-file-dispatch)
:config
(setq magit-blame-styles
'((margin
(margin-format . ("%a %A %s"))
(margin-width . 42)
(margin-face . magit-blame-margin)
(margin-body-face . (magit-blame-dimmed)))
(headings
(heading-format . "%-20a %C %s\n"))
(highlight
(highlight-face . magit-blame-highlight))
(lines
(show-lines . t)
(show-message . t))))
:bind
("C-x g" . magit-status))
(use-package git-gutter
:straight t
:diminish git-gutter-mode
:config
(global-git-gutter-mode t))
(use-package git-timemachine
:straight '(git-timemachine :host github
:branch "master"
:repo "emacsmirror/git-timemachine"))
(setq magit-repository-directories '(("\~/code" . 4)))
(defun magit-status-with-prefix-arg ()
"Call `magit-status` with a prefix."
(interactive)
(let ((current-prefix-arg '(4)))
(call-interactively #'magit-status)))
(global-set-key (kbd "M-p p") 'magit-status-with-prefix-arg)
Flycheck
is a general syntax highlighting framework which other packages hook into. It’s an improvment on the built in flymake
.
Setup is pretty simple - we just enable globally and turn on a custom eslint function, and also add a custom checker for proselint.
(use-package flycheck
:straight t
:config
(add-hook 'after-init-hook 'global-flycheck-mode)
(add-to-list 'flycheck-checkers 'proselint)
(setq-default flycheck-highlighting-mode 'lines)
;; Define fringe indicator / warning levels
(define-fringe-bitmap 'flycheck-fringe-bitmap-ball
(vector #b00000000
#b00000000
#b00000000
#b00000000
#b00000000
#b00000000
#b00000000
#b00011100
#b00111110
#b00111110
#b00111110
#b00011100
#b00000000
#b00000000
#b00000000
#b00000000
#b00000000))
(flycheck-define-error-level 'error
:severity 2
:overlay-category 'flycheck-error-overlay
:fringe-bitmap 'flycheck-fringe-bitmap-ball
:fringe-face 'flycheck-fringe-error)
(flycheck-define-error-level 'warning
:severity 1
:overlay-category 'flycheck-warning-overlay
:fringe-bitmap 'flycheck-fringe-bitmap-ball
:fringe-face 'flycheck-fringe-warning)
(flycheck-define-error-level 'info
:severity 0
:overlay-category 'flycheck-info-overlay
:fringe-bitmap 'flycheck-fringe-bitmap-ball
:fringe-face 'flycheck-fringe-info))
(use-package color-identifiers-mode
:straight t
:commands color-identifiers-mode)
Company mode provides good autocomplete options. Perhaps I should add company-quickhelp for documentation (https://github.com/expez/company-quickhelp)? It would also be good to improve integration with yasnippet as I don’t feel I’m making the best use there.
(use-package company
:straight t
:config
(add-hook 'after-init-hook 'global-company-mode)
(setq company-idle-delay t)
(use-package company-anaconda
:straight t
:config
(add-to-list 'company-backends 'company-anaconda)))
I don’t want suggestions from open files / buffers to be automatically lowercased as these are often camelcase function names.
(setq company-dabbrev-downcase nil)
Type the shortcut and press TAB
to complete, or M-/
to autosuggest a snippet.
http://ergoemacs.org/emacs/yasnippet_templates_howto.html
yasnippet-snippets has to be loaded before yasnippet for user snippets to override the pre-built ones.
(use-package yasnippet-snippets
:straight t)
(use-package yasnippet
:straight t
:diminish yas-minor-mode
:config
(add-to-list 'yas-snippet-dirs "~/.emacs.d/snippets")
(yas-global-mode 1)
(global-set-key (kbd "M-/") 'company-yasnippet))
(use-package consult-yasnippet
:straight '(consult-yasnippet :host github
:branch "master"
:repo "mohkale/consult-yasnippet"))
(defun teddy-ma/toggle-side-org-buffer ()
"Toggle org file in a side buffer for quick note taking."
(interactive)
(teddy-ma/toggle-side-buffer-with-file "~/Documents/org/work.org"))
(defun teddy-ma/buffer-visible-p (buffer)
"Check if given BUFFER is visible or not. BUFFER is a string representing the buffer name."
(or
(eq buffer (window-buffer (selected-window)))
(get-buffer-window buffer)))
(defun teddy-ma/display-buffer-in-side-window (buffer)
"Just like `display-buffer-in-side-window' but only takes a BUFFER and rest of the parameters are for my taste."
(select-window
(display-buffer-in-side-window
buffer
(list (cons 'side 'right)
(cons 'slot 0)
(cons 'window-width 84)
(cons 'window-parameters
(list (cons 'no-delete-other-windows t)
(cons 'no-other-window nil)))))))
(defun teddy-ma/remove-window-with-buffer (the-buffer-name)
"Remove window containing given THE-BUFFER-NAME."
(mapc (lambda (window)
(when (string-equal (buffer-name (window-buffer window)) the-buffer-name)
(delete-window window)))
(window-list (selected-frame))))
(defun teddy-ma/toggle-side-buffer-with-file (file-path)
"Toggle FILE-PATH in a side buffer. The buffer is opened in side window so it can't be accidentaly removed."
(let ((fname (file-name-nondirectory file-path)))
(if (teddy-ma/buffer-visible-p fname)
(teddy-ma/remove-window-with-buffer fname)
(teddy-ma/display-buffer-in-side-window
(save-window-excursion
(find-file file-path)
(current-buffer))))))
Language Server Protocol
(use-package lsp-mode
:straight t)
(use-package slime
:straight t
:config
(setq inferior-lisp-program "sbcl")
)
(use-package quickrun
:straight t)
(setq-default js-indent-level 2)
JS2 mode improves on the built in JS mode.
(use-package js2-mode
:straight t
:mode "\\.js\\'"
:config
(setq-default js2-ignored-warnings '("msg.extra.trailing.comma")))
js2-refactor
supports some useful refactoring options and builds on top of js2-mode
.
(use-package js2-refactor
:straight t
:config
(js2r-add-keybindings-with-prefix "C-c C-m")
:hook
(after-js-mode . js-refactor-mode))
(use-package rjsx-mode
:straight t)
Prettier-js autoformats JS code - much like `gofmt` - and we hook it into JS2 and RJSX modes.
(use-package prettier-js
:straight t
:config
(setq prettier-js-args '(
"--trailing-comma" "es5"
"--single-quote" "true"
"--print-width" "100"
))
:hook
(after-js2-mode . prettier-js-mode)
(after-rjsx-mode . prettier-js-mode))
(use-package json-mode
:straight t)
https://vxlabs.com/2022/06/12/typescript-development-with-emacs-tree-sitter-and-lsp-in-2022/
(use-package typescript-mode
:straight t
:after tree-sitter)
(use-package yaml-mode
:straight t)
(use-package toml-mode
:straight t)
Markdown support isn’t built into Emacs, add it with markdown-mode
.
(use-package markdown-mode
:straight t
:commands (markdown-mode gfm-mode)
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:init (setq markdown-command "multimarkdown"))
(use-package lua-mode
:straight t)
(use-package fennel-mode
:straight t)
(use-package haskell-mode
:straight t)
(use-package hindent
:straight t)
Elixir highlighting is not built into emacs at present. Elixir-mode gives all the usual niceties, and alchemist improves interaction with tools like iex
, mix
and elixir-format
.
(use-package elixir-mode
:straight t)
(use-package alchemist
:straight t)
(use-package solidity-mode
:straight t)
(use-package rake
:straight t)
;; (use-package robe
;; :straight t
;; :diminish
;; :hook
;; (after-ruby-mode . robe-mode))
(use-package ruby-hash-syntax
:straight t
:diminish
:hook
(after-ruby-mode . ruby-hash-syntax))
;; (use-package rubocop
;; :straight t
;; :diminish
;; :hook
;; (after-ruby-mode . rubocop-mode))
(use-package haml-mode
:straight t)
(use-package minitest
:straight t)
(defun teddy-ma/visit-last-dired-file ()
"Open the last file in an open dired buffer."
(interactive)
(end-of-buffer)
(previous-line)
(dired-find-file))
(defun teddy-ma/visit-last-migration ()
"Open the last file in 'db/migrate/'."
(interactive)
(dired (expand-file-name "db/migrate" (projectile-project-root)))
(teddy-ma/visit-last-dired-file)
(kill-buffer "migrate"))
https://github.com/otavioschwanck/rails-routes.el
(use-package rails-routes
:straight '(rails-routes :host github
:branch "master"
:repo "otavioschwanck/rails-routes.el"))
cls -> create class with file name
(use-package projectile-rails
:straight t
:config
(define-key projectile-rails-mode-map
(kbd "C-c r")
'projectile-rails-command-map)
(setq projectile-rails-vanilla-command "bin/rails"
projectile-rails-spring-command "bin/spring"
projectile-rails-zeus-command "bin/zeus")
(projectile-rails-global-mode))
Emacs has a great built in C/C++ mode, but we can improve on it with irony-mode
for code completion via libclang
.
(use-package irony
:straight t
:hook (c-mode . irony-mode))
Add company mode support.
(use-package company-irony
:straight t
:config
(add-to-list 'company-backends 'company-irony))
Add flycheck support.
(use-package flycheck-irony
:straight t
:hook (flycheck-mode . flycheck-irony-setup))
(use-package go-mode
:straight t)
https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/
(use-package rustic
:straight t
:bind (:map rustic-mode-map
("M-j" . lsp-ui-imenu)
("M-?" . lsp-find-references)
("C-c C-c l" . flycheck-list-errors)
("C-c C-c a" . lsp-execute-code-action)
("C-c C-c r" . lsp-rename)
("C-c C-c q" . lsp-workspace-restart)
("C-c C-c Q" . lsp-workspace-shutdown)
("C-c C-c s" . lsp-rust-analyzer-status)
("C-c C-c e" . lsp-rust-analyzer-expand-macro)
("C-c C-c d" . dap-hydra)
("C-c C-c h" . lsp-ui-doc-glance))
:config
(setq rustic-babel-format-src-block nil)
)
(use-package rust-playground
:straight t)
Web mode handles html/css/js.
(use-package web-mode
:straight t
:mode (("\\.html\\'" . web-mode)
("\\.erb\\'" . web-mode))
:config
(setq web-mode-markup-indent-offset 2)
)
C-c C-e /
C-c C-n
Web beautify prettifies html / css / js using js-beautify - install with npm install -g js-beautify
.
(use-package web-beautify
:straight t
:bind (:map web-mode-map
("C-c b" . web-beautify-html)
:map js2-mode-map
("C-c b" . web-beautify-js)))
(use-package impatient-mode
:straight t)
Emmet mode, use C-j
to expand it
;; (use-package emmet-mode
;; :straight t
;; :config
;; (add-hook 'web-mode-hook 'emmet-mode)
;; (add-hook 'css-mode-hook 'emmet-mode) ;; enable Emmet's css abbreviation.
;; )
web-mode-toggle-current-element-highlight
key | description |
---|---|
C-c C-f | toggle folding on a tag/block |
C-c C-e | a select element content |
C-c C-e k | element kill (useful when html struct complex) |
C-c C-d d | show tag mismatch (check) |
C-c C-e w | wrap element |
C-c C-e v | element vanish(remove tag) |
M-; | un/comment block |
(use-package org
:straight (:type built-in)
:diminish org-indent-mode
:config
(setq org-attach-use-inheritance t) ;; use parent node id as attachment folder
(setq org-startup-indented 'f)
(setq org-special-ctrl-a/e 't)
(setq org-startup-folded t)
(setq org-tags-column -77)
(setq org-src-tab-acts-natively t)
(setq org-src-fontify-natively t)
(setq org-src-window-setup 'current-window)
;;(setq browse-url-browser-function 'browse-url-generic
;;browse-url-generic-program "Chromium")
;;(setq org-file-apps '((auto-mode . emacs)("\\.x?html?\\'" . "Chromium %s")))
)
C-c C-n | next heading (can be difference level) |
C-c C-p | previous heading (can be difference level) |
C-c C-f | next heading (same level) |
C-c C-b | previous heading (same level) |
C-c C-u | upper level |
M+S+<left/right>
eg. press `<s` and select shell or src block
(use-package company-org-block
:straight t
:custom
(company-org-block-edit-style 'auto) ;; 'auto, 'prompt, or 'inline
:hook ((org-mode . (lambda ()
(setq-local company-backends '(company-org-block))
(company-mode +1)))))
org-narrow-to-subtree (bound in org-mode)
C-x n s
(setq org-todo-keywords '((sequence "TODO" "DOING" "|" "DONE" "BLOCKED")))
to use checkbox just typing - []
for parent check list, add [/]
use C-c C-c
to toggle finish checkbox
M-S-RET
to create new checkbox
(setq org-log-into-drawer t)
(setq org-log-done 'time)
C-c C-x ;
start
C-c C-x ,
pause or continue
C-c C-x _
stop
;; (setq emacs-org-clock-sound-voice "~/Dropbox/Public/pomodoro-wei.wav")
;; (if (file-exists-p emacs-org-clock-sound-voice)
;; (setq org-clock-sound emacs-org-clock-sound-voice))
Save Org buffers after refiling!
(setq org-refile-targets
'(("~/Documents/org/archive.org" :maxlevel . 1)))
(advice-add 'org-refile :after 'org-save-all-org-buffers)
(use-package org-capture
:straight nil
:bind ("C-c c" . org-capture)
:after org
:config
(setq org-capture-templates
'(
("g" "General To-Do"
entry (file+headline "~/Documents/org/todo.org" "General Tasks")
"* TODO [#B] %?\n:Created: %T\n "
:empty-lines 0)
("c" "Code To-Do"
entry (file+headline "~/Documents/org/todo.org" "Code Related Tasks")
"* TODO [#B] %?\n:Created: %T\n%i\n%a\nProposed Solution: "
:empty-lines-before 0)
("j" "Work Log Entry"
entry (file+datetree "~/Documents/org/work.org")
"* %?"
:empty-lines 0)
)
)
)
require pngpaste installed
(use-package org-download
:straight t
:after org
:custom
(org-download-method 'attach)
(org-download-image-dir "images")
(org-download-heading-lvl nil)
(org-download-timestamp "%Y%m%d-%H%M%S_")
(org-image-actual-width 300)
(org-download-screenshot-method "/usr/local/bin/pngpaste %s")
:bind
("C-M-y" . org-download-screenshot)
:config
(require 'org-download))
(defmacro defun-open-conf (config-name filepath)
"Open conf macro.
Argument CONFIG-NAME Alias name for your function.
Argument FILEPATH Filepath of the file."
`(defun ,(intern (format "open-conf-%s" config-name)) ()
,(format "Open %s: \"%s\"" config-name filepath)
(interactive)
(open-conf ,filepath)))
(defun open-conf (filepath)
"Argument FILEPATH Filepath of the file."
;; (switch-to-buffer
;; (find-file-noselect filepath))
(find-file-other-frame filepath))
(defun-open-conf "work" "~/Documents/org/work.org")
(defun-open-conf "blog" "~/Documents/org/blog.org")
(defun-open-conf "todo" "~/Documents/org/todo.org")
;; (defun-open-conf "note" "~/Documents/org/note.org")
(defun-open-conf "reminder" "~/Documents/org/reminder.org")
;; (defun-open-conf "index" "~/Documents/org/roam/index.org")
;; (set-register ?b (cons 'file "~/Documents/org/blog.org"))
;; (set-register ?t (cons 'file "~/Documents/org/todo.org"))
;; (set-register ?n (cons 'file "~/Documents/org/note.org"))
;; (set-register ?r (cons 'file "~/Documents/org/roam/index.org"))
I can style it myself
(setq org-html-head-include-default-style nil
org-html-htmlize-output-type 'css)
in src block press C-c C-c
to run code
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(lisp . t)
(ruby . t)
(js .t )
(lua .t )
(shell . t)))
(use-package wrap-region
:straight t
:config
(wrap-region-add-wrappers
'(("*" "*" nil org-mode)
("~" "~" nil org-mode)
("/" "/" nil org-mode)
("=" "=" "+" org-mode)
("_" "_" nil org-mode)
("$" "$" nil org-mode )))
(add-hook 'org-mode-hook 'wrap-region-mode))
Use C-c |
to fire create table function
input |||
and press TAB to quick insert a three colum table
Interactive agenda in the console https://github.com/rougier/agenda
(use-package org-agenda
:straight nil
:bind ("C-c a" . org-agenda)
:config
(setq org-agenda-files (directory-files-recursively "~/Documents/org/" "\\.org$"))
;; (setq org-agenda-files '(
;; "~/Documents/org/work.org"
;; "~/Documents/org/reminder.org"
;; ))
(setq org-agenda-start-with-log-mode t)
(setq org-agenda-prefix-format
'((agenda . " %i %-24:c%?-16t%-10e% s")
(todo . " %i %-36:c %-16e")
(tags . " %i %-24:c")
(search . " %i %-24:c")))
;; https://www.philnewton.net/blog/how-i-get-work-done-with-emacs/
(setq org-agenda-custom-commands
'(("d" "Today's Tasks"
((agenda "" ((org-agenda-span 1)
(org-agenda-overriding-header "Today's Tasks")))))))
)
(use-package emacsql-sqlite
:straight t)
(use-package org-roam
:straight (:host github :repo "org-roam/org-roam" :files (:defaults "extensions/*"))
:init
(setq org-roam-v2-ack t)
:custom
(org-roam-directory (file-truename "~/Documents/org/roam/"))
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . org-roam-node-find)
("C-c n g" . org-roam-graph)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
;; Dailies
("C-c n j" . org-roam-dailies-capture-today))
:config
(org-roam-setup))
(use-package org-roam-ui
:straight
(:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
:after org-roam
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start nil))
move the cursor to the heading, and run:
org-id-get-create
;; (custom-set-faces
;; '(default ((t (:foreground "#BBC2CF"))))
;; '(org-level-1 ((t (:foreground "#BF9D7A"))))
;; '(org-level-2 ((t (:foreground "#E4E9CD"))))
;; '(org-level-3 ((t (:foreground "#EBF2EA"))))
;; '(org-level-4 ((t (:foreground "#0ABDA0"))))
;; '(org-level-5 ((t (:foreground "#80ADD7")))))
(use-package org-superstar
:straight t
:hook (org-mode . org-superstar-mode))
(use-package org-pretty-tags
:diminish org-pretty-tags-mode
:straight t
:config
;;(setq org-pretty-tags-surrogate-strings
;; '(
;; ("work" . "⚒")
;; ("@pc" . "🖥")
;; ("@ps5" . "🎮")
;; ("@switch" . "🕹")
;; ("@script" . "📝")
;; ))
(org-pretty-tags-global-mode))
(use-package hl-todo
:straight t
:hook ((prog-mode org-mode) . teddy-ma/hl-todo-init)
:init
(defun teddy-ma/hl-todo-init ()
(setq-local hl-todo-keyword-faces '(("TODO" . "#ff9977")
("DOING" . "#FF00BC")
("DONE" . "#44bc44")
("BLOCKED" . "#003366")
))
(hl-todo-mode))
)
(use-package org-fancy-priorities
:diminish
:straight t
:hook (org-mode . org-fancy-priorities-mode)
:config
(setq org-fancy-priorities-list '("🅰" "🅱" "🅲" "🅳" "🅴")))
Set fixed pitch font for org (conflict with Chinese table)
;; conflict with chinese table in org
(defun teddy-ma/org-font-setup ()
;; (set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
;; (set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
;; (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
;; (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
)
(use-package visual-fill-column
:straight t
:hook (org-mode . visual-fill-column-mode)
:custom
(visual-fill-column-center-text t)
(visual-fill-column-width 120))
to intensify the sense of achievement.
;; (setq org-fontify-done-headline t)
;; (set-face-attribute 'org-done nil :strike-through t)
;; (set-face-attribute 'org-headline-done nil
;; :strike-through t
;; :foreground "light gray")
(defun teddy-ma/org-block-setup ()
(let ((background-color (face-background 'default))
(foreground-color (face-foreground 'default))
(primary-green "#60a83d"))
(set-face-attribute 'fringe nil :foreground foreground-color :background background-color)
(set-face-attribute 'org-indent nil :background nil :foreground nil)
(set-face-attribute 'org-block-begin-line nil :foreground primary-green :background nil)
(set-face-attribute 'org-block-end-line nil :foreground primary-green :background nil))
)
;;(set-face-attribute 'org-block nil :background "red")))
;;(set-face-attribute 'org-level-2 nil :height 1.3 :background "#60a83d")
(setq org-hide-emphasis-markers nil)
(setq org-ellipsis " ▾") ;; ↴, ▼, ▶, ⤵, ▾
(defun teddy-ma/org-buffer-setup ()
;;(push '("[ ]" . "☐" ) prettify-symbols-alist)
;;(push '("☑" . "☑" ) prettify-symbols-alist)
;;(push '("[-]" . "❍" ) prettify-symbols-alist)
(prettify-symbols-mode))
;; (setq-default prettify-symbols-alist '(("#+BEGIN_SRC" . "»") ("#+END_SRC" . "«")("#+begin_src" . "»") ("#+end_src" . "«") ("lambda" . "λ") ("->" . "→") ("->>" . "↠")))
(use-package org
:straight (:type built-in)
:diminish org-indent-mode
:hook
(org-mode . teddy-ma/org-font-setup)
(org-mode . teddy-ma/org-block-setup)
(org-mode . teddy-ma/org-buffer-setup))
M - < and M - >
press ^
press v
in dired mode, embark-export and Edit, change file names and save
for project search, use find-name-dired
select root folder path and wdired-change-to-wdired-mode
https://geekinney.com/post/emacs-workflow-file-management/
(use-package dired-subtree
:straight t
:after dired
:config
(setq dired-subtree-use-backgrounds nil)
:bind (:map dired-mode-map
("TAB" . dired-subtree-toggle)))
https://xenodium.com/emacs-clone-git-repo-from-clipboard
(defun ar/git-clone-clipboard-url ()
"Clone git URL in clipboard asynchronously and open in dired when finished."
(interactive)
(cl-assert (string-match-p "^\\(http\\|https\\|ssh\\)://" (current-kill 0)) nil "No URL in clipboard")
(let* ((url (current-kill 0))
(download-dir (expand-file-name "~/Downloads/"))
(project-dir (concat (file-name-as-directory download-dir)
(file-name-base url)))
(default-directory download-dir)
(command (format "git clone %s" url))
(buffer (generate-new-buffer (format "*%s*" command)))
(proc))
(when (file-exists-p project-dir)
(if (y-or-n-p (format "%s exists. delete?" (file-name-base url)))
(delete-directory project-dir t)
(user-error "Bailed")))
(switch-to-buffer buffer)
(setq proc (start-process-shell-command (nth 0 (split-string command)) buffer command))
(with-current-buffer buffer
(setq default-directory download-dir)
(shell-command-save-pos-or-erase)
(require 'shell)
(shell-mode)
(view-mode +1))
(set-process-sentinel proc (lambda (process state)
(let ((output (with-current-buffer (process-buffer process)
(buffer-string))))
(kill-buffer (process-buffer process))
(if (= (process-exit-status process) 0)
(progn
(message "finished: %s" command)
(dired project-dir))
(user-error (format "%s\n%s" command output))))))
(set-process-filter proc #'comint-output-filter)))
Open the Magit status buffer (C-x g
)
Press y
to get a listing of all branches and tags in the git repo
Navigate to the branch you want to delete and press k
(use-package blamer
:straight
(:host github :repo "artawower/blamer.el" :branch "master")
:custom
(blamer-idle-time 0.3)
(blamer-min-offset 70)
:custom-face
(blamer-face ((t :foreground "#7a88cf"
:background nil
:height 140
:italic t)))
)
(use-package git-link
:straight
(:host github :repo "sshaw/git-link" :branch "master"))
- Open (magit-status)
C-x g
- press
l
- limit to files
--
- press
l
again
need aspell to ispell (brew install aspell)
(setq ispell-program-name "aspell")
Proselint is a syntax checker for English language. This defines a custom checker which will run in texty modes.
Proselint is an external program, install it with pip install proselint
for this to work.
(flycheck-define-checker proselint
"A linter for prose."
:command ("proselint" source-inplace)
:error-patterns
((warning line-start (file-name) ":" line ":" column ": "
(id (one-or-more (not (any " "))))
(message (one-or-more not-newline)
(zero-or-more "\n" (any " ") (one-or-more not-newline)))
line-end))
:modes (text-mode markdown-mode gfm-mode org-mode))
(use-package pyim
:straight t
:demand t
:config
(use-package pyim-basedict
:straight t
:config (pyim-basedict-enable))
(setq default-input-method "pyim")
(setq-default pyim-english-input-switch-functions
'(pyim-probe-dynamic-english
pyim-probe-isearch-mode
pyim-probe-program-mode
pyim-probe-org-structure-template))
(setq-default pyim-punctuation-half-width-functions
'(pyim-probe-punctuation-line-beginning
pyim-probe-punctuation-after-punctuation))
;;(pyim-isearch-mode 1)
(setq pyim-page-tooltip 'posframe)
(setq pyim-page-length 5)
(setq pyim-dicts
'((:name "tsinghua"
:file "~/Dropbox/Config/pyim-tsinghua-dict.pyim")))
:bind
(("M-j" . pyim-convert-string-at-point)))
(use-package youdao-dictionary
:straight t
:config
(setq url-automatic-caching t))
eshell with git https://github.com/elken/eshell-p10k optional theme
(use-package eshell-git-prompt
:straight t)
(use-package eshell
:straight t
:config
(eshell-git-prompt-use-theme 'powerline)
(add-hook 'eshell-mode-hook (lambda ()
(setq-local global-hl-line-mode
nil))))
vterm (need compile)
;; (when(not (eq system-type 'windows-nt))
;; (use-package vterm
;; :straight t
;; :config
;; (setq vterm-shell (executable-find "fish")
;; vterm-max-scrollback 10000))
;; (use-package vterm-toggle
;; :straight t)
;; (use-package shell-pop
;; :straight t
;; :custom
;; (shell-pop-shell-type '("vterm" "*vterm*" (lambda () (vterm))))
;; (shell-pop-full-span t))
;; )
(defun hikarian-hello()
(interactive)
(message "hello"))
(defun hikarian-visit-last-migration ()
"Open the last file in 'db/migrate/'."
(interactive)
(dired (expand-file-name "db/migrate" (projectile-project-root)))
(end-of-buffer)
(previous-line)
(dired-find-file)
(kill-buffer "migrate"))
;;(setq rails-routes-list (""))
(defun hikarian-insert-route ()
"List all the routes and let user select one to insert"
;; (let* ((selected-value (split-string (completing-read "Route: " (rails-routes--get-routes-cached)) " +"))
;; (selected-route (nth (if (eq (length selected-value) 5) 3 2) selected-value)))
;; (when (not (rails-routes--guess-ignore-class)) (insert rails-routes-class-name))
;; (rails-routes--insert-value selected-value)
;; (when (or (string-match-p ":id" selected-route)
;; (string-match-p ":[a-zA-Z0-9]+_id" selected-route))
;; (progn (insert "()") (backward-char)))))
()
)
(defun hikarian-get-routes-from-command ()
"Run rails-routes-search-command and return it."
(interactive)
(message "Fetching routes. Please wait.")
(let ((command-result ((split-string (shell-command-to-string "rails routes") "\n"))))
(message "rails routes no need to run in project root, the result is: %s" command-result)
command-result))
(defun hikarian-list-resource-files(resource_name)
"list relation resource"
())
(defun hikarian--auto-insert-init-template ()
"init code template when file create."
(interactive)
;; make sure auto inser mode active
(auto-insert-mode t)
(let* ((file-re (format "^%s.*\\.rb$" (projectile-project-root)))
(current-project-cond `(,file-re . "hikarian")))
(message "file re is %s" file-re)
(define-auto-insert
current-project-cond
[
(lambda ()
(let ((snippet (hikarian-corresponding-snippet)))
(when snippet
(insert snippet))))
hikarian-expand-yas-buffer ;; after buffer with template, then expand it
]
)))
;; (string-match "app/models/\\(.+\\)\\.rb$" name)
;; (projectile-rails--snippet-for-model (match-string 1 name))
(defun hikarian-corresponding-snippet ()
;;"module %s\n extend ActiveSupport::Concern\n $0\nend")
"cls")
(defun hikarian-expand-yas-buffer ()
"Called right after buffer is populate with snippet by Auto-insert mode."
(interactive)
(yas-lookup-snippet (buffer-string) (point-min) (point-max) '((yas-indent-line 'nothing))))
(defun autoinsert-yas-expand()
"Replace text in yasnippet template."
(interactive)
(yas-expand-snippet (buffer-string) (point-min) (point-max)))
(defun test-autoinsert()
(interactive)
(yas-expand-snippet (yas-lookup-snippet "class ... end")))
;;(add-hook 'projectile-rails-mode-hook #'projectile-rails-setup-auto-insert-maybe)
(provide 'hikarian)
;;; hikarian.el ends here