diff --git a/emacs/.emacs.d/.gitignore b/emacs/.emacs.d/.gitignore index 3e51dcc..3c7a74c 100755 --- a/emacs/.emacs.d/.gitignore +++ b/emacs/.emacs.d/.gitignore @@ -18,6 +18,7 @@ transient/ .lsp-session-v1 /.extension/** url/** +**/*.bak # Org-mode .org-id-locations diff --git a/emacs/.emacs.d/init.el b/emacs/.emacs.d/init.el index ee31468..21576e7 100644 --- a/emacs/.emacs.d/init.el +++ b/emacs/.emacs.d/init.el @@ -1,901 +1,35 @@ -;; Initial greeting for debugging (message "Welcome to Emacs") (message "Loading user configuration...") -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; LOOK AND FEEL ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Load default theme -(load-theme 'wombat) - -;; Setting default font -(set-frame-font "Iosevka Nerd Font 14" nil t) - -;; Remove toolbar -(tool-bar-mode -1) - -;; Remove menu -(menu-bar-mode -1) - -;; Disable startup screen -(setq inhibit-startup-screen t) - -;; Disable splash screen -(setq inhibit-splash-screen t) - -;; Start all frames maximized -(add-to-list 'default-frame-alist '(fullscreen . maximized)) - -;; Remove scrollbar -(scroll-bar-mode -1) - -;; Simple 'y' for 'yes' and 'n' for 'no' -(defalias 'yes-or-no-p 'y-or-n-p) - -;; Set global value for paragraph witdh -(setq-default fill-column 120) - -;; Stop Emacs from losing informations -(setq undo-limit 8000000) -(setq undo-strong-limit 12000000) - -;; Smooth scroll -(setq scroll-step 3) -(setq ring-bell-function 'ignore) - -;; Add column number in the status line -(column-number-mode) - -;; View clock in the status line -(display-time) - -;; Enable line numbers in the programming mode only -(add-hook 'prog-mode-hook 'display-line-numbers-mode) - -;; Enable line numbers in the configuration mode only -(add-hook 'conf-mode-hook 'display-line-numbers-mode) - -;; Setting default directory for Org files -(setq org-directory "~/Remotes/pCloud/Org") - -;; --- Startup speed tweaks ---------------------------------------------------- -;; Temporarily increase GC threshold during init -(defvar fscotto/gc-cons-threshold-orig gc-cons-threshold) -(setq gc-cons-threshold (* 50 1000 1000)) ;; 50MB for init - -;; Speedup file-name-handler during init -(defvar fscotto/file-name-handler-alist-orig file-name-handler-alist) -(setq file-name-handler-alist nil) - -;; Restore after init -(add-hook 'emacs-startup-hook - (lambda () - (setq gc-cons-threshold fscotto/gc-cons-threshold-orig) - (setq file-name-handler-alist fscotto/file-name-handler-alist-orig) - (garbage-collect))) - -;; LSP responsiveness -(setq read-process-output-max (* 1024 1024)) ;; 1MB, utile per lsp-mode -(setq lsp-idle-delay 0.5) ;; meno ritardo prima che LSP aggiorni info -(setq inhibit-compacting-font-caches t) - -;; --------------------------------------------------------------------------- - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; EDITOR OPTIONS ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(setq standard-indent 4) -(setq tab-stop-list nil) -(setq indent-tabs-mode nil) - -;; C / C++ fallback style (Linux-like) -(setq c-default-style "linux" - c-basic-offset 4 - tab-width 8) - -(add-hook 'c-mode-common-hook - (lambda () - (setq indent-tabs-mode t))) - -;; Tree-sitter C/C++ -(setq c-ts-mode-indent-offset 4) -(setq c++-ts-mode-indent-offset 4) - -;; Setting variables -(setq vc-follow-symlinks 't) -(prefer-coding-system 'utf-8-unix) -(setq custom-file (null-device)) - -;;;;;;;;;;;;;;;;;;;; -;; USER FUNCTIONS ;; -;;;;;;;;;;;;;;;;;;;; - -;;functions to support syncing .elfeed between machines -;;makes sure elfeed reads index from disk before launching -(defun fscotto/elfeed-load-db-and-open () - "Wrapper to load the elfeed db from disk before opening URL https://pragmaticemacs.wordpress.com/2016/08/17/read-your-rss-feeds-in-emacs-with-elfeed/ - Created: 2016-08-17 - Updated: 2025-06-13" - (interactive) - (elfeed) - (elfeed-db-load) - ;; (elfeed-search-update--force) - (elfeed-update) - (elfeed-db-save)) - -(defun fscotto/project-root () - "Return projectile project root or fallback to default-directory." - (if (featurep 'projectile) - (or (projectile-project-root) default-directory) - default-directory)) - -(defun fscotto/project-vterm () - "Open vterm in project root." - (interactive) - (let ((default-directory (fscotto/project-root))) - (vterm))) - -(defun fscotto/project-magit-status () - "Open magit-status in project root." - (interactive) - (let ((default-directory (fscotto/project-root))) - (magit-status))) - -(defun fscotto/magit-dispatch () - "Load Magit if necessary and open magit-dispatch." - (interactive) - (require 'magit) - (call-interactively #'magit-dispatch)) - -(defun fscotto/disable-c-formatting () - (setq-local lsp-enable-on-type-formatting nil)) - -;; Golang development support functions -(defun fscotto/go-format-on-save () - "Format Go buffers on save using gofmt." - (add-hook 'before-save-hook #'lsp-format-buffer nil t)) - -(defun fscotto/go-mod-tidy () - "Esegue go mod tidy nella root del progetto." - (interactive) - (let ((default-directory (project-root (project-current t)))) - (compile "go mod tidy"))) - -(defun fscotto/go-mod-download () - "Scarica i moduli Go." - (interactive) - (let ((default-directory (project-root (project-current t)))) - (compile "go mod download"))) - -(defun fscotto/go-mod-after-save () - (when (and (eq major-mode 'go-mod-ts-mode) - (lsp-workspaces)) - (lsp-restart-workspace))) - -(defun fscotto/go-test-package () - "Run `go test` in the current package." - (interactive) - (let ((default-directory (project-root (project-current t)))) - (compile "go test"))) - -(defun fscotto/go-test-module () - "Run `go test ./...` in the current Go module." - (interactive) - (let ((default-directory (project-root (project-current t)))) - (compile "go test ./..."))) - -(defun fscotto/go-test-current-test () - "Run `go test -run` for the test at point." - (interactive) - (let* ((test-name (thing-at-point 'symbol t)) - (default-directory (project-root (project-current t)))) - (unless test-name - (user-error "No test name at point")) - (compile (format "go test -run '^%s$'" test-name)))) - -(defun fscotto/go-test-at-point () - "Return Go test name at point." - (let ((sym (thing-at-point 'symbol t))) - (unless (and sym (string-prefix-p "Test" sym)) - (user-error "No Go test at point")) - sym)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; PACKAGES ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Initialize package system via use-package -;; (package-initialize) -(require 'use-package) - -(use-package package - :config - ;; Setting repo priorities - (setq package-archive-priorities - '(("melpa-stable" . 2) - ("MELPA" . 1) - ("gnu" . 0))) - ;; Setting repo URL - (setq package-archives - '(("melpa-stable" . "https://stable.melpa.org/packages/") - ("MELPA" . "https://melpa.org/packages/") - ("gnu" . "https://elpa.gnu.org/packages/")))) - -;; Status line like Doom Emacs -(use-package doom-modeline - :ensure t - :config - (setq doom-modeline-height 25 - doom-modeline-bar-width 3 - doom-modeline-project-detection 'projectile) - :init (doom-modeline-mode 1)) - -;; Help to remember or discover keybindings -(use-package which-key - :ensure t - :defer 1 - :config - (which-key-mode) - (setq which-key-idle-delay 0.45 - which-key-idle-secondary-delay 0.05 - which-key-max-display-columns 3 - which-key-max-description-length 45)) - -;; ============================================================================ -;; Doom-style which-key hierarchy for fscotto -;; ============================================================================ - -(with-eval-after-load 'which-key - - ;; -------------------------------------------------------------------------- - ;; Top-level prefixes - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "C-c !" "Analyze" - "C-c o" "Open" - "C-c v" "Version control" - "C-c l" "LSP" - "C-c t" "TODO / Annotations" - "C-c b" "Buffers" - "C-c p" "Project" - "C-c d" "Debug" - "C-c g" "Git" - "C-c e" "Email / Elfeed") - - ;; -------------------------------------------------------------------------- - ;; Open (C-c o …) - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "C-c o f" "RSS (Elfeed)" - "C-c o m" "mu4e (Email Client)" - "C-c o T" "Terminal (vterm)") - - ;; -------------------------------------------------------------------------- - ;; Version control - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "C-c v g" "Magit status (legacy)") - - (which-key-add-key-based-replacements - ;; Core - "C-c g g" "Status" - "C-c g s" "Status" - ;; "C-c g b" "Branch" - ;; "C-c g c" "Commit" - "C-c g p" "Push / Pull" - "C-c g f" "Fetch" - "C-c g l" "Log" - "C-c g S" "Stash" - - ;; Files - "C-c g d" "Diff" - "C-c g D" "Diff (cached)" - "C-c g B" "Blame" - - ;; Rebase / Reset - "C-c g r" "Rebase" - "C-c g R" "Reset" - - ;; Remote - "C-c g y" "Show refs" - "C-c g o" "Browse remote") - - ;; -------------------------------------------------------------------------- - ;; Buffers - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "C-x C-b" "ibuffer") - - ;; -------------------------------------------------------------------------- - ;; TODO / hl-todo - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "C-t" "hl-todo" - "C-t p" "Previous TODO" - "C-t n" "Next TODO" - "C-t o" "Occur (list)" - "C-t i" "Insert TODO") - - ;; -------------------------------------------------------------------------- - ;; LSP (C-c l …) - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - ;; Navigation - "C-c l d" "Go to definition" - "C-c l D" "Go to type definition" - "C-c l i" "Go to implementation" - - ;; Symbols / diagnostics - "C-c l s" "Workspace symbols" - "C-c l e" "Diagnostics" - - ;; Actions - "C-c l a" "Code actions" - "C-c l r" "Rename symbol" - "C-c l f" "Format buffer" - - ;; Control - "C-c l R" "Restart workspace") - - ;; -------------------------------------------------------------------------- - ;; Elfeed modes - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "w" "Yank" - "R" "Update feeds" - "q" "Quit") - - ;; -------------------------------------------------------------------------- - ;; Debug / DAP - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "C-c d d" "Start debug session" - "C-c d b" "Toggle breakpoint") - ;; "C-c d c" "Continue" - ;; "C-c d n" "Next" - ;; "C-c d i" "Step in" - ;; "C-c d o" "Step out") - - ;; -------------------------------------------------------------------------- - ;; Project (future) - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - ;; Core - "C-c p p" "Switch project" - "C-c p f" "Find file" - "C-c p d" "Find directory" - "C-c p b" "Switch buffer" - "C-c p k" "Kill project buffers" - "C-c p r" "Recent files" - - ;; Search - "C-c p s" "Search" - "C-c p s g" "Grep (ripgrep)" - "C-c p s r" "Replace in project" - - ;; Actions - "C-c p c" "Compile" - "C-c p t" "Test" - "C-c p v" "Open term in project" - "C-c p e" "Edit project config" - "C-c p g" "Project Git status" - "C-c p x" "Open Terminal" - "C-c p 4" "Other Window" - "C-c p 5" "Other Frame" - "C-c p x 4" "Other Window" - - ;; Cache - "C-c p i" "Invalidate cache") - - ;; -------------------------------------------------------------------------- - ;; Cleanup annoying +prefix - ;; -------------------------------------------------------------------------- - (which-key-add-key-based-replacements - "+prefix" "Prefix" - "+lsp" "LSP" - "+debug" "Debug" - "+project" "Project")) - -;; Configuration for mu4e, an interface for mu email index, running inside Emacs -(use-package mu4e - :ensure nil - ;; :load-path "/usr/share/emacs/site-lisp/mu4e/" - :defer 20 ; Wait until 20 seconds after startup - :bind (:map global-map ("C-c o m" . mu4e)) - :config - - ;; This is set to 't' to avoid mail syncing issues when using mbsync - (setq mu4e-change-filenames-when-moving t) - - ;; Refresh mail using isync every 10 minutes - (setq mu4e-update-interval (* 10 60)) - (setq mu4e-get-mail-command "~/.emacs.d/scripts/email_sync.sh") - (setq mu4e-maildir "~/Maildir") - - ;; Configure email accounts - (setq mu4e-contexts - (list - ;; Protonmail Account - (make-mu4e-context - :name "Protonmail" - :match-func - (lambda (msg) - (when msg - (string-prefix-p "/ProtonMailAccount" (mu4e-message-field msg :maildir)))) - :vars '((user-mail-address . "fscottodisantolo@protonmail.com") - (user-full-name . "Fabio Scotto di Santolo") - (mu4e-drafts-folder . "/ProtonMailAccount/Drafts") - (mu4e-sent-folder . "/ProtonMailAccount/Sent") - (mu4e-refile-folder . "/ProtonMailAccount/All Mail") - (mu4e-trash-folder . "/ProtonMailAccount/Trash"))) - - ;; iCloud Account - (make-mu4e-context - :name "iCloud Mail" - :match-func - (lambda (msg) - (when msg - (string-prefix-p "/iCloudAccount" (mu4e-message-field msg :maildir)))) - :vars '((user-mail-address . "fscottodisantolo@icloud.com") - (user-full-name . "Fabio Scotto di Santolo") - (mu4e-drafts-folder . "/iCloudAccount/Drafts") - (mu4e-sent-folder . "/iCloudAccount/Sent Messages") - (mu4e-refile-folder . "/iCloudAccount/INBOX") - (mu4e-trash-folder . "/iCloudAccount/Junk"))))) - - (setq sendmail-program "/usr/bin/msmtp" - send-mail-function 'sendmail-send-it - message-sendmail-f-is-evil t - message-sendmail-extra-arguments '("--read-envelope-from") - message-send-mail-function 'message-send-mail-with-sendmail)) - -;; Configure elfeed for RSS feed -(use-package elfeed - :ensure t - :custom - (elfeed-enclosure-default-dir "~/Downloads/") - (elfeed-search-remain-on-entry t) - (elfeed-search-title-max-width 100) - (elfeed-search-title-min-width 30) - (elfeed-search-trailing-width 25) - (elfeed-show-truncate-long-urls t) - (elfeed-sort-order 'descending) - (elfeed-search-filter "+unread") - :bind - ("C-c o f" . fscotto/elfeed-load-db-and-open) - (:map elfeed-search-mode-map - ("w" . elfeed-search-yank) - ("R" . elfeed-update) - ("q" . elfeed-kill-buffer)) - (:map elfeed-show-mode-map - ("S" . elfeed-show-new-live-search) ; moved to free up 's' - ("c" . (lambda () (interactive) (org-capture nil "capture"))) - ("e" . email-elfeed-entry) - ("f" . elfeed-show-fetch-full-text) - ("w" . elfeed-show-yank)) - :hook - (elfeed-show-mode . visual-line-mode)) - -(use-package elfeed-org - :ensure t - :after elfeed - :custom - ;; Optionally specify a number of files containing elfeed - ;; configuration. If not set then the location below is used. - ;; Note: The customize interface is also supported. - (rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org"))) - -(with-eval-after-load 'elfeed - (elfeed-org)) - -;; Terminal -(use-package vterm - :ensure t - :bind (:map global-map - ("C-c o T" . vterm) - ("C-c C-t" . vterm-copy-mode))) - +;; Core +(load "~/.emacs.d/lisp/core/packages.el") +(load "~/.emacs.d/lisp/core/ui.el") +(load "~/.emacs.d/lisp/core/performance.el") +(load "~/.emacs.d/lisp/core/editor.el") +(load "~/.emacs.d/lisp/core/keybindings.el") + +;; Tools +(load "~/.emacs.d/lisp/tools/completion.el") +(load "~/.emacs.d/lisp/tools/project.el") +(load "~/.emacs.d/lisp/tools/lsp.el") +(load "~/.emacs.d/lisp/tools/dap.el") + +;; Languages +(load "~/.emacs.d/lisp/lang/c.el") +(load "~/.emacs.d/lisp/lang/golang.el") +(load "~/.emacs.d/lisp/lang/shell.el") + +;; Misc +(load "~/.emacs.d/lisp/misc/custom-functions.el") +(load "~/.emacs.d/lisp/misc/doom-modeline.el") +(load "~/.emacs.d/lisp/misc/which-key.el") +(load "~/.emacs.d/lisp/misc/email.el") +(load "~/.emacs.d/lisp/misc/rss.el") +(load "~/.emacs.d/lisp/misc/terminal.el") +(load "~/.emacs.d/lisp/misc/vcs.el") ;; FIXME PDF viewer with annotations -;; (use-package pdf-tools -;; :ensure t -;; :config -;; (pdf-tools-install)) - -;; EPub viewer -(use-package nov - :ensure t - :mode ("\\.epub\\'" . nov-mode)) - -(use-package visual-fill-column - :ensure t) - -;; Git plugin -(use-package magit - :ensure t - :commands (magit-status magit-log) - :init - ;; Entry point principale - (setq magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1) - :config - ;; Performance & UX - (setq magit-refresh-status-buffer nil) - (setq magit-repository-directories - '(("~/Projects" . 2) - ("~/Work" . 2)))) - -;; Legacy alias (keep muscle memory) -(global-set-key (kbd "C-c v g") #'magit-status) - -(global-set-key (kbd "C-c g") #'fscotto/magit-dispatch) - -;; Highlight keywords to remember the activity when coding. -(use-package hl-todo - :ensure t - :commands (global-hl-todo-mode) - :init (global-hl-todo-mode)) - -(setq hl-todo-keyword-faces - '(("TODO" . "#94e2d5") - ("FIXME" . "#f38ba8") - ("DEBUG" . "#cba6f7") - ("GOTCHA" . "#eba0ac") - ("STUB" . "#89b4fa"))) - -(keymap-set hl-todo-mode-map "C-t p" #'hl-todo-previous) -(keymap-set hl-todo-mode-map "C-t n" #'hl-todo-next) -(keymap-set hl-todo-mode-map "C-t o" #'hl-todo-occur) -(keymap-set hl-todo-mode-map "C-t i" #'hl-todo-insert) - -;; Highlight for i3 config file -(use-package i3wm-config-mode - :ensure t) - -(use-package ivy - :ensure t - :config - (ivy-mode 1)) - -(use-package consult - :ensure t - :defer t) - -(use-package ibuffer - :ensure t - :bind (:map global-map ("C-x C-b" . ibuffer))) - -(use-package ibuffer-tramp - :ensure t) - -(use-package ibuffer-vc - :ensure t) - -(use-package ibuffer-projectile - :ensure t) - -(add-hook 'ibuffer-mode-hook - (lambda () - (ibuffer-projectile-set-filter-groups))) - -;; ============================================================================ -;; Projectile - Project management -;; ============================================================================ - -(use-package projectile - :ensure t - :defer 1 - :init - ;; Root detection - (setq projectile-project-search-path '("~/Projects" "~/Work")) - (setq projectile-completion-system 'ivy) - :config - ;; Performance - (setq projectile-enable-caching t) - (setq projectile-indexing-method 'hybrid) - (setq projectile-sort-order 'recently-active) - ;; Projectile as single source of truth - (setq projectile-switch-project-action #'projectile-dired) - ;; Use ripgrep if available - (when (executable-find "rg") - (setq projectile-generic-command "rg --files --hidden --glob '!.git'")) - ;; Enable globally - (projectile-mode 1)) - -;; Projectile keybindings (Doom-style) -(with-eval-after-load 'projectile - (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)) - -(with-eval-after-load 'projectile - (define-key projectile-command-map (kbd "v") #'fscotto/project-vterm)) - -(with-eval-after-load 'projectile - (define-key projectile-command-map (kbd "g") #'fscotto/project-magit-status)) - -;; Add autocomplete feature to Emacs -(use-package company - :ensure t - :custom - (company-tooltip-align-annotations 't) - (company-minimum-prefix-length 1) - (company-idle-delay 0.1) - :hook (prog-mode . company-mode)) - -(with-eval-after-load 'company - (add-hook 'bash-ts-mode-hook 'company-mode)) - -;; Static analysis for code base -(use-package flycheck - :ensure t - :hook (prog-mode . flycheck-mode)) - -(with-eval-after-load 'flycheck - (add-hook 'bash-ts-mode-hook 'flycheck-mode)) - -(use-package treesit - :ensure nil - :config - (setq treesit-font-lock-level 4) - (setq treesit-auto-install t) - (setq major-mode-remap-alist - '((c-mode . c-ts-mode) - (c++-mode . c++-ts-mode) - (go-mode . go-ts-mode) - (go-mod-mode . go-mod-ts-mode) - (python-mode . python-ts-mode) - (sh-mode . bash-ts-mode))) - (setq treesit-language-source-alist - '((c "https://github.com/tree-sitter/tree-sitter-c") - (cpp "https://github.com/tree-sitter/tree-sitter-cpp") - (python "https://github.com/tree-sitter/tree-sitter-python") - (bash "https://github.com/tree-sitter/tree-sitter-bash") - (go "https://github.com/tree-sitter/tree-sitter-go") - (gomod "https://github.com/camdencheek/tree-sitter-go-mod")))) - -(use-package lsp-mode - :ensure t - :commands (lsp lsp-deferred) - :init - ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") - (setq lsp-keymap-prefix "C-c l") - :hook - ((c-mode - c-ts-mode - c++-mode - c++-ts-mode - python-mode - python-ts-mode - sh-mode - bash-ts-mode) . lsp-deferred) - :config - ;; Performance - (setq lsp-enable-symbol-highlighting t - lsp-enable-snippet t - lsp-log-io nil - lsp-modeline-code-actions-enable nil - lsp-modeline-diagnostics-enable nil - lsp-signature-auto-activate nil - lsp-enable-on-type-formatting nil - lsp-completion-provider :capf - lsp-diagnostics-provider :flycheck - lsp-headerline-breadcrumb-enable nil - lsp-enable-indentation nil - ;; Disable for huge projects - lsp-enable-file-watchers nil - lsp-idle-delay 0.5) - ;; Clangd configurations - (setq lsp-clients-clangd-args - '("--background-index" - "--clang-tidy" - "--completion-style=detailed" - "--header-insertion=never" - "--header-insertion-decorators" - "--pch-storage=memory" - "--log=error" - "--ranking-model=heuristics" - "--malloc-trim" - "--limit-results=500" - "--limit-references=2000"))) - -(use-package lsp-ui - :ensure t - :config - (setq lsp-ui-doc-enable t - lsp-ui-doc-delay 0.3 - lsp-ui-sideline-enable t - lsp-ui-sideline-show-code-actions t)) - -(use-package consult-lsp - :ensure t - :after (consult lsp-mode) - :commands - (consult-lsp-symbols - consult-lsp-diagnostics)) - -(with-eval-after-load 'lsp-mode - ;; Attach bash-language-server when open a shell scripts - (add-hook 'sh-mode-hook #'lsp) - - ;; Symbols - (global-set-key (kbd "C-c l s") #'consult-lsp-symbols) - - ;; Diagnostics - (global-set-key (kbd "C-c l e") #'consult-lsp-diagnostics) - - ;; Navigation (LSP core) - (global-set-key (kbd "C-c l d") #'lsp-find-definition) - (global-set-key (kbd "C-c l D") #'lsp-find-type-definition) - (global-set-key (kbd "C-c l i") #'lsp-find-implementation) - - ;; Actions - (global-set-key (kbd "C-c l a") #'lsp-execute-code-action) - (global-set-key (kbd "C-c l r") #'lsp-rename) - (global-set-key (kbd "C-c l f") #'lsp-format-buffer) - - ;; Control - (global-set-key (kbd "C-c l R") #'lsp-restart-workspace)) - -;;================================================================= -;; Go Language Support -;;================================================================= - -(use-package go-ts-mode - :ensure nil - :mode "\\.go\\'" - :hook - ((go-ts-mode . lsp-deferred) - (go-ts-mode . fscotto/go-format-on-save)) - :config - ;; Go project commands - ;; Modules - (define-key go-ts-mode-map (kbd "C-c m t") #'fscotto/go-mod-tidy) - (define-key go-ts-mode-map (kbd "C-c m d") #'fscotto/go-mod-download) - ;; Test - (define-key go-ts-mode-map (kbd "C-c t p") #'fscotto/go-test-package) - (define-key go-ts-mode-map (kbd "C-c t a") #'fscotto/go-test-module) - (define-key go-ts-mode-map (kbd "C-c t t") #'fscotto/go-test-current-test) - ;; Debug tests - (define-key go-ts-mode-map (kbd "C-c d t") #'dap-debug) - (define-key go-ts-mode-map (kbd "C-c d T") - (lambda () - (interactive) - (dap-debug - (dap--debug-configuration - "Go :: Debug test at point"))))) - -(use-package go-mod-ts-mode - :ensure nil - :mode - (("/go\\.mod\\'" . go-mod-ts-mode) - ("/go\\.sum\\'" . go-mod-ts-mode)) - :hook - ((go-mod-ts-mode . lsp-deferred) - ;; restart gopls only when go.mod/go.sum are saved (buffer-local) - (go-mod-ts-mode . (lambda () - (add-hook 'after-save-hook - (lambda () - (when (lsp-workspaces) - (lsp-restart-workspace))) - nil t))))) - -(with-eval-after-load 'project - (add-to-list 'project-vc-extra-root-markers "go.mod")) - -(with-eval-after-load 'lsp-mode - ;; gopls settings (single source of truth) - (lsp-register-custom-settings - '(("gopls.staticcheck" t) - ("gopls.gofumpt" t) - ;; ("gopls.experimentalWorkspaceModule" t) - ("gopls.expandWorkspaceToModule" t) - ("gopls.directoryFilters" ["-vendor"]) - ("gopls.analyses.unusedparams" t) - ("gopls.analyses.shadow" t) - ("gopls.analyses.nilness" t) - ("gopls.analyses.useany" t) - ("gopls.env" ((GO111MODULE . "on")))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Debugger Adapter Protocol ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(use-package dap-mode - :ensure t - :after lsp-mode - :hook (lsp-mode . dap-mode) - :init - ;; Enabling only some features - (setq dap-auto-configure-features '(sessions locals expressions repl)) - :config - (dap-mode 1) - (dap-ui-mode 1) - (dap-ui-controls-mode 1) - ;; Auto show breakpoints + REPL - (setq dap-ui-buffer-configurations - '( - ;; RIGHT SIDE — Debug data (like IntelliJ) - (dap-ui-locals . ((side . right) (slot . 1) (window-width . 0.30))) - (dap-ui-sessions . ((side . right) (slot . 2) (window-width . 0.30))) - (dap-ui-expressions . ((side . right) (slot . 3) (window-width . 0.30))) - ;; BOTTOM — Console / REPL - (dap-ui-repl . ((side . bottom) (slot . 1) (window-height . 0.25))) - (dap-ui-console . ((side . bottom) (slot . 2) (window-height . 0.25))))) - ;; (setq dap-ui-buffer-configurations - ;; '((dap-ui-repl . ((side . right) (slot . 1) (window-width . 0.33))) - ;; (dap-ui-locals . ((side . right) (slot . 2) (window-width . 0.33))) - ;; (dap-ui-breakpoints . ((side . left) (slot . 1) (window-width . 0.20))))) - ;; (setq dap-ui-controls-screen-position 'top) - ;; (setq dap-ui-repl-auto-focus nil) - ;; (setq dap-ui-stackframes-auto-expand t) - ;; ;; Loading DAP adapters - ;; For C/C++ - (require 'dap-cpptools) - ;; For Python - (require 'dap-python) - (setq dap-python-debugger 'debugpy)) - -(with-eval-after-load 'dap-mode - (global-set-key (kbd "C-c d d") #'dap-debug) - (global-set-key (kbd "C-c d b") #'dap-breakpoint-toggle) - (global-set-key (kbd "") #'dap-continue) - (global-set-key (kbd "") #'dap-next) - (global-set-key (kbd "") #'dap-step-in) - (global-set-key (kbd "") #'dap-step-out) - (global-set-key (kbd "C-c d r") #'dap-restart-frame) - (global-set-key (kbd "C-c d q") #'dap-disconnect)) - -(use-package dap-dlv-go - :after (dap-mode go-ts-mode)) - -(with-eval-after-load 'dap-dlv-go - ;; Debug all tests in module - (dap-register-debug-template - "Go :: Debug all tests" - (list :type "go" - :request "launch" - :name "Go :: Debug all tests" - :mode "test" - :program "${workspaceFolder}" - :cwd "${workspaceFolder}")) - - ;; Debug tests in current package - (dap-register-debug-template - "Go :: Debug package tests" - (list :type "go" - :request "launch" - :name "Go :: Debug package tests" - :mode "test" - :program "${fileDirname}" - :cwd "${fileDirname}")) - - ;; Debug test at point - (dap-register-debug-template - "Go :: Debug test at point" - (list :type "go" - :request "launch" - :name "Go :: Debug test at point" - :mode "test" - :program "${fileDirname}" - :cwd "${fileDirname}" - :args (list "-test.run" "${input:testName}")))) - -(add-hook 'dap-terminated-hook - (lambda (_) - (delete-other-windows))) - -;;;;;;;;;;;;;;;; -;; Formatters ;; -;;;;;;;;;;;;;;;; - -;; GOTCHA review this region -(use-package reformatter - :ensure t - :config - (reformatter-define shfmt-format - :program "shfmt" - :args '("-i" "2" "-ci"))) - -(add-hook 'bash-ts-mode-hook #'shfmt-format-on-save-mode) -(add-hook 'c-ts-mode-hook #'fscotto/disable-c-formatting) -(add-hook 'c-mode-hook #'fscotto/disable-c-formatting) +;; (load "~/.emacs.d/lisp/misc/pdf.el") +(load "~/.emacs.d/lisp/misc/epub.el") +(load "~/.emacs.d/lisp/misc/i3-config.el") (message "...user configuration loaded") diff --git a/emacs/.emacs.d/lisp/core/editor.el b/emacs/.emacs.d/lisp/core/editor.el new file mode 100644 index 0000000..4267799 --- /dev/null +++ b/emacs/.emacs.d/lisp/core/editor.el @@ -0,0 +1,23 @@ +;;; core-editor + +(setq standard-indent 4) +(setq tab-stop-list nil) +(setq indent-tabs-mode nil) + +;; C / C++ fallback style (Linux-like) +(setq c-default-style "linux" + c-basic-offset 4 + tab-width 8) + +(add-hook 'c-mode-common-hook + (lambda () + (setq indent-tabs-mode t))) + +;; Tree-sitter C/C++ +(setq c-ts-mode-indent-offset 4) +(setq c++-ts-mode-indent-offset 4) + +;; Setting variables +(setq vc-follow-symlinks 't) +(prefer-coding-system 'utf-8-unix) +(setq custom-file (null-device)) diff --git a/emacs/.emacs.d/lisp/core/keybindings.el b/emacs/.emacs.d/lisp/core/keybindings.el new file mode 100644 index 0000000..f7265e2 --- /dev/null +++ b/emacs/.emacs.d/lisp/core/keybindings.el @@ -0,0 +1,3 @@ +;; Legacy alias (keep muscle memory) +(global-set-key (kbd "C-c v g") #'magit-status) +(global-set-key (kbd "C-c g") #'fscotto/magit-dispatch) diff --git a/emacs/.emacs.d/lisp/core/packages.el b/emacs/.emacs.d/lisp/core/packages.el new file mode 100644 index 0000000..bd14974 --- /dev/null +++ b/emacs/.emacs.d/lisp/core/packages.el @@ -0,0 +1,15 @@ +;; core-packages.el -*- lexical-binding: t; -*- +(require 'use-package) + +(use-package package + :config + ;; Setting repo priorities + (setq package-archive-priorities + '(("melpa-stable" . 2) + ("MELPA" . 1) + ("gnu" . 0))) + ;; Setting repo URL + (setq package-archives + '(("melpa-stable" . "https://stable.melpa.org/packages/") + ("MELPA" . "https://melpa.org/packages/") + ("gnu" . "https://elpa.gnu.org/packages/")))) diff --git a/emacs/.emacs.d/lisp/core/performance.el b/emacs/.emacs.d/lisp/core/performance.el new file mode 100644 index 0000000..eb2b796 --- /dev/null +++ b/emacs/.emacs.d/lisp/core/performance.el @@ -0,0 +1,22 @@ +;;; core-performance.el -*- + +;; --- Startup speed tweaks ---------------------------------------------------- +;; Temporarily increase GC threshold during init +(defvar fscotto/gc-cons-threshold-orig gc-cons-threshold) +(setq gc-cons-threshold (* 50 1000 1000)) ;; 50MB for init + +;; Speedup file-name-handler during init +(defvar fscotto/file-name-handler-alist-orig file-name-handler-alist) +(setq file-name-handler-alist nil) + +;; Restore after init +(add-hook 'emacs-startup-hook + (lambda () + (setq gc-cons-threshold fscotto/gc-cons-threshold-orig) + (setq file-name-handler-alist fscotto/file-name-handler-alist-orig) + (garbage-collect))) + +;; LSP responsiveness +(setq read-process-output-max (* 1024 1024)) ;; 1MB, utile per lsp-mode +(setq lsp-idle-delay 0.5) ;; meno ritardo prima che LSP aggiorni info +(setq inhibit-compacting-font-caches t) diff --git a/emacs/.emacs.d/lisp/core/ui.el b/emacs/.emacs.d/lisp/core/ui.el new file mode 100644 index 0000000..680202f --- /dev/null +++ b/emacs/.emacs.d/lisp/core/ui.el @@ -0,0 +1,67 @@ +;;;; core-ui.el -*- + +;; Load default theme +(load-theme 'wombat) + +;; Setting default font +(set-frame-font "Iosevka Nerd Font 14" nil t) + +;; Remove toolbar +(tool-bar-mode -1) + +;; Remove menu +(menu-bar-mode -1) + +;; Disable startup screen +(setq inhibit-startup-screen t) + +;; Disable splash screen +(setq inhibit-splash-screen t) + +;; Start all frames maximized +(add-to-list 'default-frame-alist '(fullscreen . maximized)) + +;; Remove scrollbar +(scroll-bar-mode -1) + +;; Simple 'y' for 'yes' and 'n' for 'no' +(defalias 'yes-or-no-p 'y-or-n-p) + +;; Set global value for paragraph witdh +(setq-default fill-column 120) + +;; Stop Emacs from losing informations +(setq undo-limit 8000000) +(setq undo-strong-limit 12000000) + +;; Smooth scroll +(setq scroll-step 3) +(setq ring-bell-function 'ignore) + +;; Add column number in the status line +(column-number-mode) + +;; View clock in the status line +(display-time) + +;; Enable line numbers in the programming mode only +(add-hook 'prog-mode-hook 'display-line-numbers-mode) + +;; Enable line numbers in the configuration mode only +(add-hook 'conf-mode-hook 'display-line-numbers-mode) + +;; Setting default directory for Org files +(setq org-directory "~/Remotes/pCloud/Org") + +(use-package ivy + :ensure t + :config + (ivy-mode 1)) + +(use-package consult + :ensure t + :defer t) + +(use-package ibuffer + :ensure t + :bind (:map global-map ("C-x C-b" . ibuffer))) diff --git a/emacs/.emacs.d/lisp/lang/c.el b/emacs/.emacs.d/lisp/lang/c.el new file mode 100644 index 0000000..78fae28 --- /dev/null +++ b/emacs/.emacs.d/lisp/lang/c.el @@ -0,0 +1,2 @@ +(add-hook 'c-ts-mode-hook #'fscotto/disable-c-formatting) +(add-hook 'c-mode-hook #'fscotto/disable-c-formatting) diff --git a/emacs/.emacs.d/lisp/lang/golang.el b/emacs/.emacs.d/lisp/lang/golang.el new file mode 100644 index 0000000..0b85f32 --- /dev/null +++ b/emacs/.emacs.d/lisp/lang/golang.el @@ -0,0 +1,98 @@ +;;================================================================= +;; Go Language Support +;;================================================================= + +(use-package go-ts-mode + :ensure nil + :mode "\\.go\\'" + :hook + ((go-ts-mode . lsp-deferred) + (go-ts-mode . fscotto/go-format-on-save)) + :config + ;; Go project commands + ;; Modules + (define-key go-ts-mode-map (kbd "C-c m t") #'fscotto/go-mod-tidy) + (define-key go-ts-mode-map (kbd "C-c m d") #'fscotto/go-mod-download) + ;; Test + (define-key go-ts-mode-map (kbd "C-c t p") #'fscotto/go-test-package) + (define-key go-ts-mode-map (kbd "C-c t a") #'fscotto/go-test-module) + (define-key go-ts-mode-map (kbd "C-c t t") #'fscotto/go-test-current-test) + ;; Debug tests + (define-key go-ts-mode-map (kbd "C-c d t") #'dap-debug) + (define-key go-ts-mode-map (kbd "C-c d T") + (lambda () + (interactive) + (dap-debug + (dap--debug-configuration + "Go :: Debug test at point"))))) + +(use-package go-mod-ts-mode + :ensure nil + :mode + (("/go\\.mod\\'" . go-mod-ts-mode) + ("/go\\.sum\\'" . go-mod-ts-mode)) + :hook + ((go-mod-ts-mode . lsp-deferred) + ;; restart gopls only when go.mod/go.sum are saved (buffer-local) + (go-mod-ts-mode . (lambda () + (add-hook 'after-save-hook + (lambda () + (when (lsp-workspaces) + (lsp-restart-workspace))) + nil t))))) + +(with-eval-after-load 'project + (add-to-list 'project-vc-extra-root-markers "go.mod")) + +(with-eval-after-load 'lsp-mode + ;; gopls settings (single source of truth) + (lsp-register-custom-settings + '(("gopls.staticcheck" t) + ("gopls.gofumpt" t) + ;; ("gopls.experimentalWorkspaceModule" t) + ("gopls.expandWorkspaceToModule" t) + ("gopls.directoryFilters" ["-vendor"]) + ("gopls.analyses.unusedparams" t) + ("gopls.analyses.shadow" t) + ("gopls.analyses.nilness" t) + ("gopls.analyses.useany" t) + ("gopls.env" ((GO111MODULE . "on")))))) + +(use-package dap-dlv-go + :after (dap-mode go-ts-mode)) + +(with-eval-after-load 'dap-dlv-go + ;; Debug all tests in module + (dap-register-debug-template + "Go :: Debug all tests" + (list :type "go" + :request "launch" + :name "Go :: Debug all tests" + :mode "test" + :program "${workspaceFolder}" + :cwd "${workspaceFolder}")) + + ;; Debug tests in current package + (dap-register-debug-template + "Go :: Debug package tests" + (list :type "go" + :request "launch" + :name "Go :: Debug package tests" + :mode "test" + :program "${fileDirname}" + :cwd "${fileDirname}")) + + ;; Debug test at point + (dap-register-debug-template + "Go :: Debug test at point" + (list :type "go" + :request "launch" + :name "Go :: Debug test at point" + :mode "test" + :program "${fileDirname}" + :cwd "${fileDirname}" + :args (list "-test.run" "${input:testName}")))) + +(add-hook 'dap-terminated-hook + (lambda (_) + (delete-other-windows))) diff --git a/emacs/.emacs.d/lisp/lang/shell.el b/emacs/.emacs.d/lisp/lang/shell.el new file mode 100644 index 0000000..592e703 --- /dev/null +++ b/emacs/.emacs.d/lisp/lang/shell.el @@ -0,0 +1,8 @@ +(use-package reformatter + :ensure t + :config + (reformatter-define shfmt-format + :program "shfmt" + :args '("-i" "2" "-ci"))) + +(add-hook 'bash-ts-mode-hook #'shfmt-format-on-save-mode) diff --git a/emacs/.emacs.d/lisp/misc/custom-functions.el b/emacs/.emacs.d/lisp/misc/custom-functions.el new file mode 100644 index 0000000..0080e00 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/custom-functions.el @@ -0,0 +1,89 @@ +;;functions to support syncing .elfeed between machines +;;makes sure elfeed reads index from disk before launching +(defun fscotto/elfeed-load-db-and-open () + "Wrapper to load the elfeed db from disk before opening URL https://pragmaticemacs.wordpress.com/2016/08/17/read-your-rss-feeds-in-emacs-with-elfeed/ + Created: 2016-08-17 + Updated: 2025-06-13" + (interactive) + (elfeed) + (elfeed-db-load) + ;; (elfeed-search-update--force) + (elfeed-update) + (elfeed-db-save)) + +(defun fscotto/project-root () + "Return projectile project root or fallback to default-directory." + (if (featurep 'projectile) + (or (projectile-project-root) default-directory) + default-directory)) + +(defun fscotto/project-vterm () + "Open vterm in project root." + (interactive) + (let ((default-directory (fscotto/project-root))) + (vterm))) + +(defun fscotto/project-magit-status () + "Open magit-status in project root." + (interactive) + (let ((default-directory (fscotto/project-root))) + (magit-status))) + +(defun fscotto/magit-dispatch () + "Load Magit if necessary and open magit-dispatch." + (interactive) + (require 'magit) + (call-interactively #'magit-dispatch)) + +(defun fscotto/disable-c-formatting () + (setq-local lsp-enable-on-type-formatting nil)) + +;; Golang development support functions +(defun fscotto/go-format-on-save () + "Format Go buffers on save using gofmt." + (add-hook 'before-save-hook #'lsp-format-buffer nil t)) + +(defun fscotto/go-mod-tidy () + "Esegue go mod tidy nella root del progetto." + (interactive) + (let ((default-directory (project-root (project-current t)))) + (compile "go mod tidy"))) + +(defun fscotto/go-mod-download () + "Scarica i moduli Go." + (interactive) + (let ((default-directory (project-root (project-current t)))) + (compile "go mod download"))) + +(defun fscotto/go-mod-after-save () + (when (and (eq major-mode 'go-mod-ts-mode) + (lsp-workspaces)) + (lsp-restart-workspace))) + +(defun fscotto/go-test-package () + "Run `go test` in the current package." + (interactive) + (let ((default-directory (project-root (project-current t)))) + (compile "go test"))) + +(defun fscotto/go-test-module () + "Run `go test ./...` in the current Go module." + (interactive) + (let ((default-directory (project-root (project-current t)))) + (compile "go test ./..."))) + +(defun fscotto/go-test-current-test () + "Run `go test -run` for the test at point." + (interactive) + (let* ((test-name (thing-at-point 'symbol t)) + (default-directory (project-root (project-current t)))) + (unless test-name + (user-error "No test name at point")) + (compile (format "go test -run '^%s$'" test-name)))) + +(defun fscotto/go-test-at-point () + "Return Go test name at point." + (let ((sym (thing-at-point 'symbol t))) + (unless (and sym (string-prefix-p "Test" sym)) + (user-error "No Go test at point")) + sym)) diff --git a/emacs/.emacs.d/lisp/misc/doom-modeline.el b/emacs/.emacs.d/lisp/misc/doom-modeline.el new file mode 100644 index 0000000..6c3ef62 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/doom-modeline.el @@ -0,0 +1,9 @@ +;;; doom-modeline.el -*- + +(use-package doom-modeline + :ensure t + :config + (setq doom-modeline-height 25 + doom-modeline-bar-width 3 + doom-modeline-project-detection 'projectile) + :init (doom-modeline-mode 1)) diff --git a/emacs/.emacs.d/lisp/misc/email.el b/emacs/.emacs.d/lisp/misc/email.el new file mode 100644 index 0000000..1e6a167 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/email.el @@ -0,0 +1,53 @@ +;;; email.el -*- + +(use-package mu4e + :ensure nil + ;; :load-path "/usr/share/emacs/site-lisp/mu4e/" + :defer 20 ; Wait until 20 seconds after startup + :bind (:map global-map ("C-c o m" . mu4e)) + :config + + ;; This is set to 't' to avoid mail syncing issues when using mbsync + (setq mu4e-change-filenames-when-moving t) + + ;; Refresh mail using isync every 10 minutes + (setq mu4e-update-interval (* 10 60)) + (setq mu4e-get-mail-command "~/.emacs.d/scripts/email_sync.sh") + (setq mu4e-maildir "~/Maildir") + + ;; Configure email accounts + (setq mu4e-contexts + (list + ;; Protonmail Account + (make-mu4e-context + :name "Protonmail" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/ProtonMailAccount" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "fscottodisantolo@protonmail.com") + (user-full-name . "Fabio Scotto di Santolo") + (mu4e-drafts-folder . "/ProtonMailAccount/Drafts") + (mu4e-sent-folder . "/ProtonMailAccount/Sent") + (mu4e-refile-folder . "/ProtonMailAccount/All Mail") + (mu4e-trash-folder . "/ProtonMailAccount/Trash"))) + + ;; iCloud Account + (make-mu4e-context + :name "iCloud Mail" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/iCloudAccount" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "fscottodisantolo@icloud.com") + (user-full-name . "Fabio Scotto di Santolo") + (mu4e-drafts-folder . "/iCloudAccount/Drafts") + (mu4e-sent-folder . "/iCloudAccount/Sent Messages") + (mu4e-refile-folder . "/iCloudAccount/INBOX") + (mu4e-trash-folder . "/iCloudAccount/Junk"))))) + + (setq sendmail-program "/usr/bin/msmtp" + send-mail-function 'sendmail-send-it + message-sendmail-f-is-evil t + message-sendmail-extra-arguments '("--read-envelope-from") + message-send-mail-function 'message-send-mail-with-sendmail)) diff --git a/emacs/.emacs.d/lisp/misc/epub.el b/emacs/.emacs.d/lisp/misc/epub.el new file mode 100644 index 0000000..edbc0e0 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/epub.el @@ -0,0 +1,3 @@ +(use-package nov + :ensure t + :mode ("\\.epub\\'" . nov-mode)) diff --git a/emacs/.emacs.d/lisp/misc/i3-config.el b/emacs/.emacs.d/lisp/misc/i3-config.el new file mode 100644 index 0000000..fc3b569 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/i3-config.el @@ -0,0 +1,2 @@ +(use-package i3wm-config-mode + :ensure t) diff --git a/emacs/.emacs.d/lisp/misc/pdf.el b/emacs/.emacs.d/lisp/misc/pdf.el new file mode 100644 index 0000000..ccd6311 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/pdf.el @@ -0,0 +1,4 @@ +(use-package pdf-tools + :ensure t + :config + (pdf-tools-install)) diff --git a/emacs/.emacs.d/lisp/misc/rss.el b/emacs/.emacs.d/lisp/misc/rss.el new file mode 100644 index 0000000..03786c1 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/rss.el @@ -0,0 +1,39 @@ +;;; rss.el -*- + +(use-package elfeed + :ensure t + :custom + (elfeed-enclosure-default-dir "~/Downloads/") + (elfeed-search-remain-on-entry t) + (elfeed-search-title-max-width 100) + (elfeed-search-title-min-width 30) + (elfeed-search-trailing-width 25) + (elfeed-show-truncate-long-urls t) + (elfeed-sort-order 'descending) + (elfeed-search-filter "+unread") + :bind + ("C-c o f" . fscotto/elfeed-load-db-and-open) + (:map elfeed-search-mode-map + ("w" . elfeed-search-yank) + ("R" . elfeed-update) + ("q" . elfeed-kill-buffer)) + (:map elfeed-show-mode-map + ("S" . elfeed-show-new-live-search) ; moved to free up 's' + ("c" . (lambda () (interactive) (org-capture nil "capture"))) + ("e" . email-elfeed-entry) + ("f" . elfeed-show-fetch-full-text) + ("w" . elfeed-show-yank)) + :hook + (elfeed-show-mode . visual-line-mode)) + +(use-package elfeed-org + :ensure t + :after elfeed + :custom + ;; Optionally specify a number of files containing elfeed + ;; configuration. If not set then the location below is used. + ;; Note: The customize interface is also supported. + (rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org"))) + +(with-eval-after-load 'elfeed + (elfeed-org)) diff --git a/emacs/.emacs.d/lisp/misc/terminal.el b/emacs/.emacs.d/lisp/misc/terminal.el new file mode 100644 index 0000000..a3d5b27 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/terminal.el @@ -0,0 +1,7 @@ +;;; terminal.el -*- + +(use-package vterm + :ensure t + :bind (:map global-map + ("C-c o T" . vterm) + ("C-c C-t" . vterm-copy-mode))) diff --git a/emacs/.emacs.d/lisp/misc/vcs.el b/emacs/.emacs.d/lisp/misc/vcs.el new file mode 100644 index 0000000..fb58113 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/vcs.el @@ -0,0 +1,12 @@ +(use-package magit + :ensure t + :commands (magit-status magit-log) + :init + ;; Entry point principale + (setq magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1) + :config + ;; Performance & UX + (setq magit-refresh-status-buffer nil) + (setq magit-repository-directories + '(("~/Projects" . 2) + ("~/Work" . 2)))) diff --git a/emacs/.emacs.d/lisp/misc/which-key.el b/emacs/.emacs.d/lisp/misc/which-key.el new file mode 100644 index 0000000..49706c0 --- /dev/null +++ b/emacs/.emacs.d/lisp/misc/which-key.el @@ -0,0 +1,161 @@ +;;; which-key.el -*- + +(use-package which-key + :ensure t + :defer 1 + :config + (which-key-mode) + (setq which-key-idle-delay 0.45 + which-key-idle-secondary-delay 0.05 + which-key-max-display-columns 3 + which-key-max-description-length 45)) + +(with-eval-after-load 'which-key + ;; -------------------------------------------------------------------------- + ;; Top-level prefixes + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "C-c !" "Analyze" + "C-c o" "Open" + "C-c v" "Version control" + "C-c l" "LSP" + "C-c t" "TODO / Annotations" + "C-c b" "Buffers" + "C-c p" "Project" + "C-c d" "Debug" + "C-c g" "Git" + "C-c e" "Email / Elfeed") + + ;; -------------------------------------------------------------------------- + ;; Open (C-c o …) + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "C-c o f" "RSS (Elfeed)" + "C-c o m" "mu4e (Email Client)" + "C-c o T" "Terminal (vterm)") + + ;; -------------------------------------------------------------------------- + ;; Version control + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "C-c v g" "Magit status (legacy)") + + (which-key-add-key-based-replacements + ;; Core + "C-c g g" "Status" + "C-c g s" "Status" + ;; "C-c g b" "Branch" + ;; "C-c g c" "Commit" + "C-c g p" "Push / Pull" + "C-c g f" "Fetch" + "C-c g l" "Log" + "C-c g S" "Stash" + + ;; Files + "C-c g d" "Diff" + "C-c g D" "Diff (cached)" + "C-c g B" "Blame" + + ;; Rebase / Reset + "C-c g r" "Rebase" + "C-c g R" "Reset" + + ;; Remote + "C-c g y" "Show refs" + "C-c g o" "Browse remote") + + ;; -------------------------------------------------------------------------- + ;; Buffers + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "C-x C-b" "ibuffer") + + ;; -------------------------------------------------------------------------- + ;; TODO / hl-todo + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "C-t" "hl-todo" + "C-t p" "Previous TODO" + "C-t n" "Next TODO" + "C-t o" "Occur (list)" + "C-t i" "Insert TODO") + + ;; -------------------------------------------------------------------------- + ;; LSP (C-c l …) + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + ;; Navigation + "C-c l d" "Go to definition" + "C-c l D" "Go to type definition" + "C-c l i" "Go to implementation" + + ;; Symbols / diagnostics + "C-c l s" "Workspace symbols" + "C-c l e" "Diagnostics" + + ;; Actions + "C-c l a" "Code actions" + "C-c l r" "Rename symbol" + "C-c l f" "Format buffer" + + ;; Control + "C-c l R" "Restart workspace") + + ;; -------------------------------------------------------------------------- + ;; Elfeed modes + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "w" "Yank" + "R" "Update feeds" + "q" "Quit") + + ;; -------------------------------------------------------------------------- + ;; Debug / DAP + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "C-c d d" "Start debug session" + "C-c d b" "Toggle breakpoint") + ;; "C-c d c" "Continue" + ;; "C-c d n" "Next" + ;; "C-c d i" "Step in" + ;; "C-c d o" "Step out") + + ;; -------------------------------------------------------------------------- + ;; Project (future) + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + ;; Core + "C-c p p" "Switch project" + "C-c p f" "Find file" + "C-c p d" "Find directory" + "C-c p b" "Switch buffer" + "C-c p k" "Kill project buffers" + "C-c p r" "Recent files" + + ;; Search + "C-c p s" "Search" + "C-c p s g" "Grep (ripgrep)" + "C-c p s r" "Replace in project" + + ;; Actions + "C-c p c" "Compile" + "C-c p t" "Test" + "C-c p v" "Open term in project" + "C-c p e" "Edit project config" + "C-c p g" "Project Git status" + "C-c p x" "Open Terminal" + "C-c p 4" "Other Window" + "C-c p 5" "Other Frame" + "C-c p x 4" "Other Window" + + ;; Cache + "C-c p i" "Invalidate cache") + + ;; -------------------------------------------------------------------------- + ;; Cleanup annoying +prefix + ;; -------------------------------------------------------------------------- + (which-key-add-key-based-replacements + "+prefix" "Prefix" + "+lsp" "LSP" + "+debug" "Debug" + "+project" "Project")) diff --git a/emacs/.emacs.d/lisp/tools/completion.el b/emacs/.emacs.d/lisp/tools/completion.el new file mode 100644 index 0000000..781abe9 --- /dev/null +++ b/emacs/.emacs.d/lisp/tools/completion.el @@ -0,0 +1,50 @@ +;; Highlight keywords to remember the activity when coding. +(use-package hl-todo + :ensure t + :commands (global-hl-todo-mode) + :init (global-hl-todo-mode)) + +(setq hl-todo-keyword-faces + '(("TODO" . "#94e2d5") + ("FIXME" . "#f38ba8") + ("DEBUG" . "#cba6f7") + ("GOTCHA" . "#eba0ac") + ("STUB" . "#89b4fa"))) + +(keymap-set hl-todo-mode-map "C-t p" #'hl-todo-previous) +(keymap-set hl-todo-mode-map "C-t n" #'hl-todo-next) +(keymap-set hl-todo-mode-map "C-t o" #'hl-todo-occur) +(keymap-set hl-todo-mode-map "C-t i" #'hl-todo-insert) + +(use-package ibuffer-tramp + :ensure t) + +(use-package ibuffer-vc + :ensure t) + +(use-package ibuffer-projectile + :ensure t) + +(add-hook 'ibuffer-mode-hook + (lambda () + (ibuffer-projectile-set-filter-groups))) + +;; Add autocomplete feature to Emacs +(use-package company + :ensure t + :custom + (company-tooltip-align-annotations 't) + (company-minimum-prefix-length 1) + (company-idle-delay 0.1) + :hook (prog-mode . company-mode)) + +(with-eval-after-load 'company + (add-hook 'bash-ts-mode-hook 'company-mode)) + +;; Static analysis for code base +(use-package flycheck + :ensure t + :hook (prog-mode . flycheck-mode)) + +(with-eval-after-load 'flycheck + (add-hook 'bash-ts-mode-hook 'flycheck-mode)) diff --git a/emacs/.emacs.d/lisp/tools/dap.el b/emacs/.emacs.d/lisp/tools/dap.el new file mode 100644 index 0000000..5ff4b57 --- /dev/null +++ b/emacs/.emacs.d/lisp/tools/dap.el @@ -0,0 +1,36 @@ +(use-package dap-mode + :ensure t + :after lsp-mode + :hook (lsp-mode . dap-mode) + :init + ;; Enabling only some features + (setq dap-auto-configure-features '(sessions locals expressions repl)) + :config + (dap-mode 1) + (dap-ui-mode 1) + (dap-ui-controls-mode 1) + ;; Auto show breakpoints + REPL + (setq dap-ui-buffer-configurations + '(;; RIGHT SIDE — Debug data (like IntelliJ) + (dap-ui-locals . ((side . right) (slot . 1) (window-width . 0.30))) + (dap-ui-sessions . ((side . right) (slot . 2) (window-width . 0.30))) + (dap-ui-expressions . ((side . right) (slot . 3) (window-width . 0.30))) + ;; BOTTOM — Console / REPL + (dap-ui-repl . ((side . bottom) (slot . 1) (window-height . 0.25))) + (dap-ui-console . ((side . bottom) (slot . 2) (window-height . 0.25))))) + ;; Loading DAP adapters + ;; For C/C++ + (require 'dap-cpptools) + ;; For Python + (require 'dap-python) + (setq dap-python-debugger 'debugpy)) + +(with-eval-after-load 'dap-mode + (global-set-key (kbd "C-c d d") #'dap-debug) + (global-set-key (kbd "C-c d b") #'dap-breakpoint-toggle) + (global-set-key (kbd "") #'dap-continue) + (global-set-key (kbd "") #'dap-next) + (global-set-key (kbd "") #'dap-step-in) + (global-set-key (kbd "") #'dap-step-out) + (global-set-key (kbd "C-c d r") #'dap-restart-frame) + (global-set-key (kbd "C-c d q") #'dap-disconnect)) diff --git a/emacs/.emacs.d/lisp/tools/lsp.el b/emacs/.emacs.d/lisp/tools/lsp.el new file mode 100644 index 0000000..b623b5c --- /dev/null +++ b/emacs/.emacs.d/lisp/tools/lsp.el @@ -0,0 +1,102 @@ +(use-package treesit + :ensure nil + :config + (setq treesit-font-lock-level 4) + (setq treesit-auto-install t) + (setq major-mode-remap-alist + '((c-mode . c-ts-mode) + (c++-mode . c++-ts-mode) + (go-mode . go-ts-mode) + (go-mod-mode . go-mod-ts-mode) + (python-mode . python-ts-mode) + (sh-mode . bash-ts-mode))) + (setq treesit-language-source-alist + '((c "https://github.com/tree-sitter/tree-sitter-c") + (cpp "https://github.com/tree-sitter/tree-sitter-cpp") + (python "https://github.com/tree-sitter/tree-sitter-python") + (bash "https://github.com/tree-sitter/tree-sitter-bash") + (go "https://github.com/tree-sitter/tree-sitter-go") + (gomod "https://github.com/camdencheek/tree-sitter-go-mod")))) + +(use-package lsp-mode + :ensure t + :commands (lsp lsp-deferred) + :init + ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") + (setq lsp-keymap-prefix "C-c l") + :hook + ((c-mode + c-ts-mode + c++-mode + c++-ts-mode + python-mode + python-ts-mode + sh-mode + bash-ts-mode) . lsp-deferred) + :config + ;; Performance + (setq lsp-enable-symbol-highlighting t + lsp-enable-snippet t + lsp-log-io nil + lsp-modeline-code-actions-enable nil + lsp-modeline-diagnostics-enable nil + lsp-signature-auto-activate nil + lsp-enable-on-type-formatting nil + lsp-completion-provider :capf + lsp-diagnostics-provider :flycheck + lsp-headerline-breadcrumb-enable nil + lsp-enable-indentation nil + ;; Disable for huge projects + lsp-enable-file-watchers nil + lsp-idle-delay 0.5) + ;; Clangd configurations + (setq lsp-clients-clangd-args + '("--background-index" + "--clang-tidy" + "--completion-style=detailed" + "--header-insertion=never" + "--header-insertion-decorators" + "--pch-storage=memory" + "--log=error" + "--ranking-model=heuristics" + "--malloc-trim" + "--limit-results=500" + "--limit-references=2000"))) + +(use-package lsp-ui + :ensure t + :config + (setq lsp-ui-doc-enable t + lsp-ui-doc-delay 0.3 + lsp-ui-sideline-enable t + lsp-ui-sideline-show-code-actions t)) + +(use-package consult-lsp + :ensure t + :after (consult lsp-mode) + :commands + (consult-lsp-symbols + consult-lsp-diagnostics)) + +(with-eval-after-load 'lsp-mode + ;; Attach bash-language-server when open a shell scripts + (add-hook 'sh-mode-hook #'lsp) + + ;; Symbols + (global-set-key (kbd "C-c l s") #'consult-lsp-symbols) + + ;; Diagnostics + (global-set-key (kbd "C-c l e") #'consult-lsp-diagnostics) + + ;; Navigation (LSP core) + (global-set-key (kbd "C-c l d") #'lsp-find-definition) + (global-set-key (kbd "C-c l D") #'lsp-find-type-definition) + (global-set-key (kbd "C-c l i") #'lsp-find-implementation) + + ;; Actions + (global-set-key (kbd "C-c l a") #'lsp-execute-code-action) + (global-set-key (kbd "C-c l r") #'lsp-rename) + (global-set-key (kbd "C-c l f") #'lsp-format-buffer) + + ;; Control + (global-set-key (kbd "C-c l R") #'lsp-restart-workspace)) diff --git a/emacs/.emacs.d/lisp/tools/project.el b/emacs/.emacs.d/lisp/tools/project.el new file mode 100644 index 0000000..a9864d3 --- /dev/null +++ b/emacs/.emacs.d/lisp/tools/project.el @@ -0,0 +1,29 @@ +(use-package projectile + :ensure t + :defer 1 + :init + ;; Root detection + (setq projectile-project-search-path '("~/Projects" "~/Work")) + (setq projectile-completion-system 'ivy) + :config + ;; Performance + (setq projectile-enable-caching t) + (setq projectile-indexing-method 'hybrid) + (setq projectile-sort-order 'recently-active) + ;; Projectile as single source of truth + (setq projectile-switch-project-action #'projectile-dired) + ;; Use ripgrep if available + (when (executable-find "rg") + (setq projectile-generic-command "rg --files --hidden --glob '!.git'")) + ;; Enable globally + (projectile-mode 1)) + +;; Projectile keybindings (Doom-style) +(with-eval-after-load 'projectile + (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)) + +(with-eval-after-load 'projectile + (define-key projectile-command-map (kbd "v") #'fscotto/project-vterm)) + +(with-eval-after-load 'projectile + (define-key projectile-command-map (kbd "g") #'fscotto/project-magit-status))