{"id":14155508,"url":"https://github.com/slonoed/jsref","last_synced_at":"2025-03-16T09:18:33.992Z","repository":{"id":32458830,"uuid":"132952237","full_name":"slonoed/jsref","owner":"slonoed","description":"JavaScript refactoring language server","archived":false,"fork":false,"pushed_at":"2023-05-14T01:02:36.000Z","size":1300,"stargazers_count":53,"open_issues_count":11,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-16T00:48:58.658Z","etag":null,"topics":["coc","coc-nvim","javascript","language-server-protocol","refactoring","vim","vim-lsc","vscode","vscode-extension"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slonoed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-10T20:41:42.000Z","updated_at":"2025-03-14T01:32:18.000Z","dependencies_parsed_at":"2024-08-17T08:16:47.079Z","dependency_job_id":null,"html_url":"https://github.com/slonoed/jsref","commit_stats":{"total_commits":111,"total_committers":5,"mean_commits":22.2,"dds":0.5045045045045045,"last_synced_commit":"92ef0542d14e2d40ac81e14546ffd33a5d462b45"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slonoed%2Fjsref","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slonoed%2Fjsref/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slonoed%2Fjsref/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slonoed%2Fjsref/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slonoed","download_url":"https://codeload.github.com/slonoed/jsref/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243847128,"owners_count":20357330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coc","coc-nvim","javascript","language-server-protocol","refactoring","vim","vim-lsc","vscode","vscode-extension"],"created_at":"2024-08-17T08:03:44.547Z","updated_at":"2025-03-16T09:18:33.854Z","avatar_url":"https://github.com/slonoed.png","language":"TypeScript","funding_links":[],"categories":["vscode-extension"],"sub_categories":[],"readme":"# jsref\n\nJavaScript refactoring language server\n\n![Demo Animation](../assets/preview.gif?raw=true)\n\nAn idea behind this project is to have desirable refactoring experience for JavaScript (JSX, TypeScript, Flowtype)\nwithout tying to any editor.\n\nThis tool implements [language server protocol][ls] (LSP) to avoid any direct binding to code editors.\nThis means any [editor with LSP support][ls-page] can use it.\n\nIt uses babylon parser to parse and generate JavaScript.\n\nSupported refactorings:\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eRefactoring\u003c/th\u003e\n    \u003cth\u003eCode before\u003c/th\u003e\n    \u003cth\u003eCode after\u003c/th\u003e\n  \u003ctr\u003e\n  \u003ctr\u003e\n  \u003ctd\u003econst arrow to function declaration\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst a = () =\u0026gt; { return 1; }\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003efunction a() { return 1; }\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eexperimental jest only test\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit(\u0026#039;hello\u0026#039;, () =\u0026gt; {})\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit.only(\u0026#039;hello\u0026#039;, () =\u0026gt; {})\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eexperimental jest revert only\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit.only(\u0026#039;hello\u0026#039;, () =\u0026gt; {})\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit(\u0026#039;hello\u0026#039;, () =\u0026gt; {})\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eexperimental jest revert skip test\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit.skip(\u0026quot;s\u0026quot;, () =\u0026gt; { hello(); })\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit(\u0026quot;s\u0026quot;, () =\u0026gt; { hello(); })\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eexperimental jest skip test\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit(\u0026quot;s\u0026quot;, () =\u0026gt; { hello(); })\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eit.skip(\u0026quot;s\u0026quot;, () =\u0026gt; { hello(); })\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eexperimental use styled component\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eimport r from \u0026#039;r-dom\u0026#039;\n\nconst A = () =\u0026gt; {\n  return r.div()\n}\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eimport r from \u0026#039;r-dom\u0026#039;\nimport { styled } from \u0026quot;styletron-react\u0026quot;;\n\nconst StyledDiv = styled(\u0026quot;div\u0026quot;, {});\n\nconst A = () =\u0026gt; {\n  return r(StyledDiv)\n}\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eexplicit return to implicit\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e() =\u0026gt; { return test() }\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e() =\u0026gt; test()\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eextract return\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003ereturn a + b\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst result = a + b;\n\nreturn result;\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eflip if else\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eif (a) {\n  b()\n} else {\n  c()\n}\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eif (!a) {\n  c()\n} else {\n  b()\n}\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eflip ternary\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003ea ? b : c\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e!a ? c : b\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003efunction to arrow\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst a = function () { return 1; }\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst a = () =\u0026gt; { return 1; }\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003eimplicit return to explicit\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst foo = () =\u0026gt; hello()\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst foo = () =\u0026gt; {\n    return hello();\n}\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003ejsx expand empty tag\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e\u0026lt;input/\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e\u0026lt;input\u0026gt;\u0026lt;/input\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003ereplace with concatenation\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e`hello ${a}`\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003e\u0026quot;hello \u0026quot; + a\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003erequire to import\u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003econst a = require(\u0026#039;b\u0026#039;)\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n  \u003ctd\u003e\n    \u003cpre\u003e\u003ccode\u003eimport a from \u0026quot;b\u0026quot;;\u003c/code\u003e\u003c/pre\u003e\n  \u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Installation\n\n### Vim and Neovim (via coc.nvim)\n\n1. Install [coc.nvim plugin][coc-nvim-repo]\n2. Run `:CocInstall coc-jsref`\n3. Configure hotkeys. For example to use `ga`:\n\n```\nnmap ga \u003cPlug\u003e(coc-codeaction-cursor)\nxmap ga \u003cPlug\u003e(coc-codeaction-selected)\n```\n\n### [VSCode][vscode-jsref-marketplace]\n\n_VSCode extension contains server and you don't need to install global one with `brew`._\n\nSearch in **Extensions** panel for `jsref` or install via CLI\n\n`code --install-extension slonoed.jsref`\n\n### Sublime Text 3\n\nInstall **jsref** language binary via brew\n\n```\nbrew install slonoed/tap/jsref\n```\n\nor npm\n\n```\nnpm i -g @slonoed/jsref\n```\n\nInstall **LSP** package from Package Control.\n\nAdd new client to LSP via `Preferences: LSP Setting`.\n\n```\n\"jsref\": {\n  \"command\": [\"jsref\", \"--stdio\"],\n\t\"scopes\": [\"source.js\"],\n\t\"syntaxes\": [\n\t\t\"Packages/babel-sublime/JavaScript (Babel).tmLanguage\",\n\t\t\"Packages/Babel/JavaScript (Babel).sublime-syntax\",\n\t\t\"Packages/JavaScript/JavaScript.sublime-syntax\"\n\t],\n\t\"languageId\": \"javascript\",\n},\n```\n\nFinal config should look like this\n\n```\n{\n  \"clients\": {\n    \"jsref\": {\n      \"command\": [\"jsref\", \"--stdio\"],\n      \"scopes\": [\"source.js\"],\n      \"syntaxes\": [\n        \"Packages/babel-sublime/JavaScript (Babel).tmLanguage\",\n        \"Packages/Babel/JavaScript (Babel).sublime-syntax\",\n        \"Packages/JavaScript/JavaScript.sublime-syntax\"\n      ],\n      \"languageId\": \"javascript\"\n    }\n  }\n}\n```\n\n### Other editors\n\nAll other editors are supported via standard plugins for language servers.\n\njsref language server can be installed via brew\n\n```\nbrew install slonoed/tap/jsref\n```\n\nor npm\n\n```\nnpm i -g @slonoed/jsref\n```\n\n_Help needed to add instructions for other editors._\n\n\n## Plans\n\n- Ability to create custom refactorings (per user and per workspace)\n- More refactorings! If you need some specific, create an [issue][new-issue]\n\n## Development\n\nInstall deps `npm i`\n\n### coc.nvim extension\n\nBuild package `make coc-pack`\n\nAdd `set runtimepath^=~/THISREPO/build/coc/` to vimrc or run as command.\n\n[Debug guide][coc-ls-debug]\n\n### Debug VScode extension\n\nInstall LSP Inspector.\nRun debug version with extension\n\n```\nmake run-vscode\n```\n\n### Debug server\n\nRun `jsbin` with `--lspi` flag and running inspector.\n\n## Deploy\n\n### Release npm package\n\n```\nmake npm-publish\n```\n\n### Release coc packaged\n\n```\nmake coc-publish\n```\n\n### Release brew tap (after npm release)\n\nInstall **noob** package\n\n```\nbrew install zmwangx/npm-noob/noob\n```\n\nPublishing\n\n```\nmake brew-publish\n```\n\n### Release vscode extension\n\n```\nmake vscode-publish\n```\n\n## Contributing\n\nYou can easily contribute by creating new kinds of refactoring. A good example can be found [here][fixer-example]. To avoid duplication, create [an issue][new-issue] first.\n\n[js-refactor]: https://github.com/cmstead/js-refactor/blob/master/package.json\n[babylon]: https://github.com/babel/babel/tree/master/packages/babylon\n[lsc]: https://github.com/natebosch/vim-lsc\n[jtl]: https://github.com/sourcegraph/javascript-typescript-langserver/blob/master/src/plugins.ts\n[grasp]: http://www.graspjs.com/\n[ls]: https://microsoft.github.io/language-server-protocol/\n[ls-page]: https://langserver.org/\n[vim-lsc]: https://github.com/natebosch/vim-lsc/tree/master/after/plugin\n[new-issue]: https://github.com/slonoed/jsref/issues/new\n[issue-atom]: https://github.com/slonoed/jsref/issues/3\n[issue-emacs]: https://github.com/slonoed/jsref/issues/10\n[issue-sublime]: https://github.com/slonoed/jsref/issues/7\n[fixer-example]: https://github.com/slonoed/jsref/blob/master/src/fixers/implicit-return-to-explicit.ts\n[vscode-jsref-marketplace]: https://marketplace.visualstudio.com/items?itemName=slonoed.jsref\n[coc-ls-debug]: https://github.com/neoclide/coc.nvim/wiki/Debug-language-server\n[coc-nvim-repo]: https://github.com/neoclide/coc.nvim\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslonoed%2Fjsref","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslonoed%2Fjsref","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslonoed%2Fjsref/lists"}