Mac, emacs and new python3.10
I've deceided to upgrade my python to the new Python 3.10 and upgrade my IDE based on Emacs too.
Upgrading python to version 3.10
A installing python 3.10 is really simple task using a homebrew:
MacBook-Pro-Hohlov:call-me skhohlov$ brew search python ==> Formulae app-engine-python gst-python python-launcher python-tk@3.9 python@3.8 pythran boost-python ipython python-markdown python-yq python@3.9 ✔ jython boost-python3 micropython python-tabulate python@3.10 reorder-python-imports cython bpython ptpython python-tk@3.10 python@3.7 wxpython ==> Casks awips-python awips-python mysql-connector-python mysql-connector-python If you meant "python" specifically: It was migrated from homebrew/cask to homebrew/core. MacBook-Pro-Hohlov:call-me skhohlov$ brew install python@3.10 Updating Homebrew... ==> Auto-updated Homebrew! Updated 7 taps (homebrew/cask-versions, homebrew/core, homebrew/cask, homebrew/cask-fonts, homebrew/services, caskroom/versions and caskroom/cask). ==> New Formulae cassandra@3 feroxbuster g2o ly postgresql@13 rbw tfk8s cpufetch
After this switch python to the new version:
brew unlink python@3.9 Unlinking /usr/local/Cellar/python@3.9/3.9.7_1... 3 symlinks removed. MacBook-Pro-Hohlov:call-me skhohlov$ brew link python@3.10 Linking /usr/local/Cellar/python@3.10/3.10.0_2... Error: Could not symlink bin/2to3 Target /usr/local/bin/2to3 already exists. You may want to remove it: rm '/usr/local/bin/2to3' To force the link and overwrite all conflicting files: brew link --overwrite python@3.10 To list all files that would be deleted: brew link --overwrite --dry-run python@3.10
Emacs lsp
Python support Language server protocol from https://github.com/Microsoft/language-server-protocol. Idea is simple : Editor sends request with text changes to python language server and receives information about code competion, doc hints etc.
It is good idea to store all tools in one place. I'm prefering to use virtual env for this.
Creating dir for our project:
MacBook-Pro-Hohlov:python skhohlov$ mkdir emacs-lsp MacBook-Pro-Hohlov:python skhohlov$ cd emacs-lsp/
and make virtual enviroment:
pip3 install virtualenv DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621 Collecting virtualenv Downloading virtualenv-20.8.1-py2.py3-none-any.whl (5.3 MB) |████████████████████████████████| 5.3 MB 2.2 MB/s Collecting backports.entry-points-selectable>=1.0.4 Downloading backports.entry_points_selectable-1.1.0-py2.py3-none-any.whl (6.2 kB) Collecting platformdirs<3,>=2 Downloading platformdirs-2.4.0-py3-none-any.whl (14 kB) Requirement already satisfied: six<2,>=1.9.0 in /usr/local/lib/python3.10/site-packages (from virtualenv) (1.16.0) Collecting filelock<4,>=3.0.0 Downloading filelock-3.3.1-py3-none-any.whl (9.7 kB) Collecting distlib<1,>=0.3.1 Downloading distlib-0.3.3-py2.py3-none-any.whl (496 kB) |████████████████████████████████| 496 kB 9.3 MB/s Installing collected packages: platformdirs, filelock, distlib, backports.entry-points-selectable, virtualenv
Now we install packages:
(venv) MacBook-Pro-Hohlov:emacs-lsp skhohlov$ pip install 'python-language-server[all]' Collecting python-language-server[all] Using cached python_language_server-0.36.2-py2.py3-none-any.whl (51 kB) Collecting ujson>=3.0.0 Downloading ujson-4.2.0-cp310-cp310-macosx_10_14_x86_64.whl (45 kB) |████████████████████████████████| 45 kB 1.4 MB/s Collecting pluggy Using cached pluggy-1.0.0-py2.py3-none-any.whl (13 kB) Collecting jedi<0.18.0,>=0.17.2 Using cached jedi-0.17.2-py2.py3-none-any.whl (1.4 MB)
(venv) MacBook-Pro-Hohlov:emacs-lsp skhohlov$ ls venv/bin/py* venv/bin/pycodestyle venv/bin/pyflakes venv/bin/pyls venv/bin/python venv/bin/python3.10 venv/bin/pydocstyle venv/bin/pylint venv/bin/pyreverse venv/bin/python3 (venv) MacBook-Pro-Hohlov:emacs-lsp skhohlov$
Emacs
At this moment we do most of the thing and ready to add most of them to the Emacs initialization file. Take a look at the System Crafters System Crafters. Really perfect channel for emacs user.
I've separated my configuration file into small parts for the easy understanding.
Set package rules and auto packages updates
(require 'package)
(setq package-archives '(
("melpa" . "http://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")
))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
Some system setting for emacs memory usage and load path variable at the end (My mac requires this, Linux user can skip last command)
(setq read-process-output-max (* 1024 1024))
(setq gc-cons-threshold 100000000)
(add-hook 'after-init-hook (lambda () (setq gc-cons-threshold 800000)))
(require 'exec-path-from-shell)
(exec-path-from-shell-initialize)
Adding projectile Ivy helpful packages.
Projectile - package for easy project management and navigation.
Ivy - part of the complex functionality for selecting an item from the list during autocomplete
helpful - package for a showing sourse code and python doc strings
;;
;; projectile
;;
(use-package projectile
:diminish projectile-mode
:config (projectile-mode)
:custom ((projectile-completion-system 'iv))
:bind-keymap
("C-c p" . projectile-command-map))
;;;
;;; Ivy
;;;
;;;
(use-package ivy
:diminish
:bind (("C-s" . swiper)
:map ivy-minibuffer-map
)
:config
(ivy-mode 1 )
)
(use-package ivy-rich
:init
(ivy-rich-mode 1))
(use-package counsel
:bind (("M-x" . counsel-M-x)
("C-x b" . counsel-ibuffer)
("C-x C-f" . counsel-find-file)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history)
))
(use-package helpful
:ensure t
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key)
)
;;
;;hydra
;;
(use-package helm-lsp
:config
(defun netrom/helm-lsp-workspace-symbol-at-point ()
(interactive)
(let ((current-prefix-arg t))
(call-interactively #'helm-lsp-workspace-symbol)))
(defun netrom/helm-lsp-global-workspace-symbol-at-point ()
(interactive)
(let ((current-prefix-arg t))
(call-interactively #'helm-lsp-global-workspace-symbol)
)))
Python
It was a long way to add python support. But we near the finish. Take a look I've changed path to the python3 executable
(use-package pyenv-mode
:ensure t
:config
(pyenv-mode 1)
(defun projectile-pyenv-mode-set ()
"Set pyenv version matching project name."
(let ((project (projectile-project-name)))
(if (member project (pyenv-mode-versions))
(pyenv-mode-set project)
(pyenv-mode-unset))))
)
(use-package python-mode
:ensure t
:hook (python-mode . lsp-deferred)
:custom
(python-shell-interpreter "~/project/python/emacs-lsp/venv/bin/python3")
(dap-python-executable "~/project/python/emacs-lsp/venv/bin/python3python3")
(dap-python-debugger 'debugpy)
:config
(require 'dap-python)
)
after this we can add Flycheck and LSP.
Flycheck, LSP, company
Flycheck is a perfect extension for code completion and syntax checking. https://www.flycheck.org/en/latest/
LSP provides another one perfect idea. Special service is created for checking code and this service is not a part of editor. Any editor can be client of this service and Editor is a simplest.
Package company has a role competition for various languages.
Also it is interesting package company-tabnine from https://www.tabnine.com If you hang on and can not write more code, possible AI assistant can help you
;; Flycheck
(use-package flycheck
:ensure t
:init (global-flycheck-mode))
(with-eval-after-load 'flycheck
(add-hook 'flycheck-mode-hook #'flycheck-inline-mode))
(with-eval-after-load 'flycheck
'(add-hook 'flycheck-mode-hook 'flycheck-popup-tip-mode))
(use-package lsp-mode
:requires hydra
:init
(setq lsp-keymap-prefix "C-c l")
:config
(setq lsp-idle-delay 0.5
lsp-auto-configure t
lsp-clients-python-library-directories `("~/project/python/emacs-lsp/venv/lib" ,(expand-file-name "~/project/python/emacs-lsp/venv/bin"))
lsp-enable-symbol-highlighting t
lsp-enable-snippet nil ;; Not supported by company capf, which is the recommended company backend
;; lsp-pyls-plugins-pylint-enabled t
;; lsp-pyls-plugins-flake8-enabled t
;; lsp-pylsp-plugins-jedi-completion-enabled t
;; lsp-pylsp-plugins-rope-completion-enabled nil
;; lsp-pylsp-plugins-jedi-use-pyenv-environment t
;; ("pylsp.plugins.flake8.enabled" lsp-pylsp-plugins-flake8-enabled)
lsp-pyls-server-command "/Users/skhohlov/project/python/emacs-lsp/venv/bin/pyls"
lsp-modeline-diagnostics-enable t
)
(lsp-register-custom-settings
'(
("pyls.plugins.pyls_mypy.enabled" t t)
("pyls.plugins.pyls_mypy.live_mode" t t)
("pyls.plugins.pyls_black.enabled" t t)
("pyls.plugins.pyls_isort.enabled" t t)
("pyls.plugins.pylint.enabled" nil t)
("pylsp.plugins.flake8.enabled" t t )
Disable these as they're duplicated by flake8
("pyls.plugins.pycodestyle.enabled" nil t)
("pyls.plugins.mccabe.enabled" nil t)
("pyls.plugins.pyflakes.enabled" lsp-pyls-plugins-pyflakes-enabled t)
) )
:hook
(python-mode . lsp)
(django-mode . lsp)
:commands lsp
)
;;
;; lsp-ui
;;
(use-package lsp-ui
:config (setq lsp-ui-sideline-show-hover t
lsp-ui-sideline-delay 0.5
lsp-ui-doc-delay 2
;; lsp-ui-sideline-ignore-duplicates t
lsp-ui-doc-position 'bottom
lsp-ui-doc-alignment 'frame
lsp-ui-doc-header nil
lsp-ui-doc-include-signature t
lsp-ui-doc-use-childframe t)
(setq lsp-ui-doc-frame-parameters
'((left . -1)
(top . -1)
(no-accept-focus . t)
(min-width . 0)
(width . 0)
(min-height . 0)
(height . 0)
(internal-border-width . 0)
(vertical-scroll-bars)
(horizontal-scroll-bars)
(left-fringe . 0)
(right-fringe . 0)
(menu-bar-lines . 0)
(tool-bar-lines . 0)
(line-spacing . 0.1)
(unsplittable . t)
(undecorated . t)
(minibuffer . nil)
(visibility . nil)
(mouse-wheel-frame . nil)
(no-other-frame . t)
(cursor-type)
(no-special-glyphs . t)))
:commands lsp-ui-mode
)
;;
;; company
;;
;;
(use-package company-tabnine
:ensure t)
(use-package company
:ensure t
:init
(setq company-minimum-prefix-length 2
company-require-match 0
company-selection-wrap-around t
company-dabbrev-downcase nil
company-tooltip-limit 20 ; bigger popup window
company-tooltip-align-annotations 't ; align annotations to the right tooltip border
company-idle-delay 1.0 ; decrease delay before autocompletion popup shows
company-begin-commands '(self-insert-command)) ; start autocompletion only after typing
(eval-after-load 'company
'(add-to-list
'company-backends '(
company-capf
company-files
company-tabnine :with company-capf
)
))
)
amd result is here :
Comments
Post a Comment