Skip to content

Commit

Permalink
feat(lsp-cli): make it better and more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
izaakschroeder committed Mar 19, 2024
1 parent 1c1ce1a commit edc6c27
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 31 deletions.
11 changes: 1 addition & 10 deletions README.md
@@ -1,12 +1,3 @@
# @izaakschroeder/lsp-tools

Tools to work with your LSP.

```sh
lsp \
--connect 'stdio://biome/?arg=lsp-proxy' \
fix \
--ignore '**/node_modules/**' \
--rule 'quickfix.suppressRule.biome.*' \
'./src/**/*{.ts,.tsx,.js,.jsx,.mjs,.cjs}'
```
Tools and libraries to fulfill your LSP needs.
6 changes: 3 additions & 3 deletions packages/lsp-cli/README.md
Expand Up @@ -9,6 +9,6 @@ Use the LSP `textDocument/codeAction` to perform specific actions on files.
```sh
lsp fix --connect 'stdio://biome/?arg=lsp-proxy' \
--ignore '**/node_modules/**' \
--action-kind 'quickfix.suppressRule.biome.*' \
'./src/**/*{.ts,.tsx,.js,.jsx,.mjs,.cjs}'
```
--action-kind 'quickfix.suppressRule.biome.**' \
'**/*{.ts,.tsx,.js,.jsx,.mjs,.cjs}'
```
21 changes: 10 additions & 11 deletions packages/lsp-cli/package.json
Expand Up @@ -2,33 +2,32 @@
"name": "@izaakschroeder/lsp-cli",
"version": "0.0.1",
"type": "module",
"main": "./src/index.ts",
"bin": {
"lsp": "./dist/cli.js"
},
"files": ["./dist/**", "README.md", "package.json"],
"scripts": {
"build": "rollup -c",
"test": "biome check ./"
},
"dependencies": {
"@izaakschroeder/lsp-client": "workspace:^",
"chalk": "5.3.0",
"cli-progress": "3.12.0",
"clipanion": "4.0.0-rc.3",
"ku-progress-bar": "0.6.0",
"picomatch": "4.0.1",
"throat": "6.0.2",
"typanion": "3.14.0"
},
"devDependencies": {
"@biomejs/biome": "1.6.1",
"@izaakschroeder/lsp-client": "workspace:^",
"@rollup/plugin-commonjs": "25.0.7",
"@rollup/plugin-node-resolve": "15.2.3",
"@types/node": "20.11.29",
"@types/picomatch": "2.3.3",
"chalk": "5.3.0",
"cli-progress": "3.12.0",
"clipanion": "4.0.0-rc.3",
"esbuild": "0.20.2",
"fast-deep-equal": "3.1.3",
"ku-progress-bar": "0.6.0",
"picomatch": "4.0.1",
"rollup": "4.13.0",
"rollup-plugin-esbuild": "6.1.1",
"throat": "6.0.2",
"typanion": "3.14.0",
"typescript": "5.4.2"
}
}
4 changes: 3 additions & 1 deletion packages/lsp-cli/rollup.config.js
Expand Up @@ -10,7 +10,9 @@ export default [
exportConditions: ['node'],
}),
commonjs(),
esbuild(),
esbuild({
target: 'es2022',
}),
],
output: [
{
Expand Down
27 changes: 21 additions & 6 deletions packages/lsp-cli/src/FixCommand.ts
Expand Up @@ -10,6 +10,7 @@ import * as t from 'typanion';

import { BaseLspCommand } from './BaseLspCommand';
import { createActionFilter } from './createActionFilter';
import { createActionRewrite } from './createActionRewrite';
import { fixFile } from './fixFile';
import { glob } from './glob';

Expand Down Expand Up @@ -49,7 +50,19 @@ export class FixCommand extends BaseLspCommand {
Can be specified more than once to include multiple patterns.
`,
});
actionTransform = Option.String('--action-transform');
actionTextReplace = Option.Array('--action-text-replace', {
description: `
Pass a \`needle=haystack\` search/replace string to modify the
result after an action has been performed but before it has been
applied to your files.
`,
});
actionIgnoreDuplicates = Option.Boolean('--action-ignore-duplicates', {
description: `
If multiple actions are presented that do the same thing, ignore
all but one of them.
`,
});

// TODO(@izaakschroeder): Move this to `BaseLspCommand`
// TODO(@izaakschroeder): Do feature detection for workspaces.
Expand Down Expand Up @@ -115,12 +128,14 @@ export class FixCommand extends BaseLspCommand {

const actionFilter = createActionFilter(this.actionKinds);
let actionMap = null;
if (this.actionTransform) {
const parentURL = pathToFileURL(process.cwd());
const resolved = import.meta.resolve(this.actionTransform, parentURL);
actionMap = await import(resolved);
if (this.actionTextReplace) {
actionMap = createActionRewrite(this.actionTextReplace);
}
const fixOptions = { actionFilter, actionMap };
const fixOptions = {
actionFilter,
actionMap,
ignoreDuplicateActions: this.actionIgnoreDuplicates,
};

const exec = createThroat(this.parallel, async (path) => {
return await fixFile(lsp, path, fixOptions);
Expand Down
27 changes: 27 additions & 0 deletions packages/lsp-cli/src/createActionRewrite.ts
@@ -0,0 +1,27 @@
import type { CodeActionItem } from '@izaakschroeder/lsp-client';

export const createActionRewrite = (patterns: string[]) => {
const rewrites = patterns.map((patterns) => {
const [find, replace] = patterns.split('=', 2);
if (!find || !replace) {
throw new Error();
}
return (action: CodeActionItem) => {
for (const key in action.edit.changes) {
const changes = action.edit.changes[key];
if (!changes) {
continue;
}
for (const change of changes) {
change.newText = change.newText.replaceAll(find, replace);
}
}
return action;
};
});
return (action: CodeActionItem) => {
return rewrites.reduce((prev, cur) => {
return cur(prev);
}, action);
};
};
9 changes: 9 additions & 0 deletions packages/lsp-cli/src/fixFile.ts
@@ -1,6 +1,7 @@
import * as fs from 'node:fs/promises';
import { extname } from 'node:path';
import { pathToFileURL } from 'node:url';
import isEqual from 'fast-deep-equal/es6';

import type {
CodeActionItem,
Expand All @@ -24,6 +25,7 @@ const languageMap = {
interface FixFileOptions {
actionFilter?: ((action: CodeActionItem) => boolean) | null | undefined;
actionMap?: ((action: CodeActionItem) => CodeActionItem) | null | undefined;
ignoreDuplicateActions?: boolean | null | undefined;
}

export const fixFile = async (
Expand Down Expand Up @@ -81,7 +83,14 @@ export const fixFile = async (
return false;
}
let desiredActions = actions.filter((action) => {
let ignoredBecauseDuplicate = false;
if (options.ignoreDuplicateActions) {
ignoredBecauseDuplicate = actions.some((other) => {
return other !== action && isEqual(other, action);
});
}
return (
!ignoredBecauseDuplicate &&
(options.actionFilter ? options.actionFilter(action) : true) &&
action.edit.changes[uri] &&
Object.keys(action.edit.changes).length === 1
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Expand Up @@ -285,6 +285,7 @@ __metadata:
cli-progress: "npm:3.12.0"
clipanion: "npm:4.0.0-rc.3"
esbuild: "npm:0.20.2"
fast-deep-equal: "npm:3.1.3"
ku-progress-bar: "npm:0.6.0"
picomatch: "npm:4.0.1"
rollup: "npm:4.13.0"
Expand Down Expand Up @@ -880,6 +881,13 @@ __metadata:
languageName: node
linkType: hard

"fast-deep-equal@npm:3.1.3":
version: 3.1.3
resolution: "fast-deep-equal@npm:3.1.3"
checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0
languageName: node
linkType: hard

"foreground-child@npm:^3.1.0":
version: 3.1.1
resolution: "foreground-child@npm:3.1.1"
Expand Down

0 comments on commit edc6c27

Please sign in to comment.