Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
* Prolog Language server /Recent development has been sponsored by [[https://logicmoo.org][LogicMoo]] - Thank you!/ Still a work-in-progress -- please open an issue if you have any issues or feature requests!. Currently supports: - diagnostics (singleton variables, syntax errors) via xref - find references/definitions - documentation of predicates on hover - auto-completion of predicates - code formatting (✨new!✨) - symbol highlighting (✨new!✨) - variable renaming (✨new!✨) The code formatter can also be run stand-alone. After installing the ~lsp_server~ pack, you can run ~swipl formatter <file>~ at the command line. Only tested with SWI-Prolog, as it heavily uses its introspection facilities to do its stuff. It should work with any relatively-recent version of SWI-Prolog, but for best results (for "find references" in particular), use a version with ~xref_called/5~ (8.1.5 or newer; past commit [[https://github.com/SWI-Prolog/swipl-devel/commit/303f6430de5c9d7e225d8eb6fb8bb8b59e7c5f8f][303f6430de5c]]). Installable as a pack with ~swipl pack install lsp_server~ or ~?- pack_install(lsp_server).~ from a repl. As of version 2.5.0, running the server over a socket is now supported by passing in the commandline arguments ~port <port number>~ (instead of ~stdio~). If running on Windows directly (i.e. not via WSL) running the server via stdio will NOT work and you will need to run the server over a socket, so please consult that section of the documention for your editor.. * Emacs ** [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]]: *** socket server #+begin_src emacs-lisp (lsp-register-client (make-lsp-client :new-connection (lsp-tcp-connection (lambda (port) (list "swipl" "-g" "use_module(library(lsp_server))." "-g" "lsp_server:main" "-t" "halt" "--" "port" port))) :major-modes '(prolog-mode) :priority 1 :multi-root t :server-id 'prolog-ls)) #+end_src *** stdio server #+begin_src emacs-lisp (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection (list "swipl" "-g" "use_module(library(lsp_server))." "-g" "lsp_server:main" "-t" "halt" "--" "stdio")) :major-modes '(prolog-mode) :priority 1 :multi-root t :server-id 'prolog-ls)) #+end_src ** [[https://github.com/joaotavora/eglot][eglot]] *** socket server #+begin_src emacs-lisp (setopt eglot-server-programs (cons (cons 'prolog-mode (list "swipl" "-O" "-g" "use_module(library(lsp_server))." "-g" "lsp_server:main" "-t" "halt" "--" "port" :autoport)) eglot-server-programs)) #+end_src *** stdio server #+begin_src emacs-lisp (setopt eglot-server-programs (cons (cons 'prolog-mode (list "swipl" "-O" "-g" "use_module(library(lsp_server))." "-g" "lsp_server:main" "-t" "halt" "--" "stdio")) eglot-server-programs)) #+end_src * Vim/Neovim * Neovim ** [[https://github.com/neoclide/coc.nvim][CoC]] *** stdio server Put the following in ~coc-settings.json~ (which you can access by using the command ~:CocConfig~). #+begin_src json {"languageserver": { "prolog-lsp": { "command": "swipl", "args": ["-g", "use_module(library(lsp_server)).", "-g", "lsp_server:main", "-t", "halt", "--", "stdio" ], "filetypes": ["prolog"] }} } #+end_src *** socket server CoC does not support automatically starting a socket server. If you are on Windows and using CoC and hence need a socket server, you'll have to manually start the LSP process by running the following command: #+begin_src sh swipl -g 'use_module(library(lsp_server))' -g 'lsp_server:main' -t halt -- port 12345 #+end_src Where "12345" is an arbitrary, free port number. Then, with that started, add the following to ~coc-settings.json~ (accessed via ~:CocConfig~). #+begin_src json {"languageserver": { "prolog-lsp": { "host": "127.0.0.1", "port": 12345, "filetypes": ["prolog"] }} } #+end_src Ensuring the port entered in the config is the same one used when starting the server process ** Native LSP (for Neovim >= 0.11) *** stdio server Put the following in ~$XDG_CONFIG_DIR/nvim/lsp/prolog.lua~: #+begin_src lua return { cmd = { 'swipl', '-g', 'use_module(library(lsp_server))', '-g', 'lsp_server:main', '-t', 'halt', '--', 'stdio' }, root_markers = { '.git', }, filetypes = { 'prolog' }, } #+end_src And add ~vim.lsp.enable({'prolog'})~ to ~$XDG_CONFIG_DIR/nvim/init.lua~. *** socket server Put the following in ~$XDG_CONFIG_DIR/nvim/lsp/prolog.lua~: #+begin_src lua local find_port = function() local uv = vim.uv local tcp = uv.new_tcp() tcp:bind("127.0.0.1", 0) local port = tcp:getsockname().port tcp:close_reset() return port end return { cmd = function(...) local server_port = find_port() vim.system({'swipl', '-g', 'use_module(library(lsp_server))', '-g', 'lsp_server:main', '-t', 'halt', '--', 'port', server_port}, {}, function(...) print("LSP PROCESS EXITED", ...) end) vim.uv.sleep(500) return vim.lsp.rpc.connect('127.0.0.1', server_port)(...) end, root_markers = { '.git', }, filetypes = { 'prolog' }, } #+end_src And add ~vim.lsp.enable({'prolog'})~ to ~$XDG_CONFIG_DIR/nvim/init.lua~. ** Native LSP (for Neovim >= 0.5 < 0.11) Install the [[https://github.com/neovim/nvim-lspconfig][neovim/nvim-lspconfig]] package Put the following in ~$XDG_CONFIG_DIR/nvim/lua/lspconfig/prolog_lsp.lua~: #+begin_src lua local configs = require 'lspconfig/configs' local util = require 'lspconfig/util' configs.prolog_lsp = { default_config = { cmd = {"swipl", "-g", "use_module(library(lsp_server)).", "-g", "lsp_server:main", "-t", "halt", "--", "stdio"}; filetypes = {"prolog"}; root_dir = util.root_pattern("pack.pl"); }; docs = { description = [[ https://github.com/jamesnvc/prolog_lsp Prolog Language Server ]]; } } -- vim:et ts=2 sw=2 #+end_src Then add the following to ~init.vim~: #+begin_src viml lua << EOF require('lspconfig/prolog_lsp') require('lspconfig').prolog_lsp.setup{} EOF #+end_src * LazyVim ** stdio Create the following file in ~$XDG_CONFIG_DIR/nvim/lua/plugins/lsp.lua~ #+begin_src lua return { { "neovim/nvim-lspconfig", opts = { servers = { prolog = {}, }, setup = { prolog = function(_, opts) local lspconfig = require("lspconfig") local configs = require("lspconfig.configs") local util = require("lspconfig.util") local root_files = { ".git", "pack.pl" } if not configs.prolog then configs.prolog = { default_config = { cmd = { "swipl", "-g", "use_module(library(lsp_server)).", "-g", "lsp_server:main", "-t", "halt", "--", "stdio", }, filetypes = { "prolog" }, single_file_support = true, root_dir = util.root_pattern(unpack(root_files)), settings = {}, }, commands = {}, docs = { description = [[ Prolog LSP server ]], }, } end lspconfig.prolog.setup(opts) end, }, }, }, } #+end_src * VSCode Choose one from the list below: - download the latest ~.vsix~ file from the [[https://github.com/jamesnvc/lsp_server/releases][releases page]] - clone this repo and copy/symlink the ~vscode/~ directory to ~~/.vscode/extensions/~ - clone and build the ~.vsix~ file yourself by the follwing steps: 1. ~cd /path/to/clone/vscode~ 2. ~npm install~ 3. ~npx vsce package~ 4. add the resulting ~.vsix~ to VSCode by clicking the ~...~ at the top right of the "Extensions" panel then selecting ~Install from VSIX...~ * Helix Helix already includes configuration for this Prolog LSP server, so it should mostly Just Work. However, the default configuration gives the '.pl' extension to perl, so to avoid having to manually do ~:set-language prolog~ each time, you can add the following to ~$XDG_CONFIG/helix/languages.toml~ to remove Perl's association with that extension: #+begin_src toml [[language]] name = "perl" file-types = ["perl"] #+end_src * Kate Open settings, go to ~LSP Client~, select the ~User Server Settings~ tab, and add the following content (or merge with your existing settings if present): #+begin_src json { "servers": { "prolog": { "command": ["swipl", "-O", "-g", "use_module(library(lsp_server))", "-g", "lsp_server:main", "-t", "halt", "--", "stdio"], "url": "https://github.com/jamesnvc/lsp_server", "root": "" "highlightingModeRegex": "^Prolog$" } } } #+end_src