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

fix: support custom _somesass.applyExtractCodeAction command #4

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion LSP-some-sass.sublime-settings
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,6 @@
"somesass.sass.customData": []
},
"command": ["${node_bin}", "${server_path}", "--stdio"],
"selector": "source.scss"
"selector": "source.scss",
"priority_selector": "source.scss",
}
58 changes: 58 additions & 0 deletions plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
from __future__ import annotations
from .utils import get_eol
from LSP.plugin import Session, apply_text_edits
from LSP.plugin.core.protocol import DocumentUri, ExecuteCommandParams, Position, TextEdit
from LSP.plugin.core.views import position_to_offset
from lsp_utils import NpmClientHandler
from typing import Callable, Tuple, cast
import os
import sublime

ApplyExtractCodeActionArguments = Tuple[DocumentUri, int, TextEdit]


def plugin_loaded():
Expand All @@ -18,3 +27,52 @@ class LspSassPlugin(NpmClientHandler):
@classmethod
def required_node_version(cls) -> str:
return '>=20'

def on_pre_server_command(self, command: ExecuteCommandParams, done_callback: Callable[[], None]) -> bool:
session = self.weaksession()
if not session:
return False
if command['command'] == '_somesass.applyExtractCodeAction':
if 'arguments' in command:
arguments = cast(ApplyExtractCodeActionArguments, command['arguments'])
self._handle_apply_extract_code_action(arguments, session, done_callback)
else:
sublime.status_message('No arguments provided to applyExtractCodeAction command. Ignoring.')
return True
return False

def _handle_apply_extract_code_action(
self, arguments: ApplyExtractCodeActionArguments, session: Session, done_callback: Callable[[], None]
) -> None:
uri, document_version, text_edit = arguments
session_buffer = session.get_session_buffer_for_uri_async(uri)
if not session_buffer:
done_callback()
return
if document_version != session_buffer.version:
sublime.status_message('The document has changed since the extract edit was made. Please retry.')
done_callback()
return
for session_view in session_buffer.session_views:
view = session_view.view
apply_text_edits(view, [text_edit], required_view_version=document_version)
def trigger_rename() -> None:
new_text = text_edit['newText']
lines = new_text.split(get_eol(new_text))
usage_keywords = ['_variable', '_function', '_mixin']
line_of_usage = lines[len(lines) - 1]
usage_keyword_positions = [line_of_usage.find(keyword) for keyword in usage_keywords]
position: Position = {
'line': text_edit['range']['start']['line'] + len(lines) - 1,
'character': max(usage_keyword_positions) + 1,
}
point = position_to_offset(position, view)
view.sel().clear()
view.sel().add(point)
view.run_command('lsp_symbol_rename', {'session_name': LspSassPlugin.name()})
done_callback()
# Trigger rename after a timeout to ensure didChange is sent to the server beforehand.
sublime.set_timeout(trigger_rename)
return
done_callback()

9 changes: 9 additions & 0 deletions utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
def get_eol(text: str) -> str:
for i, char in enumerate(text):
if char == '\r':
if (i + 1) < len(text) and text[i + 1] == '\n':
return '\r\n'
return '\r'
elif char == '\n':
return '\n'
return '\n'