1

Тема: Emacs як IDE для C++

1. Встановлюєте Emacs. Якщо не вдається запустити його за допомогою пускача в меню програм, правою клавішею мишки зайдіть в налаштування пускача та встановіть позначку навпроти «запустити в терміналі» (це для OS Manjaro, всі подальші поради стосуються цієї ОС). Цей редактор створений для роботи в терміналі, без нього не запуститься.
2. У  вашій домашній теці знайдіть приховану директорію .emacs.d та створіть всередині неї файл init.el. Це ваш файл налаштувань, який ви змінюватимете за потреби.
3. Після запуску зайдіть в Emacs tutorial (перекладений українською) та ознайомтеся з основами керування. Там же є Emacs manual (поки що лише англійською) — це вже повноцінний підручник по Emacs. Раджу на їхньому сайті завантажити його та шпаргалку Emacs reference у форматі pdf.
4. Додайте до файлу налаштувань репозиторій MELPA. Emacs має власний менеджер пакунків через який онлайн можна встановити все, що вам треба. У цьому репозиторії кілька тисяч плагінів для Emacs.

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Comment/uncomment this line to enable MELPA Stable if desired.  See `package-archive-priorities`
;; and `package-pinned-packages`. Most users will not need or want to do this.
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)

5. За допомогою менеджера пакунків встановіть наступні програми:
auto-complete-clang — автодоповнення clang
catppuccin-theme — тема оформлення
clang-format — форматування коду С++
clang-format+  — автоматичне форматування коду при збереженні
company — основа для автодоповнення тексту (потребує певного рушія)
company-c-headers — автодоповнення для хедерів
company-ctags — підтримка ctags
dracula-theme — тема оформлення
flycheck — перевірка синтаксису, знаходження помилок «на льоту»
flycheck-clang-analyzer
flycheck-clang-tidy
flycheck-clangcheck
flycheck-flawfinder
flycheck-projectile
helm — дуже зручна програма автодоповнення будь-яких команд Emacs і не тільки
helm-company
helm-flycheck
helm-lsp
helm-projectile
helm-xref
lsp-mode — пакет для інтеграції мов програмування та взаємодії з іншими пакетами
projectile — керування проєктами
rainbow-delimiters — кольорове виділення дужок різного рівня
treemacs — менеджер файлів
treemacs-projectile
which-key — програма, що показує наявні комбінації клавіш та інформацію по ним
xclip — копіювання до clipboard та з нього
yasnippet — корисні сніппети автодоповнення, як от автоматичне додавання дужок до функцій
yasnippet-snippets

6. Тепер додайте решту файлу налаштування:

;;Налаштування поточної теми оформлення
(load-theme 'dracula t)
;;(load-theme 'catppuccin :no-confirm)

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

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

;;Налаштування швидкого автодоповнення
(setq gc-cons-threshold (* 100 1024 1024)
      read-process-output-max (* 1024 1024)
      treemacs-space-between-root-nodes nil
      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)

;;Налаштування використання готових сніппетів (наприклад, автоматичне додавання дужок для функції С++)
(add-hook 'c++-mode-hook #'yas-minor-mode)

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

;;Налаштування для менеджера файлів Treemacs
(use-package treemacs
  :ensure t
  :defer t
  :init
  (with-eval-after-load 'winum
    (define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
  :config
  (progn
    ;; The default width and height of the icons is 22 pixels. If you are
    ;; using a Hi-DPI display, uncomment this to double the icon size.
    (treemacs-resize-icons 44)

    (treemacs-follow-mode t)
    (treemacs-filewatch-mode t)
    (treemacs-fringe-indicator-mode 'always)
    (when treemacs-python-executable
      (treemacs-git-commit-diff-mode t))

    (pcase (cons (not (null (executable-find "git")))
                 (not (null treemacs-python-executable)))
      (`(t . t)
       (treemacs-git-mode 'deferred))
      (`(t . _)
       (treemacs-git-mode 'simple)))

    (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)))


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

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

;;Перевірка синтаксису flycheck
(add-hook 'after-init-hook #'global-flycheck-mode)
(add-hook 'c++-mode-hook
          (lambda () (setq flycheck-clang-language-standard "c++20")))
;;Показати помилки відразу в окремому вікні
(add-hook 'flycheck-after-syntax-check-hook
          (lambda  ()
            (if flycheck-current-errors
                (flycheck-list-errors)
              (when (get-buffer "*Flycheck errors*")
                (switch-to-buffer "*Flycheck errors*")
                (kill-buffer (current-buffer))
                (delete-window)))))


;;Налаштування керування проєктами 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 'c-mode-hook 'lsp)
(add-hook 'c++-mode-hook 'lsp)

;;Налаштування clang-format при збереженні
(defun clang-format-save-hook-for-this-buffer ()
  "Create a buffer local save hook."
  (add-hook 'before-save-hook
            (lambda ()
              (when (locate-dominating-file "." ".clang-format")
                (clang-format-buffer))
              ;; Continue to save.
              nil)
            nil
            ;; Buffer local hook.
            t))

;; Run this for each mode you want to use the hook.
(add-hook 'c++-mode-hook (lambda () (clang-format-save-hook-for-this-buffer)))

;;Налаштування для відкривання останнього робочого файлу
(recentf-mode 1)
(setq recentf-max-menu-items 25)
(setq recentf-max-saved-items 25)


;;Налаштування програми автодоповнення команд 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)

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

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

;;Прив'язка компіляції С++ до F5
(define-key global-map [f5] 'compile)
;;Автоматичне натискання Enter при компіляції
(setq compilation-read-command nil)

;;Налаштування команди компіляції
(require 'compile)
 (add-hook 'c++-mode-hook
           (lambda ()
         (unless (file-exists-p "Makefile")
           (set (make-local-variable 'compile-command)
            (let ((file (file-name-nondirectory buffer-file-name)))
                      (format "%s %s"
                              (or (getenv "CC") "cmake")
                              (or (getenv "CPPFLAGS") "-Bbuild/Debug -DCMAKE_BUILD_TYPE=Debug && cd build/Debug && make")
                  ))))))

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

Зверніть увагу, що в мене компіляція та автодоповнення коду створені під CMake файл.

cmake_minimum_required(VERSION 3.5)

project(hello_world
    VERSION 1.0.0
    LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20 )
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(${PROJECT_NAME} main.cpp)

# Цією командою можна зручно встановити бажаний стандарт [c++17, c++20, c++23]
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
# Цією командою можна легко додати дефайни, можна вписувати їх на місці
target_compile_definitions(${PROJECT_NAME} PUBLIC _GLIBCXX_DEBUG)
# Цією командою виставляємо прапорці компілятору
target_compile_options(${PROJECT_NAME}
    PUBLIC -Wall
           -Wextra
           -Wpedantic
           -fsanitize=address,undefined)
# Цією командою виставляємо прапорці лінкеру
target_link_options(${PROJECT_NAME}
    PUBLIC -fsanitize=address,undefined)


set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)



add_custom_command(
    TARGET ${PROJECT_NAME}
    POST_BUILD
    COMMAND ${PROJECT_NAME}
)



include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

Якщо ви не використовуєте CMake, вам доведеться встановити Bear для генерації відповідного файлу json (в CMake це відбувається ось тут
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)), а також переписати compile-comand в налаштуваннях.
Це лише прості базові налаштування для С++, але для початку вистачить.

2

Re: Emacs як IDE для C++

Ще раджу встановити cmake-mode та cmake-font-lock (після встановлення додайте (require 'cmake-mode) до файлу налаштувань).
Ці плагіни разом із іншими дадуть вам автодоповнення та кольорову підсвітку функцій при роботі з файлом CMakeLists.txt.

3

Re: Emacs як IDE для C++

Оновлений файл налаштувань:

;;Підсвічування пар дужок відповідним кольором
(add-hook 'c++-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)

;;Налаштування використання готових сніппетів
;;(наприклад, автоматичне додавання дужок для функції С++)
(add-hook 'c++-mode-hook #'yas-minor-mode)

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

;;Налаштування lsp-mode
(use-package lsp-mode
  :init
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  (setq lsp-keymap-prefix "C-c l"
        lsp-enable-symbol-highlighting nil
        lsp-ui-sideline-enable t
        lsp-ui-sideline-show-code-actions t
        lsp-ui-sideline-show-hover nil
        lsp-modeline-code-actions-enable nil
        lsp-diagnostics-provider :none
        lsp-ui-sideline-show-diagnostics t
        ;lsp-completion-provider :none
        lsp-completion-show-detail nil
        lsp-completion-show-kind nil
        lsp-completion-sort-initial-results t
        lsp-clients-clangd-args '("--header-insertion=never"
                                  "--fallback-style=WebKit"
                                  )
    )

  :hook (;; Прив'язка lsp-mode до певного режиму роботи
         (c++-mode . lsp)
         ;; Інтеграція з which-key
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp)

;;Налаштування lsp-ui
(use-package lsp-ui
  :commands lsp-ui-mode)

;;Налаштування 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)

;;Налаштування lsp-treemacs
(lsp-treemacs-sync-mode 1)

;;Перевірка синтаксису flycheck
(use-package flycheck
  :ensure t
  :init
  (global-flycheck-mode)
  :config
    ;; Показувати індикатори помилок в крайньому лівому стовпчику
    (setq flycheck-indication-mode 'left-margin
          ;; Затримка показу помилок
          flycheck-display-errors-delay 0.1
          ;; Перевірка згідно певного стандарту мови С++
          flycheck-clang-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)
  )

(use-package flycheck-clang-tidy
  :after flycheck
  :hook
  (flycheck-mode . flycheck-clang-tidy-setup)
  )

(use-package flycheck-clang-analyzer
  :ensure t
  :after flycheck
  :config (flycheck-clang-analyzer-setup))

(with-eval-after-load 'flycheck
  (require 'flycheck-flawfinder)
  (flycheck-flawfinder-setup)
  ;; chain after cppcheck since this is the last checker in the upstream
  ;; configuration
  (flycheck-add-next-checker 'c/c++-cppcheck '(warning . flawfinder)))

;;Налаштування керування проєктами 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 'c-mode-hook 'lsp)
(add-hook 'c++-mode-hook 'lsp)

;;Налаштування clang-format при збереженні
(defun clang-format-save-hook-for-this-buffer ()
  "Create a buffer local save hook."
  (add-hook 'before-save-hook
            (lambda ()
              (when (locate-dominating-file "." ".clang-format")
                (clang-format-buffer))
              ;; Continue to save.
              nil)
            nil
            ;; Buffer local hook.
            t))

;; Run this for each mode you want to use the hook.
(add-hook 'c++-mode-hook (lambda () (clang-format-save-hook-for-this-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)

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

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

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

;;Прив'язка компіляції С++ до F5
(define-key global-map [f5] 'compile)
;;Автоматичне натискання Enter при компіляції
(setq compilation-read-command nil)

;;Налаштування команди компіляції
(require 'compile)
  (add-hook 'c++-mode-hook
    (lambda ()
      (unless (file-exists-p "Makefile")
        (set (make-local-variable 'compile-command)
        (let ((file (file-name-nondirectory buffer-file-name)))
          (format "%s %s"
            (or (getenv "CC") "cmake")
            (or (getenv "CPPFLAGS") "-Bbuild/Debug -DCMAKE_BUILD_TYPE=Debug && cd build/Debug && make")
            ))))))

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

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

Якщо використовувати lsp-mode і flycheck,
краще вимкнути перевірку синтаксису в lsp-mode(lsp-diagnostics-provider :none),
бо налаштування lsp-mode для перевірки синтаксису будуть перебивати налаштування flycheck.
Хіба що вам більше подобаються налаштування саме lsp-mode.
Як все зараз виглядає можна побачити на знімку(це для текстового Emacs Manjaro OS).
https://replace.org.ua/misc.php?action=pun_attachment&item=2233

Post's attachments

Знімок Emacs.png 212.71 kb, 21 downloads since 2024-10-24 

4

Re: Emacs як IDE для C++

Також раджу встановити quickrun для компіляції та запуску програм.
Його зручність полягає в тому, що можна прив'язати до однієї клавіші
відразу декілька різних команд для різних мов програмування.
quickrun розпізнає поточний режим програмування (мову)
і виконує відповідну команду (стандартну або встановлену користувачем).
Ось приклад налаштувань для C++ із CMake:

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

;; Налаштування для компіляції та запуску програм С++
(quickrun-add-command "c++"
  '((:command . "cmake")
    (:exec    . ("%c -Bbuild/Debug -DCMAKE_BUILD_TYPE=Debug && cd build/Debug && make"))
    )
  :default "c++")
Подякували: leofun011

5

Re: Emacs як IDE для C++

Оновлена конфігурація Emacs.
Про всяк випадок ще раз наводжу встановлені додатки,
бо деякі старі видалив, а нові встановив.
Перелік встановлених доповнень:

clang-format 
clang-format+ 
cmake-font-lock 
cmake-mode 
company 
company-c-headers 
company-ctags 
doom-modeline 
doom-themes
dracula-theme 
flycheck 
flycheck-flawfinder 
flycheck-pkg-config 
helm 
helm-company 
helm-flycheck
helm-projectile 
helm-xref 
lsp-mode 
lsp-treemacs 
lsp-ui 
nerd-icons 
projectile 
quickrun 
rainbow-delimiters 
treemacs
treemacs-nerd-icons 
treemacs-projectile
which-key 
xclip
yasnippet 
yasnippet-snippets


Новий файл конфігурації:

;;Підсвічування пар дужок відповідним кольором
(add-hook 'c++-mode-hook #'rainbow-delimiters-mode)
(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)

(setq company-transformers '(delete-consecutive-dups
                             company-sort-prefer-same-case-prefix) ;;Сортування назв за префіксом
                             )


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

;;Налаштування швидкого автодоповнення
(setq company-idle-delay 0.0 ;; Затримка показу автодоповнення
      company-minimum-prefix-length 2 ;;Кількість літер для початку пошуку автодоповнення
      lsp-idle-delay 0.1 ;;Затримка показу автодоповнення в lsp-mode
      )

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

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

;;Зберігання місця розташування курсору
(save-place-mode 1)

;;Припасування тексту до ширини вікна для всіх вікон
(global-visual-line-mode t)

;;Налаштування максимальної кількості символів у рядку
(setq-default fill-column 80)
(global-display-fill-column-indicator-mode t)
(setq-default display-fill-column-indicator-column 80)
(set-face-attribute 'fill-column-indicator t :foreground "navy")


;;Налаштування використання готових сніппетів
;;(наприклад, автоматичне додавання дужок для функції С++)
(require 'yasnippet)
(yas-global-mode 1)

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

;;Налаштування lsp-mode
(use-package lsp-mode
  :init
  (setq lsp-keymap-prefix "C-c l"
        lsp-enable-symbol-highlighting nil
        lsp-ui-sideline-show-code-actions t ;;вмикає підказки, що треба зробити
        lsp-ui-sideline-diagnostic-max-lines 10 ;;кількість рядків повідомлення діагностики,
                                                ;;щоб вміщалося на екрані, якщо задовге
        lsp-clients-clangd-args '(
           "--header-insertion=never" ;;заборона автовставки бібліотек
           "--fallback-style=WebKit" ;;стиль форматування за відсутності файлу .clang_format
           "--function-arg-placeholders=0" ;;заборона вставки аргументів всередині дужок при автодоповненні функції
           "--clang-tidy";;діагностика з clang-tidy
           )
    )

  :hook (;; Прив'язка lsp-mode до певного режиму роботи
         (c++-mode . lsp)
         ;; Інтеграція з which-key
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp)

;;Налаштування lsp-ui
(use-package lsp-ui
  :commands lsp-ui-mode)

;; Налаштування 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-vibrant t)

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

;;Налаштування doom-modeline
(use-package doom-modeline
  :ensure t
  :init (doom-modeline-mode 1)
  :config
    (setq doom-modeline-minor-modes nil ;;Показати другорядні режими

    )
  )

;;Налаштування nerd-icons
(use-package nerd-icons
  ;; :custom
  ;; The Nerd Font you want to use in GUI
  ;; "Symbols Nerd Font Mono" is the default and is recommended
  ;; but you can use any other Nerd Font if you want
  ;; (nerd-icons-font-family "Symbols Nerd Font Mono")
  )

;;Налаштування 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)

;;Налаштування іконок для treemacs
(use-package treemacs-nerd-icons
  :config
  (treemacs-load-theme "nerd-icons"))

;;Налаштування lsp-treemacs
(lsp-treemacs-sync-mode 1)

;;Виправлення баґу з додаванням чекерів до flycheck
(require 'lsp-diagnostics)
(lsp-diagnostics-flycheck-enable)

;;Перевірка синтаксису flycheck
(use-package flycheck
  :ensure t
  :init
  (global-flycheck-mode)
  :config
    ;; Показувати індикатори помилок в крайньому лівому стовпчику
    (setq flycheck-indication-mode 'left-margin
          ;; Затримка показу помилок
          flycheck-display-errors-delay 0.1
    )
    ;; Налаштування ширини стовпчика з індикаторами помилок
    (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)
    (flycheck-add-next-checker 'lsp 'c/c++-cppcheck)
)

;;Налаштування додавання flawfinder до flycheck
(with-eval-after-load 'flycheck
  (require 'flycheck-flawfinder)
  (flycheck-flawfinder-setup)
   ;;chain after cppcheck since this is the last checker in the upstream
  ;; configuration
  (flycheck-add-next-checker 'c/c++-cppcheck '(warning . flawfinder)))


;;Налаштування керування проєктами 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 'c-mode-hook 'lsp)
(add-hook 'c++-mode-hook 'lsp)

;;Налаштування clang-format при збереженні
(defun clang-format-save-hook-for-this-buffer ()
  "Create a buffer local save hook."
  (add-hook 'before-save-hook
            (lambda ()
              (when (locate-dominating-file "." ".clang-format")
                (clang-format-buffer))
              ;; Continue to save.
              nil)
            nil
            ;; Buffer local hook.
            t))

;; Run this for each mode you want to use the hook.
(add-hook 'c++-mode-hook (lambda () (clang-format-save-hook-for-this-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)

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

;;Налаштування quickrun
(require 'quickrun)
(use-package quickrun
  :config
    (setq quickrun-focus-p t
          quickrun-truncate-lines nil)
)

;; Стандартні налаштування для компіляції та запуску програм С++
(quickrun-add-command "c++"
  '((:command . "cmake")
    (:exec    . ("%c -Bbuild/Debug -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=clang++ && cd build/Debug && make")
                )
    )
  :default "c++")


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

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

;;Прив'язка компіляції та запуску програми до F4
(define-key global-map [f5] '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 і flycheck.

   У вищенаведеному пості я помилявся, коли вважав,
що змінна lsp-diagnostics-provider :none вимикає діагностику lsp-mode. Навпаки така команда вимикає діагностику з використанням чекерів flycheck. Діагностика працює в такій послідовності: спочатку вмикається lsp-mode та шукає програму для діагностики С++(у моєму випадку це clangd, ще є ccls). Тоді ця програма встановлюється стандартним чекером. Потім він перевіряє чи встановлений у вас flycheck, який є його стандартним доповненням для діагностики, тому в налаштуваннях нічого не треба міняти, якщо хочете користуватися flycheck. Коли запускається flycheck він автоматично робить чекер з lsp-mode своїм основним чекером, але дозволяє після нього додати в чергу інші чекери. Ось на цьому етапі є невеликий баґ із додаванням у чергу. Щоб усе працювало як слід треба додати такі рядки перед налаштуваннями flycheck:

(require 'lsp-diagnostics)
(lsp-diagnostics-flycheck-enable)

.

А вже після цього можна додавати чекери в чергу зі стандартних налаштувань flycheck функцією  flycheck-add-next-checker. Не обов’язково додавати саме cppcheck. Це може бути інший чекер на ваш розсуд. Бо якщо відразу напряму спробувати додати якийсь чекер після lsp, видає помилку. При застосуванні команди flycheck-verify-setup маєте побачити активний основний сервер lsp та кілька доданих вами серверів після рядка Checkers that may run as part of the first checker's chain: .

   Додав doom-modeline та іконки nerd-icons. Щоб іконки nerd-icons працювали як слід треба встановити один зі шрифтів nerd до вашої системи та обрати його поточним шрифтом вашого терміналу. У мене це GeistMono Nerd Font Mono UltraBlack. Один із спеціально розроблених для програмування шрифтів. Раджу використовувати шрифти із окремою позначкою Mono, у них ширина всіх літер однакова, що краще для роботи в терміналі.

   Ще додав різні дрібнички, як то збереження розташування курсору, показ межі максимальної довжини рядка, перенесення тексту до видимої області вікна, якщо він задовгий.

Як усе виглядає можна побачити на нижченаведеному знімку екрана.
Це текстовий термінал. Є ще варіант з GUI, але я не користуюся ним.

https://replace.org.ua/misc.php?action=pun_attachment&item=2243

Post's attachments

Знімок екрану Emacs.png 205.18 kb, 5 downloads since 2025-04-04