Тема: 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 в налаштуваннях.
Це лише прості базові налаштування для С++, але для початку вистачить.