[HN Gopher] Bash-LSP: A language server for Bash ___________________________________________________________________ Bash-LSP: A language server for Bash Author : ducktective Score : 121 points Date : 2021-04-01 16:59 UTC (6 hours ago) (HTM) web link (github.com) (TXT) w3m dump (github.com) | alsetmusic wrote: | I clicked through to the point of skimming the documentation for | tree-sitter before giving up on understanding this quickly. There | are too many components that I haven't seen for me to extrapolate | out and get to what this does in general terms. | | Could anyone with more knowledge please explain what this is and | how one might utilize it? Fwiw, I'm deeply familiar with Bash; I | just don't recognize the rest. | sabellito wrote: | Language Servers are pieces of software that implement IDE-like | features (like go to definition, find usages, call-hierarchy, | rename method, etc) for a given language in an editor-agnostic | way. | | With that, any editor that supports Language Servers can use | those to provide better support to a language without | implementing any details. | | In this case, you can see some of the supported editors in the | README itself: https://github.com/bash-lsp/bash-language- | server#clients | zeusk wrote: | LSP is a protocol for IDE/editors to analyze code files and | provide functionality like intelligible code search | (definition, references etc) | [deleted] | adonovan wrote: | Language Server Protocol (LSP) is a standard protocol for | "plain old" editors (clients) to make RPCs to local processes | that understand the syntax, references, and types of a | particular programming language (servers). This reduces the | work to support M servers and N clients to M+N, whereas the | traditional monolithic approach required M*N integrations. This | particular project adds a server for Bash support. | JoBrad wrote: | To add to the other comments, VSCode docs has a good overview | of the motivation and usage of a Language Server. | https://code.visualstudio.com/api/language-extensions/langua... | widdershins wrote: | The other comments explained what LSP is - I'll explain what | tree-sitter is. It's a clever parser that is very fast when it | comes to reparsing a slightly changed file (it's | 'incremental'). It's also very good at handling errors and | continuing to parse your file. | | You write a grammar in json and it gets compiled to a shared | library via C. | brendanfalk wrote: | This is really cool and having spoken with the lead dev, Kenneth, | I trust that this will continue to be well supported. | | This is built on tree-sitter, but there are a couple of other | interesting shell parser projects: * | https://github.com/mvdan/sh * | https://github.com/koalaman/shellcheck | | At Fig (withfig.com), we had to write a bash parser from scratch. | These projects all work well in the IDE context, but in a repl | environment (ie when typing in your terminal) they don't support | incomplete commands very well. e.g if I type `echo "$(` the above | parsers will break as the double quote and parentheses are not | closed. | macrael wrote: | We use shellcheck all the time. Any real differences in between | these three parsers? | brendanfalk wrote: | All three are good, well maintained projects. | | Tree-sitter is more general: it aims to provide support for | many languages and so its bash support is lacking a little. | But it's very fast. It's designed for IDEs (hence why bash- | lsp is using it). It caches its results and only re-parses on | newly changed code blocks. | | sh by mvdan and shellcheck are both built specifically for | the shell. They both have really robust grammar. shellcheck | is great for error handling. sh is great for building ASTs | (it's more of a true parser) | | As always, it depends on your use case. If you need a | descriptive summary of errors / warnings in a shell script | and performance isn't crucial, use shellcheck. If you need a | really robust parser and AST output, use sh. If performance | is crucial and/or you eventually want to support different | languages, use tree-sitter. | | Please feel free to jump in if I am wrong here! | bewuethr wrote: | To me, the main value of sh is shfmt - I use it like gofmt | and never have to think about formatting again. It also | integrates with GitHub's super-linter, where you can have | your preferences in an .editorconfig file and then enforce | them automatically. | pforret wrote: | I'm really interested in fig. I develop lots of bash scripts | and I would love to see how new scripts can also from fig | autocompletion. | brendanfalk wrote: | Cool! Some of the biggest problems we have seen are: | * scripts being poorly documented: what's the point of having | a script if no one knows how to use it * scripts going | stale: often built by one person / an infra team. When they | break, no one knows how to fix them * creating scripts: | bash isn't the most popular language these days, but it's | still supported just about everywhere. How can we make | building them easier and faster but still just as powerful | usbline wrote: | Development tools like this with an obscene amount of | dependencies, not to mention multi-language dependencies, is | extremely worrying and irresponsible for the future of software | development. Especially since they're not even native to bash's | environment! If you would have told me 5 years ago I'd need to | install node and typescript in order to get auto completion for | bash, I'd have called you crazy. Yet here we are. | [deleted] | brundolf wrote: | I look forward to your dependency-free implementation! | tester756 wrote: | on the other hand... | | software is so modular nowadays that you can write language- | server in C#, for an Typescript IDE/Editor that helps you to | write Bash scripts for Linux. | methyl wrote: | > Development tools like this with an obscene amount of | dependencies, not to mention multi-language dependencies, is | extremely worrying and irresponsible for the future of software | development | | Care to elaborate why? | usbline wrote: | >Care to elaborate why? | | Not particularly, since it'll only fall on deaf ears | considering HN's demographic. | methyl wrote: | So you want to tell, it's better to have no tool at all | (given pre-tree-sitter Bash LSP doesn't exist), than to | have a tool with a lot of dependencies? I get that some may | avoid having huge number of dependencies on production, but | when it comes to local development tools, I couldn't care | less. It's 2021, I can buy 1 TB SSD for less than 100 | bucks. | kazinator wrote: | You maybe able to buy a TB SSD for < $100, but you can't | make sense of the ball of mud that is on it. | ggregoire wrote: | Curious what you think HN's demographic is. Most people on | that site probably agree with you, although "extremely | worrying and irresponsible for the future of software | development" is obviously quite exaggerated. | nicoburns wrote: | What do you expect a bash language server to be written in? | Bash? | mdip wrote: | You said it, sarcastically, but that didn't mean I didn't | think it. At first blush it sounds a little crazy, but the | more I think about it... | | Consider my problem: I use `zsh` and have created, collected | and organized a large number of completions which I | synchronize among several workstations. It _frustrates me to | no end_ that I cannot take advantage of these completions in | very many other convenient places, like VSCode[0]. The | benefit of writing it in `zsh` (I can 't speak for bash) is | that seems like it'd be pretty simple to wire up the LSB as a | sort of "completions proxy" that simply takes the inputs, | passes them to a completion script, parses the output and | formats it in the appropriate JSON response. The utility of | being able to have a single script (or set of scripts) that I | can include in my shared profile directory which will run and | handle a `zsh` LSB implementation on-demand (i.e. doesn't | need installing, sits in my scripts directory and runs | everywhere) would be a huge feature. | | This will speak to my ignorance, but can you host a web | server (in a manner that can be consumed) from just bash and | a lean environment[1]? Could you host an LSP without one | (i.e. is there enough to use a socket and would it be enough | to point it at the right place/scheme?). I believe there are | `zsh` extensions which can facilitate some/all of this, but | I'm not sure if it would work out of the box. The downside to | developing it in `zsh`, other than the language itself[2] is | performance. Both of those, assuming "the hosting/serving" | can be handled easily, don't represent big problems, maybe | they are. But performance and the language should be up to | what remains outside of that. | | [0] I had `nvim` set up correctly, once to work with | completion scripts and was able to translate that into VSCode | doing the same, about two years ago. I'm still not fully | convinced I didn't just dream this up because the few times | I've looked into it, since, I've gotten nowhere (admittedly, | I've put little effort into researching). | | [1] I'm thinking 'busybox', minimal gnu-related things, | ideally requiring as little as possible beyond a relatively | recent version of `bash` so that "if it's got bash, I can use | it". | | [2] I use `zsh` because it's easier for me to write things in | it than `bash`, and at times it can be fun. But there's a | reason we don't build solutions using it. | | [3] Everything's a string... | mikewhy wrote: | > If you would have told me 5 years ago I'd need to install | node and typescript in order to get auto completion for bash, | I'd have called you crazy. | | This line right here means there's no runtime dependencies | https://github.com/bash-lsp/bash-language-server/blob/fa5a65... | | edit: turns out there are runtime dependencies (see child | comments). Still, typescript is not one of them. | dvlsg wrote: | I think there are runtime dependencies, just not at the root | level of the repo. | | https://github.com/bash-lsp/bash-language- | server/blob/fa5a65... | mikewhy wrote: | Ah, nice catch. I'll revise my comment. | usbline wrote: | Node is not a runtime now? :) | mikewhy wrote: | No more than Bash :):):) | | And either way, you don't need TypeScript to run this | language server. You just need node. If you're not happy | with that, well, consider this repo a reference and get | cracking. | kazinator wrote: | Doesn't TypeScript work by transpilation to JavaScript? In | which case, it is _never_ a run-time dependency; JavaScript | is. | nikolay wrote: | YARGM (Yet Another Rube Goldberg Machine) | TechBro8615 wrote: | You can always tell who hasn't used a tool because they leave | comments like this. Same thing with complaints about | node_modules. Anyone who's actually worked with frontend | tooling knows it's light years ahead of the tooling in most | backend languages. | | The developer experience out of the box with TypeScript + | VSCode + Next.js is 1000x better than any stack I've ever | worked with in Python, for example. So what if you need to pull | in some dependencies? At least I don't need to figure out what | the best way to setup a Python environment is this month. | | (In fact, the current Python package manager du juor, Poetry, | took most of its ideas from what Yarn implemented five years | ago.) | | And what's this about being irresponsible? You can easily pin | your dependencies, use a lockfile, and even bake the cache into | your Docker images. There's no reason you can't have a program | that will run the same in two years as it does now. And setting | that up is a lot easier than it is with other languages. | tasogare wrote: | > Anyone who's actually worked with frontend tooling knows | it's light years ahead of the tooling in most backend | languages. The developer experience out of the box with | TypeScript + VSCode + Next.js is 1000x better than any stack | | You should practice your April fools jokes to be less | obvious, that post is not gonna make it. | mdip wrote: | I don't know that I'd agree with all of those statements, but | my expertise lies in C#, with a bit of | TypeScript/JavaScript/Front-end Web thrown in from time to | time. I used to write a lot in C++, have dabbled in C... | | The reason I don't write _everything_ in TypeScript has | nothing to do with TypeScript. Language-wise, it is my | favorite experience, hands down. I can express things in a | type-safe, strict manner, and do things generically that | simply cannot be done _outside_ of dynamic languages, while | still gaining the benefits of a statically typed language. | | Not taking node into account[0], TypeScript on its own is my | favorite language and it's _not_ the one I write software in | every day. While I agree with your arguments around pinning | and such, node is a bit of a victim of its own success and | suffers from dependency-hell in a way that is truly unique | and interesting all on its own. The only way to be certain | that code is good is if you write it, barring that ... a | trusted, supported third-party for the important things, and | inspect the rest. The problem on the node side is the | impossibility of the last task, and if you aren 't doing it, | neither is your trusted third-party. I'm not saying it's | hopeless -- I'd even wager a guess there's a comment in my | past that is far more harsh on `npm` than it | deserved/deserves[1]. | | I don't think "node-based" solutions for shell are bad. The | biggest problem I tend to run into with shell scripts in | constrained environments are related to dependencies. With | node, `install`, done (usually). I target "what's probably | there" like most people. Sometimes it's not. In the past, | when this was a bigger problem than it is now for me, I would | throw my hands up and build it in whatever I wanted because | "if I had to get a waiver to add `jq` or some other thing to | this box, I might as well have them put `python` on there" -- | same amount of work arguing over BS but less work writing it. | I'd probably apply that to `node` these days but those | problems aren't mine any longer. :) | | [0] Which some will point to `npm` as the _whole reason they | use node_ while others will point out why it 's the entirety | of its problems. | | [1] And I hate the attitude of some that implies `npm`s | problems have easy solutions, "if they just ...". No. It's | almost everyone's first language. It's really easy to publish | packages. There's a gajillion of them out there. (Yet, it | works ... every? ... time I need to solve something using | it.) | rowanG077 wrote: | Are you serious? About a third of my job is frontend with | typescript. The rest is backend and some application dev and | embedded. Frontend is seriously the worst environment. It's | great if the magic works. But that's the easy part. Once | something breaks, and it will, you have to descend to the | seventh circle of hell to figure out where something in this | mount everest of tooling and dependencies broke. | | I love the idea of frontend dev. But the tooling takes all of | the fun out of it. | mdip wrote: | But I don't think your problems with FE Dev/TypeScript are | "TypeScript" problems so much as they're problems around | the tooling you're using with `node`. | | And I agree. Unless it works out of the box, it's a half- | day of profanity at least. | | But writing a command-line tool in TypeScript doesn't | require any of that. The comment focused on FE development | with Next.js -- I have no experience with that, but a | simple React-based solution using `create-react-app` works | out-of-the-box for a lot of things[0]. I will say, it does | sometimes feel like everything TypeScript gets right is | made up for by everything "all of the bundlers/tooling | around it" screws up, but it's gotten monumentally better. | You're always going to be weighing pain points against | eachother, and folks that do front-end web development all | day long are going to find the problems they routinely | encounter to be "simple", possibly even "intuitive" based | on how the rest of the ecosystem works. | | From my perspective -- partly on the inside, partly on the | outside -- I seem to have to muck around with the | equivalent of "build scripts" about as often as I used to | (not) enjoy in the C/C++-land. But dammit-all if "time to | completely working" in TypeScript isn't always twice as | quick. TypeScript, configured correctly, catches so many | run-time issues at compile-time[1]. For me, the distance | between "it runs" and "it runs correctly" is often shorter | in TypeScript despite it not being my primary language. | | [0] To be sure, it's hard for me to say `create-react-app` | without the obligatory `fscking` inserted... it's got many | problems, but at least half the time it's an implementation | detail. | | [1] Static-type-checking time? | fouric wrote: | > irresponsible for the future of software development | | Not true. This is _highly interchangeable tooling_ - it can | have whatever dependencies you want, because there 's no | "dependency explosion" that happens with libraries. LSP is a | standardized protocol - you can swap it out with anything you | like. | | Moreover, people rarely build interactive tools on top of other | interactive tools. Now, if this were a _library_ with a bunch | of dependencies, that would be a whole different matter - then | any program or library that used this would get all of the | transitive dependencies - but, it 's not. | | Go and reimplement this tool yourself. RIIR, make a statically- | linked 500kb executable with no perceptual execution time, and | eat their lunch, because your tool is a drop-in replacement. | | Is a Node dependency a bad idea for this tool? Arguably yes. Is | it "irresponsible for the future of software development"? That | statement is so false that I suspect it's being used to try to | emotionally manipulate readers instead of making a coherent | argument. | | Also...are you aware that Bash already tab-completion, even if | it's not automatic? | | I'm beginning to wonder if this is a very subtle April Fool's | post... | cle wrote: | Node and TypeScript have the best Language Server tooling, | because that is what Microsoft uses for VS Code. | ttt0 wrote: | "JavaScript is the best language for writing HTTP servers, | because that is what web browsers use." | | Doesn't make any sense. LSP is just a protocol. You can write | language servers in whatever language you want. | kazinator wrote: | But, look at this project. | | They took a Bash parser written in C from the Tree-sitter | project, and are using the C as a compiled WebAssembly blob | out of TypeScript. | | And, actually, that Tree-sitter Bash parser is specified or | generated using JS somehow; the project for producing it | uses TypeScript also. | | That's how easy it is to write LSP server in any language? | | Maybe it's done this way so that the LSP can be integrated | right into the editor itself, so as not to have to run | somewhere else as an external piece. | cle wrote: | What are you talking about? TypeScript has the best | Language Server libraries, if you want maximum productivity | when making a Language Server, you run with TypeScript. I | don't even like TypeScript but I can at least acknowledge | that it can make sense to implement a Language Server in | it. | | Personally I would have used Go for this exact reason, but | it's reasonable to use TypeScript too. | brobdingnagians wrote: | I like minimalism, I agree with cutting down dependencies, but | the person who does the work gets to pick the language. If I | did it, I'd do it in C, Rust, or Kotlin, but I appreciate | having an LSP for a new language nonetheless. Looks like it has | no runtime library dependencies, then that removes risk of | supply chain issues, so I think they've done a good job. | michael1999 wrote: | Do you really think someone would write a lexer, a parser, and | an implementation of the LSP protocol for Bash in Bash? | kazinator wrote: | But there is a lexer and parser for Bash inside Bash. Bash | could either provide the LSP protocol itself, or else open up | some primitives for a script to gain access to the info | somehow. | usbline wrote: | There's more languages native to unix-land than Bash, you | know. Find me a linux distro that doesn't have GCC or Clang | installed by default, or even Python for that matter. | mikewhy wrote: | What about C and Python are "native to Bash's environment" | though? That's the complaint the person you're responding | to is touching on. | | Also, lots of Linux distributions don't come with GCC and | Clang by default (Ubuntu, Debian, OpenSUSE). | akvadrako wrote: | Bash is written in C so depending on C doesn't add a | dependency. | | Python is also the 2nd most popular scripting language in | the Linux world; it's even part of the Freedesktop base | runtime. Though I don't know if it's standard in BSDs. | stevenhuang wrote: | Yeah. | | When I gave this a shot a while back, I looked at its | dependencies and it was way larger than the footprint of coc- | clangd for some reason. | | Wasn't a good signal so decided to remove it after that. | mikewhy wrote: | clangd is already a language server, so coc-clangd can be | small since it only needs to be a bridge between the two. | stevenhuang wrote: | That makes sense. I'll likely revisit this plugin then, | thanks. | delusional wrote: | It also means that your text editor is now a distributed | system. | gkfasdfasdf wrote: | This is an interesting criticism. So a bash language server | must be written in bash? I think _that_ would be indeed be a | software dev monstrosity. | kazinator wrote: | > _node and typescript in order to get auto completion for | bash, I 'd have called you crazy_ | | It's worse than you think. | | This uses something called Tree-sitter: some project written in | C for providing parsers for numerous languages. | | The Tree-sitter parser for Bash itself somehow requires | Typescript, though the parser is in C. | | This Bash-LSP project uses a binary blob of that parser: it is | C compiled as C++ into WebAssembly. | | Bash-LSP, as well as the Tree-sitter Bash parser, can basically | be called IDE tooling written by and for TypeScript | programmers, who sometimes have to mess with Bash scripts. | | The target audience doesn't mind TypeScript and Node | dependencies, and in fact likely finds that preferrable to any | other kind of dependency, because working with TypeScript | dependencies is fresh in their minds, requiring little ramp-up | to handle another one. | nonbirithm wrote: | > The Tree-sitter parser for Bash itself somehow requires | Typescript, though the parser is in C. | | This is not necessarily true if you can write a compiler for | a tree-sitter grammar that outputs the parser code in your | favorite language. I know semgrep does this to make parsers | for OCaml. But, of course, that's more work to be done. | gkfasdfasdf wrote: | I have been using this for a year or so and it is awesome. I use | with neovim + LanguageClient-neovim. I don't really understand | why people are complaining about the dependencies - on macos just | brew install node@14 and npm install -g bash-language-server. | Check for updates occasionally via npm outdated -g. I really have | no idea what the dependencies are other than node and nor do I | care - its just another app on my system. ___________________________________________________________________ (page generated 2021-04-01 23:01 UTC)