关于Python配置方案请教大佬 自己折腾了两天问Ai也没解决

这是我的配置文件,为啥eglot连接不上啊,通过uv安装的pyright和ruff,已经添加到环境变量了

;; -*- lexical-binding: t -*-

(use-package treesit
  :ensure nil
  :config
  ;; Treesitter config
  ;; Tell Emacs to prefer the treesitter mode
  ;; You'll want to run the command `M-x treesit-install-language-grammar' before editing.
  (setq major-mode-remap-alist
        '((yaml-mode . yaml-ts-mode)
          (bash-mode . bash-ts-mode)
          (js2-mode . js-ts-mode)
          (typescript-mode . typescript-ts-mode)
          (json-mode . json-ts-mode)
          (css-mode . css-ts-mode)
          (python-mode . python-ts-mode)))
)

(use-package eglot
  :ensure nil
  ;; Configure hooks to automatically turn-on eglot for selected modes
  ; :hook
  ; (((python-mode ruby-mode elixir-mode) . eglot-ensure))
  :custom
  (eglot-autoshutdown t)
  (eglot-events-buffer-size 0)
  (eglot-send-changes-idle-time 0.5)
  ; :config
  ;; Sometimes you need to tell Eglot where to find the language server
  ; (add-to-list 'eglot-server-programs
  ;              '(haskell-mode . ("haskell-language-server-wrapper" "--lsp")))
)

(provide 'init-lsp)
;; init-python.el --- Initialize python configurations.	-*- lexical-binding: t -*-

;; Copyright (C) 2010-2026 Vincent Zhang

;; Author: Vincent Zhang <[email protected]>
;; URL: https://github.com/seagle0128/.emacs.d

;; This file is not part of GNU Emacs.
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;

;;; Commentary:
;;
;; Python configurations.
;;

;;; Code:

;; Python Mode
;; Install: pip install pyflakes autopep8
(use-package python
  :ensure nil
  :defines eglot-server-programs
  :functions exec-path-from-shell-copy-env
  :hook (inferior-python-mode . (lambda ()
                                  (process-query-on-exit-flag
                                   (get-process "Python"))))
  :init
  ;; Disable readline based native completion
  (setq python-shell-completion-native-enable nil)
  :config
  ;; Type checker & language server: `ty'
  (with-eval-after-load 'eglot
    (add-hook 'python-ts-mode-hook 'eglot-ensure)
    (add-to-list 'eglot-server-programs
                 '((python-ts-mode python-mode)
                   . ("pyright-langserver" "--stdio"))))

  ;; Linter & formatter: `ruff'
  (when (executable-find "ruff")
    (use-package flymake-ruff
      :ensure t
      :hook (python-base-mode . flymake-ruff-load)))

  ;; Default to Python 3. Prefer the versioned Python binaries since some
  ;; systems stupidly make the unversioned one point at Python 2.
  (when (and (executable-find "python3")
             (string= python-shell-interpreter "python"))
    (setq python-shell-interpreter "python3"))

  ;; Env vars
  (with-eval-after-load 'exec-path-from-shell
    (exec-path-from-shell-copy-env "PYTHONPATH")))

(provide 'init-python)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; init-python.el ends here

直接用 lsp-bridge

1 个赞

你要给 python-ts-mode-hook 加一个 (eglot-ensure) 才能自动连接 lsp。因为 eglot 的默认逻辑是让用户手动开启 lsp。

2 个赞

(add-hook 'python-ts-mode-hook 'eglot-ensure) 我添加了 M-x eglot RET 手动开启也是连不上不知道为什么

你的写法容易造成启动顺序的问题

(use-package python
  :ensure nil
  :mode ("\\.py\\'" . python-ts-mode)
  :hook ((python-ts-mode . eglot-ensure)
         (python-ts-mode . corfu-mode))
  :custom
  (python-indent-offset 4)
  (python-indent-guess-indent-offset nil))

试试这样写

打开 eglot buffer 看看 log

eglot:

[jsonrpc] D[12:09:56.553] Running language server: pyright-langserver --stdio
[jsonrpc] e[12:09:56.554] --> initialize[1] {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":14636,"clientInfo":{"name":"Eglot","version":"1.19"},"rootPath":"d:/test/","rootUri":"file:///d%3A/test","initializationOptions":{},"capabilities":{"workspace":{"applyEdit":true,"executeCommand":{"dynamicRegistration":false},"workspaceEdit":{"documentChanges":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":false},"semanticTokens":{"refreshSupport":true},"configuration":true,"workspaceFolders":true},"textDocument":{"synchronization":{"dynamicRegistration":false,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":false,"completionItem":{"snippetSupport":true,"deprecatedSupport":true,"resolveSupport":{"properties":["documentation","details","additionalTextEdits"]},"tagSupport":{"valueSet":[1]},"insertReplaceSupport":true},"contextSupport":true},"hover":{"dynamicRegistration":false,"contentFormat":["plaintext"]},"signatureHelp":{"dynamicRegistration":false,"signatureInformation":{"parameterInformation":{"labelOffsetSupport":true},"documentationFormat":["plaintext"],"activeParameterSupport":true}},"references":{"dynamicRegistration":false},"definition":{"dynamicRegistration":false,"linkSupport":true},"declaration":{"dynamicRegistration":false,"linkSupport":true},"implementation":{"dynamicRegistration":false,"linkSupport":true},"typeDefinition":{"dynamicRegistration":false,"linkSupport":true},"documentSymbol":{"dynamicRegistration":false,"hierarchicalDocumentSymbolSupport":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"documentHighlight":{"dynamicRegistration":false},"codeAction":{"dynamicRegistration":false,"resolveSupport":{"properties":["edit","command"]},"dataSupport":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"isPreferredSupport":true},"formatting":{"dynamicRegistration":false},"rangeFormatting":{"dynamicRegistration":false},"rename":{"dynamicRegistration":false},"semanticTokens":{"dynamicRegistration":false,"requests":{"quote":{"full":{"delta":true}}},"overlappingTokenSupport":true,"multilineTokenSupport":true,"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator","decorator"],"tokenModifiers":["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],"formats":["relative"]},"inlayHint":{"dynamicRegistration":false},"callHierarchy":{"dynamicRegistration":false},"typeHierarchy":{"dynamicRegistration":false},"publishDiagnostics":{"relatedInformation":false,"versionSupport":true,"codeDescriptionSupport":false,"tagSupport":{"valueSet":[1,2]}}},"window":{"showDocument":{"support":true},"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"workDoneProgress":true},"general":{"positionEncodings":["utf-32","utf-8","utf-16"]},"experimental":{}},"workspaceFolders":[{"uri":"file:///d%3A/test","name":"d:/test/"}]}}
[jsonrpc] e[12:09:57.272] <-- window/logMessage {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"Pyright language server 1.1.408 starting"}}
[jsonrpc] e[12:09:57.272] <-- window/logMessage {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"Server root directory: file:///c%3A/Users/fluzzy/AppData/Roaming/uv/tools/pyright/Lib/site-packages/pyright/dist/dist"}}
[jsonrpc] e[12:09:57.281] <-- window/logMessage {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"Starting service instance \"d:/test/\""}}
[jsonrpc] e[12:09:57.281] <-- initialize[1] {"jsonrpc":"2.0","id":1,"result":{"capabilities":{"textDocumentSync":2,"definitionProvider":{"workDoneProgress":true},"declarationProvider":{"workDoneProgress":true},"typeDefinitionProvider":{"workDoneProgress":true},"referencesProvider":{"workDoneProgress":true},"documentSymbolProvider":{"workDoneProgress":true},"workspaceSymbolProvider":{"workDoneProgress":true},"hoverProvider":{"workDoneProgress":true},"documentHighlightProvider":{"workDoneProgress":true},"renameProvider":{"prepareProvider":true,"workDoneProgress":true},"completionProvider":{"triggerCharacters":[".","[","\"","'"],"resolveProvider":true,"workDoneProgress":true,"completionItem":{"labelDetailsSupport":true}},"signatureHelpProvider":{"triggerCharacters":["(",",",")"],"workDoneProgress":true},"codeActionProvider":{"codeActionKinds":["quickfix","source.organizeImports"],"workDoneProgress":true},"executeCommandProvider":{"commands":[],"workDoneProgress":true},"callHierarchyProvider":true,"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":true}}}}}
[jsonrpc] e[12:09:57.281] --> initialized {"jsonrpc":"2.0","method":"initialized","params":{}}
[jsonrpc] e[12:09:57.282] --> textDocument/didOpen {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///d%3A/test/test.py","version":0,"languageId":"python","text":"# cspell:words nostarch\n\n# 2.3.1\nname = \"ada lovelace\"\nprint(name.title())\nprint(name.upper())\nprint(name.lower())\nprint(f\"Hello, {name.title()}\")\n\nfilename = \"python_notes.txt\"\nprint(filename.removesuffix(\".txt\"))\n"}}}
[jsonrpc] e[12:09:57.283] --> workspace/didChangeConfiguration {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}
[jsonrpc] e[12:09:57.316] <-- client/registerCapability[0] {"jsonrpc":"2.0","id":0,"method":"client/registerCapability","params":{"registrations":[{"id":"07f50433-473c-4d80-9022-b08d869697c1","method":"workspace/didChangeWatchedFiles","registerOptions":{"watchers":[{"globPattern":"**/pyrightconfig.json","kind":7},{"globPattern":"**","kind":7}]}}]}}
[jsonrpc] e[12:09:59.760] --> client/registerCapability[0] {"jsonrpc":"2.0","id":0,"error":{"code":-32603,"message":"Internal error"}}
[jsonrpc] e[12:09:59.760] <-- workspace/configuration[1] {"jsonrpc":"2.0","id":1,"method":"workspace/configuration","params":{"items":[{"scopeUri":"file:///d%3A/test","section":"python"}]}}
[jsonrpc] e[12:09:59.761] --> workspace/configuration[1] {"jsonrpc":"2.0","id":1,"result":[null]}
[jsonrpc] e[12:09:59.763] --> textDocument/codeAction[2] {"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///d%3A/test/test.py"},"range":{"start":{"line":8,"character":0},"end":{"line":8,"character":0}},"context":{"diagnostics":[],"triggerKind":2}}}
[jsonrpc] e[12:09:59.763] --> textDocument/documentHighlight[3] {"jsonrpc":"2.0","id":3,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///d%3A/test/test.py"},"position":{"line":8,"character":0}}}
[jsonrpc] e[12:09:59.763] --> textDocument/hover[4] {"jsonrpc":"2.0","id":4,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///d%3A/test/test.py"},"position":{"line":8,"character":0}}}
[jsonrpc] e[12:09:59.763] --> textDocument/signatureHelp[5] {"jsonrpc":"2.0","id":5,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"file:///d%3A/test/test.py"},"position":{"line":8,"character":0}}}
[jsonrpc] D[12:10:00.036] Connection state change: `exited abnormally with code 1
'

----------b---y---e---b---y---e----------
[stderr]  
[stderr]  
[stderr]  nil
[stderr]  nil
[stderr]  Process EGLOT (test/(python-ts-mode python-mode)) stderr finished

flymake log:

Warning [flymake.el *scratch*]: Disabling backend elisp-flymake-byte-compile because (user-error "Disabling elisp-flymake-byte-compile in *scratch* (untrusted content)")
Warning [flymake.el test.py]: Disabling backend python-flymake because (error "Cannot find a suitable checker")

warnings:

Warning (eglot): Not auto-reconnecting, last one didn’t last long.

messages:

Loading c:/Users/fluzzy/AppData/Roaming/.emacs.d/recentf.eld...done
Cleaning up the recentf list...done (0 removed)
Disabling elisp-flymake-byte-compile in *scratch* (untrusted content)
For information about GNU Emacs and the GNU system, type C-h C-a.
Error in post-command-hook (evil-normal-post-command): (void-variable evil-mode-buffers)
Can’t guess python-indent-offset, using defaults: 4 [2 times]
Ignoring unknown directive "NOTE" in file: c:/Users/fluzzy/AppData/Roaming/.emacs.d/elpa/yasnippet-snippets-1.0/snippets/python-mode/function_docstring
Error in post-command-hook (evil-normal-post-command): (void-variable evil-mode-buffers)
[eglot] Connected! Server ‘EGLOT (test/(python-ts-mode python-mode))’ now managing ‘(python-ts-mode python-mode)’ buffers in project ‘test’.
[jsonrpc] Server exited with status 1
[eglot] (warning) Not auto-reconnecting, last one didn’t last long.
Error in post-command-hook (evil-normal-post-command): (void-variable evil-mode-buffers)
Mark set [2 times]
Copied text from "[jsonrpc] D[12:09:56.553] Running langua"
SPC <menu-bar> is undefined
Error in post-command-hook (evil-normal-post-command): (void-variable evil-mode-buffers)
<buffer> is undefined
Mark set
Error in post-command-hook (evil-normal-post-command): (void-variable evil-mode-buffers)
Beginning of buffer [2 times]
Error in post-command-hook (evil-normal-post-command): (void-variable evil-mode-buffers) [2 times]
Beginning of buffer

從報錯信息來看,你的問題是 pyright 啟動了以後又自動退出了。所以是 basedpyright 為什麼啟動以後會自動退出,是需要你解決的問題。你可以在命令行裡直接運行 basedpyright 的那個啟動命令看看會是什麼情況。

注意看 log 信息,先是說 eglot succesfully managed xxx project with basedpyright,緊接著下一行就是 exit with code 1

大佬我找到原因了,原来是因为根目录下要包含“.git”、“pyproject.toml”、“pyrightconfig.json”等root_marker,但是打开任意目录的python文件eglot都能连接可以通过配置做到吗?

同时也感谢楼上各位提供指导的大佬们