1

Тема: Emacs як IDE для Java

Попередні кроки щодо встановлення Emacs, його файлу конфігурації та менеджера пакунків
можна поглянути тут (лише пункти 1-4): https://replace.org.ua/topic/15994/
Далі встановлюєте наступні програми з менеджера пакунків Emacs:
doom-themes - величезний набір різних тем оформлення
sideline - програма для показу помилок у відповідному рядку
sideline-flycheck - доповнення для роботи з flycheck
company — основа для автодоповнення тексту (потребує певного рушія)
flycheck — перевірка синтаксису, знаходження помилок «на льоту»
flycheck-projectile
flycheck-eglot
helm — дуже зручна програма автодоповнення будь-яких команд Emacs і не тільки
helm-company
helm-flycheck
helm-projectile
helm-xref
projectile — керування проєктами
rainbow-delimiters — кольорове виділення дужок різного рівня
treemacs — менеджер файлів
treemacs-projectile
which-key — програма, що показує наявні комбінації клавіш та інформацію по ним
xclip — копіювання до clipboard та з нього
yasnippet — корисні сніппети автодоповнення, як от автоматичне додавання дужок до функцій
yasnippet-snippets
quickrun - дуже корисний додаток для запуску програм,
підтримує різні мови програмування, тому до однієї клавіші
можна прив'язати компіляцію і запуск для кількох різних мов програмування,
цей додаток розпізнає якою мовою ви програмуєте і запускає відповідні налаштуванння
eglot-java - підтримка Language Server Protocol для Java
eglot - загальна підтримка LSP, окремо встановлювати не треба, він вбудований в Emacs

Тепер додаєте ось ці налаштування до вашого файлу конфігурації Emacs:

;;Підсвічування пар дужок відповідним кольором
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)

;;Налаштування для відкривання останнього робочого файлу
(recentf-mode 1)
(setq recentf-max-menu-items 5
      recentf-max-saved-items 5
      recentf-exclude '("~/.emacs.d/.cache/treemacs-persist")
)

;;Автодоповнення дужок
(electric-pair-mode 1)
(setq electric-pair-preserve-balance nil)

;;Company — програма, що є основою для автодоповнення
(add-hook 'after-init-hook 'global-company-mode)

;;Показати нумерацію рядків
(add-hook 'prog-mode-hook 'display-line-numbers-mode)

;;Налаштування швидкого автодоповнення
(setq gc-cons-threshold (* 100 1024 1024)
      read-process-output-max (* 1024 1024)
      company-idle-delay 0.0
      company-minimum-prefix-length 1
      lsp-idle-delay 0.1
      )

;;Налаштування автопрокручування вікна компіляції до першої помилки
(setq compilation-scroll-output 'first-error)

;;Налаштування розміру табуляції
(setq-default tab-width 4)

;;Налаштування максимальної кількості символів у рядку
(setq-default fill-column 80)

;;Налаштування використання готових сніппетів
(require 'yasnippet)
(yas-global-mode 1)

;;Налаштування автоматичного копіювання до clipboard
(xclip-mode 1)

;;Налаштування eglot для Java
(use-package eglot
  :ensure t
  :hook (
        (prog-mode . eglot-ensure)
        )
  )

;;Налаштування eglot-java
(require 'eglot-java)
(eglot-java-mode 1)

;;Налаштування flycheck
(use-package flycheck-eglot
  :ensure t
  :after (flycheck eglot)
  :custom (flycheck-eglot-exclusive nil) ;;Задіяно всі чеккери Eglot+flycheck
  :config
  (global-flycheck-eglot-mode 1))


;;Налаштування sideline показ помилок в рядку
(use-package sideline
  :init
  (setq sideline-backends-left-skip-current-line t   ; don't display on current line (left)
        sideline-backends-right-skip-current-line t  ; don't display on current line (right)
        sideline-order-left 'down                    ; or 'up
        sideline-order-right 'up                     ; or 'down
        sideline-format-left "%s   "                 ; format for left aligment
        sideline-format-right "   %s"                ; format for right aligment
        sideline-priority 100                        ; overlays' priority
        sideline-display-backend-name t)            ; display the backend name
        )


(use-package sideline
  :hook (flycheck-mode . sideline-mode)
  :init
  (setq sideline-backends-right '(sideline-flycheck)))

(use-package sideline-flycheck
  :hook (flycheck-mode . sideline-flycheck-setup))

;; Налаштування hydra
(use-package hydra)

;;Налаштування doom-themes
(use-package doom-themes
  :ensure t
  :config
  ;; Global settings (defaults)
  (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-one t)

  ;;Corrects (and improves) org-mode's native fontification.
  (doom-themes-org-config)
  )

;;Налаштування treemacs
(use-package treemacs
  :ensure t
  :defer t
  :config
  (progn
    (setq treemacs-show-hidden-files nil)

    (treemacs-follow-mode t)
    (treemacs-filewatch-mode t)
    (treemacs-fringe-indicator-mode 'always)

    (treemacs-hide-gitignored-files-mode nil))
  :bind
  (:map global-map
        ("M-0"       . treemacs-select-window)
        ("C-x t 1"   . treemacs-delete-other-windows)
        ("C-x t t"   . treemacs)
        ("C-x t d"   . treemacs-select-directory)
        ("C-x t B"   . treemacs-bookmark)
        ("C-x t C-t" . treemacs-find-file)
        ("C-x t M-t" . treemacs-find-tag)))

(use-package treemacs-projectile
  :after (treemacs projectile)
  :ensure t)


;;Перевірка синтаксису flycheck
(use-package flycheck
  :ensure t
  :init
  (global-flycheck-mode)
  :config
    ;; Показувати індикатори помилок в крайньому лівому стовпчику
    (setq flycheck-indication-mode 'left-margin
          ;; Затримка показу помилок
          flycheck-display-errors-delay 0.1
          ;; Перевірка згідно певного стандарту мови С++
          flycheck-gcc-language-standard "c++20"


    )
    ;; Налаштування ширини стовпчика з індикаторами помилок
    (defun my/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))
    ;; Поява індикаторів щоразу при відкритті нового буфера
    (add-hook 'flycheck-mode-hook #'my/set-flycheck-margins)
    ;; Додавання перевірки синтаксису clang в чергу після cppcheck
    (flycheck-add-next-checker 'c/c++-cppcheck 'c/c++-clang)

  )

;;Налаштування керування проєктами Projectile
(projectile-mode +1)
;; Recommended keymap prefix on Windows/Linux
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)

;;Налаштування автодоповнення команд which-key
(which-key-mode)
(add-hook 'java-mode-hook 'lsp)

;;Автоформатування файлу перед збереженням
(add-hook 'before-save-hook 'eglot-format-buffer)

;;Налаштування програми автодоповнення команд Helm
(helm-mode)
(require 'helm-xref)
(define-key global-map [remap find-file] #'helm-find-files)
(define-key global-map [remap execute-extended-command] #'helm-M-x)
(define-key global-map [remap switch-to-buffer] #'helm-mini)

;;Налаштування quickrun
(require 'quickrun)

;;Налаштування прив'язки клавіш клавіатури
;;Прив'язка клавіші F2 до збереження файлу
(global-set-key [f2] 'save-buffer)

;;Прив'язка показу нещодавніх файлів до клавіші F3
(global-set-key [f3] 'recentf-open-files)

;;Прив'язка компіляції та запуску програми Java до F4
(define-key global-map [f4] 'quickrun)

;; Показ переліку всіх помилок в окремому буфері
(define-key global-map [f6] 'flycheck-list-errors)

;;Прив'язка виклику менеджера файлів treemacs до F7
(define-key global-map [f7] 'treemacs)

;;Прив'язка виклику переліку функції та класів у treemacs
(define-key global-map [f8] 'lsp-treemacs-symbols)

Ще є можливість використати поєднання lsp-mode(lsp-java) плюс Flymake(вбудований)
замість eglot(eglot-java) плюс Flycheck,
але lsp-mode дає жахливі глюки на Java (цілі шматки коду раптово видаляються),
а Flymake(альтернатива Flycheck) має гіршу підтримку для С++.
Тому я їх не використовую.
Це налаштування для створення дуже простих програм початкового рівня,
бо з іншими я поки що не працював.