Тема: Emacs як IDE для Python
Для початку вам треба додати репозиторій Melpa до вашого файлу налаштувань init.el
та встановити такі додатки:
company doom-modeline doom-themes
flycheck flycheck-pkg-config helm helm-company
helm-flycheck helm-projectile helm-xref lsp-mode
lsp-treemacs lsp-ui nerd-icons projectile pylint pyvenv
quickrun rainbow-delimiters ruff-format treemacs
treemacs-nerd-icons treemacs-projectile which-key xclip
yasnippet yasnippet-snippetsЩоб встановити всі програми за раз краще написати скрипт.
Наприклад, можна створити ось такий .el файл для Emacs:
;; Перелік пакунків, які хочете встановити
(setq package-list '(company doom-modeline doom-themes
flycheck flycheck-pkg-config helm helm-company
helm-flycheck helm-projectile helm-xref lsp-mode
lsp-treemacs lsp-ui nerd-icons projectile pylint pyvenv
quickrun rainbow-delimiters ruff-format treemacs
treemacs-nerd-icons treemacs-projectile which-key xclip
yasnippet yasnippet-snippets))
;; Перелік репозиторіїв, де вони знаходяться
(setq package-archives (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t))
;; Активація встановлення пакунків
(package-initialize)
;; Оновлення переліку пакунків у репозиторіях
(unless package-archive-contents
(package-refresh-contents))
;; Встановлення обраних вами пакунків, якщо вони ще не встановлені
(dolist (package package-list)
(unless (package-installed-p package)
(package-install package)))
;; Вихід з Emacs після встановлення пакунків
(kill-emacs)Тоді відкриваєте термінал у теці, де знаходиться такий .el файл і вводите команду:
emacs --batch -l ваш_файл.elОсь мої налаштування в init.el для Python:
;;Репозиторій плагінів Melpa
(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)
;;Підсвічування рядка, де знаходиться курсор
(global-hl-line-mode 1)
;;Підсвічування пар дужок відповідним кольором
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
;;Налаштування для відкривання останнього робочого файлу
(recentf-mode 1)
(setq recentf-max-menu-items 9
recentf-max-saved-items 9
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)
;;Налаштування показу часу й дати в modeline
(setq display-time-format "%a, %d %b %Y %H:%M %Z")
(display-time-mode t)
;;Показ заряду батареї
(display-battery-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-prefer-flymake nil
)
:hook (;; Прив'язка lsp-mode до певного режиму роботи
(python-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 'python-ruff)
(flycheck-add-next-checker 'python-ruff 'python-pylint)
)
;; Встановлення шляху до pylint
(add-hook 'python-mode-hook
(lambda ()
(setq flycheck-python-pylint-executable "/usr/bin/pylint")
;;(setq flycheck-pylintrc "/home/tools/.pylintrc")
)
)
;;Налаштування керування проєктами 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)
;;Форматування файлу Python при збереженні
(require 'ruff-format)
(add-hook 'python-mode-hook 'ruff-format-on-save-mode)
;;Налаштування автоматичного використання venv для Python
(use-package pyvenv
:ensure t)
;;Функція, що шукає вказану теку з venv в директоріях вище за поточний файл
(defun pyvenv-autoload ()
"Активує версію pyvenv, якщо вказана тека існує."
(f-traverse-upwards (lambda (path)
(let ((venv-path (f-expand "tutorial-env" path)))
(if (f-exists? venv-path)
(progn (pyvenv-activate venv-path) t)
nil)))))
(add-hook 'python-mode-hook 'pyvenv-autoload)
;;Налаштування програми автодоповнення команд 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)
(use-package quickrun
:config
(setq quickrun-focus-p t
quickrun-truncate-lines nil
quickrun-timeout-seconds 90
)
)
;;Налаштування прив'язки глобальних клавіш клавіатури
;;Прив'язка клавіші 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)
;;Перехід між різними буферами
(define-key global-map [f9] 'switch-to-buffer-other-window)Зверніть увагу на ось цю частину:
;;Функція, що шукає вказану теку з venv в директоріях вище за поточний файл
(defun pyvenv-autoload ()
"Активує версію pyvenv, якщо вказана тека існує."
(f-traverse-upwards (lambda (path)
(let ((venv-path (f-expand "tutorial-env" path)))
(if (f-exists? venv-path)
(progn (pyvenv-activate venv-path) t)
nil)))))
(add-hook 'python-mode-hook 'pyvenv-autoload)Тут pyvenv автоматично завантажує обране вами
віртуальне середовище (venv), що знаходиться в батьківській директорії
стосовно файлу, з яким ви працюєте. У даному випадку це tutorial-env,
вам треба ввести назву потрібного вам venv.
У цих налаштуваннях використовуються pylint та ruff
для перевірки синтаксису та форматування при збереженні.
У мене вони встановлені глобально, а не в окреме віртуальне середовище.
Якщо бажаєте переконатися,
що ви знаходитеся в правильному віртуальному середовищі,
додайте ці рядки до вашого файлу:
import sys
if hasattr(sys, "real_prefix") or (
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
):
print(f"Inside virtual environment: {sys.prefix}")
else:
print("Not in a virtual environment.")Як виглядає Emacs IDE для Python можна подивитися в прикріпленому знімку екрана.