From 60c3073de3d08a040109e69c48ba171f15aaddce Mon Sep 17 00:00:00 2001 From: XeroOl Date: Wed, 3 May 2023 00:11:27 -0500 Subject: [PATCH] Make the README much more pleasant --- README.md | 141 +++++++++--------------------------------------------- TODO.md | 80 +++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 118 deletions(-) create mode 100644 TODO.md diff --git a/README.md b/README.md index c22fbb2..7b6a134 100644 --- a/README.md +++ b/README.md @@ -1,143 +1,48 @@ # fennel-ls A language server for fennel-ls. -Uses static analysis, and doesn't actually run your code, which makes it perfect for analyzing your (os.execute "rm -rf") code. -If you want live analysis of your code as it runs, consider using a REPL. +Supports Go-to-definition, and a little bit of completion suggestions. +Fennel-LS uses static analysis, and does not execute your code. -For now, you can ask fennel-ls to treat your file as a macro file if the very first characters in the file exactly match `;; fennel-ls: macro-file`. Expect this to break at some point in the future when I come up with a better way to specify which files are meant to be macro files. +For now, you can ask fennel-ls to **treat your file as a macro file** if the very first characters in the file exactly match `;; fennel-ls: macro-file`. Expect this to change at some point in the future when I come up with a better way to specify which files are meant to be macro files. -Features / To Do List / Things I would enjoy patches for: -([X] = complete, [ ] = planned) +## Building / Installing +The build dependencies are `make` and `lua`. Lua 5.1 or higher is needed. Every other dependency is already included in the repository. See the License section at the bottom of the readme if you care about what other dependencies are being used. -- [X] Able to connect to a client -- [ ] Support for UTF-8 characters that aren't just plain ASCII. (especially `λ`) -- [ ] Settings to configure lua / fennel path, allowed globals, etc -- [ ] Supporting builds for anything other than arch linux -- [ ] Testing/support/instructions for any clients: (LSP is supposed to be editor-agnostic, but that's only if you're able to actually follow the spec, and I'm not sure that fennel-ls is compliant) - - [X] Neovim (This project isn't a neovim plugin, but there are instructions on how to inform neovim of the fennel-ls binary once you build it.) - - [ ] emacs - - [ ] vscode - - [ ] vim+coc -- [x] Go-to-definition: - - [X] literal table constructor - - [X] table destructuring - - [X] multisyms - - [X] `.` special form (when called with constants) - - [X] `do` and `let` special form - - [X] `require` and cross-module definition lookups - - [ ] goes to a.method on `(: a :method)` when triggered at `:method` - - [X] expanded macros (a little bit) - - [X] table mutation via `fn` special: `(fn obj.new-field [])` - - [ ] macro calls / which macros are in scope - - [ ] setmetatable - - [ ] function arguments / function calls - - [ ] local/table mutation via set/tset - - [ ] .lua files (antifennel decompiler) - - [ ] mutation on aliased tables (difficult) -- [ ] Completion Suggestions - - [X] from globals - - [X] from current scope - - [ ] from macros (only on first form in a list) - - [ ] from specials (only on first form in a list) - - [X] "dot completion" for table fields - - [ ] dot completion is aware of a stdlib - - [ ] from anywhere else that I'm forgetting right now - - [ ] actually compliant rules about lexical scope (only see things declared before, not after) - - [ ] show docs/icons on each suggestion - - [ ] "dot completion" for metatable `__index` fields - - [ ] `(. obj :` string completions - - [ ] `(: "foo" :` string completions - - [ ] `(require :` module completions - - [ ] snippets? I guess? -- [X] Reports compiler errors - - [.] Report more than one error per top-level form -- [ ] Reports linting issues - - [ ] Unused locals - - [ ] Discarding results from pcall/xpcall/other functions - - [ ] `unpack` or `values` into an operator special - - [ ] `do`/`values` with only one inner form - - [ ] redundant `do` as the last/only item in a form that accepts a "body" - - [ ] `var` forms that could be `local` - - [ ] Dead code (I'm not sure what sort of things cause dead code) - - [ ] Unused fields (difficult) - - [ ] unification in a `match` pattern (difficult) - - [ ] Brainstorm more linting patterns (I spent a couple minutes brainstorming these ideas, other ideas are welcome of course) -- [X] Hover over a symbol for documentation -- [ ] Signature help - - [ ] Regular help - - [ ] hide or grey out the `self` in an `a:b` multisym call -- [ ] Go-to-references - - [ ] lexical scope in the same file - - [ ] fields - - [ ] go to references of fields when tables are aliased - - [ ] global search across other files -- [ ] Options / Configuration - - [ ] Configure over LSP - - [ ] Configure with some sort of per-project config file - - [ ] Configure with environment variables I guess?? - - [ ] fennel/lua path - - [ ] lua version - - [ ] allowed global list - - [ ] enable/disable various linters -- [ ] rename - - [ ] local symbols - - [ ] module fields (may affect code behavior, may modify other files) - - [ ] arbitrary fields (may affect code behavior, may modify other files) -- [ ] formatting with fnlfmt -- [ ] Type annotations? Global type inference? +Pick your favorite command to build and install the language server. -## Setup: -You can match my environment to develop with the following steps. - -1. Build the binary ```sh make && sudo make install # to install into /usr/local/bin -make install PREFIX=$HOME # if you have ~/bin on your $PATH +make && make install PREFIX=$HOME # if you have ~/bin on your $PATH ``` -2. Configure your editor to use this language server -LSP is editor-agnostic, but that's only if you're able to actually follow the spec, and I'm not sure if fennel-ls is compliant. +For now, the only way to install is to build from source, but I plan on adding fennel-ls to luarocks soon. -So far, I've only ever tested it with Neovim using the native language client and `lspconfig`. -If you know what that means, here's the relevant code to help you set up Neovim in the same way: +## Set Up Your Editor +Once you've installed the binary somewhere on your computer, the next step is to set up your text editor! Each editor has a different way of doing it. + +If you are using vim+lspconfig, it is pretty simple: ```lua -local lspconfig = require('lspconfig') --- inform lspconfig about fennel-ls -require("lspconfig.configs")["fennel-ls"] = { - default_config = { - cmd = {"/path/to/fennel-ls/fennel-ls"}, - filetypes = {"fennel"}, - root_dir = function(dir) return lspconfig.util.find_git_ancestor(dir) end, - settings = {} - } -} --- setup fennel-ls --- If you're using a completion system like nvim-cmp, you probably need to modify this line. -lspconfig["fennel-ls"].setup( - vim.lsp.protocol.make_client_capabilities() -) +require('lspconfig').fennel_ls.setup() ``` -For Emacs, (eglot, built-in to 29+) put this in your config: - +For Emacs, (eglot, built-in to 29+): ```lisp (with-eval-after-load 'eglot (add-to-list 'eglot-server-programs '(fennel-mode . ("fennel-ls")))) ``` -It should be possible to set up for other clients, but I haven't looked into these steps. If you get it working in any other environments, I'd love to know! It would be great to have instructions on how to set up other editors! +It should be possible to set up for other text editors, but the instructions depend on which editor you use. +Generally this involves somehow configuring this information: +* "fennel-ls" is a language server program on the path +* it should be run for .fnl files. -## Caveats -So far, I am only testing this project with Neovim. Since Neovim also uses Lua, there may be instances where fennel-ls encodes JSON incorrectly which may be compatible with Neovim, but not other editors. (ie, a json field that is supposed to be null may be missing, or [] and {} may be conflated). User beware! - -If you want to help fix this, `./src/fennel-ls/message.fnl` is where messages are being constructed, -and `./src/fennel-ls/json-rpc.fnl` is where messages are being converted to json. I suspect a different json library will be necessary. +If you get it working in any other environments, I'd love to know! It would be great to have instructions on how to set up other editors! ## License fennel-ls is licensed under the MIT license. See LICENSE for more info. -However, this project contains files from other projects: -* test/pl comes from [Penlight](https://github.com/lunarmodules/Penlight) [MIT license] -* src/json comes from [json.lua](https://github.com/rxi/json.lua) [MIT license] +This project also contains files from other projects: +* test/pl/* comes from [Penlight](https://github.com/lunarmodules/Penlight) [MIT license] +* src/json/* comes from [json.lua](https://github.com/rxi/json.lua) [MIT license] +* test/lust.lua comes from [lust](https://github.com/bjornbytes/lust) [MIT license] * fennel and src/fennel.lua are compiled from [fennel](https://git.sr.ht/~technomancy/fennel) [MIT license] - -fennel-ls's license may not apply to these files; check those projects for more details. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..e619858 --- /dev/null +++ b/TODO.md @@ -0,0 +1,80 @@ +Features / To Do List / Things I would enjoy patches for: +([X] = complete, [ ] = planned) + +- [X] Able to connect to a client +- [ ] Support for UTF-8 characters that aren't just plain ASCII. (especially `λ`) +- [ ] Settings to configure lua / fennel path, allowed globals, etc +- [ ] Supporting builds for anything other than arch linux +- [ ] Testing/support/instructions for any clients: (LSP is supposed to be editor-agnostic, but that's only if you're able to actually follow the spec, and I'm not sure that fennel-ls is compliant) + - [X] Neovim (This project isn't a neovim plugin, but there are instructions on how to inform neovim of the fennel-ls binary once you build it.) + - [ ] emacs + - [ ] vscode + - [ ] vim+coc +- [x] Go-to-definition: + - [X] literal table constructor + - [X] table destructuring + - [X] multisyms + - [X] `.` special form (when called with constants) + - [X] `do` and `let` special form + - [X] `require` and cross-module definition lookups + - [ ] goes to a.method on `(: a :method)` when triggered at `:method` + - [X] expanded macros (a little bit) + - [X] table mutation via `fn` special: `(fn obj.new-field [])` + - [ ] macro calls / which macros are in scope + - [ ] setmetatable + - [ ] function arguments / function calls + - [ ] local/table mutation via set/tset + - [ ] .lua files (antifennel decompiler) + - [ ] mutation on aliased tables (difficult) +- [ ] Completion Suggestions + - [X] from globals + - [X] from current scope + - [ ] from macros (only on first form in a list) + - [ ] from specials (only on first form in a list) + - [X] "dot completion" for table fields + - [ ] dot completion is aware of a stdlib + - [ ] from anywhere else that I'm forgetting right now + - [ ] actually compliant rules about lexical scope (only see things declared before, not after) + - [ ] show docs/icons on each suggestion + - [ ] "dot completion" for metatable `__index` fields + - [ ] `(. obj :` string completions + - [ ] `(: "foo" :` string completions + - [ ] `(require :` module completions + - [ ] snippets? I guess? +- [X] Reports compiler errors + - [.] Report more than one error per top-level form +- [ ] Reports linting issues + - [ ] Unused locals + - [ ] Discarding results from pcall/xpcall/other functions + - [ ] `unpack` or `values` into an operator special + - [ ] `do`/`values` with only one inner form + - [ ] redundant `do` as the last/only item in a form that accepts a "body" + - [ ] `var` forms that could be `local` + - [ ] Dead code (I'm not sure what sort of things cause dead code) + - [ ] Unused fields (difficult) + - [ ] unification in a `match` pattern (difficult) + - [ ] Brainstorm more linting patterns (I spent a couple minutes brainstorming these ideas, other ideas are welcome of course) +- [X] Hover over a symbol for documentation +- [ ] Signature help + - [ ] Regular help + - [ ] hide or grey out the `self` in an `a:b` multisym call +- [ ] Go-to-references + - [ ] lexical scope in the same file + - [ ] fields + - [ ] go to references of fields when tables are aliased + - [ ] global search across other files +- [ ] Options / Configuration + - [ ] Configure over LSP + - [ ] Configure with some sort of per-project config file + - [ ] Configure with environment variables I guess?? + - [ ] fennel/lua path + - [ ] lua version + - [ ] allowed global list + - [ ] enable/disable various linters +- [ ] rename + - [ ] local symbols + - [ ] module fields (may affect code behavior, may modify other files) + - [ ] arbitrary fields (may affect code behavior, may modify other files) +- [ ] formatting with fnlfmt +- [ ] Type annotations? Global type inference? +