From 479ff0d434261dadbff728027a4f1e95576792f1 Mon Sep 17 00:00:00 2001 From: Carl Gay Date: Sat, 20 Apr 2024 13:51:30 -0400 Subject: [PATCH] doc: create initial doc, based on README.md Also added a section on developing lsp-dylan. --- README.md | 104 +------------- documentation/Makefile | 20 +++ documentation/make.bat | 35 +++++ documentation/source/conf.py | 58 ++++++++ documentation/source/index.rst | 241 +++++++++++++++++++++++++++++++++ dylan-package.json | 1 + 6 files changed, 357 insertions(+), 102 deletions(-) create mode 100644 documentation/Makefile create mode 100644 documentation/make.bat create mode 100644 documentation/source/conf.py create mode 100644 documentation/source/index.rst diff --git a/README.md b/README.md index 03ab5dd..a49be3f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Dylan. ## Current Status -As of 2022-11-07, the server implements +As of 2024-04-19, the server implements * Jump to declaration * Jump to definition @@ -19,104 +19,4 @@ definition" will show a list containing the generic function and its specific methods, whereas "jump to declaration" will jump straight to the generic function. -We are currently using version [3.15 of the LSP -protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-3-15/). - - -## Opening Projects - -The LSP server needs to be able to open a project (that is, a Dylan library) -associated with the file you're editing when you turn on LSP in your editor. It -assumes you are using a [dylan-tool](https://github.com/dylan-lang/dylan-tool) -workspace and searches for a project to open as follows: - -1. If there is a `workspace.json` file and that file has a `"default-library"` - property, the specified library is opened. - -2. It uses `dylan-tool` to choose a library defined in the workspace. This is - [generally](https://github.com/dylan-lang/dylan-tool/blob/292b7bf761745c9fa810511c9888f802dd787011/sources/workspaces/workspaces.dylan#L151) - the test suite library, if one exists. - -Normally you shouldn't need to set any environment variables; everything is -derived from the full pathname to the `dylan-compiler` executable, which must -be on your `PATH`. - -## Emacs Usage - -1. Make sure the `dylan-lsp-server` executable is on your `PATH`, or customize - the `lsp-dylan-exe-pathname` elisp variable. See below for more on - customization. - -1. Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) and Dylan mode. - Both of these are available from MELPA. - -2. When you jump to another `.dylan` file, that file does not automatically - have LSP enabled so you must use `M-x lsp` again. To make this automatic, - add this to your emacs init file: - - `(add-hook 'dylan-mode-hook 'lsp)` - -3. Start emacs and make sure that `lsp-dylan.el` is loaded. For example: - - `emacs --load=/path/to/lsp-dylan/lsp-dylan.el` - - You will probably want to modify your Emacs init file to load the file. - -4. Open a Dylan source file and type `M-x lsp` to start the client (unless you - added the hook above, in which case it started automatically). - -The client starts the LSP server (the `dylan-lsp-server` executable) and -connects to it. - -The emacs client has a customization group "lsp-dylan" which is a member of the -"Language Server (lsp-mode)" group, and has the following variables: - -* `lsp-dylan-exe-pathname` -* `lsp-dylan-extra-command-line-options` -* `lsp-dylan-log-pathname` -* `lsp-dylan-open-dylan-release` - -These are documented in the customization interface within emacs. Use `M-x -customize-group` `lsp-dylan` to customize these variables. - -## Visual Studio Code Usage - -These instructions were tested on Linux and macOS. - -1. Install Visual Studio Code and `npm`. -2. The VS Code extension is in the folder `vscode-dylan`. It is necessary to - run `npm install` in this folder before starting the extension for the - first time, and any time a git pull updates the dependencies. -3. Open the `vscode-dylan` folder in VS Code. -4. In the debug viewlet, click the green play arrow (Launch Extension) or - press `F5`. -5. A build process will begin in 'watch mode'; whenever the source is changed, - the extension will be rebuilt. It is possible to debug the VS Code - extension in this window, set breakpoints, watch variables and so on. -6. A new VS Code window will open with the extension running. -7. Open a folder with a Dylan project in it. -8. If `dylan-lsp-server` is on the system path, it will be found. Otherwise, - open the Settings *in the new extension window*, find the Dylan section - under Extensions, and edit the path to the LSP server. The full, absolute - pathname to the executable needs to be specified. It is usually better to - set this in the 'User' scope, otherwise it will only apply to that - particular project. -9. It should now be possible to use the extension window to edit Dylan code - using LSP. -10. If the VS Code extension is changed, it is necessary to restart the - extension host, or just close and re-open the extension window. - - -## References - -* [Intro to LSP from - Microsoft](https://docs.microsoft.com/en-us/visualstudio/extensibility/language-server-protocol) - Besides being a quick introduction, this has links to some other tools that - would help in developing VS Code integration for Dylan. - -* [LSP v3.15 - Specification](https://microsoft.github.io/language-server-protocol/specifications/specification-3-15/) - This is the version we are currently coding to. - -* [langserver.org](https://langserver.org/) lists LSP implementations that - support at least one of the six major LSP features. +See documentation/source/index.rst for full documentation. diff --git a/documentation/Makefile b/documentation/Makefile new file mode 100644 index 0000000..be50b8a --- /dev/null +++ b/documentation/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -v +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/documentation/make.bat b/documentation/make.bat new file mode 100644 index 0000000..6247f7e --- /dev/null +++ b/documentation/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/documentation/source/conf.py b/documentation/source/conf.py new file mode 100644 index 0000000..80d8ba3 --- /dev/null +++ b/documentation/source/conf.py @@ -0,0 +1,58 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../../_packages/sphinx-extensions/current/src/sphinxcontrib')) +sys.path.insert(0, os.path.abspath('../../../_packages/sphinx-extensions/current/src/sphinxcontrib')) +import dylan.themes as dylan_themes + + +# -- Project information ----------------------------------------------------- + +project = 'lsp-dylan' +copyright = '2019, Peter Hull' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'dylan.domain' +] + +# Necessary to make things like '.. current-module:: foo' work. +primary_domain = 'dylan' + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'furo' +# html_theme = dylan_themes.get_html_theme_default() + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/documentation/source/index.rst b/documentation/source/index.rst new file mode 100644 index 0000000..b53d324 --- /dev/null +++ b/documentation/source/index.rst @@ -0,0 +1,241 @@ +.. highlight:: shell + +********************* +Dylan Language Server +********************* + +This is an implementation of the `Language Server Protocol +`_ for Dylan. + +.. toctree:: + :hidden: + +Current Status +============== + +As of 2024-04-19, the server implements + +* Jump to declaration +* Jump to definition +* Diagnostics (i.e., compiler warnings) +* Hover (i.e., argument lists) + +When applied to a symbol which is bound to a generic function, "jump to +definition" will show a list containing the generic function and its specific +methods, whereas "jump to declaration" will jump straight to the generic +function. + +Installation +============ + +1. First install `Open Dylan `_ 2023.1 or newer. + +2. Clone the `lsp-dylan repository `_:: + + $ git clone --recursive https://github.com/dylan-lang/lsp-dylan + +3. Update the workspace so that dependencies are installed and the registry is + created:: + + $ cd lsp-dylan + $ dylan update + +4. Build the ``dylan-lsp-server`` binary. This will install the binary in + ``${DYLAN}/bin``. If :envvar:`DYLAN` is not defined it defaults to + ``${HOME}/dylan``. + :: + + $ make install + + or just run these commands:: + + $ dylan build --unify dylan-lsp-server + $ cp _build/sbin/dylan-lsp-server /usr/local/bin/ + +5. Make sure ``dylan-lsp-server`` is on your :envvar:`PATH`. + + +Usage +===== + +The LSP server needs to be able to open a project (that is, a Dylan library) +associated with the file you're editing when you turn on LSP in your editor. It +assumes you are using a `dylan-tool +`_ workspace and searches for a +project to open as follows: + +1. If there is a :file:`workspace.json` file and that file has a + `"default-library"` property, the specified library is opened. + +2. It uses the :program:`dylan` tool to choose a library defined in the + workspace. This is `generally + `_ + the test suite library, if one exists; otherwise it chooses a project + arbitrarily. + +Normally you shouldn't need to set any environment variables; everything is +derived from the full pathname to the :program:`dylan-compiler` executable, +which must be on your :envvar:`PATH`. + +When you open each new file in your editor the LSP client may try to start a +new project if the file isn't part of the same :program:`dylan` workspace +directory. If you want the client to use just one project, use a `multi-package +workspace `_. + +.. note:: Always run ``dylan update`` and ``dylan build -a`` in your workspace + **before** starting the LSP server, or :program:`dylan-lsp-server` + may not be able to open your project. (This requirement will be + removed in a future release.) + + +Emacs Usage +----------- + +1. Make sure the :program:`dylan-lsp-server` executable is on your + :envvar:`PATH`, or customize the ``lsp-dylan-exe-pathname`` elisp variable. See + below for more on customization. + +2. Install `lsp-mode `_ and `dylan-mode + `_. Both of these are + available from MELPA. + +3. When you jump to another :file:`.dylan` file, that file does not + automatically have LSP enabled so you must use ``M-x lsp`` again. To make + this automatic, add this to your emacs init file: + + .. code-block:: elisp + + (add-hook 'dylan-mode-hook 'lsp) + +4. Start emacs and make sure that :file:`lsp-dylan.el` is loaded. For example:: + + emacs --load=/path/to/lsp-dylan/lsp-dylan.el + + You will probably want to modify your Emacs init file to load the file with + + .. code-block:: elisp + + (load "/path/to/lsp-dylan/lsp-dylan.el") + +5. Open a Dylan source file and type ``M-x lsp`` to start the client (unless + you added the hook above, in which case it started automatically). + +The client starts the LSP server (the `dylan-lsp-server` executable) and +connects to it. You should see a message telling you what Dylan project was +opened. + +The emacs client has a customization group "lsp-dylan" which is a member of the +"Language Server (lsp-mode)" group, and has the following variables: + +* ``lsp-dylan-exe-pathname`` +* ``lsp-dylan-extra-command-line-options`` +* ``lsp-dylan-log-pathname`` +* ``lsp-dylan-open-dylan-release`` + +These are documented in the customization interface within emacs. Use ``M-x +customize-group`` ``lsp-dylan`` to customize these variables. + +.. note:: Emacs lsp-mode saves state in :file:`~/.emacs.d/.lsp-session-v1`. If + you have a problem with Dylan's LSP support it's a good idea to + delete this file and try again. + + +Visual Studio Code Usage +------------------------ + +These instructions were tested on Linux and macOS. + +1. Install Visual Studio Code and ``npm``. + +2. The VS Code extension is in the folder ``vscode-dylan``. It is necessary to + run ``npm install`` in this folder before starting the extension for the + first time, and any time a ``git pull`` updates the dependencies. + +3. Open the ``vscode-dylan`` folder in VS Code. + +4. In the debug viewlet, click the green play arrow (Launch Extension) or + press ``F5``. + +5. A build process will begin in 'watch mode'; whenever the source is changed, + the extension will be rebuilt. It is possible to debug the VS Code + extension in this window, set breakpoints, watch variables and so on. + +6. A new VS Code window will open with the extension running. + +7. Open a folder with a Dylan project in it. + +8. If :program:`dylan-lsp-server` is on the system path, it will be + found. Otherwise, open the Settings *in the new extension window*, find the + Dylan section under Extensions, and edit the path to the LSP server. The + full, absolute pathname to the executable needs to be specified. It is + usually better to set this in the 'User' scope, otherwise it will only + apply to that particular project. + +9. It should now be possible to use the extension window to edit Dylan code + using LSP. + +10. If the VS Code extension is changed, it is necessary to restart the + extension host, or just close and re-open the extension window. + + +LSP Server Development +====================== + +This section contains notes for people interested in helping to improve LSP +support for Dylan. + +Open Dylan +---------- + +Unless you're an Open Dylan expert already, you'll probably find that you want +to add debug statements in the Open Dylan IDE code to figure out what's going +on.... + +1. Turn on the ``--debug-opendylan`` by customizing + ``lsp-dylan-extra-command-line-options``. This causes extra in the + ``*lsp-dylan::stderr*`` buffer from calls to the ``debug-out`` macro. + +2. Create a multi-package workspace with both the ``lsp-dylan`` repo and the + ``opendylan`` repo:: + + $ mkdir lsp; cd lsp + $ git clone --recursive https://github.com/dylan-lang/lsp-dylan + $ git clone --recursive https://github.com/dylan-lang/opendylan + $ echo '{ "default-library": "dylan-lsp-server" }' > workspace.json + +3. Sprinkle calls like ``debug-out(#"lsp", "your message here", ...)`` around + in the Open Dylan code as needed. + +4. Remember to delete :file:`~/.emacs.d/.lsp-session-v1`` as needed. I (cgay) + usually start a new emacs after rebuilding :program:``dylan-lsp-server``, + like this:: + + $ rm -f ~/.emacs.d/.lsp-session-v1; emacs & + + If you don't start a new emacs, you probably want to at least kill the old + :program:`dylan-lsp-server` process. I (cgay) usually rebuild like this:: + + $ pkill -f bin/dylan-lsp-server; make install + + +References +========== + +* `Intro to LSP from Microsoft + `_ - + Besides being a quick introduction, this has links to some other tools that + would help in developing VS Code integration for Dylan. + +* `LSP v3.15 Specification + `_ - + This is the version we are currently coding to. + +* `langserver.org `_ lists LSP implementations that + support at least one of the six major LSP features. + + +Index and Search +================ + +* :ref:`genindex` +* :ref:`search` diff --git a/dylan-package.json b/dylan-package.json index 45027a6..094fa34 100644 --- a/dylan-package.json +++ b/dylan-package.json @@ -10,6 +10,7 @@ "uncommon-dylan@0.2", ], "dev-dependencies": [ + "sphinx-extensions", "testworks", "vscode-dylan" ],