Skip to content

Latest commit

 

History

History
645 lines (577 loc) · 21.5 KB

myinit.org

File metadata and controls

645 lines (577 loc) · 21.5 KB

Init Setting

;; Increase garbage collection threshold to accelerate startup
(setq gc-cons-threshold 64000000)

;; Set number of spaces for c/c++ source file
(setq c-basic-offset 2)
;; For a buffer-local variable, setq can only apply to current buffer,
;; while setq-default can apply to all buffers.
(setq-default tab-width 4)

;; Make the backspace properly erase the tab instead of
;; removing 1 space at a time.
(setq backward-delete-char-untabify-method 'hungry)

;; Prevent emacs from making backup files
(setq make-backup-files nil)

;; Set the default text coding system
(setq default-buffer-file-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

;; Remove trailing whitespaces
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(setq deleting-trailing-whitespace-switch t)
;; Toggle automatically deleting trailing whitespace
(defun toggle-deleting-trailing-whitespace ()
  (interactive)
  (if deleting-trailing-whitespace-switch
    (progn
      (remove-hook 'before-save-hook 'delete-trailing-whitespace)
      (setq deleting-trailing-whitespace-switch nil)
      (message "Toggle off delete-trailing-whitespace"))
    (progn
      (add-hook 'before-save-hook 'delete-trailing-whitespace)
      (setq deleting-trailing-whitespace-switch t)
      (message "Toggle on delete-trailing-whitespace"))))

(global-set-key (kbd "C-c w") 'toggle-deleting-trailing-whitespace)

;; Change TAB key behavior to insert spaces instead
(setq-default indent-tabs-mode nil)

;; More powerful automatic adjustments according to whitespace-style
;; variable, which may influence leading whitespaces.
;; (add-hook 'before-save-hook 'whitespace-cleanup)

;; Add a value to 'load-path'
(add-to-list 'load-path "~/.emacs.d/site-lisp")

Keybinding

(defun next-lines ()
  (interactive)
  (forward-line 5))

(defun previous-lines()
  (interactive)
  (forward-line -5))

(global-set-key (kbd "M-n") 'next-lines)
(global-set-key (kbd "M-p") 'previous-lines)

;; Revert buffer from disk
(defun refresh-file ()
  (interactive)
  (revert-buffer t (not (buffer-modified-p)) t))

(global-set-key (kbd "<f5>") 'refresh-file)

(global-set-key (kbd "C-x k") 'kill-this-buffer)

Common

;; Coding mode configurations
(defun coding-mode ()
  ;; Highlight trailing whitespaces and exceeding part
  ;; when lines are longer than whitespace-line-column
  (setq show-trailing-whitespace t)
  ;; If we want to tolerate projects with particularly long lines of code,
  ;; set the following variable to a bigger number.
  ;; (setq whitespace-line-column 200)
  ;; Auto-fill when current line is longer than 80 characters
  (setq fill-column 80)
  (setq auto-fill-function 'do-auto-fill)
  (whitespace-mode t))

(defun add-multiple-hooks (hook-function hooks)
  (mapc (lambda (hook) (add-hook hook hook-function)) hooks))

(add-multiple-hooks 'coding-mode
  '(sh-mode-hook
    c-mode-hook
    c++-mode-hook
    python-mode-hook))

(defun infer-indentation-style ()
  ;; if our source file uses tabs, we use tabs, if spaces spaces, and if
  ;; neither, we use the current indent-tabs-mode
  (let ((space-count (how-many "^  " (point-min) (point-max)))
        (tab-count (how-many "^\t" (point-min) (point-max))))
    (if (> tab-count space-count)
          (progn
            (setq indent-tabs-mode nil)
            (local-set-key (kbd "TAB") 'self-insert-command)
            ;; Indentation offset equals one TAB
            (setq c-basic-offset 4)

            ;; We're changing the value of variable c-offsets-alist to change indentation behavior
            ;; Make substatement block following if/while
            (c-set-offset 'substatement-open 0)
            ;; Make case statement indent
            (c-set-offset 'case-label '+)

            (message "infer indent-tabs-mode enabled")))))

(defun infer-trailing-whitespace-style ()
  (setq disable-threshold 5)
  (let ((trail-space-count (how-many " $" (point-min) (point-max))))
    (if (> trail-space-count disable-threshold)
          (toggle-deleting-trailing-whitespace))))

(add-hook 'c-mode-common-hook 'infer-indentation-style)
(add-hook 'c-mode-common-hook 'infer-trailing-whitespace-style)

Interface Tweak

;; Use y-n instead of yes-no
(fset 'yes-or-no-p 'y-or-n-p)

;; Display column number
(setq column-number-mode t)

;; Ignore ring-bell-function
(setq ring-bell-function 'ignore)

;; Put an newline at end of file if it doesn't exist
;; Newline character is regard as the end of each line, and
;; it may cause header file including error without it.
(setq require-final-newline t)

;; Highlight cursor line
(global-hl-line-mode t)

;; Remove tab-mark if TAB is generally used in a project.
(setq whitespace-style '(face tabs trailing lines space-before-tab
  empty space-after-tab tab-mark))

Package Archives

(require 'package)
;; (setq package-archives '(("gnu" . "http://elpa.emacs-china.org/gnu/")
;;                          ("melpa" . "http://elpa.emacs-china.org/melpa/")
;;                          ("org" . "http://elpa.emacs-china.org/org/")))
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

;; Disable automatically loading after processing the init file
(setq package-enable-at-startup nil)

;; Avoid automatically adding (package-initialize) to the init file
(setq package--init-file-ensured t)

Use-package bootstrap

;; Install use-package
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

;; Enable use-package
(eval-when-compile
  (require 'use-package))

;; Always download absent packages
(setq use-package-always-ensure t)

Ibuffer

(require 'ibuffer)

(global-set-key (kbd "C-x C-b") 'ibuffer)

;; Define buffer groups
(setq ibuffer-saved-filter-groups

      (quote (("default"
               ("dired" (mode . dired-mode))
               ("emacs" (or
                         (name . "^\\*scratch\\*$")
                         (name . "^\\*Help\\*$")
                         (name . "^\\*Messages\\*$")))
               ("programming" (or
                               (mode . python-mode)
                               (mode . c++-mode)
                               (mode . c-mode)
                               (mode . perl-mode)
                               (mode . python-mode)
                               (mode . emacs-lisp-mode)))
               ("shell" (or
                         (mode . sh-mode)
                         (mode . term-mode)
                         (mode . shell-mode)
                         (mode . eshell-mode)))
               ("edit" (or
                        (mode . org-mode)
                        (mode . markdown-mode)
                        (mode . text-mode)))
               ("git" (or
                       (mode . diff-mode)
                       (name . "^magit.*")
                       (name . ".gitignore")))
               ("gdb" (or
                       (mode . gdb-frames-mode)
                       (mode . gdb-inferior-io-mode)
                       (mode . gdb-breakpoints-mode)
                       (mode . gud-mode)
                       (mode . gdb-threads-mode)
                       (mode . gdb-locals-mode)))
               ("gnus" (or
                        (mode . message-mode)
                        (mode . bbdb-mode)
                        (mode . mail-mode)
                        (mode . gnus-group-mode)
                        (mode . gnus-summary-mode)
                        (mode . gnus-article-mode)
                        (name . "^\\.bbdb$")
                        (name . "^\\.newsrc-dribble")))))))

(add-hook 'ibuffer-mode-hook
          (lambda ()
            (ibuffer-switch-to-saved-filter-groups "default")))

;; Stop showing groups in which there is no buffer
(setq ibuffer-show-empty-filter-groups nil)

;; Hide the last two summary lines
(setq ibuffer-display-summary nil)

;; Do not ask for confirmation when deleting marked buffers
(setq ibuffer-expert t)

;; Use human readable Size column instead of original one
(define-ibuffer-column size-h
  (:name "Size" :inline t)
  (cond
   ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
   ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0)))
   ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
   (t (format "%8d" (buffer-size)))))

;; Modify the default ibuffer-formats
(setq ibuffer-formats
      '((mark modified read-only " "
              (name 18 18 :left :nil)
              " "
              (size-h 9 -1 :right)
              " "
              (mode 16 16 :left :elide)
              " "
              filename-and-process)))

Which Key

(use-package which-key)
(which-key-mode)

Ace Window

(use-package ace-window
  :bind ("M-o" . 'ace-window)
  :config
  (setq aw-scope 'frame)
  (setq aw-background nil)
  (setq aw-dispatch-always t)
  (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))

Command Log

(use-package command-log-mode)

Undo tree

(use-package undo-tree)
;; Prevent undo tree files from polluting your git repo
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
;; C-/ undo; M-_ redo; C-x u visulaize.
(global-undo-tree-mode t)

C/C++

Basic C/C++

(add-to-list 'auto-mode-alist '("\\.ic\\'" . c++-mode))
(add-to-list 'auto-mode-alist '("\\.yy\\'" . c++-mode))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

;; Syntax highlight for latest C++
(use-package modern-cpp-font-lock)
(add-hook 'c-mode-common-hook 'modern-c++-font-lock-global-mode)

;; Google c/c++ style
(use-package google-c-style)

(add-hook 'c-mode-common-hook 'google-set-c-style)
(add-hook 'c-mode-common-hook 'google-make-newline-indent)

;; Fold code block with `C-c @ C-c`
(add-hook 'c-mode-common-hook 'hs-minor-mode)

CMake mode

(use-package cmake-mode)
(add-to-list 'auto-mode-alist '("CMakeLists\\.txt\\'" . cmake-mode))
(add-to-list 'auto-mode-alist '("\\.cmake\\'" . cmake-mode))

Code check

(use-package flycheck)
(setq flycheck-clang-language-standard "c++11")

Code completion

(use-package company)
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 3)
(setq company-show-numbers t)
;; Popup the completion window manually
(global-set-key (kbd "C-c c") 'company-capf)

Code navigation

;; lsp-mode settings
;; NOTE: clangd cannot correctly find the references if the project directory is
;; under a symlinked parent directory. See https://github.com/clangd/clangd/issues/503
(defun init-lsp ()
  "Load lsp-mode."
  (use-package lsp-mode
    :init (setq lsp-keymap-prefix "C-c l")
    :custom (lsp-idle-delay 0.5)
    (lsp-completion-provider :capf)
    (lsp-enable-folding t)
    (lsp-enable-snippet t)
    (lsp-headerline-breadcrumb-enable nil)
    (lsp-server-trace "verbose")
    (lsp-clients-clangd-args
     '("-j=32" "-background-index" "-log=verbose"
       "-all-scopes-completion" "-suggest-missing-includes")))
  (add-hook 'c-mode-common-hook #'lsp-deferred)

  ;; Don't collect completion symbols. If there are too many symbols in current file, will hang for seconds
  (cl-defmethod my-xref-backend-identifier-completion-table ((_backend (eql xref-lsp)))
    )
  (advice-add 'xref-backend-identifier-completion-table :override #'my-xref-backend-identifier-completion-table)

  ;; Input symbol name to find the definition
  (cl-defmethod my-xref-backend-identifier-at-point ((_backend (eql xref-lsp)))
    (let ((thing (thing-at-point 'symbol)))
      (and thing (propertize thing
                             'identifier-at-point t))))

  (advice-add 'xref-backend-identifier-at-point :override #'my-xref-backend-identifier-at-point)

  (cl-defmethod my-xref-backend-definitions ((_backend (eql xref-lsp)) identifier)
    (save-excursion
      (if (not (get-text-property 0 'identifier-at-point identifier))
          (-if-let (pos (assoc identifier lsp--symbols-cache))
              (progn (goto-char (cl-rest pos))
                     (lsp--locations-to-xref-items (lsp-request "textDocument/definition"
                                                                (lsp--text-document-position-params))))
            (xref-backend-apropos _backend identifier))
        (lsp--locations-to-xref-items (lsp-request "textDocument/definition"
                                                   (lsp--text-document-position-params))))))

  (advice-add 'xref-backend-definitions :override #'my-xref-backend-definitions))

;; rtags settings
(defun init-rtags ()
  "Load rtags."
  (setq rtags-process-flags (concat "--rp-nice-value 10 "
                                    "--job-count 8 "
                                    "--error-limit 50000 "
                                    "--log-file-log-level debug "
                                    "--completion-logs"))
  ;; The hook will be called everytime we find definitions or references, causing multiple
  ;; emacs kill each other's rdm and launch its own, which is slow at startup. Not advised.
  ;; (add-hook 'c-mode-common-hook 'rtags-start-process-unless-running)
  ;;
  ;; Using the following command to keep a daemon rdm backend on the server. Multiple emacs clients can share it.
  ;; rdm --rp-nice-value 10 --job-count 8 --error-limit 50000 --log-file-log-level debug --completion-logs --daemon
  (setq rtags-completions-enabled t)
  (require 'rtags-xref)
  (add-hook 'c-mode-common-hook #'rtags-xref-enable)
  (require 'company)
  (setq rtags-autostart-diagnostics t)
  (rtags-diagnostics)
  (setq rtags-completions-enabled t)
  (push 'company-rtags company-backends)
  (add-hook 'c-mode-common-hook 'company-mode)
  (define-key c-mode-base-map (kbd "<C-tab>") (function company-complete)))

(defvar navigation-mode "lsp"
  "The navigation mode used. It is either 'rtags' or 'lsp'.")

(cond ((equal navigation-mode "rtags")
       (init-rtags))
      ((equal navigation-mode "lsp")
       (init-lsp)))

;; Don't prompt if there's value at point for following functions
(setq xref-prompt-for-identifier '(not xref-find-definitions xref-find-references))

Swiper

(use-package swiper
  :bind (("C-s" . swiper)))

Yasnippet

(use-package yasnippet)
(use-package yasnippet-snippets)

Iedit

(use-package iedit)

Git

Magit

(use-package magit
  :bind (("C-x g" . magit-status)
         ("C-o" . magit-diff-visit-file-other-window)))

Ivy

(use-package ivy
  :custom
  (ivy-use-virtual-buffers t)
  (ivy-count-format "%d/%d ")
  (ivy-display-style 'fancy)
  :config
  (ivy-mode t))

Counsel

(use-package counsel
  :custom
  (counsel-find-file-ignore-regexp "^#\\|/#\\|/\\.#\\|\\.(orig|rej)$\\|clangd.*\\(.idx\\)$")
  :config
  (counsel-mode t)
  (require 'map)
  ;; ivy has a sort function list to provide sort method's to functions.
  (map-put ivy-sort-functions-alist #'counsel-M-x #'string-lessp))

Helm

(use-package helm
  :ensure t
  :custom
  (helm-split-window-inside-p t)
  (helm-ff-file-name-history-use-recentf t)
  :bind (("M-x" . 'helm-M-x)
         ("M-y" . 'helm-show-kill-ring)
         ("C-x C-f" . 'helm-find-files)
         ("C-x b" . 'helm-mini))
  :config
  (helm-autoresize-mode t)
  (helm-mode t))

(define-key helm-map (kbd "C-z")  'helm-select-action) ; list actions using C-z

;; `C-c h m` run man
(global-set-key (kbd "C-c h") 'helm-command-prefix)
(global-unset-key (kbd "C-x c"))

;; Interactive search with ag(Silver Searcher)
(use-package helm-ag
  :ensure t
  ;; `C-c C-f` follow search result mode
  :bind (("C-c C-r" . 'helm-do-ag)
         ("C-c C-g" . 'helm-do-ag-project-root)))

Projectile

(use-package projectile
  :config
  (projectile-mode +1)
  (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))

Smartparens

(use-package smartparens
  :config
  (smartparens-global-mode t)
  (show-smartparens-global-mode t))

Avy

(use-package avy
  :ensure t
  :bind (("M-g w" . avy-goto-word-1)))

Gdb

;; Enable mouse support
(add-hook 'gud-mode-hook (lambda ()
                           (setq gdb-show-main t)))

;; Conflict with tmux prefix C-t
(global-set-key (kbd "C-x C-a C-q") 'gud-tbreak)

Smart Mode Line

;; smart-mode-line's dependency
(use-package rich-minority)
(require 'smart-mode-line)
(setq sml/no-confirm-load-theme t)
(setq sml/theme 'respectful)
(sml/setup)

Git timemachine

;; View a file between different versions `M-x git-timemachine`
(use-package git-timemachine
  :ensure t)

SQL

;; Predefine database configurations
(setq sql-connection-alist
      '((local-test
         (sql-product 'mysql)
         (sql-server "127.0.0.1")
         (sql-user "root")
         (sql-password "")
         (sql-database "test")
         (sql-port 33332))))

(defun sql-connect-preset (name)
  "Connect to a predefined SQL connection listed in `sql-connection-alist'"
  (eval `(let ,(cdr (assoc name sql-connection-alist))
           (flet ((sql-get-login (&rest what)))
                 (sql-product-interactive sql-product)))))

(defun mysql-local ()
  (interactive)
  (sql-connect-preset 'local-test))

;; Link the current buffer to client buffer
(defun mysqli-link()
  (interactive)
  (sql-mode)
  (sql-set-product "mysql")
  (sql-set-sqli-buffer))

(global-set-key (kbd "<f9>") 'mysql-local)

Other Manually Packages

Solarized Theme

;; Load solarized theme
(add-to-list 'custom-theme-load-path
             "~/.emacs.d/site-lisp/emacs-color-theme-solarized")
(load-theme 'solarized t)
(add-hook 'after-init-hook
          (lambda ()
            (if (display-graphic-p)
                ;; GUI
                (set-frame-parameter nil 'background-mode 'light)
              ;; Terminal
              (set-terminal-parameter nil 'background-mode 'dark))
            (enable-theme 'solarized)))

Others

Compilation

(setq compilation-scroll-output 't)
;; Display colors normally in compilation output
(add-hook 'compilation-filter-hook 'ansi-color-compilation-filter)

(defun my-compile-func()
  (interactive)
  (if (vc-root-dir) (setq root-dir (vc-root-dir))
    (setq root-dir default-directory))

  (setq build-path-options '())
  (setq build-path nil)

  ;; Find directory in which makefile exists
  (let ((files (directory-files root-dir t "^build\\|^\\.")))
    (dolist (direc-path files)
      (if (file-exists-p (concat direc-path "/Makefile"))
          (setq build-path-options (cons direc-path build-path-options)))))

  (if (> (length build-path-options) 1)
      (progn
        ;; Prompt user to select a choice from list
        (setq build-path (completing-read "Choose directory to build: " build-path-options nil t)))
    (if (= (length build-path-options) 1)
        (setq build-path (car build-path-options)))) ;; Choose the first option in list

  (if (not (null build-path))
      (progn
        (cd build-path)
        (message "Makefile at %s" build-path)
        (setq compile-command "make -j16"))
    (setq compile-command (concat "g++ -std=c++11 -g " buffer-file-name)))
  (compile compile-command))

(defun apg-compile-func()
  (interactive)
  (setq compile-command "brazil-build rebuild")
  (compile compile-command)
  (shell-command "python /local/home/zboli/tmp/test.py"))

(global-set-key (kbd "<f12>") 'apg-compile-func)

(global-set-key (kbd "<f10>") 'my-compile-func)