Giter VIP home page Giter VIP logo

purescript-language-server's Introduction

PureScript language server

Node-based Language Server Protocol server for PureScript based on the PureScript IDE server (aka psc-ide / purs ide server). Used as the vscode plugin backend but should be compatible with other Language Server Client implementations.

The language server is a wrapper around the IDE server included as part of the compiler distribution, providing editing assistance and build features according to support available. This means that the server will start its own purs ide server instance to talk to for the project directory it is started in.

Features

  • Completion provider
  • Definition provider
  • Formatting provider
  • Document & workspace symbol providers
  • Hover provider
  • Code action provider
    • Compiler fix suggestions for imports/missing types
  • Build on save (via IDE server "fast rebuild" facility, certain limitations apply)
    • Provides diagnostics
  • Commands
    • Build (full build via purs compile / configured build command) - provides diagnostics
    • Case split
    • Add clause
    • Replace suggestion
    • Add completion import
    • Start IDE server
    • Stop IDE server
    • Restart IDE server
  • Config
    • purescript.*

Usage

This LSP implmementation is consumed by vscode and Atom plugins as a node module, and bundled along with those plugins.

To use with another LSP client, you will want to install this either globally or locally for npm, e.g.

npm i -g purescript-language-server

And then use the resulting executable, e.g. purescript-language-server --stdio.

This language server is based on vscode-languageserver-node which means it should support --stdio, --socket=[number], --node-ipc or --pipe methods of communication, see vscode-languageserver-node for details.

Version support policy

PureScript compiler version support is as follows:

  • The current minor version of the compiler is supported at all patch versions (e.g. 0.14.xx)
  • The previous minor version of the compiler is supported at the latest patch version (e.g. 0.13.8) for new functionality, and where possible all patch versions for existing functionality
  • Any older compiler versions are not officially supported - they may continue to work and will not be intentionally broken, but no particular effort will be made for continued support in the face of API changes

Formatting provider

The purescript-language-server comes with support for formatting PureScript code via several external tools, exposed as a standard LSP formatting provider. When a formatting operation is requested, purescript-language-server will attempt to find the configured tool via its standard name in your $PATH (or the local npm install path if purescript.addNpmPath is set).

The formatting tool is selected via purescript.formatter, with the following options

  • No formatter - simply leave the setting unset or empty (default)
  • purs-tidy (or simply tidy). If you do not have any existing preferences this would be the suggested pick.
  • pose
  • purty

VSCode

Use vscode-ide-purescript.

Atom

Use atom-ide-purescript.

Neovim’s built-in language server + nvim-lspconfig

As of 0.5.0, Neovim has a built-in language server client. A popular plugin to help with configuring this server is nvim-lspconfig. This plugin includes purescriptls which will automatically find and root the language server as well as connect PSCIDE, etc. (for more info, read the config). To use, add this to your init.lua or inside a EOF << lua … EOF block in your init.vim.

nvim_lsp.purescriptls.setup {
  " Your personal on_attach function referenced before to include
  " keymaps & other ls options
  on_attach = on_attach,
  settings = {
    purescript = {
      addSpagoSources = true -- e.g. any purescript language-server config here
    }
  },
  flags = {
    debounce_text_changes = 150,
  }
}

Vim/LSP

Auto configuration with vim-lsp-settings

Vim/CoC

Configuration with coc.nvim

Run :CocConfig and add "purescript" in the "languageserver" section as follows:

  "languageserver": {
    "purescript": {
      "command": "purescript-language-server",
      "args": ["--stdio"],
      "filetypes": ["purescript"],
      "trace.server": "off",
      "rootPatterns": ["bower.json", "psc-package.json", "spago.dhall"],
      "settings": {
        "purescript": {
          "addSpagoSources": true,
          "addNpmPath": true, // Set to true if using a local purty install for formatting
          "formatter": "purs-tidy"
          // etc
        }
      }
    }
  }

CoC can be configured to format your code using the purescript-language-server's formatting provider, which is backed by purty. If you don't have CoC-based code formatting setup in CoC already, you can add a command or key mapping like this:

command! -nargs=0  Format      :call CocAction('format')
nmap               <leader>f   :Format<cr>

If you want the formatter to run on save, run :CocConfig and add "purescript" to the "coc.preferences.formatOnSaveFiletypes":

  "coc.preferences.formatOnSaveFiletypes": [
    // ...other languages
    "purescript"
  ]

You can also organize PureScript imports in Vim with a command and/or key mapping like this:

command! -nargs=0  OrganizeImports :call CocAction('runCommand', 'editor.action.organizeImport')
nmap               <leader>o       :OrganizeImports<cr>

Vim/LanguageClient_neovim

Use vimmer-ps.

Other clients

Config may be supplied via client-push on startup (workspace.didChangeConfiguration), server-request (workspace.configuration), or at last resort by JSON object on the command line with --config option.

Config

See config defined in vscode plugin.

Usage with alternate backends

When using the language server together with alternate backends, the only requirement is to stop purs ide server from attempting to generate JS when rebuilding, this is done via the config

"purescript.codegenTargets": [ "corefn" ]

(and you should make sure the build command is in accordance with that, if used, eg specify backend in spago config).

Commands

Various commands are provided. Some are triggered via completion etc, some must be called explicitly from a LSP client.

purescript.build

No arguments. Provides diagnostics.

purescript.startPscIde

No arguments. Start IDE server according to configuration.

purescript.stopPscIde

No arguments. Stop running IDE server.

purescript.restartPscIde

No arguments. Stop any running IDE server then start a new one according to configuration.

purescript.addCompletionImport

Arguments: identifier, module, document URI.

purescript.addModuleImport

Arguments: module, qualifier, document URI.

purescript.getAvailableModules

No arguments. Get list of available modules.

purescript.replaceSuggestion

Arguments: document URI, replacement, replacement range.

purescript.search

Flex search for identifier.

Arguments: search text.

purescript.fixTypo

Arguments: document URI, line, character.

purescript.caseSplit-explicit

(Used to back the case split command in VS Code UI).

Arguments: document URI, line, character, type.

purescript.addClause-explicit

(Used to back the add clause command in VS Code UI).

Arguments: document URI, line, character.

purescript.typedHole-explicit

(Used to back the purescript.typedHole code action triggered in the VS Code UI)

Arguments: hole name, document URI, hole range, PscIde.Command.TypeInfo of chosen replacement option

Development

To develop (rather than use) this language server

  1. Clone this repo and npm install
  2. Make changes and npm run build
  3. Ensure the built module is picked up by your editor

For 3, if the editor integrates using the node module rather than standalone binary, I suggest using npm link - this will work for atom and vscode at least.

For atom, clone atom-ide-purescript and:

  1. In purescript-language-server run npm link, in atom-ide-purescript run npm link purescript-language-server
  2. In atom-ide-purescript run apm link to pick up local changes
  3. In atom-ide-purescript, run npm run bundle to build the plugin itself
  4. Reload any atom window to pick up changes

For vscode, clone vscode-ide-purescript and:

  1. Run npm install
  2. In purescript-language-server run npm link, in vscode-ide-purescript run npm link purescript-language-server
  3. Open vscode-ide-purescript in vscode (code .) and hit F5 to "launch extension"
  4. Use the newly launched Extension Development Host to test language server changes

See vscode plugin repo, atom plugin. Common code via purescript-ide-purescript-core.

purescript-language-server's People

Contributors

alessioprestileo avatar andys8 avatar andywhite37 avatar aranchelk avatar dariooddenino avatar dependabot[bot] avatar dretch avatar f-f avatar hrajchert avatar i-am-the-slime avatar justinwoo avatar klarkc avatar krzysztof-cieslak avatar milesfrain avatar natefaubion avatar nwolverson avatar sriharshachilakapati avatar stevenyap avatar toastal avatar ursi avatar vanceism7 avatar wclr avatar williamboman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-language-server's Issues

Completion on qualifiers

Using the pattern of

import Appropriately.Qualified.LongModuleName as LongModuleName

...LongModuleName.blah

It would be nice to complete on LongModuleName itself, as well as the qualified completions after the .

Usage with generic plugins

I tried integrating this project with Vim plugins that communicate over generic Language Servers, but I haven't gotten it to work yet. Any insight you have is appreciated:

LanguageClient-neovim Issue: autozimu/LanguageClient-neovim#527

Ale PR: dense-analysis/ale#1737

(btw - is there a way to generate some log on the server side? I see the client can trigger it but maybe there's some independent flag?)

Thanks!

Windows diagnostic paths discrepancy

Full build is returning paths like file:///c%3a/... while path returned for single file rebuild is file:///C:/... (just returned back to the caller), in a sense it seems these may both work after normalisation but

  1. This is resulting in sending an empty array of diagnostics for the old version while sending the new diagnostics for the new version
  2. atom-ide-ui diagnostics will navigate to file correctly for the full build version but doesn't normalise to relative path or filter it with "show this file".

It seems a server will start in VSCode and Atom regardless of the setting to autostart

I have a scenario where I'd like to setup my own server so that I can edit code in some bower link'd projects and have the server take care of compiling code regardless of the project I'm in. It works fine in vim, so I know the server setup is good, but when I use VSCode or Atom they both start up their own server regardless of the "autostart on load" setting, which means they don't talk to the server I've setup for my own purposes.

I'll look through this code and see if I can figure out how to resolve this, but might be better if someone who understood this codebase better took a look

Clarify --config option (provide example)

Hey, I'm trying to use this language server with vim. According to README, the flag --config is required, but there is no explanation on what should the value contain. There is a link to vscode-ide-purescript's package.json but it doesn't help much. Would be great if you provided some example config.

Not launching with NPM bin for purs executable

We had some projects that are using different purescript compiler versions, and hence I decided to add the purescript version that we use as an NPM dev-dependency so that everyone will have the same compiler version.

However, I'm having some trouble trying to launch multiple projects at the same time (in different NVIM instances of course). I looked into the configuration, and added the purescript.addNpmPath key to true in the config JSON, but still using npm-bin was coming out as false.

let config =
    \ { 'purescript.autoStartPscIde': v:true
    \ , 'purescript.pscIdePort': v:null
    \ , 'purescript.autocompleteAddImport': v:true
    \ , 'purescript.pursExe': 'purs'
    \ , 'purescript.trace.server': 'verbose'
    \ , 'purescript.addNpmPath': v:true
    \ }

This is the output I'm getting from the language server client. Can you explain what am I doing wrong here?

[LC] [Log] Starting with args: [ "/Users/sriharshachilakapati/.nvm/versions/node/v11.9.0/bin/node", "/Users/sriharshachilakapati/.nvm/versions/node/v11.9.0/bin/purescript-language-server", "--stdio", "--config", "{\"purescript.pscIdePort\": null, \"purescript.addNpmPath\": true, \"purescript.autocompleteAddImport\": true, \"purescript.trace.server\": \"verbose\", \"purescript.autoStartPscIde\": true, \"purescript.pursExe\": \"purs\"}" ]
[LC] [Log] Starting with cwd: /Users/sriharshachilakapati/Projects/*****-*******-**** and using root path: /Users/sriharshachilakapati/Projects/*****-*******-****
[LC] [Info] Resolved IDE server paths (npm-bin: false) from PATH of /Users/sriharshachilakapati/.nvm/versions/node/v11.9.0/bin:/Users/sriharshachilakapati/.nvm/versions/node/v9.5.0/bin:/Users/sriharshachilakapati/.jenv/shims:/Users/sriharshachilakapati/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/sriharshachilakapati/.nvm/versions/node/v9.5.0/bin:/Users/sriharshachilakapati/.jenv/shims:/Users/sriharshachilakapati/bin:/Users/sriharshachilakapati/Library/Android/sdk/build-tools/:/Users/sriharshachilakapati/Library/Android/sdk/platform-tools/:/Users/sriharshachilakapati/Library/Android/sdk/tools/:/Users/sriharshachilakapati/Library/Android/sdk/build-tools/:/Users/sriharshachilakapati/Library/Android/sdk/platform-tools/:/Users/sriharshachilakapati/Library/Android/sdk/tools/ (1st is used):
[LC] [Info] /Users/sriharshachilakapati/.nvm/versions/node/v11.9.0/bin/purs: 0.12.3
[LC] [Info] /Users/sriharshachilakapati/.nvm/versions/node/v9.5.0/bin/purs: 0.11.7
[LC] [Info] /Users/sriharshachilakapati/.nvm/versions/node/v9.5.0/bin/purs: 0.11.7
[LC] [Warning] Found multiple IDE server executables; using /Users/sriharshachilakapati/.nvm/versions/node/v11.9.0/bin/purs
[LC] [Info] Found existing port from file: 15275
[LC] [Info] Starting IDE server on port 15965 with cwd
[LC] [Log] Started IDE server (port 15965)
[LC] [Info] [Error] Version mismatch for the externs at: /Users/sriharshachilakapati/Projects/*****-*******-****/output/Control.Monad.Except.Trans/externs.js Expected: 0.12.3 Found: 0.12.2

Local definitions

Right now the language server cannot show type info for local definitions.

Check reloading on build

"Full build should fix everything" - are we reloading dependencies on build completion?
Should affect

  • First project build
  • Adding dependency

No instantaneous diagnostics feedback?

First thanks for this project.

I noticed this server behaves differently than all others I use, it only provide errors on file save. Any plans to provide instantaneous diagnostics like others? Some servers provide a flag for this, bingo for example provide the --diagnostics-style option.

Found existing IDE server on port (%d) with wrong PATH

A user of my Vim wrapper reported today that he is not able to use an existing IDE server with the language server. From the logs, this is the configuration that I'm passing to the language server.

{ "purescript":
    { "autoStartPscIde": true
    , "pscIdePort": 8898
    , "autocompleteAddImport": true
    , "pursExe": "purs"
    , "addNpmPath": true
    }
}

And he's greeted with an error as follows:

[LC] [Error] Found existing IDE server on port '8898' with wrong path: '/home/paluh/programming/purescript/projects/audiocarrier'. Correct, kill or configure a different port, and restart.

I've tried this myself, to check if it is the path that is wrong indeed, and found it is not the case:

CWD checks

Any idea on what are we doing wrong?

Original issue on my Vim plugin: shivamashtikar/vimmer-ps#4

Improve compiler mismatch experience

Currently we offer rebuild suggestion on module mismatch error message, but if we can get some compiler info that there is an externs mismatch we can be more proactive

Completion of Prim modules

Not sure if this is a duplicate, or if this is even the right repo to report this issue.

I noticed that automatic import with completion in my IDE (vscode) doesn't work on Prim classes. For example, I can type getBody, press tab, and then this line is inserted:

import Node.Express.Request (getBody)

But typing RowToList doesn't bring up any autocomplete options, and I need to manually add this import:

import Prim.RowList (class RowToList)

Sort/Clean/Format imports

(Not sure if this can be done without a purs-ide change)

Be nice to have a reformat imports command, currently I can apply import suggestions easily, but to apply the auto ordering, the easiest thing is to tab-complete a new import then remove it.

I don't think this is the same as code formatting necessarily, as this is something already done in purs ide server, though there is certainly overlap if a formatter works on regions rather than whole files

Add ranking for preferred modules

Right now it uses preferred modules when the same thing is exported from multiple places, but I think we should also rank preferred modules higher even when the exports aren't the same.

Modules not found when bower is not used as package manager

First of all thanks for the language server.

I'm having an issue going through the tutorials of https://github.com/adkelley/javascript-to-purescript.
The dependencies gets installed in the .psc-package folder instead of the bower_components
I believe the problem is that the server assumes (and It was correct in the past) that the deps are in the bower_components folder, see

packagePath = getString "packagePath" "bower_components"

If that is the issue maybe I can provide some help with your guidance, I'm trying to learn PS.

Go-to-definition only works for bower projects in Atom - due to sourceGlobs / packagePath config mismatch

Right now go-to-definition does not work for Spago projects (even when setting the source paths to include the .spago folder), and I think this is why:

I changed purescript-language-server locally so it looked at sourceGlobs, and go-to-definition starting working with my .spago folder... but making the change would likely break vscode, which is not good. I need to do some more digging before I can suggest a proper fix.

Find References feature broken

Whenever I try to issue a find references command, I get this output instead.

[LC] [Info] [Error] Parsing the command failed. Command: {"params":{"identifier":"liftEff","namespace":"value","module":"Control.Monad.Eff.Class"},"command":"usages"} @(main:Command.Ide app/Command/Ide.hs
:187:17)

Using PureScript 0.12.5, latest purescript-language-server.

Client is LanguageClient_NeoVim, and invoked using the built-in function LanguageClient_textDocument_references() which gives references of the identifier under cursor.

onivim test run

Hello there!

I tried installing the language server (in ubuntu 18.10: npm i -g purescript-language-server) and using it in onivim with no success. Onivim comes with language server support and it does seem that there's some purescript-language-server activity (in the developer console), but it doesn't do anything more than that, as it can be seen in the screenshot. I have no idea if this is oni's fault or not, I was hoping you could give me some pointers on how I could debug this, perhaps you could think of something :)

image

The language server is configured in oni with:

"language.purescript.languageServer.command": "purescript-language-server",
"language.purescript.languageServer.arguments": ["--stdio"],

oni support only --stdio. Can't think of anything else right now. Thanks!

Autocompletion not working for qualified modules

Hey there, thanks for making this awesome lsp wrapper for purescript.

I'm currently working at creating the purescript adapter for lsp-mode in emacs. It seems that it's working for the most part, but I'm not receiving any autocompletion prompts for fully qualified modules.
E.g:

import Data.Foo as Foo
-- Typing Foo. doesn't bring up any autocompletion prompts for types/functions within Foo

I notice this warning popping up in the logs anytime I try to "dot" into a module

[Warn] Listing the loaded modules command is DEPRECATED, use the completion command and filter it to modules instead

Does this perhaps have anything to do with the issue. I gave this a try with vscode as well. It sort of works in vscode if you know what you're looking for, but doesn't give a valid set of members right off the bat. I also noticed this error in the logs when running vscode.

Thanks again!

Integrating with LanguageClient Neovim

LanguageClient-neovim is the most popular language client for neovim and vim. I currently have five language servers that happily integrate. This one, unfortunately, isn't working yet. Although there's psc-ide-vim which does have some juicy actions language clients lack, I love the focused trend language servers are creating.

So let's see if we can get this server (wrapper) integrated 🙌 . Thanks for all the work so far!

Rank autocomplete suggestions

Rank by unimported qualified identifier

  • Explicit type import Data.Map (Map) with Map.fromFol should rank Data.Map suggestions first.
  • Namespace segment Array.toUnfol should suggest Data.Array items first

`spago` support

It would be nice to have spago support. Something like Add Spago Sources option in settings. And maybe even spago build -- --json-errors as a default Build Command.

How about an Install section for the docs?

It says 'node based' and 'use as a node module' but in sections that aren't strictly about how to get this going.

Having npm i -g purescript-language-server somewhere could be nice also because language servers are installed in all sorts of different ways and users might not be familiar with the JS ecosystem.

The install note could also go into the Usage section.

Would you be interested in a PR for either suggestion?

Configurable Prelude import

If an auto complete suggestion is fulfilled by a configurable Prelude module it could import it unqualified.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.