Skip to content
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

handle editor.action.rename command for interoperability with VSCode #2249

Closed
wants to merge 8 commits into from

Conversation

rchl
Copy link
Member

@rchl rchl commented May 9, 2023

Added support for the editor.action.rename command since Volar and possibly other servers use it.

I had to move handling of VSCode-specific commands from LspExecuteCommand to Session.execute_command because when triggering a code action, the code doesn't go through the Text Command.

Since those VSCode-specific commands kinda required View, I'm passing it though to execute_command so that I don't have to use hacky way of "get any or active view for session".

Volar returns code actions like:

  {
    "command": {
      "arguments": [
        "file:///usr/local/workspace/github/volar-vue2-test/pages/index.vue",
        {
          "character": 8,
          "line": 8
        }
      ],
      "command": "editor.action.rename",
      "title": ""
    },
    "data": {
      "original": {
        "edit": {
          "documentChanges": [
            {
              "edits": [
                {
                  "newText": "newFunction()",
                  "range": {
                    "end": {
                      "character": 15,
                      "line": 3
                    },
                    "start": {
                      "character": 8,
                      "line": 3
                    }
                  }
                },
                {
                  "newText": "function newFunction() {\nreturn 'Index';\n}\n\n",
                  "range": {
                    "end": {
                      "character": 0,
                      "line": 21
                    },
                    "start": {
                      "character": 0,
                      "line": 21
                    }
                  }
                }
              ],
              "textDocument": {
                "uri": "file:///usr/local/workspace/github/volar-vue2-test/pages/index.vue.js",
                "version": null
              }
            }
          ]
        }
      },
      "serviceId": "typescript",
      "type": "service",
      "uri": "file:///usr/local/workspace/github/volar-vue2-test/pages/index.vue",
      "version": 5
    }

@predragnikolic
Copy link
Member

I will try my best to review this till Friday (if not then next week)

But +1 for the idea. Unfortunately it is better to handle vs code specific commands in lsp rather than lsp plugins to avoid repetition. It would be better if that was at least part of the LSP spec, but I don't mind it.

@@ -1561,7 +1592,9 @@ def execute_command(self, command: ExecuteCommandParams, progress: bool) -> Prom
)
)

def run_code_action_async(self, code_action: Union[Command, CodeAction], progress: bool) -> Promise:
def run_code_action_async(
self, code_action: Union[Command, CodeAction], progress: bool, source_view: Optional[sublime.View] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just call source_view -> view.

Copy link
Member

@predragnikolic predragnikolic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LSP-jdtls and metals use execute_command
but this change is backwards compatible, so all good.

How could I test this with volar?

I wasn't able to find a code action that will do editor.action.rename,
could you give me a hint?

I tried a couple of refactoring code actions with volar but none of them seem to trigger the editor.action.rename.

@rchl
Copy link
Member Author

rchl commented May 15, 2023

You can try selecting the value of the name property and triggering code actions manually:

Screen.Recording.2023-05-15.at.23.53.55.mov

Note that I found some of those code actions pretty broken but it's the same in VSCode so I would blame Volar not handling those too well. (Those code actions come from TS but run in this weird Vue context so probably are not always handled correctly)

@predragnikolic
Copy link
Member

predragnikolic commented May 15, 2023

Yeah, I tried the "Extract to constant in enclosing scope", and I see that the text edits are applied, but I do not see a editor.action.rename command on the code action.

:: [00:10:46.815] <<< LSP-volar (37) (duration: 8ms): [{'data': {'originalItem': {'data': {'refactorName': 'Extract Symbol', 'actionName': 'constant_scope_2', 'range': {'end': 72, 'pos': 69}, 'type': 'refactor', 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts', 'fileName': '/home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'title': 'Extract to constant in module scope', 'diagnostics': [], 'kind': 'refactor.extract.constant'}, 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue', 'map': {'embeddedDocumentUri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'pluginId': 9}, 'title': 'Extract to constant in module scope', 'diagnostics': [], 'kind': 'refactor.extract.constant'}, {'data': {'originalItem': {'data': {'refactorName': 'Extract Symbol', 'actionName': 'constant_scope_1', 'range': {'end': 72, 'pos': 69}, 'type': 'refactor', 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts', 'fileName': '/home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'title': 'Extract to constant in arrow function', 'diagnostics': [], 'kind': 'refactor.extract.constant'}, 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue', 'map': {'embeddedDocumentUri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'pluginId': 9}, 'title': 'Extract to constant in arrow function', 'diagnostics': [], 'kind': 'refactor.extract.constant'}, {'data': {'originalItem': {'data': {'refactorName': 'Extract Symbol', 'actionName': 'constant_scope_0', 'range': {'end': 72, 'pos': 69}, 'type': 'refactor', 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts', 'fileName': '/home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'title': 'Extract to constant in enclosing scope', 'diagnostics': [], 'kind': 'refactor.extract.constant'}, 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue', 'map': {'embeddedDocumentUri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'pluginId': 9}, 'title': 'Extract to constant in enclosing scope', 'diagnostics': [], 'kind': 'refactor.extract.constant'}, {'data': {'originalItem': {'data': {'refactorName': 'Extract Symbol', 'actionName': 'function_scope_2', 'range': {'end': 72, 'pos': 69}, 'type': 'refactor', 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts', 'fileName': '/home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'title': 'Extract to function in module scope', 'diagnostics': [], 'kind': 'refactor.extract.function'}, 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue', 'map': {'embeddedDocumentUri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'pluginId': 9}, 'title': 'Extract to function in module scope', 'diagnostics': [], 'kind': 'refactor.extract.function'}, {'data': {'originalItem': {'data': {'refactorName': 'Extract Symbol', 'actionName': 'function_scope_0', 'range': {'end': 72, 'pos': 69}, 'type': 'refactor', 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts', 'fileName': '/home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'title': 'Extract to inner function in arrow function', 'diagnostics': [], 'kind': 'refactor.extract.function'}, 'uri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue', 'map': {'embeddedDocumentUri': 'file:///home/predragnikolic/Documents/sandbox/my-vue-app/src/App.vue.ts'}, 'pluginId': 9}, 'title': 'Extract to inner function in arrow function', 'diagnostics': [], 'kind': 'refactor.extract.function'}]

I assumed that code action to have such command on it, and right after the text edits were applied, I expected to see a rename request being triggered. But that is not case... I will try tomorrow. :)

@rchl
Copy link
Member Author

rchl commented May 16, 2023

You might try with sublimelsp/LSP-volar#174.

@predragnikolic
Copy link
Member

You might try with sublimelsp/LSP-volar#174.

I still do not get the command "editor.action.rename" for code actions.

@rchl
Copy link
Member Author

rchl commented May 16, 2023

It reproduces here in https://github.com/rchl/nuxt-2-playground in pages/index.vue

Screen.Recording.2023-05-16.at.21.41.02.mov

@predragnikolic
Copy link
Member

Thanks
I am able to trigger the rename,
but I will get this error:

outputd

@rchl
Copy link
Member Author

rchl commented May 17, 2023

Yeah, it basically doesn't work in Vue which I would guess is due to Volar just not supporting those cases.

We can wait with this and see if there are any actually working cases in Volar.

@predragnikolic
Copy link
Member

predragnikolic commented May 17, 2023

I would wait only because none of the existing LSP-* plugins don't intercept any of the following commands:
"editor.action.triggerSuggest"
"editor.action.rename"
"editor.action.triggerParameterHints"

Volar uses it, but it is broken for now.
When Volar fixes that or a different server needs to handle these commands, I am for merging this PR. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants