-
-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add code actions for React #112
base: develop
Are you sure you want to change the base?
Conversation
Hm, the idea is cool, but I have mixed feelings of simple code actions like wrap into condition. I was always using Surround extension for wrapping anything 🤷, on the other hand I think we can also provide these code actions when user doesn't have any selection and cursor is jsx opening tag name, so user can save some time with selecting component to wrap. While having your code actions is fine (as long as most of them have unique activation ranges) I'd like to see another a few more unique code actions, such as code action to quickly introduce useRef variable, there is an example with // typographyRef is undefined within component
<Typography ref={typographyRef}>404</Typography> Quickfix to add useRef add to top (we need to place a new useRef directly after last useRef): const A = () => {
const typographyRef = useRef<HTMLSpanElement>(null!) // notice type inferrence
return <Typography ref={typographyRef} />
} As you noticed, it more looks like a quickfix for not defined variable, instead of refactoring... Also what do you think of adding refactorings to infer types for
VS Code uses simple text replace, because TS doesn't support snippets in code actions: microsoft/TypeScript#50166 However, not all code actions are in Aaand finally, I don't really like doing the same thing that already was done before (thats why I try to avoid adding refactorings from abracadabra, but not from p42 though). Most code actions you are looking for were already implemented in Typescript React hooks Tools, it also has some high-quality code. Probably I'd improve that extension instead, but only if its still maintained. I hope you do support this idea. Otherwise we can reuse most of the logic from these refactorings, but they should be improved as they don't add auto-imports, but its easy to fix. Because of that I don't recommend changing these duplicated code actions for now. Anyway, you can try to add proposed new code actions (as they should be easy to go), feel free to ask questions about them. I'll also provide additional feedback on the auto-imports soon |
typescript/src/codeActions/custom/React/conditionalRendering.ts
Outdated
Show resolved
Hide resolved
typescript/src/codeActions/custom/React/conditionalRendering.ts
Outdated
Show resolved
Hide resolved
Okay, nevermind I've heard its bad idea to display surround snippet without selection only in one specific location, WDYT? Also, only these refactorings require snippets (cursor positioning), so maybe you can it will be easier to use that Surround extension instead? What are downsides of such approach? Here is I'm attaching my Surround snippets:"surround.custom": {
"renderCond": {
"label": "renderCond",
"snippet": "{$1 ? $TM_SELECTED_TEXT : $2}",
"languageIds": [
"typescriptreact",
"javascriptreact",
"vue"
]
},
"renderAnd": {
"label": "renderAnd",
"snippet": "{$1 && $TM_SELECTED_TEXT}",
"languageIds": [
"typescriptreact",
"javascriptreact",
"vue"
]
},
"renderStringCond": {
"label": "renderStringCond",
"snippet": "{$1 ? '$TM_SELECTED_TEXT' : $2}",
"languageIds": [
"typescriptreact",
"javascriptreact",
"vue"
]
},
"objectCond": {
"label": "objectCond",
"snippet": "...$1 ? {$TM_SELECTED_TEXT} : null",
"languageIds": [
"typescript",
"javascript",
"typescriptreact",
"javascriptreact",
"vue"
]
},
"cond": {
"label": "cond",
"snippet": "$1 ? $TM_SELECTED_TEXT : $2",
"languageIds": [
"typescript",
"javascript",
"typescriptreact",
"javascriptreact",
"vue"
]
},
"condElse": {
"label": "condElse",
"snippet": "$1 ? $2 : $TM_SELECTED_TEXT",
"languageIds": [
"typescript",
"javascript",
"typescriptreact",
"javascriptreact",
"vue"
]
},
"`": {
"label": "`",
"snippet": "`$1${$TM_SELECTED_TEXT}$2`",
"languageIds": [
"typescript",
"javascript",
"typescriptreact",
"javascriptreact",
"vue"
]
},
"lnIf": {
"label": "lnIf",
"snippet": "if ($1) $TM_SELECTED_TEXT",
"languageIds": [
"typescript",
"javascript",
"typescriptreact",
"javascriptreact",
"vue"
]
},
"describeOnly": {
"label": "describeOnly",
"snippet": "describe.only('$1', () => {\n\t$TM_SELECTED_TEXT\n})",
"languageIds": [
"typescript",
"javascript",
]
},
"setTimeout": {
"label": "setTimeout",
"snippet": "setTimeout(() => {\n\t$TM_SELECTED_TEXT\n}, $1)",
"languageIds": [
"typescript",
"typescriptreact",
"javascript",
"javascriptreact",
"vue",
]
},
"console.time": {
"label": "console.time",
"snippet": "console.time('$1')\n$TM_SELECTED_TEXT\nconsole.timeEnd('$1')",
"languageIds": [
"typescript",
"javascript",
"typescriptreact",
"javascriptreact",
"vue"
]
}
} |
Well, I don't really like that Surround uses the command palette instead of CodeActions. Also, to use Surround you need to select the text, and if you have a large nesting, selecting it may take more time than just using Code Action on the right tag. The only thing I would do in our case is move them to the Surround category instead of Rewrite. Although, like you said, it's bad practice to use Surround Code Actions without highlighting, so I'm not sure. By the way, some of these Code Actions were inspired by React Buddy for WebSotrm. There this refactoring is implemented through both WebSotrm's built-in "Wrap with" and Code Actions.
In general, not just there. For example, for
I originally wanted the user to enter the tags themselves, but since it's not a snippet, I just made a
In general, I plan to do a few more Code Actions from the plugin, which I mentioned above (for example, generating event-handlers, adding props, and your suggestion with Perhaps we should create an issue listing all the Code Actions for React that should be in the extension (including the ones already implemented and the ones I named above).
First, Typescript React hooks Tools contains only two Code Actions, of which I implemented only one (namely "Wrap with useCallback"). I did not implement "Wrap with useMemo", because I have not yet figured out when to show it, so as not to be annoying. Second, Typescript React hooks Tools uses selection to show the action. I, on the other hand, show the action when the cursor is inside the variable (which makes more sense to me). Maybe I should also add support for normal functions ( Third, it is unlikely that the developer will support this extension, the last changes were there more than two years ago. Let's wait a couple of days and see if he responded to your issue. In the meantime I think I can take some practices from his code to improve my Code Actions (like dependency detection). If the developer agrees to accept the PR, I can remove "Wrap with useCallback" from here and improve that extension. And finally: I agree that it is better not to create what has already been done, but in this case it would be better to leave these Code Actions in this extension, because that plugin is not particularly supported, and in our extension we can fix or improve them at any time. Also, instead of the user would install an additional extension, he could use the Code Actions in our plugin. Also, other plugins could use a less productive solution for Code Actions (not in this case, but I just wanted to mention that) |
Remember that you can use Expand Selection command that uses TS knowledge and saves a lot of time. On the other hand I see your point here. It is much faster to do a quick selection with mouse and apply code action.
But there is already
Yeah, but I want to know for what cases you are also going to include code actions (such as event handler generation)? And, by the way will you be interested in doing non-react interactive code actions in future as well?
This is unnecessary for code actions that are you're adding here, but you can create issue for code actions that are you not going to include in this PR in order we don't forget about them (and for easier duscission as I said above).
Generally I do not support this idea at all, I work with more than 100 extensions installed and never try to copy existing functionality, I'd better to have similar extensions links in readme (just saying) Also Typescript React hooks Tools has npm extension and I wonder we can reuse it for our code actions |
I removed the
I don't mind in general, but first I would prefer to do all the Code Actions for react that I have planned
Created #115, check if everything is ok, maybe you want to add something else
Unfortunately, the npm package does not provide any API, it just allows you to initialize the plugin. Therefore, it is not possible to access internal functions and methods |
Hey, @AgentRBY I pushed a few changes:
Also could you change |
I think all code actions except wrap into memo and useCallback should use snippet edit, see declareMissingProperties.ts for example |
Would you be up for cleaning up wrap memo & callback actions? (if you like the idea I showed in useMemo action) ALso I'm currently thinking of how its possible to reuse builtin logic for adding auto-imports edits |
I've been busy the last couple of days, I'll try to take a look today |
Hi @zardoy, if you can complete this PR it will be very good, I will be busy soon, so there is not much time for it, sorry |
Made 6 code actions for React.
Also, I have a couple of questions: