;;; common.el --- Common programming settings. -*- lexical-binding: t; -*- ;; Time-stamp: <2020-01-20T19:53:44+0100> ;;; Commentary: ;;; Code: (require 'basics/global-variables) (use-package emacs :ensure nil :custom (compilation-scroll-output 'first-error) :config (setq-default indent-tabs-mode nil ; Set default indentation. tab-width 4) (electric-pair-mode t) ; Auto-type closing brackets. ) ;; Guess indentation and if spaces or tabs are to be used. (use-package dtrt-indent :after (editorconfig) :hook (dtrt-indent-mode . editorconfig-apply) (prog-mode . dtrt-indent-mode) ) ;; Online documentation mode. (use-package eldoc :hook (prog-mode . turn-on-eldoc-mode) ) ;; Syntax checking with many plugins. (unless slow-computer (use-package flycheck :defer nil :functions (flycheck-add-mode) :custom (flycheck-cppcheck-checks '("style" "warning" "information")) (flycheck-emacs-lisp-load-path 'inherit) ; Use load-path of Emacs. :config (global-flycheck-mode) ;; (setq flycheck-check-syntax-automatically '(save new-line mode-change)) (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 :custom ;; Show suggestions after entering one character. (company-minimum-prefix-length 1) ;; Wrap around at end/beginning of list. (company-selection-wrap-around t) ;; Align annotation to the right border. (company-tooltip-align-annotations t) :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 (GUI). ("TAB" . company-complete-selection) ; Same 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 :after (treemacs ivy) :init (defvar my/cmake-compile-command ; cmake command for compiling with 1 (concat "cmake --build . -- -j" ; core less than available. (substring (shell-command-to-string "nproc --ignore=1") 0 -1))) (defun my/switch-project () "Add project to treemacs." (treemacs-add-and-display-current-project) (treemacs-collapse-other-projects) (treemacs-toggle-node)) (defun my/projectile-kill-buffers () "Kill project buffers and remove project from treemacs." (interactive) (projectile-kill-buffers) (let ((current-prefix-arg (projectile-project-name))) (treemacs-remove-project-from-workspace))) :custom (projectile-project-compilation-dir "build") (projectile-switch-project-action 'my/switch-project) (projectile-project-configure-cmd "cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -GUnix\\ Makefiles ..") (projectile-completion-system 'ivy) :config (setq projectile-project-compilation-cmd (concat my/cmake-compile-command " && cd tests && ctest -Q")) (projectile-mode +1) ;; Mark variables as safe. This prevents prompts when using .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)) ) ) ; 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-x 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) ) ;; Fold code. (use-package fold-dwim :bind ("C-c f" . fold-dwim-toggle) :hook (prog-mode . hs-minor-mode) ) ;; Highlight indentation. (use-package hl-indent :custom-face (hl-indent-face ((t (:inherit hl-indent-face ; Reversed whitespace. :background "gray18" :foreground "#1c1e1f" )))) :hook (prog-mode . hl-indent-mode) ) ;; Tries to find points of interest in buffer and jumps to them. (use-package imenu :custom (imenu-auto-rescan t) :bind ("M-i" . imenu) ) ;; Tries to find points of interest in all open buffers and jumps to them. (use-package imenu-anywhere :after (imenu ivy) :bind ("C-M-i" . ivy-imenu-anywhere) ) ;; 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 :config (editorconfig-mode 1) ) (use-package smerge :ensure nil ; Builtin. :defines (smerge-mode-map) :bind (:map smerge-mode-map ("" . smerge-prev) ("" . smerge-next) ("" . smerge-resolve) ) ) ;; Git integration. (use-package git-commit :pin melpa ) (unless slow-computer ;; magit from melpa needs transient from melpa. (use-package transient :pin melpa) (use-package magit :pin melpa :custom (magit-diff-refine-hunk 'all) ; Show word-granularity differences. :bind ("C-x g" . magit-status) ("C-x M-g" . magit-dispatch) :hook (after-save . magit-after-save-refresh-status) ) ;; Use libgit rather than git. (use-package magit-libgit :pin melpa ) ;; Show TODOs in magit-status. (use-package magit-todos :after magit :config ;; Mark variables as safe. This prevents prompts when using .dir-locals.el. (put 'magit-todos-depth 'safe-local-variable #'integerp) :hook (magit-mode . magit-todos-mode) ) ;; Work with Git forges from Magit. (use-package forge :pin melpa ; :after magit :config (add-to-list 'forge-alist '("schlomp.space" "schlomp.space/api/v1" "schlomp.space" forge-gitea-repository)) ) ) ; unless slow-computer. (unless slow-computer ;; Client for Language Server Protocol servers. (use-package lsp-mode :if (executable-find "clangd") :after (whitespace) :custom (lsp-prefer-flymake nil) ; Disable flymake. (lsp-auto-guess-root t) ; Don't ask for project root. (lsp-clients-clangd-args '("-compile-commands-dir=build")) (lsp-eldoc-render-all t) ; Display all eldoc information. :config (defun my/lsp-ws-toggle () (if lsp-ui-peek-mode (my/whitespace-mode-off) (my/whitespace-mode-on))) :hook (c++-mode . lsp) (c-mode . lsp) (lsp-ui-peek-mode . my/lsp-ws-toggle) ; Dots in wrong color. ) ;; Eye-candy and flycheck support for lsp-mode. (use-package lsp-ui :after (lsp-mode flycheck) :custom (lsp-ui-sideline-enable nil) ; Do not insert doc into buffer. (lsp-ui-doc-include-signature t) ; Include signature in doc popup. (lsp-ui-doc-enable nil) ; Disable doc popup. :bind (:map lsp-ui-mode-map ("M-." . lsp-ui-peek-find-definitions) ("C-M-." . lsp-ui-peek-find-references) ) :hook (lsp-mode . lsp-ui-mode) ) ;; Completions with lsp-mode. (use-package company-lsp :after (lsp-mode company) :config (push 'company-lsp company-backends) ) ;; ivy interface to lsp-mode. (use-package lsp-ivy :after (lsp-mode ivy) ) ;; Integration between lsp-mode and treemacs. (use-package lsp-treemacs :after (treemacs lsp-mode) :bind (:map lsp-ui-mode-map ("" . lsp-treemacs-errors-list) ; Use treemacs for error list. ("M-i" . lsp-treemacs-symbols) ; Display symbols using treemacs. ) ) ) ; unless slow-computer. (provide 'programming/common) ;;; common.el ends here