diff --git a/.gitignore b/.gitignore index f3a0c40..16eafff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /emacs/secrets.el /emacs/eln-cache/ /emacs/url/ +/emacs/recentf diff --git a/emacs/custom.el b/emacs/custom.el index b2666af..3521e46 100644 --- a/emacs/custom.el +++ b/emacs/custom.el @@ -10,7 +10,7 @@ '(indent-tabs-mode nil) '(mac-option-modifier '(:ordinary meta :function meta :mouse meta)) '(package-selected-packages - '(flx counsel-projectile counsel ivy python-mode rainbow-mode language-detection jiralib2 request ox-jira ejira jirascope winner-mode fzf prescient doom-modeline emms denote-explore denote multi-vterm ox-hugo plz flycheck-projectile ob-go devil realgud projectile dash async yasnippet ace-jump ace-jump-mode async-status cape corfu dired-git dired-git-info embark eshell-toggle eshell-vterm fic-mode flycheck git-lens git-link go-projectile go-scratch graphviz-dot-mode json-mode kotlin-mode lsp-mode magit mmm-mode multi-web-mode multifiles multiple-cursors multishell nerd-icons-completion nerd-icons-corfu nerd-icons-dired nerd-icons-ibuffer orderless org-ai org-context org-dashboard persistent-scratch php-mode plantuml-mode project-explorer projectile-ripgrep protobuf-mode quelpa-use-package rego-mode unicode-fonts vertico vterm-toggle wgrep which-key yaml-mode)) + '(company-box company ivy-prescient flx counsel-projectile counsel ivy python-mode rainbow-mode language-detection jiralib2 request ox-jira ejira jirascope winner-mode fzf prescient doom-modeline emms denote-explore denote multi-vterm ox-hugo plz flycheck-projectile ob-go devil realgud projectile dash async yasnippet ace-jump ace-jump-mode async-status cape corfu dired-git dired-git-info embark eshell-toggle eshell-vterm fic-mode flycheck git-lens git-link go-projectile go-scratch graphviz-dot-mode json-mode kotlin-mode lsp-mode magit mmm-mode multi-web-mode multifiles multiple-cursors multishell nerd-icons-completion nerd-icons-corfu nerd-icons-dired nerd-icons-ibuffer orderless org-ai org-context org-dashboard persistent-scratch php-mode plantuml-mode project-explorer projectile-ripgrep protobuf-mode quelpa-use-package rego-mode unicode-fonts vertico vterm-toggle wgrep which-key yaml-mode)) '(tab-width 4) '(tool-bar-mode nil) '(use-short-answers t)) diff --git a/emacs/init.el b/emacs/init.el index e3d18c3..715b2c1 100644 --- a/emacs/init.el +++ b/emacs/init.el @@ -6,6 +6,21 @@ ;; helper functions ;; ===== +(defun my/swiper-query-replace () + "Run `query-replace-regexp' on Swiper results." + (interactive) + (if (not (window-minibuffer-p)) + (user-error "Call this from swiper") + (let* ((enable-recursive-minibuffers t) + (from (ivy--regex ivy-text)) + (to (query-replace-read-to from + (concat "Query replace (regexp " from ") with: ") + t))) + (ivy-exit-with-action + (lambda (_) + (let ((case-fold-search (ivy--case-fold-p ivy-text))) + (query-replace-regexp from to))))))) + (defun my/visit-todo () "Visit TODO.org in home" (interactive) @@ -139,6 +154,8 @@ (global-set-key (kbd "") 'speedbar) (global-set-key (kbd "M-/") 'hippie-expand) + (with-eval-after-load 'swiper + (define-key swiper-map (kbd "M-%") #'my/swiper-query-replace)) (global-set-key (kbd "C-=") 'multi-vterm-dedicated-toggle) (global-set-key (kbd "C-x r") 'replace-regexp) (global-set-key (kbd "C-x R") 'replace-string) @@ -148,6 +165,7 @@ (global-set-key (kbd "C-x E n f") #'narrow-to-defun) (global-set-key (kbd "C-x E n r") #'narrow-to-region) (global-set-key (kbd "C-x E w") #'widen) + (when (file-exists-p custom-file) (load custom-file))) @@ -294,6 +312,34 @@ (use-package fic-mode :ensure t :defer t) (use-package flycheck :ensure t :defer t) +(use-package eglot + :ensure t + :hook ((python-mode . eglot-ensure) + (rust-mode . eglot-ensure) + (c-mode . eglot-ensure) + (c++-mode . eglot-ensure) + (js-mode . eglot-ensure) + (typescript-mode . eglot-ensure)) + :config + (setq eglot-autoshutdown t) + (setq eglot-sync-connect 1) + (setq eglot-connect-timeout 10) + (setq eglot-autoreconnect t) + (setq completion-category-defaults nil) + (setq completion-category-overrides '((eglot (styles orderless)))) + (setq eglot-completion-style 'orderless) + (setq eglot-completion-provider :company) + (with-eval-after-load 'orderless + (setq orderless-matching-styles '(orderless-flex orderless-regexp orderless-initialism))) + :bind (:map eglot-mode-map + ("s-l a" . eglot-code-actions) + ("s-l r" . eglot-rename) + ("s-l f" . eglot-format) + ("s-l d" . eglot-find-declaration) + ("s-l i" . eglot-find-implementation) + ("s-l t" . eglot-find-typeDefinition))) + + ;; navigation ;; === (use-package ace-jump-mode :ensure t :defer t @@ -309,16 +355,12 @@ ;; === (use-package ivy :ensure t - :diminish :config - (ivy-mode 1) - (setq ivy-use-virtual-buffers t - ivy-count-format "%d/%d " - ivy-initial-inputs-alist nil - ivy-virtual-abbreviate 'full - ivy-use-selectable-prompt t) - (setq ivy-re-builders-alist - '((t . ivy--regex-plus)))) + (setq ivy-re-builders-alist + '((swiper . ivy--regex-plus) + (t . orderless-ivy-re-builder))) + (setq ivy-initial-inputs-alist nil) + (setq orderless-matching-styles '(orderless-flex orderless-literal orderless-regexp))) (use-package counsel :ensure t @@ -326,7 +368,9 @@ :config (counsel-mode 1) (setq counsel-grep-base-command - "rg -i -M 120 --no-heading --line-number --color never '%s' %s")) + "rg -i -M 120 --no-heading --line-number --color never '%s' %s") + (setq counsel-rg-base-command + "rg -i -M 120 --no-heading --line-number --color never %s .")) (use-package projectile :ensure t @@ -341,14 +385,13 @@ (setq projectile-generic-command (format "%s . -0 --type f --color=never" (executable-find "fd")))) :bind-keymap - ("C-x p" . projectile-command-map)) ; Changed from C-c p to C-x p + ("C-x p" . projectile-command-map)) (use-package counsel-projectile :ensure t :after (counsel projectile) :config (counsel-projectile-mode 1) - (setq counsel-projectile-find-file-matcher 'ivy--regex-plus) :bind (:map projectile-command-map ("f" . counsel-projectile-find-file) @@ -362,10 +405,45 @@ ("5 b" . counsel-projectile-switch-to-buffer-other-frame) ("5 d" . projectile-dired-other-frame))) -;; Use prescient for faster sorting and filtering (use-package ivy-prescient :ensure t :after counsel :config (ivy-prescient-mode 1) - (prescient-persist-mode 1)) + (prescient-persist-mode 1) + (setq ivy-prescient-enable-filtering nil) + (setq ivy-prescient-enable-sorting t)) + + +(use-package orderless + :ensure t + :custom + (completion-styles '(orderless basic)) + (completion-category-overrides '((file (styles basic partial-completion))))) + +;; completion +;; === +(use-package company + :ensure t + :hook (after-init . global-company-mode) + :config + (setq company-idle-delay 0.1 + company-minimum-prefix-length 1 + company-tooltip-align-annotations t + company-tooltip-limit 10 + company-tooltip-flip-when-above t + company-require-match nil + company-dabbrev-downcase nil + company-dabbrev-ignore-case t)) + +(use-package company-box + :ensure t + :hook (company-mode . company-box-mode)) + +(use-package swiper + :ensure t + :after ivy + :bind (("C-s" . swiper) + ("C-r" . swiper-backward) + :map swiper-map + ("M-%" . swiper-query-replace)))