Update theme with sun.
(use-package celestial-mode-line
:config
(require 'kimim)
(defun kimim/update-theme-with-sun (orig-fun &optional date)
(let* ((sunrise-symbol
(cdr (assoc
'sunrise
celestial-mode-line-sunrise-sunset-alist)))
(sunset-symbol
(cdr (assoc
'sunset
celestial-mode-line-sunrise-sunset-alist)))
(sunrise-before
(string-search sunrise-symbol
celestial-mode-line-string))
(sunset-before
(string-search sunset-symbol
celestial-mode-line-string)))
(apply orig-fun date)
(let* ((sunrise-after
(string-search sunrise-symbol
celestial-mode-line-string))
(sunset-after
(string-search sunset-symbol
celestial-mode-line-string)))
(cond
((and (not sunset-before)
sunset-after)
(kimim/theme-light))
((and (not sunrise-before)
sunrise-after)
(kimim/theme-night))))))
(advice-add 'celestial-mode-line-update
:around
#'kimim/update-theme-with-sun)
(celestial-mode-line-start-timer))
lsp-mode
aims to provide IDE-like experience.
If you got error: Symbol’s function definition is void: -compose
, make sure
that dash version higher than 2.18 is installed[fn:11].
(use-package dash
:ensure t)
(use-package goto-addr
:config
;;(setq goto-address-uri-schemes-ignored '("mailto:" "data:" "jar:"))
(setq goto-address-uri-schemes
(cons "C:" (seq-reduce (lambda (accum elt) (delete elt accum))
goto-address-uri-schemes-ignored
(copy-sequence thing-at-point-uri-schemes))))
(setq goto-address-url-regexp
(concat "\\<"
(regexp-opt goto-address-uri-schemes t)
thing-at-point-url-path-regexp)))
(use-package treemacs)
lsp-mode
will add company-capf
in front for company-backends
, then it
will prevent my global company-backends
settings. You can customize
lsp-completion-provider
to :none
prevent this.
(use-package lsp-mode
:after goto-addr
:commands lsp
:custom
(lsp-headerline-breadcrumb-icons-enable t)
(lsp-headerline-breadcrumb-enable t)
(lsp-modeline-code-action-fallback-icon "✶")
(lsp-completion-provider :none)
:bind (:map
lsp-mode-map
("C-x l l" . lsp-ui-doc-glance)
("C-." . lsp-find-definition)
("C-," . xref-go-back)
("C-x ." . kimim/lsp-find-definition-other-window)
("C-x l t s" . lsp-treemacs-symbols))
:hook ((c-mode c++-mode clojure-mode) . lsp)
:config
(require 'dash)
(require 'goto-addr)
(define-key lsp-mode-map (kbd "C-x l") lsp-command-map)
(add-hook 'xref-after-return-hook 'recenter)
(defun kimim/lsp-find-definition-other-window ()
(interactive)
(lsp-find-definition :display-action 'window)
(other-window 1)))
UI helper for lsp-mode.
(use-package lsp-ui
:commands lsp-ui-mode
:custom
(lsp-ui-doc-text-scale-level -1)
(lsp-ui-doc-show-with-cursor nil)
(lsp-ui-doc-show-with-mouse nil)
(lsp-ui-sideline-show-code-actions t)
(lsp-ui-doc-alignment 'window)
(lsp-ui-doc-max-width 90))
(use-package lsp-clangd
:ensure lsp-mode
:custom (lsp-clients-clangd-args
'("--header-insertion-decorators=0"
"--all-scopes-completion"
"--completion-style=detailed"
"--background-index"
"--clang-tidy"
"--header-insertion=iwyu"
"--pch-storage=memory"
"-j=12")))
lsp-clangd
cannot find definition before visiting the .c
file, so we
will use ggtags
to locate the definition in .c
file. After that,
lsp-clangd
can index .c
files.
(use-package yasnippet
:defer 10
:diminish yas-minor-mode
:defines warning-suppress-types
:config
(require 'warnings)
(add-to-list
'yas-snippet-dirs (concat kimim/path-sync-emacs "snippets"))
(yas-global-mode 1)
(setq warning-suppress-types '((yasnippet backquote-change))))
In order to remove following warning:
Warning (yasnippet): ‘xxx’ modified buffer in a backquote expression. To hide this warning, add (yasnippet backquote-change) to ‘warning-suppress-types’.
(use-package clj-refactor
:config
(setq clojure-thread-all-but-last t)
(cljr-add-keybindings-with-prefix "C-c r")
(define-key clj-refactor-map "\C-ctf" #'clojure-thread-first-all)
(define-key clj-refactor-map "\C-ctl" #'clojure-thread-last-all)
(define-key clj-refactor-map "\C-cu" #'clojure-unwind)
(define-key clj-refactor-map "\C-cU" #'clojure-unwind-all)
(add-to-list 'cljr-magic-require-namespaces '("s" . "clojure.string")))
(use-package company
:defer 10
:functions (company-abort)
:bind
(("C-x m c" . company-mode)
:map company-active-map
("C-n" . company--select-next-and-warn)
("C-p" . company--select-previous-and-warn)
("C-h" . delete-backward-char)
("C-d" . delete-forward-char)
("SPC" . (lambda ()
(interactive)
(company-abort)
(insert-char ?\x20))))
:diminish company-mode
:commands (global-company-mode)
:custom
(company-idle-delay 0)
(company-minimum-prefix-length 1)
:config
(require 'company-posframe)
(global-company-mode t)
(setq company-backends
'((company-yasnippet
company-keywords
company-capf
company-files :separate)
(company-dabbrev
company-dabbrev-code
company-ebdb
company-ispell :with))))
complete with keyword and annotation. need special dict files for different mode.
(use-package company-dict
:config
;; Where to look for dictionary files
(setq company-dict-dir (concat kimim/path-sync-emacs "dict")))
(use-package company-shell
:commands company-shell
:config
(add-hook
'eshell-mode-hook
(lambda ()
(make-local-variable company-backends)
(setq company-backends
'((company-shell company-files)
company-capf company-yasnippet
company-dabbrev company-ebdb company-ispell
(company-dabbrev-code
company-gtags
company-etags company-keywords))))))
If no candidates satisfies our needs, we can type C-\
to get more
candidates from following backends from company-backends
.
(use-package company-try-hard
:bind ("C-\\" . company-try-hard))
This extension won’t clutter the buffer contents.
(use-package company-posframe
:diminish company-posframe-mode
:config
(company-posframe-mode 1))
(use-package company-ebdb)
Sort candidates using completion history.
(use-package company-statistics
:config
(company-statistics-mode 1))
(use-package text-mode
:ensure nil
:config
(add-hook
'text-mode-hook
(lambda ()
(make-local-variable 'company-backends)
(setq company-backends
'((company-ispell company-capf
company-yasnippet company-dabbrev
company-ebdb company-files :seperate))))))
If org-modern-star
is not enabled, not workaround is required for
org-indent:
(defun org-indent--compute-prefixes ()
"Compute prefix strings for regular text and headlines."
(setq org-indent--heading-line-prefixes
(make-vector org-indent--deepest-level nil))
(setq org-indent--inlinetask-line-prefixes
(make-vector org-indent--deepest-level nil))
(setq org-indent--text-line-prefixes
(make-vector org-indent--deepest-level nil))
(dotimes (n org-indent--deepest-level)
(let ((indentation (if (<= n 1) 0
(* (1- org-indent-indentation-per-level)
(1- n)))))
;; Headlines line prefixes.
(let ((heading-prefix (make-string indentation ?*)))
(aset org-indent--heading-line-prefixes
n
(org-add-props heading-prefix nil 'face 'org-indent))
;; Inline tasks line prefixes
(aset org-indent--inlinetask-line-prefixes
n
(cond ((<= n 1) "")
((bound-and-true-p org-inlinetask-show-first-star)
(concat org-indent-inlinetask-first-star
(substring heading-prefix 1)))
(t (org-add-props heading-prefix nil
'face 'org-indent)))))
;; Text line prefixes.
;; remove one prefix char in indent
(let ((remove-space (if (> n 0)
(- n 1)
0)))
(aset org-indent--text-line-prefixes
n
(org-add-props
(concat
(make-string
(- (+ n indentation) remove-space) ?\s)
(and (> n 0)
(char-to-string org-indent-boundary-char)))
nil 'face 'org-indent))))))
(use-package org-superstar
:ensure t
:hook
((org-mode . org-superstar-mode)
(org-mode . (lambda ()
"Beautify Org Symbols"
(push '(":category:" . "▲") prettify-symbols-alist)
(push '("[X]" . "☑" ) prettify-symbols-alist)
(push '("[ ]" . "☐" ) prettify-symbols-alist)
(push '("#+begin_src" . "«" ) prettify-symbols-alist)
(push '("#+end_src" . "»" ) prettify-symbols-alist)
(prettify-symbols-mode))))
:custom
(org-superstar-remove-leading-stars t)
(org-superstar-headline-bullets-list
'(?⦿ ?○ ?● ?◌))
(org-superstar-item-bullet-alist
'((?* . ?●) (?+ . ?♦) (?- . ?▬))))
Before an emacsclient first connect to daemon, the daemon is working
in terminal mode. Thus (display-graphic-p)
will return nil
. So I add
raise-frame
in after-make-frame-functions
to force emacs to bring the
new frame to the front and apply the gui related settings.
(use-package frame
:ensure nil
:defer 1
:bind ("C-x m w" . make-frame)
:config
(add-hook 'after-make-frame-functions
(lambda (frame)
(select-frame frame)
(kimim/menu-and-bar)
(kimim/frame-and-font)
(raise-frame frame))))
(use-package swiper
:custom
(swiper-action-recenter t)
:bind
("C-s" . swiper)
("M-s ." . swiper-thing-at-point))
[2023-05-18 Thu] Many markdown file contains long lines,
visual-fill-column
can visually wrap lines. But because I use
olivetti-mode
for text files, now I don’t use this package anymore.
(use-package visual-fill-column
:hook (markdown-mode . visual-fill-column-mode))
(use-package consult-org-roam
:ensure t
:diminish consult-org-roam-mode
:custom
(consult-org-roam-grep-func #'consult-ripgrep)
:bind
("C-c n e" . consult-org-roam-file-find)
("C-c n l" . consult-org-roam-backlinks)
("C-c n s" . consult-org-roam-search)
:config
(require 'consult-org-roam)
;; Activate the minor-mode
(consult-org-roam-mode 1)
;; Eventually suppress previewing for certain functions
(consult-customize
consult-org-roam-forward-links
:preview-key "M-.")
(consult-customize
org-roam-node-find
:preview-key "M-."))
ag
[fn:9] is really a very fast grep tool, and ag.el
[fn:10] provide the
Emacs interface to ag
:
(use-package ag
:bind
("C-x g" . ag-project)
:config
(setq ag-highlight-search t))
Because counsel-ag
is not working in my Win64 machine, so I switch to pt
now.
Download pt
from
https://github.com/monochromegane/the_platinum_searcher/releases, and it works
out of the box.
(use-package ivy
:diminish ivy-mode
:bind ("<f6>" . ivy-resume)
:config
(setq ivy-use-virtual-buffers t)
(setq ivy-count-format "(%d/%d) ")
(setq ivy-wrap nil)
(ivy-mode 1))
counsel
will enhance many built-in commands with nice ivy completion candidates.
(use-package counsel
:bind
(("M-x" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("C-x m f" . counsel-describe-function)
("C-x m v" . counsel-describe-variable)
("C-x m l" . counsel-load-library)
("C-x m i" . counsel-info-lookup-symbol)
("C-x m j" . counsel-bookmark)
("C-x m u" . counsel-unicode-char)
("C-c j" . counsel-git-grep)
("C-c g" . counsel-grep)
("C-x b" . counsel-ibuffer)
("C-c k" . counsel-ag)
("C-c p" . counsel-pt)
:map read-expression-map
("C-r" . counsel-minibuffer-history))
:config
(require 'ivy)
(require 'smex)
(add-hook 'counsel-grep-post-action-hook 'recenter))
guru-mode
warns you when you type arrow keys, home or end. This could
help you to establish the habit of efficiently using emacs keybinding.
(use-package guru-mode
:diminish guru-mode
:config
(guru-global-mode +1))
C-x u
is undo command, now it is rebind to undo-tree
, when it is
invoked, emacs will show the undo tree of current buffer. By default,
undo-tree file is kept in the same folder,
undo-tree-history-directry-alist
is used to specify the one directory
for all backups.
(use-package undo-tree
:diminish undo-tree-mode
:custom
(undo-tree-visualizer-timestamps t)
(undo-tree-visualizer-diff t)
(undo-tree-history-directory-alist '(("." . "~/temp/")))
:config
(global-undo-tree-mode))
Automatically highlight current symbol where the cursor is inside.
(use-package auto-highlight-symbol
:diminish auto-highlight-symbol-mode
:bind ("C-x m e" . ahs-edit-mode)
:config
(global-auto-highlight-symbol-mode t))
Polymode [fn:21] is a framework for multiple major modes (MMM) inside a single Emacs buffer. It is comfortable to enable it during literating program.
;;(use-package poly-org
;; :ensure t)
(use-package deft
:bind
("C-x d" . deft-find-file)
:custom (deft-text-mode 'org-mode)
:functions (kimim/deft-open-file-advice
kimim/deft-new-file-named-advice
kimim/genfile-timestamp)
:config
(use-package ivy)
(setq deft-extensions '("txt" "org" "md"))
(setq deft-directory kimim/path-notes)
(setq deft-recursive t)
;; disable auto save
(setq deft-auto-save-interval 0)
(setq deft-file-naming-rules '((noslash . "_")))
(setq deft-use-filter-string-for-filename t)
(setq deft-org-mode-title-prefix t)
(setq deft-use-filename-as-title nil)
(setq deft-strip-summary-regexp
(concat "\\("
"[\n\t]" ;; blank
"\\|^#\\+[[:upper:]_]+:.*$" ;; org-mode metadata
"\\|^#\\+[[:alnum:]_]+:.*$" ;; org-mode metadata
"\\)"))
;;advise deft-open-file to replace spaces in file names with _
(require 'kimim)
(defun kimim/deft-open-file-advice (orig-fun &rest args)
(let (name title)
(setq name (pop args))
(if (file-exists-p name)
(progn
(push name args)
(apply orig-fun args))
(progn
(setq title (file-name-sans-extension
(file-name-nondirectory name)))
(setq name (concat
(file-name-directory name)
(kimim/genfile-timestamp)
(downcase
(replace-regexp-in-string
" " "_" (file-name-nondirectory name)))
(if (not (file-name-extension name))
".txt")))
(push name args)
(apply orig-fun args)
(insert (concat "#+TITLE: " title "\n\n"))))))
(advice-add 'deft-open-file
:around #'kimim/deft-open-file-advice)
(defun kimim/deft-new-file-named-advice (orig-fun &rest args)
(let (name title)
(setq name (pop args))
(setq title name)
(setq name (concat
(kimim/genfile-timestamp)
(downcase
(replace-regexp-in-string
" " "_" name))))
(push name args)
(apply orig-fun args)
(insert (concat "#+TITLE: " title "\n\n"))))
(advice-add 'deft-new-file-named
:around #'kimim/deft-new-file-named-advice))
New link to use everything to locate a file with unique ID:
(use-package org
:functions org-match-open
:config
(org-link-set-parameters "match"
:follow #'org-match-open)
(defun org-match-open (path)
"Visit the match search on PATH.
PATH should be a topic that can be thrown at everything/?."
(w32-shell-execute
"open" "Everything" (concat "-search " path))))
Because Incosolata font is really great for programming, and Microsoft Yahei is nice font to view Chinese characters, you’d better download and install these fonts from:
For Windows and macOS, you can view and install fonts with font viewer.
For Linux, you could just move all above font files to
/usr/local/share/fonts/
.
Everything[fn:14] is a wonderful fast file and folder search engine, it provide
a command line tool to get search result from Everything to command line output:
es.exe
[fn:15].
Reminded that Everything should be running in background to do the real search
task for es.exe
.
(use-package everything
:defer t
:ensure t
:init
(setq everything-cmd (concat kimim/path-kimikit "bin/es.exe")))
(use-package helm)
(use-package markdown-mode
:defer t
:ensure t
)
(use-package simplenote2
:defer t
:ensure t
:bind
(
("C-x p" . simplenote2-list)
;; when in Chinese environment, / is a dot, confusing
("C-;" . simplenote2-list-filter-notes)
("C-." . simplenote2--create-note-locally))
:config
(require 'simplenote2)
(require 'markdown-mode)
;;(require 'visual-fill-column)
(setq simplenote2-notes-mode 'markdown-mode)
;;(add-hook 'simplenote2-note-mode-hook 'visual-fill-column-mode)
(simplenote2-setup)
)
New orgmode link type for simplenote2. The reason for creating a new kind of link type is that the newly added note is located under folder “new”, while the synchronized notes are in “notes”. We should ensure that all the link points to note in “notes” folder.
(use-package org
:defer t
:config
(org-add-link-type "simplenote2" 'org-simplenote2-open)
(defun org-simplenote2-open (path)
(find-file (concat simplenote2-directory "notes/" path)))
(defun simplenotes-linkto-note ()
"extract orgmode link string to this note"
(interactive)
(unless (buffer-file-name)
(error "No file for buffer %s" (buffer-name)))
(beginning-of-buffer)
(let (title msg)
;;fetch first line string as title
(setq title (buffer-substring-no-properties
(line-beginning-position) (line-end-position)))
;;package orgmode line with buffer name and title
(setq msg (format "[[simplenote2:%s][%s]]"
(file-name-nondirectory (buffer-file-name))
title))
(kill-new msg)
(message msg))))
(use-package bbdb
:defer t
:bind
:config
(setq bbdb-file (concat kimim/path-sync "kimikit/emacs.d/bbdb"))
;; https://www.emacswiki.org/emacs/BbdbMailingLists
;;(add-hook 'message-setup-hook 'bbdb-mail-aliases)
)
;; gnus settings
(use-package gnus
:ensure nil
:defer t
:bind
(("C-x m m" . kimim/mail-new-empty)
("C-x m n" . kimim/mail-new)
("C-x m y" . kimim/mail-attach-files)
:map gnus-summary-mode-map
("g" . gnus-summary-insert-new-articles)
("f" . gnus-summary-forward-with-original)
("R" . gnus-summary-very-wide-reply-with-original)
("<delete>" . gnus-summary-delete-article)
("<insert>" . mail-archive-kimim))
:config
(message "......gnus[0]")
(use-package ebdb)
(use-package gnus-dired :ensure nil)
(setq gnus-visible-headers
"^Subject:\\|^From:\\|^To:\\|^[BGF]?CC:\\|^Date:")
(setq gnus-sorted-header-list
'("^Subject:" "^From:""^To:" "^[BGF]?CC:" "^Date:"))
(setq compose-mail-user-agent-warnings nil) ;; remove warning
(setq message-directory "~/Gnus/Mail/")
(setq gnus-directory "~/Gnus/News/")
(setq nnfolder-directory "~/Gnus/Mail/Archive")
;; unfortunately, following variable not support CN strings
(setq gnus-permanently-visible-groups "\\(Inbox\\|INBOX\\|已发送邮件\\)")
(setq mail-self-blind t)
(setq gnus-alias-override-user-mail-address t)
(setq mail-signature-file (concat kimim/path-sync "kimikit/emacs.d/signature.txt"))
(setq gnus-asynchronous t)
(setq gnus-use-article-prefetch 1000)
(setq gnus-fetch-old-headers 'some)
;; fetch only 50 latest articles to speed up downloading
(setq gnus-large-newsgroup 50)
(setq message-forward-as-mime t)
(setq message-forward-before-signature t) ;; put signature before the fwd msg
(setq message-forward-included-headers "^Date\\|^From\\|^To\\|^Subject:")
(setq message-make-forward-subject-function 'message-forward-subject-fwd)
(setq gnus-user-date-format-alist
'(((gnus-seconds-today) . "Today %H:%M")
((+ 86400 (gnus-seconds-today)) . "Yest. %H:%M")
(604800 . "%a %H:%M") ; That's one week
((gnus-seconds-month) . "%a %H:%M")
((gnus-seconds-year) . "%b %d")
(t . "%b %d %Y")))
(setq gnus-summary-line-format
":%U%R | %d%13&user-date; %-13,13f (%5k) | %B %s %-120= \n")
(setq gnus-article-sort-functions '((not gnus-article-sort-by-date)))
(setq gnus-thread-sort-functions '((not gnus-thread-sort-by-date)))
(setq gnus-thread-ignore-subject t)
(setq gnus-agent t)
(setq gnus-agent-expire-days 90)
; prompt for how many articles only for larger than 1000 articles
(setq gnus-large-newsgroup 100)
(setq gnus-use-cache t)
(setq gnus-fetch-old-headers 1) ; show previous messages in a thread
(setq gnus-thread-indent-level 1)
(setq gnus-show-threads t)
(setq gnus-thread-hide-subtree nil)
(add-hook 'gnus-summary-prepare-hook 'gnus-summary-hide-all-threads)
;;(use-package orgalist)
;;(add-hook 'message-mode-hook 'orgalist-mode)
(add-hook 'message-mode-hook 'turn-off-auto-fill)
(defun gnus-summary-forward-with-original (n &optional wide)
"Start composing a reply mail to the current message.
The original article will be yanked."
(interactive "P")
(gnus-summary-reply (gnus-summary-work-articles n) wide)
(mail-to)
(message-beginning-of-line)
(kill-line)
(mail-subject)
(message-beginning-of-line)
(delete-char 2)
(narrow-to-region (line-beginning-position) (line-end-position))
(goto-char (point-min))
(while (search-forward "Fw: " nil t)
(replace-match ""))
(while (search-forward "转发: " nil t)
(replace-match ""))
(widen)
(message-beginning-of-line)
(insert "FW")
(mail-to))
(define-key gnus-summary-mode-map
[remap gnus-summary-followup-with-original]
'gnus-summary-forward-with-original)
(define-key gnus-summary-mode-map
[remap gnus-summary-reply]
'gnus-summary-reply-with-original)
(define-key gnus-summary-mode-map
[remap gnus-summary-wide-reply]
'gnus-summary-very-wide-reply-with-original)
(add-hook 'gnus-message-setup-hook 'kimim/mail-setup))
;; Define the modes/packages you need
(use-package company-irony)
(use-package company-c-headers)
(use-package irony
:diminish irony-mode
:config
(setq w32-pipe-read-delay 0)
(use-package company-irony)
(add-hook 'irony-mode-hook 'company-irony-setup-begin-commands)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
(require 'flycheck)
(add-hook 'c-mode-hook 'flycheck-mode)
(add-hook 'c++-mode-hook 'flycheck-mode)
(use-package company)
(use-package company-c-headers)
(add-to-list 'company-c-headers-path-system "/usr/include")
;; replace the `completion-at-point' and `complete-symbol' bindings in
;; irony-mode's buffers by irony-mode's function
(defun my-irony-mode-hook ()
(define-key irony-mode-map [remap completion-at-point]
'irony-completion-at-point-async)
(define-key irony-mode-map [remap complete-symbol]
'irony-completion-at-point-async))
(add-hook 'irony-mode-hook 'my-irony-mode-hook))
(use-package company-c-headers)
(use-package flycheck
:config
;; set up flycheck
(add-hook 'flycheck-mode-hook #'flycheck-irony-setup))
(use-package cc-mode
:ensure nil
:config
(add-to-list 'auto-mode-alist '("\\.C\\w*\\'" . c-mode))
(use-package company)
(use-package company-irony)
(add-to-list 'company-backends 'company-irony)
(use-package company-c-headers)
(add-to-list 'company-c-headers-path-system "/usr/include")
(require 'irony)
(add-hook 'c-mode-hook 'irony-mode)
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'objc-mode-hook 'irony-mode)
(require 'flycheck)
(add-hook 'c-mode-hook 'flycheck-mode)
(add-hook 'c++-mode-hook 'flycheck-mode)
(require 'ggtags)
(add-hook 'c-mode-hook 'ggtags-mode)
(add-hook 'c++-mode-hook 'ggtags-mode)
(add-hook 'c-mode-common-hook
(lambda ()
;; show column width indicator
;;(fci-mode 0)
;;(syntax-subword-mode 1)
;;(hs-minor-mode 0)
;;(c-set-style "gnu")
(c-toggle-auto-newline 0)
(c-toggle-auto-hungry-state 0)
(c-toggle-syntactic-indentation 1)
;;(highlight-indentation-mode 1)
(which-function-mode 1)
(local-set-key "\C-co" 'ff-find-other-file)
;;(my-c-mode-common-hook-if0)
(setq c-basic-offset 4))))
irony-mode
is developed by Sarcasm [fn:13]. It is an Emacs minor-mode that
aims at improving the editing experience for the C, C++ and Objective-C
languages. It works by using a combination of an Emacs package and a C++ program
(irony-server
) that uses libclang. When correctly configured, it can provide
wonderful auto completion for functions and variables. The function prototypes
with parameters can be triggered as a yasnippet automatically.
It is quite easy to install irony-server
under macOS, just invoke the command
“M-x irony-install-server”, and Emacs will compile and install it to
~/.emacs.d/irony/bin/irony-server
, by invoking the make commands:
cmake -DCMAKE_INSTALL_PREFIX\=/Users/kimim/.emacs.d/irony/
/Users/kimim/.emacs.d/elpa/irony-20160925.1030/server && cmake --build
. --use-stderr --config Release --target install
For Cygwin/Windows, first we should install libclang
3.8.1-1 and
libclang-devel
3.8.1-1 and cmake
with setup.exe
.
Then compile irony-server
with cmake
and make
:
~/.emacs.d/elpa/irony-20160925.1030/server/build
$ cmake -DCMAKE_INSTALL_PREFIX=~/.emacs.d/irony/ -G "Unix Makefiles" ..
~/.emacs.d/elpa/irony-20160925.1030/server/build
$ make install
Scanning dependencies of target irony-server
[ 14%] Building CXX object src/CMakeFiles/irony-server.dir/support/CommandLineParser.cpp.o
[ 28%] Building CXX object src/CMakeFiles/irony-server.dir/support/TemporaryFile.cpp.o
[ 42%] Building CXX object src/CMakeFiles/irony-server.dir/Command.cpp.o
[ 57%] Building CXX object src/CMakeFiles/irony-server.dir/Irony.cpp.o
[ 71%] Building CXX object src/CMakeFiles/irony-server.dir/TUManager.cpp.o
[ 85%] Building CXX object src/CMakeFiles/irony-server.dir/main.cpp.o
[100%] Linking CXX executable ../bin/irony-server.exe
[100%] Built target irony-server
Install the project...
-- Install configuration: "Release"
-- Up-to-date: /home/kimim/.emacs.d/irony/bin/irony-server.exe
(defun org-babel-execute:clojure (body params)
"Execute a block of Clojure code with Babel.
The underlying process performed by the code block can be output
using the :show-process parameter."
(let* ((expanded (org-babel-expand-body:clojure body params))
(response (list 'dict))
result)
(cl-case org-babel-clojure-backend
(cider
(require 'cider)
(let ((result-params (cdr (assq :result-params params)))
(show (cdr (assq :show-process params))))
(if (member show '(nil "no"))
;; Run code without showing the process.
(progn
(setq response
(let ((nrepl-sync-request-timeout
org-babel-clojure-sync-nrepl-timeout))
(nrepl-sync-request:eval expanded
(cider-current-connection))))
(setq result
(concat
(nrepl-dict-get response
(if (or (member "output" result-params)
(member "pp" result-params))
"out"
"value"))
(nrepl-dict-get response "ex")
(nrepl-dict-get response "root-ex")
(nrepl-dict-get response "err"))))
;; Show the process in an output buffer/window.
(let ((process-buffer (switch-to-buffer-other-window
"*Clojure Show Process Sub Buffer*"))
status)
;; Run the Clojure code in nREPL.
(nrepl-request:eval
expanded
(lambda (resp)
(when (member "out" resp)
;; Print the output of the nREPL in the output buffer.
(princ (nrepl-dict-get resp "out") process-buffer))
(when (member "ex" resp)
;; In case there is an exception, then add it to the
;; output buffer as well.
(princ (nrepl-dict-get resp "ex") process-buffer)
(princ (nrepl-dict-get resp "root-ex") process-buffer))
(when (member "err" resp)
;; In case there is an error, then add it to the
;; output buffer as well.
(princ (nrepl-dict-get resp "err") process-buffer))
(nrepl--merge response resp)
;; Update the status of the nREPL output session.
(setq status (nrepl-dict-get response "status")))
(cider-current-connection))
;; Wait until the nREPL code finished to be processed.
(while (not (member "done" status))
(nrepl-dict-put response "status" (remove "need-input" status))
(accept-process-output nil 0.01)
(redisplay))
;; Delete the show buffer & window when the processing is
;; finalized.
(mapc #'delete-window
(get-buffer-window-list process-buffer nil t))
(kill-buffer process-buffer)
;; Put the output or the value in the result section of
;; the code block.
(setq result
(concat
(nrepl-dict-get response
(if (or (member "output" result-params)
(member "pp" result-params))
"out"
"value"))
(nrepl-dict-get response "ex")
(nrepl-dict-get response "root-ex")
(nrepl-dict-get response "err")))))))
(slime
(require 'slime)
(with-temp-buffer
(insert expanded)
(setq result
(slime-eval
`(swank:eval-and-grab-output
,(buffer-substring-no-properties (point-min) (point-max)))
(cdr (assq :package params))))))
(lein-exec
(let ((result-params (cdr (assq :result-params params))))
(if (or (member "output" result-params)
(member "pp" result-params))
(write-region (concat "(use 'clojure.pprint)
" expanded) nil "tmp.clj")
(write-region (concat "(use 'clojure.pprint)
(clojure.pprint/pprint
(do " expanded "))") nil "tmp.clj"))
(setq result
(replace-regexp-in-string
"
" ""
(shell-command-to-string (concat "cat tmp.clj | lein exec")))))))
(org-babel-result-cond (cdr (assq :result-params params))
result
(condition-case nil (org-babel-script-escape result)
(error result)))))
It will be difficult to mark the parent directory. Thus let’s disable this extention now.
(use-package dired-collapse)
(use-package selectrum-prescient
:config
(selectrum-prescient-mode +1)
(prescient-persist-mode +1))
(use-package marginalia
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
;; The :init configuration is always executed (Not lazy!)
:init
(marginalia-mode)
;; When using Selectrum, ensure that Selectrum is refreshed when cycling annotations.
(advice-add #'marginalia-cycle :after
(lambda () (when (bound-and-true-p selectrum-mode) (selectrum-exhibit)))))
(use-package selectrum
:defer 1
:config
(selectrum-mode +1)
(use-package selectrum-prescient)
(selectrum-prescient-mode +1)
(prescient-persist-mode +1)
(use-package marginalia)
(marginalia-mode +1))
original elpa’s:
;; upstream
(setq package-archives
'(("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")))
;; tsinghua mirror
(setq package-archives
'(("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
("org" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))
(use-package ggtags
:bind (("C-c f" . ggtags-find-file))
;;("M-." . ggtags-find-tag-dwim)
;;("M-*" . pop-tag-mark))
:config
;; (use-package ggtags)
;; (add-hook 'c-mode-hook 'ggtags-mode)
;; (add-hook 'c++-mode-hook 'ggtags-mode)
(setq ggtags-global-ignore-case t)
(setq ggtags-sort-by-nearness t))
do not embed svg in file now.
(defun org-babel-result-to-file (result &optional description)
"Convert RESULT into an `org-mode' link with optional DESCRIPTION.
If the `default-directory' is different from the containing
file's directory then expand relative links."
(when (stringp result)
(if (string= "svg" (file-name-extension result))
(progn
(with-temp-buffer
(if (file-exists-p (concat result ".html"))
(delete-file (concat result ".html")))
(rename-file result (concat result ".html"))
(insert-file-contents (concat result ".html"))
(message (concat result ".html"))
(format "#+BEGIN_HTML
<div style=\"text-align: center;\">
%s
</div>
#+END_HTML"
(buffer-string)
)))
(progn
(format "[[file:%s]%s]"
(if (and default-directory
buffer-file-name
(not (string= (expand-file-name default-directory)
(expand-file-name
(file-name-directory buffer-file-name)))))
(expand-file-name result default-directory)
result)
(if description (concat "[" description "]") ""))))))
(use-package unicode-fonts
:defer 3
:config
(defun unicode-fonts-setup-advice ()
(if window-system
(set-fontset-font
"fontset-default"
'cjk-misc (font-spec :family "YaheiInconsolata"))))
(advice-add 'unicode-fonts-setup :after 'unicode-fonts-setup-advice)
(defun kimim/add-font (group font)
(let ((font-list (assoc group unicode-fonts-block-font-mapping)))
(setf (cadr font-list) (cons font (cadr font-list)))))
(seq-map (lambda (group) (kimim/add-font group "YaheiInconsolata"))
'("Bopomofo" "Bopomofo Extended" "CJK Compatibility" "CJK Compatibility Forms"
"CJK Compatibility Ideographs" "CJK Compatibility Ideographs Supplement"
"CJK Radicals Supplement" "CJK Strokes" "CJK Symbols and Punctuation"
"CJK Unified Ideographs" "CJK Unified Ideographs Extension A"
"CJK Unified Ideographs Extension B" "CJK Unified Ideographs Extension C"
"CJK Unified Ideographs Extension D" "CJK Unified Ideographs Extension E"
"Enclosed Ideographic Supplement" "Halfwidth and Fullwidth Forms"
"Hangul Compatibility Jamo" "Hangul Jamo" "Hangul Jamo Extended-A"
"Hangul Jamo Extended-B" "Hangul Syllables" "Ideographic Description Characters"
"IPA Extensions" "Mathematical Alphanumeric Symbols"))
(seq-map (lambda (group) (kimim/add-font group "Consolas"))
'("Combining Diacritical Marks" "Combining Half Marks" "Cyrillic"
"Cyrillic Supplement" "Greek Extended" "Greek and Coptic" "Phonetic Extensions"
"Phonetic Extensions Supplement" "Superscripts and Subscripts"))
(add-to-list 'unicode-fonts-block-font-mapping
'("Spacing Modifier Letters"
("Consolas" "Monaco" "YaheiInconsolata")))
(unicode-fonts-setup))
C-x l
keychord can store deft links in deft mode, but cannot fetch the link
from deft note. Below defines a function to fetch a deft style link, which can
be used to paste directly in other org files, such as work journal. Buffer file
name handling function can be found from emacs manual[fn:22].
(use-package org
:bind
(("C-x m d" . kimim/deft-store-link))
:config
(defun kimim/deft-store-link()
"get deft link of current note file."
(interactive)
(unless (buffer-file-name)
(error "No file for buffer %s" (buffer-name)))
(let ((msg (format "[[deft:%s]]"
(file-name-nondirectory (buffer-name)))))
(kill-new msg)
(message msg))))
The Sunrise Commmander is a powerful and versatile double-pane file manager for GNU Emacs. It’s built atop of Dired and takes advantage of most of its functions, but also provides many handy features of its own.
To list directories first, you need to set ls-lisp-dirs-first
to non-nil. [fn:11]
(use-package sunrise-commander
:bind (("<f10>" . sunrise)
:map sr-mode-map
("D" . dired-do-delete)
("<f2>" . nil)
("o" . kimim/open-external)
("b" . sr-dired-prev-subdir)
("<left>" . sr-dired-prev-subdir)
("<right>" . sr-advertised-find-file))
:custom
(sr-cursor-follows-mouse nil)
(sr-windows-default-ratio 80)
(sr-listing-switches "-AGhlgov")
(sr-attributes-display-mask '(nil nil nil t t t))
(sr-show-file-attributes nil)
:config
(require 'dired)
(if (eq system-type 'darwin)
(setq sr-listing-switches "-Ahlgo")))
TL;DR stands for “Too Long; Didn’t Read”[fn:9]. tldr.el
[fn:10] is the Emacs
client.
(use-package tldr)
(add-hook 'org-agenda-after-show-hook 'org-narrow-to-subtree)
(defun org-agenda-add-note (&optional arg)
"Add a time-stamped note to the entry at point. DO NOT show other
headers when adding notes"
(interactive "P")
(org-agenda-check-no-diary)
(let* ((marker (or (org-get-at-bol 'org-marker)
(org-agenda-error)))
(buffer (marker-buffer marker))
(pos (marker-position marker))
(hfdmarker (org-get-at-bol 'org-hd-marker))
(inhibit-read-only t))
(with-current-buffer buffer
(org-narrow-to-subtree) ;; change from widen to org-narrow-to-subtree
(goto-char pos)
(org-show-context 'agenda)
(org-add-note))))