- Basic Setting
- Custom Function
- Packages
- Using Emacs China Package Source
- Elpaca Package Manager
- Evil Mode
- Workspace Managment
- Buffer Managment
- Theme
- Org Package
- Latex
- General Config
- Focus Mode
- Indentation
- Auto Pair
- Jumping
- Magit
- Rainbow-Bracket
- Rainbow-Delimters
- Highlight-TODO
- Icons
- Neotree
- BugHunter
- Modeline
- Which Key
- Dashboard
- Project File
- Minibuffer
- Fly Check
- Completion
- Consult
- Search
- Development
- Terminal
- Sudo Edit
- Window Manager
- Blog
- KeyCast
- Hacker News
- EPMV
- Elfeed
- Nov
- Ztree
- SimpleClip
- ChatGpt-Shell
(setq inhibit-startup-message t)
;; disable tool bar menu bar scroll bar
(tool-bar-mode -1)
(menu-bar-mode -1)
;;(scroll-bar-mode -1)
;; highlight current line
(global-hl-line-mode t)
;; show line number
(line-number-mode t)
;; auto refresh when configure is updated
(global-auto-revert-mode t)
;; line number mode
(require 'display-line-numbers)
(defun display-line-numbers--turn-on ()
"Turn on display-line-numbers-mode."
(unless (or (minibufferp) (eq major-mode 'pdf-view-mode))
(display-line-numbers-mode)))
(global-display-line-numbers-mode 1)
(global-visual-line-mode t)
;; backup files
(setq backup-directory-alist '((".*" . "~/.local/share/Trash/files")))
;; auto pair
(electric-pair-mode nil)
;; dired auto refresh
(add-hook 'dired-mode-hook 'auto-revert-mode)
(set-face-attribute 'default nil
:font "JetBrainsMono Nerd Font"
:height 110
:weight 'medium)
(set-face-attribute 'variable-pitch nil
:font "JetBrainsMono Nerd Font"
:height 120
:weight 'medium)
(set-face-attribute 'fixed-pitch nil
:font "JetBrainsMono Nerd Font"
:height 110
:weight 'medium)
;; Makes commented text and keywords italics.
;; This is working in emacsclient but not emacs.
;; Your font must have an italic face available.
(set-face-attribute 'font-lock-comment-face nil
:slant 'italic)
(set-face-attribute 'font-lock-keyword-face nil
:slant 'italic)
;; This sets the default font on all graphical frames created after restarting Emacs.
;; Does the same thing as 'set-face-attribute default' above, but emacsclient fonts
;; are not right unless I also add this method of setting the default font.
(add-to-list 'default-frame-alist '(font . "JetBrainsMono Nerd Font"))
;; Uncomment the following line if line spacing needs adjusting.
(setq-default line-spacing 0.12)
(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "<C-wheel-up>") 'text-scale-increase)
(global-set-key (kbd "<C-wheel-down>") 'text-scale-decrease)
;; reload configuration
(defun reload-init-file ()
(interactive)
(load-file user-init-file)
(load-file user-init-file)
)
(defun eval-and-append-result ()
"Evaluate the expression before the point, append the result, and insert a new line with a comment."
(interactive)
(let ((result (eval (preceding-sexp))))
;; Insert the result as a string
(insert (format " ; => %s" result))
))
(defun eval-region-and-append-result (start end)
"Evaluate the region from START to END and append the result as a comment."
(interactive "r") ; 'r' means this command works on the current region
(let ((result (eval (read (buffer-substring start end)))))
;; Move point to the end of the current region
(goto-char end)
;; Insert the result as a comment
(insert (format " ; => %s" result)))
)
(setq package-archives '(("gnu" . "http://1.15.88.122/gnu/")
("melpa" . "http://1.15.88.122/melpa/")))
(defvar elpaca-installer-version 0.7)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
:ref nil :depth 1
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
:build (:not elpaca--activate-package)))
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
(build (expand-file-name "elpaca/" elpaca-builds-directory))
(order (cdr elpaca-order))
(default-directory repo))
(add-to-list 'load-path (if (file-exists-p build) build repo))
(unless (file-exists-p repo)
(make-directory repo t)
(when (< emacs-major-version 28) (require 'subr-x))
(condition-case-unless-debug err
(if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
,@(when-let ((depth (plist-get order :depth)))
(list (format "--depth=%d" depth) "--no-single-branch"))
,(plist-get order :repo) ,repo))))
((zerop (call-process "git" nil buffer t "checkout"
(or (plist-get order :ref) "--"))))
(emacs (concat invocation-directory invocation-name))
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
((require 'elpaca))
((elpaca-generate-autoloads "elpaca" repo)))
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
(error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
(unless (require 'elpaca-autoloads nil t)
(require 'elpaca)
(elpaca-generate-autoloads "elpaca" repo)
(load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))
;; Install a package via the elpaca macro
;; See the "recipes" section of the manual for more details.
;; (elpaca example-package)
;; Install use-package support
(elpaca elpaca-use-package
;; Enable use-package :ensure support for Elpaca.
(elpaca-use-package-mode))
;; Block until current queue processed.
(elpaca-wait)
;;When installing a package which modifies a form used at the top-level
;;(e.g. a package which adds a use-package key word),
;;use `elpaca-wait' to block until that package has been installed/configured.
;;For example:
;;(use-package general :ensure t :demand t)
;;(elpaca-wait)
;;Turns off elpaca-use-package-mode current declaration
;;Note this will cause the declaration to be interpreted immediately (not deferred).
;;Useful for configuring built-in emacs features.
;;(use-package emacs :ensure nil :config (setq ring-bell-function #'ignore))
;; Don't install anything. Defer execution of BODY
;;(elpaca nil (message "deferred"))
;; Expands to: (elpaca evil (use-package evil :demand t))
(use-package evil
:init
(setq evil-want-integration t)
(setq evil-want-keybinding nil)
(setq evil-vsplit-window-right t)
(setq evil-split-window-below t)
:ensure t
:demand nil
:config
(evil-mode)
(setq x-select-enable-clipboard nil)
)
(use-package evil-collection
:after evil
:ensure t
:demand nil
:config
(setq evil-collection-mode-list
'(dashboard dired ibuffer pdf magit neotree vterm elfeed nov)
)
(evil-collection-init))
(use-package evil-commentary
:after evil
:ensure t
:demand nil
:config
(evil-commentary-mode))
(use-package evil-surround
:after evil
:ensure t
:demand nil
:config
(global-evil-surround-mode))
(use-package evil-org
:ensure t
:after org
:hook (org-mode . (lambda () evil-org-mode))
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys)
)
(add-hook 'org-capture-mode-hook 'evil-insert-state)
(elpaca-wait)
(use-package perspective
:ensure t
:init
(persp-mode)
)
(setq persp-suppress-no-prefix-key-warning t)
(setq dired-dwim-target t)
(use-package frog-jump-buffer :ensure t)
(use-package doom-themes
:ensure t
:config
;; Global settings (defaults)
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-molokai t)
;; Enable flashing mode-line on errors
(doom-themes-visual-bell-config)
;; Enable custom neotree theme (all-the-icons must be installed!)
(doom-themes-neotree-config)
;; or for treemacs users
(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
(doom-themes-treemacs-config)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config))
(add-hook 'org-mode-hook 'org-indent-mode)
;; Increase line spacing
(setq-default line-spacing 2)
(setq org-todo-keywords
'((sequence "TODO" "IN-PROGRESS" "WAITING" "|" "DONE" "CANCELED")))
(setq org-directory "~/Org/"
org-agenda-files '("~/Org/agenda.org")
org-default-notes-file (expand-file-name "notes.org" org-directory)
org-ellipsis " ▼ "
org-log-done 'time
org-journal-dir "~/Org/journal/"
org-journal-date-format "%B %d, %Y (%A) "
org-journal-file-format "%Y-%m-%d.org"
org-hide-emphasis-markers t)
(setq org-src-preserve-indentation nil
org-src-tab-acts-natively t
org-edit-src-content-indentation 0
org-startup-align-all-tables t
org-src-fontify-natively t
org-confirm-babel-evaluate nil)
(setq org-agenda-custom-commands
'(("f" occur-tree "FIXME")))
(setq org-startup-align-all-tables t)
(setq org-log-done 'time)
(setq org-agenda=include-diary t)
(setq org-startup-folded "showall")
;; (setq org-agenda-time-grid t)
;; update checkbox automatically
(defun update_checkbox()
(org-update-checkbox-count t)
)
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook 'update_checkbox nil 'make-it-local)))
;; Clocking Work Time
(setq org-clock-persist 'histroy)
;;(org-clock-persistance-insinuate)
;; Setting org-capture
(setq org-capture-templates '(("t" "Todo" entry (file+headline "~/Org/gtd.org" "Tasks")
"* TODO %T \n %?\n")
("i" "Idea" entry (file+datetree "~/Org/idea.org")
"* Idea \n %? ")))
(use-package toc-org
:ensure t
:commands toc-org-enable
:init (add-hook 'org-mode-hook 'toc-org-enable))
;;(org-babel-do-load-languages
;;'org-babel-load-languages
;;'((emacs-lisp . t)
;;(julia . t)
;;(python . t)
;;(jupyter . t)))
(use-package org-modern
:ensure t
:config
(add-hook 'org-mode-hook 'global-org-modern-mode)
(setq
;; Edit settings
org-auto-align-tags nil
org-tags-column 0
org-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t
;; Org styling, hide markup etc.
org-hide-emphasis-markers t
org-pretty-entities t
org-ellipsis "…"
;; Agenda styling
org-agenda-tags-column 0
org-agenda-block-separator ?─
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
org-agenda-current-time-string
"◀── now ─────────────────────────────────────────────────")
)
;; Option 2: Globally
(use-package org-appear
:ensure t
:config
(add-hook 'org-mode-hook 'org-appear-mode)
(setq org-appear-trigger 'manual)
(add-hook 'org-mode-hook (lambda ()
(add-hook 'evil-insert-state-entry-hook
#'org-appear-manual-start
nil
t)
(add-hook 'evil-insert-state-exit-hook
#'org-appear-manual-stop
nil
t)))
)
(use-package org-bullets :ensure t)
;;(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
(require 'org-tempo)
(use-package org-super-agenda :ensure t :config (org-super-agenda-mode t))
;; This is an Emacs package that creates graphviz directed graphs from
;; the headings of an org file
(use-package org-mind-map
:init
(require 'ox-org)
:ensure t
;; Uncomment the below if 'ensure-system-packages` is installed
;;:ensure-system-package (gvgen . graphviz)
:config
(setq org-mind-map-engine "dot") ; Default. Directed Graph
;; (setq org-mind-map-engine "neato") ; Undirected Spring Graph
;; (setq org-mind-map-engine "twopi") ; Radial Layout
;; (setq org-mind-map-engine "fdp") ; Undirected Spring Force-Directed
;; (setq org-mind-map-engine "sfdp") ; Multiscale version of fdp for the layout of large graphs
;; (setq org-mind-map-engine "twopi") ; Radial layouts
;; (setq org-mind-map-engine "circo") ; Circular Layout
)
(use-package org-preview-html :ensure t)
(use-package org-auto-tangle
:ensure t
:hook (org-mode . org-auto-tangle-mode)
)
org roam for note-taking
(use-package org-roam
:ensure t
:init
(setq org-roam-v2-ack t)
:custom
;; TODO: create dir before loading
(org-roam-directory (file-truename "~/Org/Note"))
(org-roam-dailies-directory (file-truename "~/Org/Journal"))
(org-roam-completion-everywhere t)
(org-roam-capture-templates '(("d" "default" plain "%?"
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n")
:unnarrowed t)
)
)
: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
;; If you're using a vertical completion framework, you might want a more informative completion interface
(setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
(org-roam-db-autosync-mode)
;; If using org-roam-protocol
(require 'org-roam-protocol)
(require 'org-roam-dailies)
;; TODO
;; (setq org-roam-dailies-capture-templates
;; )
)
(use-package org-roam-ui
:ensure t
(:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
:after org-roam
;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
;; a hookable mode anymore, you're advised to pick something yourself
;; if you don't care about startup time, use
;; :hook (after-init . org-roam-ui-mode)
: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 t))
(use-package org-journal
:ensure
t
:bind
("C-c n j" . org-journal-new-entry)
:custom
(org-journal-date-prefix "#+title: ")
(org-journal-file-format "%Y-%m-%d.org")
(org-journal-dir "~/Org/Journal")
(org-journal-date-format "%A, %d %B %Y")
:config
(setq org-journal-dir "~/Org/Journal")
(setq org-journal-enable-agenda-integration t)
)
(defun org-journal-find-location ()
;; Open today's journal, but specify a non-nil prefix argument in order to
;; inhibit inserting the heading; org-capture will insert the heading.
(org-journal-new-entry t)
(unless (eq org-journal-file-type 'daily)
(org-narrow-to-subtree))
(goto-char (point-max)))
(setq org-capture-templates '(("j" "Journal entry" plain (function org-journal-find-location)
"** %(format-time-string org-journal-time-format)%^{Title}\n%i%?"
:jump-to-captured t :immediate-finish t)))
(use-package org-download
:ensure t
:after org
:bind
(:map org-mode-map
(("s-Y" . org-download-screenshot)
("s-y" . org-download-yank))))
;; Drag-and-drop to `dired`
(add-hook 'dired-mode-hook 'org-download-enable)
(use-package org-pomodoro :ensure t)
(use-package org-ref :ensure t)
(use-package org-noter :ensure t)
(use-package org-web-tools :ensure t)
(use-package org-fragtog
:ensure t
:after org
:custom
(org-startup-with-latex-preview t)
:hook
(org-mode . org-fragtog-mode)
:custom
(org-format-latex-options
(plist-put org-format-latex-options :scale 5)
(plist-put org-format-latex-options :foreground 'auto)
(plist-put org-format-latex-options :background 'auto)))
;;(setq org-format-latex-options (plist-put org-format-latex-options :scale 2:0.0))
TODO all packages keymap using general for configuration
(use-package general
:ensure t
:init
(setq general-override-states '(insert
emacs
hybrid
normal
visual
motion
operator
replace
))
:config
(general-evil-setup)
;; set up 'SPC' as the global leader key
(general-create-definer leader-key
:states '(normal insert visual emacs)
:keymaps 'override
:prefix "SPC" ;; set leader
:global-prefix "M-SPC") ;; access leader in insert mode
;; evil rebind ecs key to bn: bn means "back to normal"
(general-imap "b"
(general-key-dispatch 'self-insert-command
:timeout 0.1
"n" 'evil-normal-state))
;; help
(leader-key
"h" '(:ignore t :wk "Help")
"h v" '(describe-variable :wk "Describe Variable")
"h f" '(describe-function :wk "Describe Function")
)
;; fast execute M-x
(leader-key
"h" '(:ignore t :wk "Help")
"h v" '(describe-variable :wk "Describe Variable")
"h f" '(describe-function :wk "Describe Function")
)
(general-def 'normal 'override
"C-h" 'evil-window-left
"C-j" 'evil-window-down
"C-k" 'evil-window-up
"C-l" 'evil-window-right
"m" 'delete-other-windows
)
(general-def 'insert 'override
"C-b" 'frog-jump-buffer
)
(leader-key
"b" '(:ignore t :wk "Bookmarks/Buffers")
"b s" '(switch-to-buffer :wk "Switch to buffer")
"b c" '(clone-indirect-buffer :wk "Create indirect buffer copy in a split")
"b C" '(clone-indirect-buffer-other-window :wk "Clone indirect buffer in new window")
"b i" '(ibuffer :wk "Ibuffer")
"b n" '(next-buffer :wk "Next buffer")
"b p" '(previous-buffer :wk "Previous buffer")
"b k" '(kill-current-buffer :wk "Kill current buffer")
)
;; window
(leader-key
"w m" '(delete-other-windows :wk "Delete Other Windows")
)
;; Navigating
(leader-key
"g w" '(avy-goto-word-1 :wk "Avy Go To Word")
"g c" '(avy-goto-char-timer :wk "Avy Go To Char With Timer")
"g l" '(avy-goto-line :wk "Avy Go To Link")
)
;; config
(leader-key
"f f" '(find-file :wk "Find file")
"f c" '((lambda () (interactive) (find-file "~/.emacs.d/config.org")) :wk "Edit emacs config") "f r" '(counsel-recentf :wk "Find recent files")
"f a" '((lambda () (interactive) (find-file "~/Org/agenda.org")) :wk "Open My Agneda") "f r" '(counsel-recentf :wk "Find recent files")
"f p" '((lambda () (interactive) (find-file "~/Org/project.org")) :wk "Open My Projects") "f r" '(counsel-recentf :wk "Find recent files")
"f i" '((lambda () (interactive) (find-file "~/Org/idea.org")) :wk "Open Idea.Org") "f r" '(counsel-recentf :wk "Find recent files")
"f r" '(reload-init-file :wk "Reload Config")
)
;; org
(leader-key
"o a" '(org-agenda :wk "Open Org Agenda")
"o c" '(org-roam-capture :wk "Org Roam Capture Node")
"o t" '(org-pomodoro :wk "Pomodoro Timing")
"o s" '(org-schedule :wk "Add Schedule Timestamp")
"o d" '(org-deadline :wk "Add Deadline Timestamp")
"o p" '(org-open-at-point :wk "Org Open At Point")
"o j" '(org-journal-new-entry :wk "New Org Jounral")
)
;; magit
(leader-key
"g g" '(magit :wk "Call Magit")
)
;; use perspective to manage workspace
(leader-key
"p n" '(persp-next :wk "Perspective next")
"p p" '(persp-prev :wk "Perspective previous")
"p c" '(persp-switch :wk "Perspective switch")
"p r" '(persp-rename :wk "Rename Perspective")
)
;; completition
(leader-key
"c" '(company-complete :wk "Call Company Completion")
)
;; file explorer
(leader-key
"e" '(neotree-toggle :wk "Open Neotree")
)
;; Embark
(leader-key
"a" '(embark-act :wk "Embark Act")
)
;; projectile
(leader-key
"p s" '(projectile-switch-project :wk "Projectile Switch Project")
)
;; other
(leader-key
"z" '(darkroom-mode :wk "Zen Mode")
)
)
(use-package focus :ensure t)
(use-package dimmer :ensure t :config
(dimmer-configure-which-key)
(dimmer-configure-helm)
(dimmer-mode t))
DarkRoom for Zen Mode
(use-package darkroom :ensure t)
(use-package aggressive-indent
:ensure t
:config
(add-to-list 'aggressive-indent-excluded-modes '(
html-mode c++-ts-mode c++-mode
))
(global-aggressive-indent-mode 1)
)
(use-package smartparens-mode
:ensure smartparens ;; install the package
:hook (prog-mode text-mode markdown-mode) ;; add `smartparens-mode` to these hooks
:config
;; load default config
(require 'smartparens-config))
(use-package avy :ensure t)
TODO learn magit link
(use-package transient :ensure t)
(use-package magit :ensure t :after transient)
(use-package rainbow-mode :ensure t :hook org-mode prog-mode)
(use-package rainbow-delimiters
:ensure t
:hook ((org-mode . rainbow-delimiters-mode)
(prog-mode . rainbow-delimiters-mode)))
(use-package hl-todo
:ensure t
:hook ((org-mode . hl-todo-mode)
(prog-mode . hl-todo-mode))
:config
(setq hl-todo-highlight-punctuation ":"
hl-todo-keyword-faces
`(("TODO" warning bold)
("PROJECT" font-lock-keyword-face bold)
("ACTION" font-lock-keyword-face bold)
("FIXME" error bold)
("HACK" font-lock-constant-face bold)
("REVIEW" font-lock-keyword-face bold)
("DONE" success bold)
("NOTE" success bold)
("LATER" font-lock-constant-face bold)
("DEPRECATED" font-lock-doc-face bold))))
(use-package all-the-icons
:ensure t
:if (display-graphic-p))
(use-package all-the-icons-dired
:ensure t
:hook (dired-mode . (lambda () (all-the-icons-dired-mode t))))
(use-package all-the-icons-completion
:ensure t
:after (marginalia all-the-icons)
:hook (marginalia-mode . all-the-icons-completion-marginalia-setup)
:init
(all-the-icons-completion-mode))
(use-package neotree
:ensure t
:config
(setq neo-smart-open t
neo-show-hidden-files t
neo-window-width 35
neo-window-fixed-size nil
inhibit-compacting-font-caches t
projectile-switch-project-action 'neotree-projectile-action)
)
(setq neo-theme (if (display-graphic-p) 'icons 'arrow))
bug hunter for hunting emacs configuration file
(use-package bug-hunter
:ensure t
)
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1)
:config
(setq doom-modeline-height 35 ;; sets modeline height
doom-modeline-bar-width 5 ;; sets right bar width
doom-modeline-persp-name t ;; adds perspective name to modeline
doom-modeline-persp-icon t)) ;; adds folder icon next to persp name
(use-package which-key
:ensure t
:init
(which-key-mode 1)
:config
(setq which-key-side-window-location 'bottom
which-key-sort-order #'which-key-key-order-alpha
which-key-sort-uppercase-first nil
which-key-add-column-padding 1
which-key-max-display-columns nil
which-key-min-display-lines 6
which-key-side-window-slot -10
which-key-side-window-max-height 0.25
which-key-idle-delay 0.8
which-key-max-description-length 25
which-key-allow-imprecise-window-fit t
which-key-separator " → " ))
;;install dashboard
(use-package dashboard
:ensure t
:init
(setq dashboard-set-heading-icons t)
(setq dashboard-set-file-icons t)
(setq dashboard-banner-logo-title "emacs rocks")
(setq dashboard-startup-banner 'logo)
(setq dashboard-center-content t)
(setq dashboard-icon-type 'all-the-icons)
(setq dashboard-week-agenda t)
(setq dashboard-projects-backend 'projectile)
(setq dashboard-items '((recents . 5)
(projects . 3)
(agenda . 3)))
:config
(add-hook 'elpaca-after-init-hook #'dashboard-insert-startupify-lists)
(add-hook 'elpaca-after-init-hook #'dashboard-initialize)
(dashboard-setup-startup-hook)
)
(use-package projectile
:ensure t
:config
(projectile-mode +1)
(setq projectile-auto-discover t)
;; (projectile-register-project-type 'npm '("package.json")
;; :project-file "package.json"
;; :compile "npm install"
;; :test "npm test"
;; :run "npm start"
;; :test-suffix ".spec")
(projectile-register-project-type 'evans-project '("project-org")
:project-file "project.org"
)
)
;;install vertico
(use-package vertico
:ensure t
:init
(vertico-mode)
;; Different scroll margin
;; (setq vertico-scroll-margin 0)
;; Show more candidates
(setq vertico-count 20)
;; Grow and shrink the Vertico minibuffer
(setq vertico-resize t)
;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
(setq vertico-cycle t))
;; Enable rich annotations using the Marginalia package
(use-package marginalia
;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding
;; available in the *Completions* buffer, add it to the
;; `completion-list-mode-map'.
:ensure t
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
;; The :init section is always executed.
:init
;; Marginalia must be actived in the :init section of use-package such that
;; the mode gets enabled right away. Note that this forces loading the
;; package.
(marginalia-mode))
(use-package flycheck
:ensure t :config (add-hook 'after-init-hook #'global-flycheck-mode))
(use-package company
:ensure t
:init
(global-company-mode t)
:custom
(company-begin-commands '(self-insert-command)
(company-minimum-prefix-length 1)
(company-selection-wrap-around t)
(company-tng-configure-default)
(company-idle-delay 0.05))
)
(setq completion-ignore-case t)
;; With use-package:
(use-package company-box
:ensure t
:after company
:hook (company-mode . company-box-mode))
(use-package company-quickhelp
:ensure t
:after company
:init
(company-quickhelp-mode)
)
;; Add extensions
(use-package cape
:ensure t
:demand t
;; Bind dedicated completion commands
;; Alternative prefix keys: C-c p, M-p, M-+, ...
:bind (("C-c p p" . completion-at-point) ;; capf
("C-c p t" . complete-tag) ;; etags
("C-c p d" . cape-dabbrev) ;; or dabbrev-completion
("C-c p h" . cape-history)
("C-c p f" . cape-file)
("C-c p k" . cape-keyword)
("C-c p s" . cape-elisp-symbol)
("C-c p e" . cape-elisp-block)
("C-c p a" . cape-abbrev)
("C-c p l" . cape-line)
("C-c p w" . cape-dict)
("C-c p :" . cape-emoji)
("C-c p \\" . cape-tex)
("C-c p _" . cape-tex)
("C-c p ^" . cape-tex)
("C-c p &" . cape-sgml)
("C-c p r" . cape-rfc1345))
:init
;; Add to the global default value of `completion-at-point-functions' which is
;; used by `completion-at-point'. The order of the functions matters, the
;; first function returning a result wins. Note that the list of buffer-local
;; completion functions takes precedence over the global list.
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
(add-to-list 'completion-at-point-functions #'cape-file)
(add-to-list 'completion-at-point-functions #'cape-elisp-block)
;;(add-to-list 'completion-at-point-functions #'cape-history)
;;(add-to-list 'completion-at-point-functions #'cape-keyword)
;;(add-to-list 'completion-at-point-functions #'cape-tex)
;;(add-to-list 'completion-at-point-functions #'cape-sgml)
;;(add-to-list 'completion-at-point-functions #'cape-rfc1345)
;;(add-to-list 'completion-at-point-functions #'cape-abbrev)
;;(add-to-list 'completion-at-point-functions #'cape-dict)
;;(add-to-list 'completion-at-point-functions #'cape-elisp-symbol)
;;(add-to-list 'completion-at-point-functions #'cape-line)
)
(use-package embark
:ensure t
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:config
;; Hide the mode line of the Embark live/completions buffers
(setq prefix-help-command 'embark-prefix-help-command)
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:ensure t ; only need to install it, embark loads it after consult if found
:hook
(embark-collect-mode . consult-preview-at-point-mode))
;; Example configuration for Consult
(use-package consult
;; Replace bindings. Lazily loaded due by `use-package'.
:ensure t
;:bind ;; C-c bindings in `mode-specific-map'
;; ("C-c M-x" . consult-mode-command)
;; ("C-c h" . consult-history)
;; ("C-c k" . consult-kmacro)
;; ("C-c m" . consult-man)
;; ("C-c i" . consult-info)
;; ([remap Info-search] . consult-info)
;; ;; C-x bindings in `ctl-x-map'
;; ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
;; ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
;; ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
;; ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
;; ("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
;; ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
;; ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; ;; Custom M-# bindings for fast register access
;; ("M-#" . consult-register-load)
;; ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
;; ("C-M-#" . consult-register)
;; ;; Other custom bindings
;; ("M-y" . consult-yank-pop) ;; orig. yank-pop
;; ;; M-g bindings in `goto-map'
;; ("M-g e" . consult-compile-error)
;; ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
;; ("M-g g" . consult-goto-line) ;; orig. goto-line
;; ("M-g M-g" . consult-goto-line) ;; orig. goto-line
;; ("M-g o" . consult-outline) ;; Alternative: consult-org-heading
;; ("M-g m" . consult-mark)
;; ("M-g k" . consult-global-mark)
;; ("M-g i" . consult-imenu)
;; ("M-g I" . consult-imenu-multi)
;; ;; M-s bindings in `search-map'
;; ("M-s d" . consult-find) ;; Alternative: consult-fd
;; ("M-s c" . consult-locate)
;; ("M-s g" . consult-grep)
;; ("M-s G" . consult-git-grep)
;; ("M-s r" . consult-ripgrep)
;; ("M-s l" . consult-line)
;; ("M-s L" . consult-line-multi)
;; ("M-s k" . consult-keep-lines)
;; ("M-s u" . consult-focus-lines)
;; ;; Isearch integration
;; ("M-s e" . consult-isearch-history)
;; :map isearch-mode-map
;; ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
;; ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
;; ("M-s l" . consult-line) ;; needed by consult-line to detect isearch
;; ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; ;; Minibuffer history
;; :map minibuffer-local-map
;; ("M-s" . consult-history) ;; orig. next-matching-history-element
;; ("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Optionally configure the narrowing key.
;; Both and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; "C-+"
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
;; By default `consult-project-function' uses `project-root' from project.el.
;; Optionally configure a different project root function.
;;;; 1. project.el (the default)
;; (setq consult-project-function #'consult--default-project--function)
;;;; 2. vc.el (vc-root-dir)
;; (setq consult-project-function (lambda (_) (vc-root-dir)))
;;;; 3. locate-dominating-file
;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git")))
;;;; 4. projectile.el (projectile-project-root)
;; (autoload 'projectile-project-root "projectile")
;; (setq consult-project-function (lambda (_) (projectile-project-root)))
;;;; 5. No project support
;; (setq consult-project-function nil)
)
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
(use-package rg :ensure t :config (rg-enable-default-bindings))
(use-package fzf
:ensure t
:bind
;; Don't forget to set keybinds!
:config
(setq fzf/args "-x --color bw --print-query --margin=1,0 --no-hscroll"
fzf/executable "fzf"
fzf/git-grep-args "-i --line-number %s"
;; command used for `fzf-grep-*` functions
;; example usage for ripgrep:
;; fzf/grep-command "rg --no-heading -nH"
fzf/grep-command "grep -nrH"
;; If nil, the fzf buffer will appear at the top of the window
fzf/position-bottom t
fzf/window-height 15))
(use-package treesit-auto
:ensure t
:custom
(treesit-auto-install 'prompt)
:config
(treesit-auto-add-to-auto-mode-alist 'all)
(global-treesit-auto-mode))
(setq treesit-font-lock-level 4)
Eglot for Lsp
(use-package eglot
:ensure nil
:demand nil
:hook
(prog-mode . eglot-ensure)
(c-ts-mode . eglot-ensure)
(c++-ts-mode . eglot-ensure)
(cmake-ts-mode . eglot-ensure)
)
(setq eglot-stay-out-of '(flymake))
;; (use-package eldoc
;; :ensure t
;; :after eglot
;; :init
;; (global-eldoc-mode)
;; )
;; Configure Tempel
(use-package tempel
;; Require trigger prefix before template name when completing.
;; :custom
;; (tempel-trigger-prefix "<")
:bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
("M-*" . tempel-insert))
:init
;; Setup completion at point
(defun tempel-setup-capf ()
;; Add the Tempel Capf to `completion-at-point-functions'.
;; `tempel-expand' only triggers on exact matches. Alternatively use
;; `tempel-complete' if you want to see all matches, but then you
;; should also configure `tempel-trigger-prefix', such that Tempel
;; does not trigger too often when you don't expect it. NOTE: We add
;; `tempel-expand' *before* the main programming mode Capf, such
;; that it will be tried first.
(setq-local completion-at-point-functions
(cons #'tempel-expand
completion-at-point-functions)))
(add-hook 'conf-mode-hook 'tempel-setup-capf)
(add-hook 'prog-mode-hook 'tempel-setup-capf)
(add-hook 'text-mode-hook 'tempel-setup-capf)
;; Optionally make the Tempel templates available to Abbrev,
;; either locally or globally. `expand-abbrev' is bound to C-x '.
;; (add-hook 'prog-mode-hook #'tempel-abbrev-mode)
;; (global-tempel-abbrev-mode)
)
;; Optional: Add tempel-collection.
;; The package is young and doesn't have comprehensive coverage.
(use-package tempel-collection
:ensure t
:after tempel
)
(use-package elisp-slime-nav :ensure t
:config
(add-hook 'emacs-lisp-mode-hook 'elisp-slime-nav-mode)
)
;; (use-package paredit :ensure t)
;; (add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode)
;; (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)
;; (add-hook 'ielm-mode-hook #'enable-paredit-mode)
;; (add-hook 'lisp-mode-hook #'enable-paredit-mode)
;; (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode)
;; (add-hook 'scheme-mode-hook #'enable-paredit-mode)
(use-package markdown-mode
:ensure t
:mode ("README\\.md\\'" . gfm-mode)
:init
(setq markdown-command "multimarkdown")
)
;;(use-package jupyter :ensure t)
(use-package sly :ensure t)
TODO
(use-package vterm :ensure t )
(use-package vterm-toggle
:ensure t
:after vterm
:config
;; When running programs in Vterm and in 'normal' mode, make sure that ESC
;; kills the program as it would in most standard terminal programs.
(evil-define-key 'normal vterm-mode-map (kbd "<escape>") 'vterm--self-insert)
(setq vterm-toggle-fullscreen-p nil)
(setq vterm-toggle-scope 'project)
(add-to-list 'display-buffer-alist
'((lambda (buffer-or-name _)
(let ((buffer (get-buffer buffer-or-name)))
(with-current-buffer buffer
(or (equal major-mode 'vterm-mode)
(string-prefix-p vterm-buffer-name (buffer-name buffer))))))
(display-buffer-reuse-window display-buffer-at-bottom)
;;(display-buffer-reuse-window display-buffer-in-direction)
;;display-buffer-in-direction/direction/dedicated is added in emacs27
;;(direction . bottom)
;;(dedicated . t) ;dedicated is supported in emacs27
(reusable-frames . visible)
(window-height . 0.4))))
(use-package sudo-edit :ensure t)
(use-package ox-hugo
:ensure t ;Auto-install the package from Melpa
:pin melpa ;`package-archives' should already have ("melpa" . "https://melpa.org/packages/")
:after ox)
(use-package pdf-tools
:ensure t
:defer t
:commands (pdf-loader-install)
:mode "\\.pdf\\'"
:bind (:map pdf-view-mode-map
("SPC" . ignore)
("j" . pdf-view-next-line-or-next-page)
("J" . pdf-view-next-page)
("k" . pdf-view-previous-line-or-previous-page)
("K" . pdf-view-last-page)
("/" . pdf-isearch-occur)
("C-=" . pdf-view-enlarge)
("C--" . pdf-view-shrink)
("C-f" . pdf-view-next-page)
("C-b" . pdf-view-previous-page)
("C-b" . switch-to-buffer)
("m" . delete-other-windows)
("x" . kill-current-buffer)
("p" . previous-buffer)
("C-e" . neotree-toggle))
:init (pdf-loader-install)
:config
;; (evil-set-initial-state 'pdf-view-mode 'normal)
(add-to-list 'revert-without-query ".pdf")
(add-hook 'pdf-view-mode-hook #'(lambda () (interactive) (global-display-line-numbers-mode -1) (display-line-numbers-mode -1) (blink-cursor-mode -1) (doom-modeline-mode -1))))
;; (add-to-list 'pdf-view-incompatible-modes 'display-line-numbers-mode)
(use-package pdf-view-restore
:ensure t
:after pdf-tools
:config
(add-hook 'pdf-view-mode-hook 'pdf-view-restore-mode))
(use-package keycast
:ensure t
)
(use-package hackernews :ensure t)
(use-package empv :ensure t)
(use-package elfeed :ensure t)
(use-package elfeed-org
:ensure t
:config
(elfeed-org)
(setq rmh-elfeed-org-files (list "~/Org/elfeed.org"))
)
(run-at-time nil (* 8 60 60) #'elfeed-update)
(setq elfeed-show-entry-switch #'elfeed-display-buffer)
(defun elfeed-display-buffer (buf &optional act)
(pop-to-buffer buf)
(set-window-text-height (get-buffer-window) (round (* 0.7 (frame-height)))))
(defun elfeed-show-eww-open (&optional use-generic-p)
"open with eww"
(interactive "P")
(let ((browse-url-browser-function #'eww-browse-url))
(elfeed-show-visit use-generic-p)))
(defun elfeed-search-eww-open (&optional use-generic-p)
"open with eww"
(interactive "P")
(let ((browse-url-browser-function #'eww-browse-url))
(elfeed-search-browse-url use-generic-p)))
(defvar arxiv-paper-path "~/Documents/Paper/")
(defun arxiv-download-and-open ()
"Download and open the PDF file for the ArXiv URL at point."
(interactive)
(let* ((url (thing-at-point 'url t))
(arxiv-url-p (string-match "^https?://arxiv.org/abs/\\([0-9]+\.[0-9]+\\)" url))
(arxiv-id (match-string 1 url)))
(if arxiv-url-p
(let* ((pdf-url (format "https://arxiv.org/pdf/%s.pdf" arxiv-id))
(pdf-buffer (get-buffer-create (format "*ArXiv PDF: %s*" arxiv-id)))
(pdf-file (expand-file-name (format "%s.pdf" arxiv-id) arxiv-paper-path)))
(url-copy-file pdf-url pdf-file t)
(message "load pdf url: %s, pdf-file: %s, pdf-buffer: %s" pdf-url pdf-file pdf-buffer)
(switch-to-buffer pdf-buffer)
(with-current-buffer pdf-buffer
(insert-file-contents pdf-file)
(pdf-view-mode)
(display-buffer pdf-buffer))
(message "Downloaded and opened PDF for %s" arxiv-id))
(message "No ArXiv URL at point"))))
(add-to-list 'evil-motion-state-modes 'elfeed-search-mode)
(add-to-list 'evil-motion-state-modes 'elfeed-show-mode)
;; (evil-define-key* 'motion elfeed-search-mode-map
;; "gb" #'elfeed-search-browse-url
;; "gr" #'elfeed-search-update--force
;; "gR" #'elfeed-search-fetch)
;; (evil-define-key* 'motion elfeed-show-mode-map
;; "gl" #'elfeed-show-eww-open
;; )
(use-package elfeed-score
:ensure t
:config
(progn
(elfeed-score-enable)
(define-key elfeed-search-mode-map "=" elfeed-score-map)))
Nov for epub reader
;; (elpaca (nov-xwidget :host github :repo "chenyanming/nov-xwidget"))
;; (elpaca-wait)
(use-package nov :ensure t)
(add-hook 'nov-mode-hook (lambda () (display-line-numbers-mode -1) (darkroom-mode 1)))
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
(setq nov-text-width t)
;; TODO: beautiful nov mode; (add-hook 'nov-post-html-render-hook 'my-nov-post-html-render-hook)
(use-package ztree :ensure t)
(use-package simpleclip
:ensure t
:init
(simpleclip-mode 1)
)
(use-package chatgpt-shell
:ensure t
:custom
((chatgpt-shell-openai-key
(lambda ()
(auth-source-pass-get 'secret "openai-key"))))
)
(setq chatgpt-shell-openai-key (getenv "OPENAI_API_KEY"))