;;; common.el --- Common programming settings. -*- lexical-binding: t; -*- ;; Time-stamp: <2020-11-15T19:51:36+0100> ;;; Commentary: ;;; Code: (require 'basics/package-management) (require 'basics/global-variables) (use-package emacs :demand t :after (compile) :defines (compilation-mode-map) :custom (compilation-scroll-output 'first-error) :config (progn (setq-default indent-tabs-mode nil ; Set default indentation. tab-width 4) (electric-pair-mode t) ; Auto-type closing brackets. (defun my/clangd-version () "Returns the version of clangd as float." (string-to-number (nth 2 (split-string (shell-command-to-string "clangd --version"))))) (which-function-mode)) :bind (("C-:" . ff-find-other-file) ; Switch between header and source. (:map compilation-mode-map ("" . compilation-previous-error) ("" . compilation-next-error)))) ;; Guess indentation and if spaces or tabs are to be used. (use-package dtrt-indent :after (editorconfig) :diminish dtrt-indent-mode :hook ((dtrt-indent-mode . editorconfig-apply) (prog-mode . dtrt-indent-mode))) ;; Online documentation mode. (use-package eldoc :diminish eldoc-mode :hook (prog-mode . turn-on-eldoc-mode)) ;; Syntax checking with many plugins. (unless slow-computer (use-package flycheck :demand t :functions (flycheck-add-mode) :diminish flycheck-mode :custom ((flycheck-cppcheck-checks '("style" "warning" "information")) (flycheck-emacs-lisp-load-path 'inherit) ; Use load-path of Emacs. (flycheck-idle-change-delay 2.0)) :config (progn (global-flycheck-mode) (flycheck-add-mode 'html-tidy 'web-mode) (flycheck-add-mode 'css-csslint 'web-mode)) :bind (:map flycheck-mode-map ("" . flycheck-previous-error) ("" . flycheck-next-error) ("" . flycheck-list-errors))) ) ; unless slow-computer. ;; Autocompletion mode with many plugins. (unless slow-computer (use-package company :diminish company-mode :custom ((company-minimum-prefix-length 1) ; Suggestions after 1 character. (company-selection-wrap-around t) (company-tooltip-align-annotations t) ; Align to the right border. (company-idle-delay 0.5)) :bind (:map company-active-map ("" . nil) ; Disable completion on return. ("RET" . nil) ; https://emacs.stackexchange.com/a/13290 ("" . company-complete-selection) ; Make tab work in lists. ("TAB" . company-complete-selection)) ; Tab in terminals. :hook (after-init . global-company-mode)) ;; Fuzzy autocompletion for company. (use-package company-flx :after company :config (company-flx-mode +1)) (use-package company-statistics :after company :hook (after-init . company-statistics-mode)) ;; Documentation popups for completions. (use-package company-quickhelp :config (company-quickhelp-mode)) ) ; unless slow-computer. ;; Automatic project management. (unless slow-computer (use-package projectile :demand t :after (treemacs ivy window-purpose) :functions (f-directory? treemacs-collapse-other-projects treemacs-toggle-node my/projectile-kill-buffers purpose-set-window-purpose-dedicated-p) :diminish projectile-mode :init (progn (defvar my/cmake-compile-command ; cmake command for compiling with (concat "cmake --build . -- -j" ; 1 core less than available. (substring (shell-command-to-string "nproc --ignore=1") 0 -1))) (defun my/projectile-enable-caching? (&rest args) "Turn on caching for certain projects. Ignores ARGS." (if (string= (projectile-project-name) ".emacs.d") (progn (message "Turning on caching for \"%s\"." (projectile-project-name)) (setq-local projectile-enable-caching t)) (kill-local-variable 'projectile-enable-caching))) (advice-add 'projectile-find-file :before #'my/projectile-enable-caching?) (advice-add 'counsel-projectile-find-file :before #'my/projectile-enable-caching?) (defun my/switch-project () "Find file in project, add project to `treemacs' and collapse other projects." ; Enable caching maybe before listing files. (my/projectile-enable-caching?) (if (member 'counsel-projectile-mode minor-mode-list) (counsel-projectile-find-file) (projectile-find-file)) (when (>= (frame-width) 120) (treemacs-add-and-display-current-project) (treemacs-collapse-other-projects) (other-window 1))) (defun my/projectile-kill-buffers () "Kill project buffers and delete other windows." (interactive) (projectile-kill-buffers) (delete-other-windows) (purpose-set-window-purpose-dedicated-p nil nil))) :custom ((projectile-project-compilation-dir "build") (projectile-switch-project-action 'my/switch-project) (projectile-project-configure-cmd "cmake -GUnix\\ Makefiles -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DWITH_TESTS=YES ..") (projectile-completion-system 'ivy) (projectile-indexing-method 'hybrid) ; Allow filtering. (projectile-globally-ignored-file-suffixes '("~"))) :config (progn (setq projectile-project-compilation-cmd (concat my/cmake-compile-command " && cd tests && ctest -Q")) (projectile-mode +1) ;; Mark variables as safe. Prevents prompts with .dir-locals.el. (put 'projectile-project-compilation-cmd 'safe-local-variable #'stringp) (put 'projectile-project-configure-cmd 'safe-local-variable #'stringp) ;; Auto-search for projects. (if (f-directory? "~/Projekte") (setq projectile-project-search-path '("~/Projekte")))) :bind (("C-c p" . 'projectile-command-map) (:map projectile-command-map ("k" . 'my/projectile-kill-buffers)) (:map projectile-mode-map ; Only override in projectile-mode. ("C-x C-f" . 'projectile-find-file)))) ) ; unless slow-computer. ;; Highlight TODO, FIXME, NOTE and so on. (use-package hl-todo :bind (:map hl-todo-mode-map ("C-c t" . hl-todo-occur)) :hook (prog-mode . hl-todo-mode)) ;; Better commenting. (use-package smart-comment :bind ("C-c c" . smart-comment)) ;; Toggle betweeen beginning/end of line and beginning/end of code. (use-package mwim :bind (("" . mwim-beginning-of-line-or-code) ("" . mwim-end-of-line-or-code))) ;; Needs to be here in order to diminish it. (use-package hideshow :defer 4 :diminish hs-minor-mode) ;; Fold code. (use-package fold-dwim :after (hideshow) :bind ("C-c f" . fold-dwim-toggle) :hook (prog-mode . hs-minor-mode)) ;; Highlight indentation. (use-package hl-indent :after (doom-themes whitespace) :config (progn (set-face-background 'hl-indent-face ; Reverse whitespace-space. (face-foreground 'whitespace-space)) (set-face-foreground 'hl-indent-face (face-background 'default))) :hook (prog-mode . hl-indent-mode)) ;; Jump to definition using grep. (use-package dumb-jump :after (ivy) :custom (dumb-jump-selector 'ivy) :bind ("M-." . dumb-jump-go)) ; Will be overwritten by more intelligent modes. ;; Support .editorconfig files. (use-package editorconfig :defer 2 :diminish editorconfig-mode :config (editorconfig-mode 1)) (use-package smerge-mode :defines (smerge-mode-map) :bind (:map smerge-mode-map ("" . smerge-prev) ("" . smerge-next) ("" . smerge-resolve) ("C-" . smerge-keep-upper) ("C-" . smerge-keep-lower))) (use-package copyright :config (defun my/maybe-copyright-update () "Update existing copyright notice to indicate the current year if mode is derived from prog-mode." (if (and my/reformat-save (derived-mode-p 'prog-mode)) (copyright-update))) :hook (before-save . my/maybe-copyright-update)) ;; Highlights parentheses, brackets or braces according to their depth. (use-package rainbow-delimiters :custom (rainbow-delimiters-max-face-count 2) :custom-face (rainbow-delimiters-depth-1-face ((t (:inherit rainbow-delimiters-base-face :foreground "LightPink")))) (rainbow-delimiters-depth-2-face ((t (:inherit rainbow-delimiters-base-face :foreground "LightGreen")))) (rainbow-delimiters-depth-3-face ((t (:inherit rainbow-delimiters-base-face :foreground "MediumPurple1")))) (rainbow-delimiters-depth-4-face ((t (:inherit rainbow-delimiters-base-face :foreground "LightSkyBlue")))) :hook (prog-mode . rainbow-delimiters-mode)) ;; Make bug references clickable. (use-package bug-reference :straight nil ; Inbuilt. :config (put 'bug-reference-url-format 'safe-local-variable #'stringp) :hook (prog-mode . bug-reference-prog-mode)) (provide 'programming/common) ;;; common.el ends here