diff --git a/bin/doom b/bin/doom index 5351c7fa2..5f64df4cd 100755 --- a/bin/doom +++ b/bin/doom @@ -1,16 +1,16 @@ #!/usr/bin/env sh :; # -*- mode: emacs-lisp; lexical-binding: t -*- :; case "$EMACS" in *term*) EMACS=emacs ;; *) EMACS="${EMACS:-emacs}" ;; esac +:; [ "$EMACS" = emacs ] && { type emacs >/dev/null 2>&1 || err=1; } +:; [ -n "$err" ] && { echo "Error: failed to run Emacs with command '$EMACS'"; echo; echo "Are you sure Emacs is installed and in your \$PATH?"; exit 1; } >&2 :; emacs="$EMACS ${DEBUG:+--debug-init} -q --no-site-file --batch" -:; tmpdir=`$emacs -Q --eval '(princ (temporary-file-directory))' 2>/dev/null` -:; [ -z "$tmpdir" ] && { >&2 echo "Error: failed to run Emacs with command '$EMACS'"; >&2 echo; >&2 echo "Are you sure Emacs is installed and in your \$PATH?"; exit 1; } :; export __DOOMPID="${__DOOMPID:-$$}" :; export __DOOMSTEP="${__DOOMSTEP:-0}" :; export __DOOMGEOM="${__DOOMGEOM:-`tput cols 2>/dev/null`x`tput lines 2>/dev/null`}" :; export __DOOMGPIPE=${__DOOMGPIPE:-$__DOOMPIPE} :; export __DOOMPIPE=; [ -t 0 ] || __DOOMPIPE="${__DOOMPIPE}0"; [ -t 1 ] || __DOOMPIPE="${__DOOMPIPE}1" :; $emacs --load "$0" -- "$@" || exit=$? -:; [ "${exit:-0}" -eq 254 ] && { sh "${tmpdir}/doom.${__DOOMPID}.${__DOOMSTEP}.sh" "$0" "$@" && true; exit="$?"; } +:; [ "${exit:-0}" -eq 254 ] && { export TMPDIR="${TMPDIR:-${TEMP:-`$emacs -Q --eval '(princ (temporary-file-directory))' 2>/dev/null`}}"; sh "${TMPDIR}/doom.${__DOOMPID}.${__DOOMSTEP}.sh" "$0" "$@" && true; exit="$?"; } :; exit $exit ;; This magical mess of a shebang is necessary for any script that relies on diff --git a/bin/doom.ps1 b/bin/doom.ps1 index a8f77646b..be05fe305 100644 --- a/bin/doom.ps1 +++ b/bin/doom.ps1 @@ -7,32 +7,34 @@ if (!(Get-Command -Erroraction silentlycontinue emacs.exe)) { $doom = "$PSScriptRoot/doom" $emacs = if ($env:EMACS) { $env:EMACS } else { (Get-Command emacs.exe).Path } -$emacsargs = "-q", "--no-site-file", "--batch" $oldemacsdir = $env:EMACSDIR try { - $env:EMACSDIR = if (-not $env:EMACSDIR) { (get-item $PSScriptRoot).parent.FullName } else { $env:EMACSDIR } - $env:__DOOMSH = if (-not $env:__DOOMSH) { "ps1" } else { $env:__DOOMSH } - $env:__DOOMPID = if (-not $env:__DOOMPID) { $PID } else { $env:__DOOMPID } - $env:__DOOMSTEP = if (-not $env:__DOOMSTEP) { 0 } else { $env:__DOOMSTEP } - $cols = (Get-Host).UI.RawUI.WindowSize.Width - $lines = (Get-Host).UI.RawUI.WindowSize.Height - $env:__DOOMGEOM = if (-not $env:__DOOMGEOM) { "$cols`x$lines" } else { $env:__DOOMGEOM } + if (-not $env:EMACSDIR) { $env:EMACSDIR = (get-item $PSScriptRoot).parent.FullName; } + if (-not $env:__DOOMSH) { $env:__DOOMSH = "ps1"; } + if (-not $env:__DOOMPID) { $env:__DOOMPID = $PID; } + if (-not $env:__DOOMSTEP) { $env:__DOOMSTEP = 0; } + if (-not $env:__DOOMGEOM) { + $cols = (Get-Host).UI.RawUI.WindowSize.Width + $lines = (Get-Host).UI.RawUI.WindowSize.Height + $env:__DOOMGEOM = "$cols`x$lines" + } # $env:__DOOMGPIPE = if (-not $env:__DOOMGPIPE) { $env:__DOOMPIPE } else { $env:__DOOMGPIPE } # $env:__DOOMPIPE = "" - & $emacs $emacsargs --load "$doom" -- --no-color $args - $exit = $LASTEXITCODE + & $emacs -q --no-site-file --batch --load "$doom" -- --no-color $args + if ($LASTEXITCODE -eq 254) { + & pwsh "$($env:temp)\doom.$($env:__DOOMPID).$($env:__DOOMSTEP).ps1" $PSCommandPath $args + $exit = $LASTEXITCODE + } + exit $exit } finally { - $env:EMACSDIR = $oldemacsdir - Remove-Item Env:\__DOOMSH - Remove-Item Env:\__DOOMPID - Remove-Item Env:\__DOOMSTEP - Remove-Item Env:\__DOOMGEOM + # Only clear the env at top-level + if ($env:__DOOMSTEP -eq 0) { + $env:EMACSDIR = $oldemacsdir + Remove-Item Env:\__DOOMSH + Remove-Item Env:\__DOOMPID + Remove-Item Env:\__DOOMSTEP + Remove-Item Env:\__DOOMGEOM + } } - -if ($exit -eq 254) { - & pwsh "$($env:temp)\doom.$($env:__DOOMPID).$($env:__DOOMSTEP).ps1" $PSCommandPath $args - $exit = $LASTEXITCODE -} -exit $exit diff --git a/lisp/init.el b/lisp/init.el index 301d8b0ad..8426ef16a 100644 --- a/lisp/init.el +++ b/lisp/init.el @@ -13,4 +13,25 @@ (doom-require 'doom-projects) (doom-require 'doom-editor) +;; COMPAT: `safe-local-variable-directories' was introduced in Emacs 30.1 +(unless (boundp 'safe-local-variable-directories) + (defvar safe-local-variable-directories ()) + (define-advice hack-local-variables-filter (:around (fn variables dir-name) respect) + (let ((enable-local-variables + (if (delq nil (mapcar (lambda (dir) + (and dir-name dir + (file-equal-p dir dir-name))) + safe-local-variable-directories)) + :all + enable-local-variables))) + (funcall fn variables dir-name)))) + +;; Ensure .dir-locals.el in $EMACSDIR and $DOOMDIR are always respected +(add-to-list 'safe-local-variable-directories doom-emacs-dir) +(add-to-list 'safe-local-variable-directories doom-user-dir) + +;;; Support for Doom-specific file extensions +(add-to-list 'auto-mode-alist '("/\\.doom\\(?:project\\|module\\|profile\\)?\\'" . lisp-data-mode)) +(add-to-list 'auto-mode-alist '("/\\.doomrc\\'" . emacs-lisp-mode)) + ;;; init.el ends here diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index b1da1068b..7ff7900c0 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -249,6 +249,10 @@ (:when (modulep! :ui treemacs) :desc "Project sidebar" "p" #'+treemacs/toggle :desc "Find file in project rsidebar" "P" #'treemacs-find-file) + (:when (modulep! :emacs dired +dirvish) + :desc "Open directory in dirvish" "/" #'dirvish + :desc "Project sidebar" "p" #'dirvish-side + :desc "Find file in project sidebar" "P" #'+dired/dirvish-side-and-follow) (:when (modulep! :term shell) :desc "Toggle shell popup" "t" #'+shell/toggle :desc "Open shell here" "T" #'+shell/here) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index eaa92cc14..d6633ef38 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -697,6 +697,10 @@ (:when (modulep! :ui treemacs) :desc "Project sidebar" "p" #'+treemacs/toggle :desc "Find file in project sidebar" "P" #'treemacs-find-file) + (:when (modulep! :emacs dired +dirvish) + :desc "Open directory in dirvish" "/" #'dirvish + :desc "Project sidebar" "p" #'dirvish-side + :desc "Find file in project sidebar" "P" #'+dired/dirvish-side-and-follow) (:when (modulep! :term shell) :desc "Toggle shell popup" "t" #'+shell/toggle :desc "Open shell here" "T" #'+shell/here) diff --git a/modules/emacs/dired/autoload.el b/modules/emacs/dired/autoload.el index e44d3dda0..c2009ecbf 100644 --- a/modules/emacs/dired/autoload.el +++ b/modules/emacs/dired/autoload.el @@ -13,3 +13,37 @@ (and (not (file-remote-p default-directory)) (locate-dominating-file "." ".git") (dired-git-info-mode 1))) + +;;;###autoload +(defun +dired/dirvish-side-or-follow (&optional arg) + "Open `dirvish-side' then find the currently focused file. + +If dirvish is already open, remotely jump to the file in Dirvish. +If given the prefix ARG, then prompt for a directory (replaces existing Dirvish +sidebars)." + (interactive "P") + (save-selected-window + (let ((win (dirvish-side--session-visible-p))) + (when (and win arg) + (with-selected-window win + (dirvish-quit)) + (setq win nil)) + (unless win + (call-interactively #'dirvish-side)) + (when-let* (((not dirvish--this)) + (dir (or (dirvish--get-project-root) default-directory)) + (win (dirvish-side--session-visible-p)) + (dv (with-selected-window win (dirvish-curr))) + ((not (active-minibuffer-window))) + (file buffer-file-name)) + (with-selected-window win + (when dir + (setq dirvish--this dv) + (let (buffer-list-update-hook) (dirvish-find-entry-a dir)) + (if dirvish-side-auto-expand (dirvish-subtree-expand-to file) + (dired-goto-file file)) + (dirvish-prop :cus-header 'dirvish-side-header) + (dirvish--setup-mode-line (car (dv-layout dv))) + (dirvish-update-body-h)) + (setq dirvish--this nil))))) + (select-window (dirvish-side--session-visible-p))) diff --git a/modules/emacs/vc/config.el b/modules/emacs/vc/config.el index 5006e19e9..c2cbfd2bf 100644 --- a/modules/emacs/vc/config.el +++ b/modules/emacs/vc/config.el @@ -142,27 +142,6 @@ info in the `header-line-format' is a more visible indicator." :n "gtc" #'git-timemachine-show-commit)) -(use-package! git-commit - :hook (doom-first-file . global-git-commit-mode) - :config - (set-yas-minor-mode! 'git-commit-mode) - - ;; Enforce git commit conventions. - ;; See https://chris.beams.io/posts/git-commit/ - (setq git-commit-summary-max-length 50 - git-commit-style-convention-checks '(overlong-summary-line non-empty-second-line)) - (setq-hook! 'git-commit-mode-hook fill-column 72) - - (add-hook! 'git-commit-setup-hook - (defun +vc-start-in-insert-state-maybe-h () - "Start git-commit-mode in insert state if in a blank commit message, -otherwise in default state." - (when (and (bound-and-true-p evil-mode) - (not (evil-emacs-state-p)) - (bobp) (eolp)) - (evil-insert-state))))) - - (after! browse-at-remote ;; It's more sensible that the user have more options. If they want line ;; numbers, users can request them by making a selection first. Otherwise diff --git a/modules/emacs/vc/packages.el b/modules/emacs/vc/packages.el index 18adebb42..2c925ae91 100644 --- a/modules/emacs/vc/packages.el +++ b/modules/emacs/vc/packages.el @@ -6,7 +6,6 @@ (package! smerge-mode :built-in t) (package! browse-at-remote :pin "76aa27dfd469fcae75ed7031bb73830831aaccbf") -(package! git-commit :pin "0aa26864e3fc4e6949711a4821caf6819e7ab171") (package! git-timemachine ;; The original lives on codeberg.org; which has uptime issues. :recipe (:host github :repo "emacsmirror/git-timemachine") diff --git a/modules/lang/cc/README.org b/modules/lang/cc/README.org index 390620545..5f152353b 100644 --- a/modules/lang/cc/README.org +++ b/modules/lang/cc/README.org @@ -6,10 +6,11 @@ * Description :unfold: This module adds support for the C-family of languages: C, C++, and Objective-C. -- Code completion (~company-irony~) -- eldoc support (~irony-eldoc~) -- Syntax-checking (~flycheck-irony~) -- Code navigation (~rtags~) +Through LSP, this module offers: +- Code completion +- eldoc support +- Syntax-checking +- Code navigation - File Templates ([[../../editor/file-templates/templates/c-mode][c-mode]], [[../../editor/file-templates/templates/c++-mode][c++-mode]]) - Snippets ([[https://github.com/hlissner/doom-snippets/tree/master/cc-mode][cc-mode]], [[https://github.com/hlissner/doom-snippets/tree/master/c-mode][c-mode]], [[https://github.com/hlissner/doom-snippets/tree/master/c++-mode][c++-mode]]) - Several improvements to C++11 indentation and syntax highlighting. @@ -22,32 +23,22 @@ This module adds support for the C-family of languages: C, C++, and Objective-C. ** Module flags - +lsp :: Enable LSP support for ~c-mode~, ~c++-mode~, and ~objc-mode~. Requires [[doom-module::tools - lsp]] and a langserver (supports ccls, clangd, and cquery). Replaces irony & - rtags. + lsp]] and a langserver (supports ccls, clangd, and cquery). - +tree-sitter :: Leverages tree-sitter for better syntax highlighting and structural text editing. Requires [[doom-module::tools tree-sitter]]. ** Packages - [[doom-package:cmake-mode]] -- [[doom-package:company-glsl]] - [[doom-package:cuda-mode]] - [[doom-package:demangle-mode]] - [[doom-package:disaster]] - [[doom-package:glsl-mode]] + - [[doom-package:company-glsl]] - [[doom-package:modern-cpp-font-lock]] unless [[doom-module:+tree-sitter]] - [[doom-package:opencl-mode]] - if [[doom-module:+lsp]] - [[doom-package:ccls]] if [[doom-module::tools lsp -eglot]] -- else - - [[doom-package:company-irony]] - - [[doom-package:company-irony-c-headers]] - - [[doom-package:flycheck-irony]] - - [[doom-package:helm-rtags]] if [[doom-module::completion helm]] - - [[doom-package:irony]] - - [[doom-package:irony-eldoc]] - - [[doom-package:ivy-rtags]] if [[doom-module::completion ivy]] - - [[doom-package:rtags]] ** Hacks /No hacks documented for this module./ @@ -62,7 +53,6 @@ This module adds support for the C-family of languages: C, C++, and Objective-C. This module's requirements change depending on how you use it. - If [[doom-module:+lsp]] is enabled, you need one of *clangd v9+* or *ccls*. -- If [[doom-module:+lsp]] is *not* enabled, you need *irony-server* and *rtags*. - Other features in this module depend on: - (optional) glslangValidator, for GLSL completion in ~glsl-mode~ - (optional) cmake, for code completion in ~cmake-mode~ @@ -87,51 +77,6 @@ recommended. alternative install methods listed [[https://github.com/MaskRay/ccls/wiki/Install][in the project's wiki]]. + cmake-language-server :: available through ~pip~ on most distributions -** irony-server -Irony powers the code completion, eldoc and syntax checking systems. - -After installing its dependencies (Clang and CMake), run ~M-x -irony-install-server~ in Emacs. - -*** macOS -Due to linking issues, macOS users must compile irony-server manually: -#+begin_src sh -brew install cmake -brew install llvm -git clone https://github.com/Sarcasm/irony-mode irony-mode -#+end_src - -#+begin_src sh -mkdir irony-mode/server/build -pushd irony-mode/server/build - -DEST="$HOME/.emacs.d/.local/etc/irony-server/" -cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/llvm \ - -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \ - -DCMAKE_INSTALL_PREFIX="$DEST" ../ -cmake --build . --use-stderr --config Release --target install - -install_name_tool -change @rpath/libclang.dylib \ - /usr/local/opt/llvm/lib/libclang.dylib \ - "$DEST/bin/irony-server" - -# Cleanup -popd -rm -rf irony-mode -#+end_src - -** rtags -Code navigation requires an [[https://github.com/Andersbakken/rtags][rtags]] server (~rdm~) installed. This should be -available through your OS's package manager. - -This module will auto-start ~rdm~ when you open C/C++ buffers (so long as one -isn't already running). If you prefer to run it yourself: - -#+begin_src sh -rdm & -rc -J $PROJECT_ROOT # loads PROJECT_ROOT's compile_commands.json -#+end_src - ** =:editor format= The formatter used is [[doom-executable:clang-format]] which should be installed alongside =clang=. @@ -163,28 +108,20 @@ additional function to get inheritance type hierarchy is added: #+end_quote ** Project compile settings -By default, a set of default compile settings are defined in -~+cc-default-compiler-options~ for C, C++ and Objective C. Irony, rtags and -flycheck will fall back to these. *This variable does nothing for LSP users.* - -For a more universal solution: both LSP servers and irony will recognize a -[[https://sarcasm.github.io/notes/dev/compilation-database.html#ninja][compilation database]] (a ~compile_commands.json~ file). There are [[https://sarcasm.github.io/notes/dev/compilation-database.html][many ways to -generate one]]. Here is an example using [[http://www.cmake.org/][CMake]] and [[https://github.com/rizsotto/Bear][bear]]: - +LSP servers and Flycheck will recognize a [[https://sarcasm.github.io/notes/dev/compilation-database.html#ninja][compilation database]] (a +~compile_commands.json~ file). There are [[https://sarcasm.github.io/notes/dev/compilation-database.html][many ways to generate one]]. Here is an +example using [[http://www.cmake.org/][CMake]] and [[https://github.com/rizsotto/Bear][bear]]: #+begin_src sh # For CMake projects -cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . +$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . #+end_src #+begin_src sh # For non-CMake projects -make clean -bear make +$ make clean +$ bear make #+end_src -Use ~M-x +cc/reload-compile-db~ to reload your compile db in an already-open -C/C++/ObjC buffer. - *** Known issues with bear on macOS MacOS' [[https://support.apple.com/en-us/HT204899][System Integrity Protection (SIP)]] might interfere with bear if ~make~ is under ~/usr/bin/~ which results in an empty compilation database. @@ -228,6 +165,7 @@ Search for your combination of =(LSP client package, LSP server)=. You are using *** LSP-mode with clangd #+begin_src emacs-lisp +;;; add to $DOOMDIR/config.el (after! lsp-clangd (setq lsp-clients-clangd-args '("-j=3" @@ -244,6 +182,7 @@ server everywhere clangd can be used. *** LSP-mode with ccls #+begin_src emacs-lisp +;;; add to $DOOMDIR/config.el (after! ccls (setq ccls-initialization-options '(:index (:comments 2) :completion (:detailedLabel t))) (set-lsp-priority! 'ccls 2)) ; optional as ccls is the default in Doom @@ -255,7 +194,9 @@ documentation]] lists available options, use =t= for ~true~, =:json-false= for *** Eglot with clangd #+begin_src emacs-lisp -(set-eglot-client! 'cc-mode '("clangd" "-j=3" "--clang-tidy")) +;;; add to $DOOMDIR/config.el +(after! cc-mode + (set-eglot-client! 'cc-mode '("clangd" "-j=3" "--clang-tidy"))) #+end_src This will both set your clangd flags and choose clangd as the default server (if @@ -263,7 +204,9 @@ it is the last =set-eglot-client! 'cc-mode= in your config). *** Eglot with ccls #+begin_src emacs-lisp -(set-eglot-client! 'cc-mode '("ccls" "--init={\"index\": {\"threads\": 3}}")) +;;; add to $DOOMDIR/config.el +(after! cc-mode + (set-eglot-client! 'cc-mode '("ccls" "--init={\"index\": {\"threads\": 3}}"))) #+end_src This will both set your ccls flags and choose ccls as the default server (if it diff --git a/modules/lang/cc/autoload.el b/modules/lang/cc/autoload.el index 41b6ff1c4..a57d97cd9 100644 --- a/modules/lang/cc/autoload.el +++ b/modules/lang/cc/autoload.el @@ -93,40 +93,6 @@ simpler." ;; ;; Commands -;;;###autoload -(defun +cc/reload-compile-db () - "Reload the current project's JSON compilation database." - (interactive) - (unless (memq major-mode '(c-mode c++-mode objc-mode)) - (user-error "Not a C/C++/ObjC buffer")) - ;; first rtag - (when (and (featurep 'rtags) - rtags-enabled - (executable-find rtags-rc-binary-name)) - (with-temp-buffer - (message "Reloaded compile commands for rtags daemon") - (rtags-call-rc :silent t "-J" (or (doom-project-root) default-directory)))) - ;; then irony - (when (and (featurep 'irony) irony-mode) - (+cc-init-irony-compile-options-h)) - ;; Otherwise, LSP - (when (bound-and-true-p lsp-mode) - (lsp-workspace-restart)) - (when (bound-and-true-p eglot-managed-mode) - (eglot-reconnect))) - -;;;###autoload -(defun +cc/imenu () - "Invoke `rtags-imenu' if a running rdm process is available, otherwise invoke -`imenu'." - (interactive) - (call-interactively - (if (and (processp rtags-rdm-process) - (not (eq (process-status rtags-rdm-process) 'exit)) - (not (eq (process-status rtags-rdm-process) 'signal))) - #'rtags-imenu - #'imenu))) - ;; Eglot specific helper, courtesy of MaskRay ;;;###autoload (defun +cc/eglot-ccls-show-inheritance-hierarchy (&optional derived) @@ -181,52 +147,14 @@ the children of class at point." t))) (defvar +cc--project-includes-alist nil) -;;;###autoload -(defun +cc-init-irony-compile-options-h () - "Initialize compiler options for irony-mode. It searches for the nearest -compilation database and initailizes it, otherwise falling back on -`+cc-default-compiler-options' and `+cc-default-include-paths'. - -See https://github.com/Sarcasm/irony-mode#compilation-database for details on -compilation dbs." - (when (memq major-mode '(c-mode c++-mode objc-mode)) - (require 'irony-cdb) - (unless (irony-cdb-autosetup-compile-options) - (let ((project-root (doom-project-root)) - (include-paths (+cc-resolve-include-paths))) - (setf (alist-get project-root +cc--project-includes-alist) - include-paths) - (irony-cdb--update-compile-options - (append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options))) - (cl-loop for path in include-paths - collect (format "-I%s" path))) - project-root))))) - -;; ;;;###autoload -;; (defun +cc|init-ccls-compile-options () -;; "TODO" -;; (when (memq major-mode '(c-mode c++-mode objc-mode)) -;; (when-let (include-paths (+cc-resolve-include-paths)) -;; (let ((args (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options))))) -;; (setf (alist-get (or (lsp-workspace-root) -;; (lsp--suggest-project-root) -;; (doom-project-root)) -;; +cc--project-includes-alist) -;; include-paths) -;; (setq ccls-initialization-options -;; `(:clang (:extraArgs -;; [,@(cl-loop for path in include-paths -;; collect (format "-I%s" path))]))))))) - ;;;###autoload (defun +cc-init-ffap-integration-h () "Takes the local project include paths and registers them with ffap. This way, `find-file-at-point' (and `+lookup/file') will know where to find most header files." - (when-let (project-root (or (bound-and-true-p irony--working-directory) - (and (featurep 'lsp) - (or (lsp-workspace-root) - (doom-project-root))))) + (when-let (project-root (and (featurep 'lsp) + (or (lsp-workspace-root) + (doom-project-root)))) (require 'ffap) (make-local-variable 'ffap-c-path) (make-local-variable 'ffap-c++-path) diff --git a/modules/lang/cc/config.el b/modules/lang/cc/config.el index 76fd6efbe..3a6e1cd64 100644 --- a/modules/lang/cc/config.el +++ b/modules/lang/cc/config.el @@ -4,8 +4,8 @@ (list "include" "includes") "A list of default relative paths which will be searched for up from the -current file, to be passed to irony as extra header search paths. Paths can be -absolute. This is ignored if your project has a compilation database. +current file. Paths can be absolute. This is ignored if your project has a +compilation database. This is ignored by ccls.") @@ -13,21 +13,6 @@ This is ignored by ccls.") "Fallback major mode for .h files if all other heuristics fail (in `+cc-c-c++-objc-mode').") -(defvar +cc-default-compiler-options - `((c-mode . nil) - (c++-mode - . ,(list "-std=c++1z" ; use C++17 draft by default - (when (featurep :system 'macos) - ;; NOTE beware: you'll get abi-inconsistencies when passing - ;; std-objects to libraries linked with libstdc++ (e.g. if you - ;; use boost which wasn't compiled with libc++) - "-stdlib=libc++"))) - (objc-mode . nil)) - "A list of default compiler options for the C family. These are ignored if a -compilation database is present in the project. - -This is ignored by ccls.") - ;; ;;; Packages @@ -37,9 +22,8 @@ This is ignored by ccls.") ;; Use `c-mode'/`c++-mode'/`objc-mode' depending on heuristics :mode ("\\.h\\'" . +cc-c-c++-objc-mode) ;; Ensure find-file-at-point recognize system libraries in C modes. It must be - ;; set up before the likes of irony/lsp are initialized. Also, we use - ;; local-vars hooks to ensure these only run in their respective major modes, - ;; and not their derived modes. + ;; set up before lsp is initialized. Also, we use local-vars hooks to ensure + ;; these only run in their respective major modes, and not derived modes. :hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc-init-ffap-integration-h) ;;; Improve fontification in C/C++ (also see `modern-cpp-font-lock') :hook (c-mode-common . rainbow-delimiters-mode) @@ -139,38 +123,6 @@ This is ignored by ccls.") :hook (c++-mode . modern-c++-font-lock-mode)) -(use-package! irony - :unless (modulep! +lsp) - :commands irony-install-server - ;; Initialize compilation database, if present. Otherwise, fall back on - ;; `+cc-default-compiler-options'. - :hook (irony-mode . +cc-init-irony-compile-options-h) - ;; Only initialize `irony-mode' if the server is available. Otherwise fail - ;; quietly and gracefully. - :hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc-init-irony-mode-maybe-h) - :preface (setq irony-server-install-prefix (concat doom-data-dir "irony-server/")) - :config - (defun +cc-init-irony-mode-maybe-h () - (if (file-directory-p irony-server-install-prefix) - (irony-mode +1) - (message "Irony server isn't installed"))) - - (setq irony-cdb-search-directory-list '("." "build" "build-conda")) - - (use-package! irony-eldoc - :hook (irony-mode . irony-eldoc)) - - (use-package! flycheck-irony - :when (and (modulep! :checkers syntax) - (not (modulep! :checkers syntax +flymake))) - :config (flycheck-irony-setup)) - - (use-package! company-irony - :when (modulep! :completion company) - :init (set-company-backend! 'irony-mode '(:separate company-irony-c-headers company-irony)) - :config (require 'company-irony-c-headers))) - - ;; ;; Major modes @@ -198,57 +150,7 @@ This is ignored by ccls.") ;; -;; Rtags Support - -(use-package! rtags - :unless (modulep! +lsp) - ;; Only initialize rtags-mode if rtags and rdm are available. - :hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc-init-rtags-maybe-h) - :preface (setq rtags-install-path (concat doom-data-dir "rtags/")) - :config - (defun +cc-init-rtags-maybe-h () - "Start an rtags server in c-mode and c++-mode buffers. -If rtags or rdm aren't available, fail silently instead of throwing a breaking error." - (and (require 'rtags nil t) - (rtags-executable-find rtags-rdm-binary-name) - (rtags-start-process-unless-running))) - - (setq rtags-autostart-diagnostics t - rtags-use-bookmarks nil - rtags-completions-enabled nil - rtags-display-result-backend - (cond ((modulep! :completion ivy) 'ivy) - ((modulep! :completion helm) 'helm) - ('default)) - ;; These executables are named rtags-* on debian - rtags-rc-binary-name - (or (cl-find-if #'executable-find (list rtags-rc-binary-name "rtags-rc")) - rtags-rc-binary-name) - rtags-rdm-binary-name - (or (cl-find-if #'executable-find (list rtags-rdm-binary-name "rtags-rdm")) - rtags-rdm-binary-name) - ;; If not using ivy or helm to view results, use a pop-up window rather - ;; than displaying it in the current window... - rtags-results-buffer-other-window t - ;; ...and don't auto-jump to first match before making a selection. - rtags-jump-to-first-match nil) - - (set-lookup-handlers! '(c-mode c++-mode) - :definition #'rtags-find-symbol-at-point - :references #'rtags-find-references-at-point) - - ;; Use rtags-imenu instead of imenu/counsel-imenu - (define-key! (c-mode-map c++-mode-map) [remap imenu] #'+cc/imenu) - - ;; Ensure rtags cleans up after itself properly when exiting Emacs, rather - ;; than display a jarring confirmation prompt for killing it. - (add-hook! 'kill-emacs-hook (ignore-errors (rtags-cancel-process))) - - (add-hook 'rtags-jump-hook #'better-jumper-set-jump)) - - -;; -;; LSP +;;; LSP (when (modulep! +lsp) (add-hook! '(c-mode-local-vars-hook @@ -258,25 +160,6 @@ If rtags or rdm aren't available, fail silently instead of throwing a breaking e cuda-mode-local-vars-hook) :append #'lsp!) - (map! :after ccls - :map (c-mode-map c++-mode-map) - :n "C-h" (cmd! (ccls-navigate "U")) - :n "C-j" (cmd! (ccls-navigate "R")) - :n "C-k" (cmd! (ccls-navigate "L")) - :n "C-l" (cmd! (ccls-navigate "D")) - (:localleader - :desc "Preprocess file" "lp" #'ccls-preprocess-file - :desc "Reload cache & CCLS" "lf" #'ccls-reload) - (:after lsp-ui-peek - (:localleader - :desc "Callers list" "c" #'+cc/ccls-show-caller - :desc "Callees list" "C" #'+cc/ccls-show-callee - :desc "References (address)" "a" #'+cc/ccls-show-references-address - :desc "References (not call)" "f" #'+cc/ccls-show-references-not-call - :desc "References (Macro)" "m" #'+cc/ccls-show-references-macro - :desc "References (Read)" "r" #'+cc/ccls-show-references-read - :desc "References (Write)" "w" #'+cc/ccls-show-references-write))) - (when (modulep! :tools lsp +eglot) (set-eglot-client! 'cuda-mode '("clangd")) @@ -308,11 +191,9 @@ If rtags or rdm aren't available, fail silently instead of throwing a breaking e (add-to-list 'projectile-globally-ignored-directories "^.ccls-cache$") (add-to-list 'projectile-project-root-files-bottom-up ".ccls-root") (add-to-list 'projectile-project-root-files-top-down-recurring "compile_commands.json")) - ;; Avoid using `:after' because it ties the :config below to when `lsp-mode' - ;; loads, rather than `ccls' loads. - (after! lsp-mode (require 'ccls)) :config (set-evil-initial-state! 'ccls-tree-mode 'emacs) + (set-lsp-priority! 'ccls -2) ; Prioritize clangd over ccls ;; Disable `ccls-sem-highlight-method' if `lsp-enable-semantic-highlighting' ;; is nil. Otherwise, it appears ccls bypasses it. (setq-hook! 'lsp-configure-hook @@ -329,4 +210,22 @@ If rtags or rdm aren't available, fail silently instead of throwing a breaking e `(:clang ,(list :extraArgs ["-isystem/Library/Developer/CommandLineTools/usr/include/c++/v1" "-isystem/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" "-isystem/usr/local/include"] - :resourceDir (cdr (doom-call-process "clang" "-print-resource-dir")))))))) + :resourceDir (cdr (doom-call-process "clang" "-print-resource-dir"))))))) + (map! :after cc-mode + :map (c-mode-map c++-mode-map) + :n "C-h" (cmd! (ccls-navigate "U")) + :n "C-j" (cmd! (ccls-navigate "R")) + :n "C-k" (cmd! (ccls-navigate "L")) + :n "C-l" (cmd! (ccls-navigate "D")) + (:localleader + :desc "Preprocess file" "lp" #'ccls-preprocess-file + :desc "Reload cache & CCLS" "lf" #'ccls-reload) + (:when (modulep! :tools lsp +peek) + (:localleader + :desc "Callers list" "c" #'+cc/ccls-show-caller + :desc "Callees list" "C" #'+cc/ccls-show-callee + :desc "References (address)" "a" #'+cc/ccls-show-references-address + :desc "References (not call)" "f" #'+cc/ccls-show-references-not-call + :desc "References (Macro)" "m" #'+cc/ccls-show-references-macro + :desc "References (Read)" "r" #'+cc/ccls-show-references-read + :desc "References (Write)" "w" #'+cc/ccls-show-references-write)))) diff --git a/modules/lang/cc/doctor.el b/modules/lang/cc/doctor.el index 21c4bba08..f83f6c092 100644 --- a/modules/lang/cc/doctor.el +++ b/modules/lang/cc/doctor.el @@ -9,19 +9,6 @@ (modulep! :tools tree-sitter)) "This module requires (:tools tree-sitter)") -(when (require 'rtags nil t) - ;; rtags - (when-let (bins (cl-remove-if #'rtags-executable-find - (list rtags-rdm-binary-name - rtags-rc-binary-name))) - (warn! "Couldn't find the rtag client and/or server programs %s. Disabling rtags support" - bins))) - -;; irony server -(when (require 'irony nil t) - (unless (file-directory-p irony-server-install-prefix) - (warn! "Irony server isn't installed. Run M-x irony-install-server"))) - (when (modulep! :completion company) ;; glslangValidator (unless (executable-find "glslangValidator") diff --git a/modules/lang/cc/packages.el b/modules/lang/cc/packages.el index 44721a76e..8a34ca29f 100644 --- a/modules/lang/cc/packages.el +++ b/modules/lang/cc/packages.el @@ -7,9 +7,10 @@ (package! cuda-mode :pin "c3dae31b3d1abedf4d0b98840127e2cac73d6ad8") (package! demangle-mode :pin "04f545adab066708d6151f13da65aaf519f8ac4e") (package! disaster :pin "b20f8e1ef96167a7beed5eb4fc6ef72488bd3662") +(package! opencl-mode :pin "204d5d9e0f5cb2cbe810f2933230eb08fe2c7695") + (unless (modulep! +tree-sitter) (package! modern-cpp-font-lock :pin "43c6b68ff58fccdf9deef11674a172e4eaa8455c")) -(package! opencl-mode :pin "204d5d9e0f5cb2cbe810f2933230eb08fe2c7695") (when (package! glsl-mode :pin "9b2e5f28e489a1f73c4aed734105618ac0dc0c43") (when (modulep! :completion company) @@ -17,20 +18,6 @@ :recipe (:host github :repo "Kaali/company-glsl") :pin "404cd0694ab34971f9c01eb22126cd2e7d3f9dc4"))) -(if (modulep! +lsp) - (unless (modulep! :tools lsp +eglot) - ;; ccls package is necessary only for lsp-mode. - (package! ccls :pin "41399b0eba03f9b80769ced71501ba702db4cd62")) - (when (package! irony :pin "40e0ce19eb850bdf1f77225f11713cc816250d95") - (package! irony-eldoc :pin "73e79a89fad982a2ba072f2fcc1b4e41f0aa2978") - (when (and (modulep! :checkers syntax) - (not (modulep! :checkers syntax +flymake))) - (package! flycheck-irony :pin "42dbecd4a865cabeb301193bb4d660e26ae3befe")) - (when (modulep! :completion company) - (package! company-irony :pin "b44711dfce445610c1ffaec4951c6ff3882b216a") - (package! company-irony-c-headers :pin "72c386aeb079fb261d9ec02e39211272f76bbd97"))) - (when (package! rtags :pin "f472b5d0a05270d5c93945b6a71771ab69068147") - (when (modulep! :completion ivy) - (package! ivy-rtags)) - (when (modulep! :completion helm) - (package! helm-rtags)))) +(when (and (modulep! +lsp) + (not (modulep! :tools lsp +eglot))) + (package! ccls :pin "41399b0eba03f9b80769ced71501ba702db4cd62")) diff --git a/modules/lang/emacs-lisp/autoload.el b/modules/lang/emacs-lisp/autoload.el index 24e4388f8..e003de2e2 100644 --- a/modules/lang/emacs-lisp/autoload.el +++ b/modules/lang/emacs-lisp/autoload.el @@ -669,7 +669,6 @@ Adapted from URL `https://www.reddit.com/r/emacs/comments/d7x7x8/finally_fixing_ ;; performance sensitive, so we compile this file on-demand, at least, until ;; Doom adds a formal compile step to 'doom sync'. (doom-compile-functions #'+emacs-lisp-highlight-vars-and-faces - #'+emacs-lisp-truncate-pin #'+emacs-lisp--calculate-lisp-indent-a) ;;; autoload.el ends here diff --git a/modules/lang/haskell/config.el b/modules/lang/haskell/config.el index 20752918b..9c78fbced 100644 --- a/modules/lang/haskell/config.el +++ b/modules/lang/haskell/config.el @@ -53,7 +53,6 @@ :init (add-hook 'haskell-mode-local-vars-hook #'lsp! 'append) (add-hook 'haskell-literate-mode-local-vars-hook #'lsp! 'append) - (after! lsp-mode (require 'lsp-haskell)) :config ;; Does some strange indentation if it pastes in the snippet (setq-hook! 'haskell-mode-hook yas-indent-line 'fixed)) diff --git a/modules/lang/java/+lsp.el b/modules/lang/java/+lsp.el index f681f9515..3fc072b74 100644 --- a/modules/lang/java/+lsp.el +++ b/modules/lang/java/+lsp.el @@ -2,7 +2,7 @@ ;;;###if (and (modulep! +lsp) (not (modulep! :tools lsp +eglot))) (use-package! lsp-java - :after lsp-mode + :defer t :preface (setq lsp-java-workspace-dir (concat doom-data-dir "java-workspace")) (add-hook 'java-mode-local-vars-hook #'lsp! 'append) diff --git a/modules/lang/julia/config.el b/modules/lang/julia/config.el index 08dc89471..462b42b10 100644 --- a/modules/lang/julia/config.el +++ b/modules/lang/julia/config.el @@ -76,8 +76,10 @@ (use-package! lsp-julia :when (modulep! +lsp) :unless (modulep! :tools lsp +eglot) - :after lsp-mode - :preface (setq lsp-julia-default-environment nil) + :defer t + :preface + (after! lsp-mode (add-to-list 'lsp-client-packages 'lsp-julia)) + (setq lsp-julia-default-environment nil) :init ;; If no environment is set, then auto-detect one in ~/.julia/environments/, ;; falling back to `lsp-julia-default-environment's default. diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index e76d8c74b..c2e1f9324 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -46,10 +46,8 @@ ;; TODO Adjust when this is added to GNU ELPA (when (modulep! +contacts) (package! org-contacts - :pin "f0a430442b2ae60035dcd74fc6a76299875694f3" - :recipe (:host nil - :type git - :repo "https://repo.or.cz/org-contacts.git"))) + :recipe (:host github :repo "doomelpa/org-contacts") + :pin "f0a430442b2ae60035dcd74fc6a76299875694f3")) (when (and (featurep :system 'macos) (modulep! :os macos)) @@ -135,9 +133,7 @@ (package! ob-nim :pin "6fd060a3ecd38be37e4ec2261cd65760a3c35a91")) (when (modulep! :lang php) (package! ob-php - :recipe (:type git - :host nil - :repo "https://repo.or.cz/ob-php.git") + :recipe (:host github :repo "doomelpa/ob-php") :pin "6ebf7799e9ded1d5114094f46785960a50000614")) (when (modulep! :lang racket) (package! ob-racket diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index 7d3f57281..a68672366 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -288,7 +288,7 @@ ;; explicitly. Afterwards, run M-x `conda-env-activate' to switch between ;; environments (or (cl-loop for dir in (cons conda-anaconda-home conda-home-candidates) - if (file-directory-p dir) + if (and dir (file-directory-p dir)) return (setq conda-anaconda-home (expand-file-name dir) conda-env-home-directory (expand-file-name dir))) (message "Cannot find Anaconda installation")) @@ -353,7 +353,7 @@ :when (modulep! +lsp) :when (modulep! +pyright) :when (not (modulep! :tools lsp +eglot)) - :after lsp-mode + :defer t :init (when-let ((exe (executable-find "basedpyright"))) (setq lsp-pyright-langserver-command exe))) diff --git a/modules/lang/swift/config.el b/modules/lang/swift/config.el index ab66f2c48..fd9024458 100644 --- a/modules/lang/swift/config.el +++ b/modules/lang/swift/config.el @@ -26,8 +26,9 @@ (use-package! lsp-sourcekit - :when (and (modulep! +lsp) (not (modulep! :tools lsp +eglot))) - :after swift-mode + :when (modulep! +lsp) + :when (not (modulep! :tools lsp +eglot)) + :defer t :init (add-hook 'swift-mode-local-vars-hook #'lsp! 'append) :config (set-formatter! 'swiftformat '("swiftformat" "--output" "stdout")) diff --git a/modules/tools/magit/config.el b/modules/tools/magit/config.el index 9ca268930..8ed0f1d03 100644 --- a/modules/tools/magit/config.el +++ b/modules/tools/magit/config.el @@ -255,3 +255,24 @@ Only has an effect in GUI Emacs.") (undefine-key! magit-section-mode-map "M-1" "M-2" "M-3" "M-4" "1" "2" "3" "4" "0") ;; `evil-collection-magit-section' binds these redundant keys. (map! :map magit-section-mode-map :n "1" nil :n "2" nil :n "3" nil :n "4" nil))) + + +(use-package! git-commit + :hook (doom-first-file . global-git-commit-mode) + :config + (set-yas-minor-mode! 'git-commit-mode) + + ;; Enforce git commit conventions. + ;; See https://chris.beams.io/posts/git-commit/ + (setq git-commit-summary-max-length 50 + git-commit-style-convention-checks '(overlong-summary-line non-empty-second-line)) + (setq-hook! 'git-commit-mode-hook fill-column 72) + + (add-hook! 'git-commit-setup-hook + (defun +vc-start-in-insert-state-maybe-h () + "Start git-commit-mode in insert state if in a blank commit message, +otherwise in default state." + (when (and (bound-and-true-p evil-local-mode) + (not (evil-emacs-state-p)) + (bobp) (eolp)) + (evil-insert-state))))) diff --git a/modules/ui/indent-guides/config.el b/modules/ui/indent-guides/config.el index 9a11dac5a..24c3c3733 100644 --- a/modules/ui/indent-guides/config.el +++ b/modules/ui/indent-guides/config.el @@ -13,6 +13,7 @@ be enabled. If any function returns non-nil, the mode will not be activated." ;;; Packages (use-package! indent-bars + :unless noninteractive :hook ((prog-mode text-mode conf-mode) . +indent-guides-init-maybe-h) :init (defun +indent-guides-init-maybe-h () @@ -26,8 +27,8 @@ be enabled. If any function returns non-nil, the mode will not be activated." ;; testing to see if it's specific to ns or emacs-mac builds, or is ;; just a general MacOS issue. (featurep :system 'macos) - ;; FIX: A bitmap init bug in PGTK builds of Emacs before v30 that could - ;; cause crashes (see jdtsmith/indent-bars#3). + ;; FIX: A bitmap init bug in emacs-pgtk (before v30) could cause + ;; crashes (see jdtsmith/indent-bars#3). (and (featurep 'pgtk) (< emacs-major-version 30))) @@ -56,24 +57,20 @@ be enabled. If any function returns non-nil, the mode will not be activated." (defun +indent-guides-in-ein-notebook-p () (and (bound-and-true-p ein:notebook-mode) (bound-and-true-p ein:output-area-inlined-images))) - ;; Don't display indent guides in childframe popups (not helpful in - ;; completion or eldoc popups). + ;; Don't display indent guides in childframe popups (which are almost always + ;; used for completion or eldoc popups). ;; REVIEW: Swap with `frame-parent' when 27 support is dropped (defun +indent-guides-in-childframe-p () (frame-parameter nil 'parent-frame))) - ;; HACK: `indent-bars-mode' interactions with some packages poorly. This - ;; section is dedicated to package interop fixes. + ;; HACK: `indent-bars-mode' interactions with some packages poorly, often + ;; flooding whole sections of the buffer with indent guides. This section is + ;; dedicated to fixing interop with those packages. (when (modulep! :tools magit) (after! magit-blame (add-to-list 'magit-blame-disable-modes 'indent-bars-mode))) (when (modulep! :tools lsp) - ;; HACK: lsp-ui-peek uses overlays, and indent-bars doesn't know how to deal - ;; with all the whitespace it uses to format its popups, spamming it with - ;; indent guides. Making the two work together is a project for another - ;; day, so disable `indent-bars-mode' while its active instead. Doesn't - ;; affect character bars though. ;; REVIEW: Report this upstream to `indent-bars'? (defadvice! +indent-guides--remove-after-lsp-ui-peek-a (&rest _) :after #'lsp-ui-peek--peek-new @@ -89,4 +86,21 @@ be enabled. If any function returns non-nil, the mode will not be activated." (defadvice! +indent-guides--restore-after-lsp-ui-peek-a (&rest _) :after #'lsp-ui-peek--peek-hide (unless indent-bars-prefer-character - (indent-bars-setup))))) + (indent-bars-setup)))) + + ;; HACK: Both indent-bars and tree-sitter-hl-mode use the jit-font-lock + ;; mechanism, and so they don't play well together. For those particular + ;; cases, we'll use `highlight-indent-guides', at least until the + ;; tree-sitter module adopts treesit. + (defvar-local +indent-guides-p nil) + (add-hook! 'tree-sitter-mode-hook :append + (defun +indent-guides--toggle-on-tree-sitter-h () + (if tree-sitter-mode + (when (bound-and-true-p indent-bars-mode) + (with-memoization (get 'indent-bars-mode 'disabled-in-tree-sitter) + (doom-log "Disabled `indent-bars-mode' because it's not supported in `tree-sitter-mode'") + t) + (indent-bars-mode -1) + (setq +indent-guides-p t)) + (when +indent-guides-p + (indent-bars-mode +1)))))) diff --git a/modules/ui/nav-flash/README.org b/modules/ui/nav-flash/README.org index 155f1fada..188b5bf6f 100644 --- a/modules/ui/nav-flash/README.org +++ b/modules/ui/nav-flash/README.org @@ -40,7 +40,6 @@ is added to the jump-list (managed by [[doom-package:better-jumper]]). [[fn:recenter]] is called after many hooks and commands, such as: - [[var:better-jumper-post-jump-hook]] -- [[var:rtags-after-find-file-hook]] - [[var:org-follow-link-hook]] - [[var:imenu-after-jump-hook]] - [[var:counsel-grep-post-action-hook]]