Files
home/.emacs
Alexandre Tuleu 96416217ba [emacs] Clean lsp-inline-comment-mode integration
Cleanly integrate it with company and other.
2025-10-30 22:24:56 +01:00

1037 lines
30 KiB
Plaintext

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
;;lsp performances
(setq gc-cons-threshold (* 100 1024 1024));; 100MB
(setq read-process-output-max (* 3 1024 1024));; 3MB
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(c-basic-offset 4)
'(compilation-scroll-output 'first-error)
'(custom-safe-themes
'("162201cf5b5899938cfaec99c8cb35a2f1bf0775fc9ccbf5e63130a1ea217213"
"e3daa8f18440301f3e54f2093fe15f4fe951986a8628e98dcd781efbec7a46f2"
"6622bb651e72d8ebd66454bd86db6c3990324243ff4325c1b6df252aba63b13e"
"2f8eadc12bf60b581674a41ddc319a40ed373dd4a7c577933acaff15d2bf7cc6"
"f458b92de1f6cf0bdda6bce23433877e94816c3364b821eb4ea9852112f5d7dc"
"016f665c0dd5f76f8404124482a0b13a573d17e92ff4eb36a66b409f4d1da410"
"13096a9a6e75c7330c1bc500f30a8f4407bd618431c94aeab55c9855731a95e1"
"8b148cf8154d34917dfc794b5d0fe65f21e9155977a36a5985f89c09a9669aa0"
"bf948e3f55a8cd1f420373410911d0a50be5a04a8886cabe8d8e471ad8fdba8e"
"680f62b751481cc5b5b44aeab824e5683cf13792c006aeba1c25ce2d89826426"
"631c52620e2953e744f2b56d102eae503017047fb43d65ce028e88ef5846ea3b"
default))
'(display-time-24hr-format t)
'(display-time-default-load-average nil)
'(doom-modeline-github t)
'(doom-modeline-indent-info t)
'(doom-modeline-minor-modes t)
'(doom-modeline-total-line-number t)
'(fill-column 80)
'(global-auto-revert-mode t)
'(global-display-line-numbers-mode t)
'(global-subword-mode t)
'(gofmt-command "goimports")
'(inhibit-startup-screen t)
'(lisp-body-indent 4)
'(lisp-indent-offset 4)
'(lisp-lambda-list-keyword-alignment t)
'(lisp-lambda-list-keyword-parameter-alignment t)
'(lisp-lambda-list-keyword-parameter-indentation 4)
'(lisp-loop-forms-indentation 4)
'(lisp-loop-keyword-indentation 4)
'(lisp-simple-loop-indentation 4)
'(lisp-tag-body-indentation 4)
'(lisp-tag-indentation 4)
'(lsp-copilot-enabled t)
'(lsp-inline-completion-idle-delay 99999999)
'(org-agenda-files '("~/org/1.TODO.org"))
'(package-enable-at-startup nil)
'(package-selected-packages nil)
'(safe-local-variable-values
'((vc-follow-symlinks . t) (TeX-master . t) (TeX-parse-self . t)))
'(system-packages-noconfirm t)
'(tab-width 4)
'(warning-suppress-log-types '((comp)))
'(whitespace-style
'(face trailing tabs lines-tail newline space-before-tab::tab
space-before-tab::space space-before-tab tab-mark)))
(if (display-graphic-p)
(if (fboundp 'tool-bar-mode)
(tool-bar-mode -1))
(if (fboundp 'toggle-scroll-bar)
(toggle-scroll-bar -1))
(menu-bar-mode -1)
(if (fboundp 'tool-bar-mode)
(tool-bar-mode -1))
)
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(add-hook 'before-save-hook 'delete-trailing-whitespace)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; package.el and use-package bootstrap
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(unless (package-installed-p 'quelpa)
(with-temp-buffer
(url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el")
(eval-buffer)
(quelpa-self-upgrade)))
(setq quelpa-checkout-melpa-p nil)
(setq quelpa-use-package-inhibit-loading-quelpa t)
(quelpa
'(quelpa-use-package
:fetcher github
:repo "quelpa/quelpa-use-package"))
(require 'quelpa-use-package)
(require 'use-package-ensure)
(setq use-package-always-ensure t)
(use-package system-packages)
;(use-package use-package-ensure-system-package)
;; required because vterm wants this before loading.
(use-package emacs
:demand t
:ensure-system-package (
(cmake . cmake)
("/usr/include/vterm.h" . libvterm-dev)
)
:init
;; Add prompt indicator to `completing-read-multiple'.
;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
(defun crm-indicator (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
;; Emacs 28: Hide commands in M-x which do not work in the current mode.
;; Vertico commands are hidden in normal buffers.
(setq read-extended-command-predicate
#'command-completion-default-include-p)
;; Enable recursive minibuffers
(setq enable-recursive-minibuffers t)
(defconst atu/numprocs
(string-to-number (shell-command-to-string "nproc"))
"The number of processor on the system")
)
;; Enable vertico
(use-package vertico
:init
(vertico-mode)
;; Different scroll margin
;; (setq vertico-scroll-margin 0)
;; Show more candidates
(setq vertico-count 10)
;; Grow and shrink the Vertico minibuffer
(setq vertico-resize t)
;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
(setq vertico-cycle t)
:config
(vertico-reverse-mode)
(keymap-set vertico-map "TAB" #'minibuffer-complete)
)
;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
:init
(savehist-mode))
;; Optionally use the `orderless' completion style.
(use-package orderless
:init
;; Configure a custom style dispatcher (see the Consult wiki)
;; (setq orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch)
;; orderless-component-separator #'orderless-escapable-split-on-space)
(setq completion-styles '(partial-completion orderless basic)
;;completion-category-defaults nil
completion-category-overrides '((file (styles basic partial-completion ))))
)
;; Example configuration for Consult
(use-package consult
;; Replace bindings. Lazily loaded due by `use-package'.
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c M" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings in `search-map'
("M-s d" . consult-find) ;; Alternative: consult-fd
("M-s D" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; "C-+"
(autoload 'projectile-project-root "projectile")
(setq consult-project-function (lambda (_) (projectile-project-root)))
)
(use-package marginalia
:config
(marginalia-mode))
(use-package embark
:bind
("C-x m" . embark-act) ;; pick some comfortable binding
("M-." . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings) ;; alternative for `describe-bindings'
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
;; Show the Embark target at point via Eldoc. You may adjust the Eldoc
;; strategy, if you want to see the documentation from multiple providers.
(add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:demand t
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(use-package doom-modeline
:init
(doom-modeline-mode 1)
(display-time-mode 1))
(use-package delight
:config
(delight '((eldoc-mode nil "eldoc")
(subword-mode nil "subword")))
)
(use-package multiple-cursors
:bind (("C-c m >" . 'mc/mark-next-like-this)
("C-c m <" . 'mc/mark-previous-like-this)
("C-c m a" . 'mc/mark-all-like-this)
("C-c m e" . 'mc/edit-lines)
)
)
(use-package doom-themes
:config
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-spacegrey t)
;; Enable flashing mode-line on errors
(doom-themes-visual-bell-config )
;; or for treemacs users
;;(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
;;(doom-themes-treemacs-config)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config)
(defun atu/toggle-display-line-mode ()
"toggle between relative and absolute display-line-mode"
(interactive)
(if (eq display-line-numbers 'relative)
(setq display-line-numbers 'absolute)
(setq display-line-numbers 'relative)
)
)
:init
(setq whitespace-line-column nil)
(global-whitespace-mode 1)
:bind (
("C-c d l" . 'atu/toggle-display-line-mode)
)
)
(use-package xterm-color
:config
(setq compilation-environment '("TERM=xterm-256color"))
(defun atu/advice-compilation-filter (f proc string)
(funcall f proc (xterm-color-filter string)))
(advice-add 'compilation-filter :around #'atu/advice-compilation-filter)
)
(use-package aggressive-indent
:hook
(emacs-lisp-mode . aggressive-indent-mode)
)
(use-package magit
:commands (magit-status)
:bind ("C-x g" . magit-status)
:hook
(magit-mode .
(lambda () (setq-local whitespace-style nil)))
:custom
(magit-credential-cache-daemon-socket nil)
)
(use-package yasnippet
:delight yas-minor-mode
:bind ( :map yas-minor-mode-map
("TAB" . nil)
)
)
(use-package yasnippet-snippets
:after yasnippet
)
(use-package company
:after yasnippet
:delight
:bind ( ("M-TAB" . company-complete) )
:init
(defun atu/company-prog-mode ()
"Starts yas company and set up backends accordingly"
(yas-minor-mode)
(company-mode)
)
:config
(setq
company-minimum-prefix-length 1
company-idle-delay 0.5)
(setq company-backends
'(
(company-capf :separate company-yasnippet)
company-files
company-keywords
)
)
:hook
(prog-mode . atu/company-prog-mode)
)
(use-package cmake-mode
:ensure-system-package (
(cmake . cmake)
(pipx . pipx)
(cmake-format . "pipx install cmakelang[YAML]")
(cmake-language-server . "pipx install cmake-language-server")
)
:config
(setq cmake-tab-width 4)
(defun atu/create-or-erase-buffer (buffer-name)
""
(let ((existing-buffer (get-buffer buffer-name)))
(when existing-buffer
(with-current-buffer existing-buffer
(erase-buffer)))
(get-buffer-create buffer-name))
)
(defun atu/cmake-format-buffer ()
"Formats the current buffer using cmake-format"
(interactive)
(let (
(error-buffer (atu/create-or-erase-buffer "*cmake-format:stderr*"))
(cmake-format-config-file-exists
(file-exists-p (projectile-expand-root ".cmake-format.yaml"))
)
)
(setq-local atu/after-save-message nil)
(if cmake-format-config-file-exists
(if (eq 0 (call-process-region
;;region
(point-min)
(point-max)
"cmake-format"
nil ;do not delete buffer
;; discard stdout copy stderr to buffer
error-buffer
nil ;dont-redisplay buffer
"-"
))
(let ((current-point (point)))
(call-process-region
(point-min) (point-max)
"cmake-format"
t t t; replace current buffer and redisplay it
"--log-level=error" "-"
)
(goto-char (+ (point-min) current-point))
nil
)
(message
"cmake-format: could not format %s see buffer %s for details"
(buffer-name) error-buffer)
(current-message)
)
(message "cmake-format: skipping as no configuration file found")
)
)
)
(defun atu/cmake-before-save-hook ()
""
(setq-local atu/after-save-message (atu/cmake-format-buffer))
)
(defun atu/cmake-after-save-hook ()
""
(when atu/after-save-message
(message atu/after-save-message)
)
)
:hook
(cmake-mode . lsp-deferred)
(cmake-mode . (lambda ()
(add-hook 'before-save-hook 'atu/cmake-before-save-hook nil 'local)
(add-hook 'after-save-hook 'atu/cmake-after-save-hook nil 'local))
)
)
(use-package cc-mode
:ensure nil
:ensure-system-package
(clangd . clangd)
:config
(setq lsp-clients-clangd-args
'("--header-insertion-decorators=0" "--query-driver=/**/arm-none-eabi-*" "--log=verbose"))
:hook
(c-mode . lsp-deferred)
(c++-mode . lsp-deferred)
(c++-mode . (lambda () (setq-local lsp-enable-on-type-formatting nil)))
)
(use-package clang-format+
:ensure-system-package
(clang-format . clang-format)
:hook
(c-mode-common . clang-format+-mode)
)
(use-package string-inflection
:bind
("C-c u" . string-inflection-all-cycle)
)
(use-package polymode
:config
(define-hostmode poly-pio-hostmode
:mode 'asm-mode)
(define-auto-innermode poly-pio-c-innermode
:mode 'c-mode
:head-matcher "^%c-sdk{$"
:tail-matcher "^%}$"
:head-mode 'host
:tail-mode 'host)
(define-polymode poly-pio-mode
:hostmode 'poly-pio-hostmode
:innermodes '(poly-pio-c-innermode))
(add-to-list 'auto-mode-alist '("\\.pio$" . poly-pio-mode))
)
(use-package projectile
:bind ( :map projectile-mode-map
( "C-c p" . 'projectile-command-map)
)
:delight
:config
(projectile-mode +1)
(setq projectile-per-project-compilation-buffer t)
(projectile-register-project-type 'ng2 '("angular.json" "package.json" "tsconfig.json")
:project-file "angular.json"
:compile "npm install"
:test "ng test --progress=false"
:run "ng serve"
:test-suffix ".spec")
(defun atu/cmake-cc-inference (dir)
"Detects if the current root is a CMake C/C++ project"
(let ((cmakelists-file (projectile-expand-root "CMakeLists.txt" dir)))
(if (file-exists-p cmakelists-file)
(with-temp-buffer
(insert-file-contents cmakelists-file)
(goto-char (point-min))
(re-search-forward "project[[:space:]]*([^)]+\\([[:space:]]C\\(XX\\)?[[:space:]]\\)[^)]+)" nil t)
)))
)
(defun atu/cc-related-files (path)
"Returns related files path for a C/C++ file for a given path"
(let* (
(ext (file-name-extension path))
(basename (file-name-base path))
(dirpath (file-name-directory path))
(impl-rx "\\([.-]?[Ii]mp[l]?\\)$")
)
(if (member ext '("h" "hh" "hpp"))
(if (string-match impl-rx basename)
(list :other (concat dirpath
(string-replace
(match-string 1 basename)
""
basename)
"."
ext))
(list :other
(mapcar (lambda (sfx) (concat dirpath basename sfx))
(list
(concat "Imp." ext)
(concat "Impl." ext)
(concat "imp." ext)
(concat "impl." ext)
(concat ".Imp." ext)
(concat ".Impl." ext)
(concat ".imp." ext)
(concat ".impl." ext)
(concat "-Imp." ext)
(concat "-Impl." ext)
(concat "-imp." ext)
(concat "-impl." ext)
".cpp"
".c"
)))
)
(when (member ext '("c" "cc" "cpp"))
(list :other
(mapcar (lambda (sfx) (concat dirpath basename sfx))
'( ".h" ".hh" ".hpp" )))
)
)
)
)
(projectile-register-project-type 'cmake-cc #'atu/cmake-cc-inference
:project-file "CMakeLists.txt"
:configure "cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=On"
:compile (format "cmake --build build -j %d" atu/numprocs)
:test (format "cmake --build build -j %d --target check" atu/numprocs)
:related-files-fn
(list
#'atu/cc-related-files
(projectile-related-files-fn-test-with-suffix "cpp" "Test")
(projectile-related-files-fn-test-with-suffix "cpp" "UTest")
)
)
)
;; (use-package polymode
;; :config
;; (define-hostmode poly-pio-hostmode
;; :mode 'asm-mode)
;; (define-innermode poly-pio-c-innermode
;; :mode 'c-mode
;; :head-matcher "^% c-sdk {$"
;; :tail-matcher "^%}$"
;; :head-mode 'host
;; :tail-mode 'host)
;; (define-polymode poly-pio-mode
;; :hostmode 'poly-pio-hostmode
;; :innermodes '(poly-pio-c-innermode))
;; (add-to-list 'auto-mode-alist '("\\.pio$" . poly-pio-mode))
;; )
(use-package vterm)
(use-package flycheck
:delight
:bind (("C-c C-n" . 'flycheck-next-error))
:config
(defvar-local atu/flycheck-local-cache nil)
(defun atu/flycheck-checker-get (fn checker property)
(or (alist-get property (alist-get checker atu/flycheck-local-cache))
(funcall fn checker property)))
(advice-add 'flycheck-checker-get :around 'atu/flycheck-checker-get)
(setq flycheck-indication-mode 'left-margin)
;; Adjust margins and fringe widths…
(defun atu/set-flycheck-margins ()
(setq left-fringe-width 8 right-fringe-width 8
left-margin-width 1 right-margin-width 0)
(flycheck-refresh-fringes-and-margins))
:hook
(flycheck-mode . atu/set-flycheck-margins)
)
(use-package which-key
:delight
:config
(which-key-mode)
(which-key-setup-side-window-right-bottom)
)
(use-package lsp-mode
:delight
:after (flycheck)
:init
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "C-c l")
:bind-keymap ("C-c l" . lsp-command-map)
:config
(if (display-graphic-p)
(setq lsp-ui-doc-use-webkit t)
)
(add-to-list 'lsp-language-id-configuration '("\\.postcss\\'" . "css"))
(defun atu/lsp-inline-completion-display-toggle-key ()
"Add or remove `i` key from the lsp-command-map` depending on `lsp-inline-completion-mode`"
(if lsp-inline-completion-mode
(define-key lsp-command-map (kbd "i") #'lsp-inline-completion-display)
(define-key lsp-command-map (kbd "i") nil)))
(with-eval-after-load 'lsp-inline-completion
(define-key lsp-inline-completion-active-map (kbd "C-j") #'lsp-inline-completion-accept)
)
:bind (("C-c C-d" . lsp-ui-doc-toggle))
:hook (
(lsp-mode . lsp-enable-which-key-integration)
(lsp-inline-completion-mode . lsp-inline-completion-company-integration-mode)
(lsp-inline-completion-mode . atu/lsp-inline-completion-display-toggle-key)
)
:commands
(lsp lsp-deferred)
)
(use-package lsp-ui
:commands lsp-ui-mode
:config
(setq lsp-ui-sideline-show-diagnostics nil)
:custom-face
(lsp-ui-doc-background ((t (:background "#373B41"))))
)
(use-package treemacs
:bind (("C-x t t" . treemacs)
("M-0" . treemacs-select-window))
:config
(add-hook 'treemacs-mode-hook (lambda () (display-line-numbers-mode -1)))
(treemacs-project-follow-mode t)
)
(use-package treemacs-projectile)
(use-package nerd-icons )
(use-package treemacs-nerd-icons
:config
(treemacs-load-theme "nerd-icons"))
(use-package lsp-treemacs
:after lsp-mode
)
(use-package lsp-ltex
:init
(setq lsp-ltex-version "15.2.0")) ; make sure you have set this, see below
(use-package ng2-mode
:hook
(typescript-mode . lsp-deferred)
)
(use-package lsp-pyright
:hook
(python-mode . (lambda ()
(require 'lsp-pyright)
(lsp-deferred))) ; or lsp-deferred
)
(use-package yaml-mode)
(use-package python
:custom
(python-shell-interpreter "ipython")
(python-shell-interpreter-args "-i --simple-prompt")
(python-indent-guess-indent-offset-verbose nil)
:hook
(python-mode . (lambda () (setq-local company-prescient-sort-length-enable nil)))
(python-mode . (lambda () (setq-local fill-column 88)))
(python-mode . lsp-deferred)
(python-mode . atu/activate-venv)
(lsp-managed-mode . (lambda ()
(when (derived-mode-p 'python-mode)
(setq atu/flycheck-local-cache '((lsp . ((next-checkers . (python-flake8)))))))))
)
(use-package pyvenv
:after (projectile)
:config
(defun atu/get-direnv-venv ()
"Gets .direnv from project root python venv if any"
(when-let* ((root-dir (projectile-project-root))
(direnv (concat (file-name-as-directory root-dir) ".direnv"))
(direnv-exists (file-directory-p direnv))
(venvs (directory-files direnv t "python-.*")))
(car (last venvs)))
)
(defun atu/get-dotvenv ()
"Gets .venv from project root if any"
(when-let* ((root-dir (projectile-project-root))
(venv-file (concat (file-name-as-directory root-dir) ".venv"))
(venv-exists (file-exists-p venv-file))
(venv-name (with-temp-buffer
(insert-file-contents venv-file)
(nth 0 (split-string (buffer-string))))))
venv-name)
)
(defun atu/get-venv-name ()
"Gets venv name from project root. Support .venv and .direnv structure"
(or (atu/get-dotvenv) (atu/get-direnv-venv))
)
(defun atu/activate-venv ()
"Activate python environment according to the project root"
(when-let ((venv-name (atu/get-venv-name)))
(setenv "WORKON_HOME" venv-name)
(pyvenv-mode)
(pyvenv-workon venv-name)
(pyvenv-activate venv-name)
(message (format "Using python: %s" venv-name))
)
)
(defun atu/get-venv-python ()
"returns python executable from current venv"
(when-let* ((venv-name (atu/get-venv-name))
(python-exec (concat (file-name-as-directory venv-name) "bin/python3"))
(python-exists (file-executable-p python-exec))
)
python-exec)
)
(defun atu/activate-flycheck ()
"Activate flycheck unless its in the venv"
(if-let ((venv-name (atu/get-venv-name)))
(unless (and buffer-file-name (file-in-directory-p buffer-file-name venv-name))
(flycheck-mode))
(flycheck-mode))
)
(defun atu/pyls-set-jedi-environment ()
"Sets the jedi environment according to the discovered venv"
(when-let ((venv-name (atu/get-venv-name)))
(setq lsp-pylsp-plugins-jedi-environment venv-name))
)
(defun atu/append-workspace-extra-paths ()
"Appends needed extra-paths to lsp-jedi workspace if found"
(when-let* ((venv-name (atu/get-venv-name))
(site-packages (file-expand-wildcards (concat (file-name-as-directory venv-name) "lib/python*/site-packages")))
(site-package (car site-packages)))
(setq lsp-jedi-workspace-extra-paths
(vconcat lsp-jedi-workspace-extra-paths (vector site-package))
)
)
)
(defun atu/flycheck-set-python-paths ()
"Sets the rights executable for flycheck"
(when-let ((python-exec (atu/get-venv-python)))
(flycheck-set-checker-executable 'python-flake8 python-exec)
(flycheck-set-checker-executable 'python-pylint python-exec)
(flycheck-set-checker-executable 'python-mypy python-exec)
(flycheck-reset-enabled-checker 'python-flake8)
(flycheck-reset-enabled-checker 'python-pylint)
(flycheck-add-next-checker 'lsp 'python-pylint)
)
)
:hook
(python-mode . atu/pyls-set-jedi-environment)
;(python-mode . atu/activate-flycheck)
;(python-mode . atu/append-workspace-extra-paths)
(lsp-managed-mode . atu/flycheck-set-python-paths)
)
(use-package blacken
:commands blacken-mode blacken-buffer
:hook
(python-mode . blacken-mode)
)
(use-package py-isort
:commands py-isort-buffer
:hook
(python-mode . (lambda ()
(add-hook 'before-save-hook 'py-isort-before-save)))
)
(use-package code-cells
:mode ("\\.sync.py'" . code-cells-mode)
:config
(defun atu/jupyter-ascending-sync ()
"Runs synchronization with jupyter-ascending "
(interactive)
(when (string-match-p ".sync.py\\'" (buffer-name))
(unless (and (boundp 'atu/jupyter-sync-inhibit) atu/jupyter-sync-inhibit)
(call-process "python"
nil nil nil
"-m" "jupyter_ascending.requests.sync" "--filename" (buffer-file-name)
)
)
)
)
(defun atu/jupyter-ascending-eval (start end)
"Runs cell via jupyter-ascending or python-shell-send-region"
(interactive)
(if (not (string-match-p ".sync.py\\'" (buffer-name)))
(python-shell-send-region start end)
(setq-local atu/jupyter-sync-inhibit t)
(save-buffer)
(setq-local atu/jupyter-sync-inhibit nil)
(call-process "python"
nil nil nil
"-m" "jupyter_ascending.requests.execute"
"--filename" (buffer-file-name)
"--linenumber" (number-to-string (line-number-at-pos))
)
)
)
(setq code-cells-eval-region-commands
(mapcar (lambda (pair)
(if (eq (car pair) 'python-mode)
(cons 'python-mode 'atu/jupyter-ascending-eval)
pair))
code-cells-eval-region-commands))
:hook
(python-mode . code-cells-mode-maybe)
(code-cells-mode . (lambda ()
(add-hook 'after-save-hook 'atu/jupyter-ascending-sync nil 'local)))
)
(use-package markdown-mode)
(use-package go-mode
:after (projectile)
:config
(unbind-key "C-c C-d" go-mode-map)
(defun atu/go-compile-command ()
"returns a string to compile a go project"
(interactive)
(let ((project-makefile (concat (file-name-as-directory (projectile-project-root)) "Makefile")))
(if (file-exists-p project-makefile)
"make"
"go build && go test && go vet"
)
)
)
(projectile-update-project-type
'go
:compile 'atu/go-compile-command)
:hook
(go-mode . lsp-deferred)
(go-mode . (lambda ()
(add-hook 'before-save-hook #'lsp-format-buffer t t)
(add-hook 'before-save-hook #'lsp-organize-imports t t)
))
)
(use-package glsl-mode)
(use-package opencl-c-mode)
(use-package protobuf-mode
:mode "\\.proto\\'"
:config
(defconst my-protobuf-style
'((c-basic-offset . 4)
(indent-tabs-mode . t))
)
;; (c-add-style "my-style" my-protobuf-style t)
)
(use-package typescript-mode
:config
(progn
(setq create-lockfiles nil)
(add-to-list 'compilation-error-regexp-alist '("^Error: \\(.*?\\):\\([0-9]+\\):\\([0-9]+\\)" 1 2 3))
)
)
(use-package json-mode)
(use-package prettier
:delight "PR"
:config
(setq prettier-mode-sync-config-flag t)
:hook
(web-mode . prettier-mode)
(typescript-mode . prettier-mode)
(js-mode . prettier-mode)
)
(use-package web-mode
:mode "\\.html?\\'" "\\.svelte\\'" "\\.\\(post\\)?css\\'"
:interpreter "html" "css" "svelte"
:config
(setq web-mode-content-types-alist
'(("css" . "\\.\\(post\\)?css\\'")))
:hook
(web-mode . lsp-deferred)
)
(use-package dockerfile-mode
:hook
(dockerfile-mode . lsp-deferred)
)
(use-package spdx
:quelpa (spdx :fetcher github :repo "condy0919/spdx.el")
:bind (:map prog-mode-map
("C-c i l" . spdx-insert-spdx))
:custom
(spdx-copyright-holder 'auto)
(spdx-project-detection 'auto))
;; Local Variables:
;; vc-follow-symlinks: t
;; End: