Skip to content

Commit

Permalink
Merge from 5.x: PR #20317
Browse files Browse the repository at this point in the history
Fixes # 20282
  • Loading branch information
dalthviz committed Jan 9, 2023
2 parents c48f11f + 2bb3542 commit 2e9c380
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 14 deletions.
32 changes: 18 additions & 14 deletions spyder/plugins/editor/widgets/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ def __init__(self, parent=None):
self.format_on_save = False
self.format_eventloop = QEventLoop(None)
self.format_timer = QTimer(self)
self.__cursor_position_before_format = 0
self.__line_number_before_format = 0

# Mouse tracking
self.setMouseTracking(True)
Expand Down Expand Up @@ -1781,10 +1781,6 @@ def handle_go_to_definition(self, position):
# -------------------------------------------------------------------------
def format_document_or_range(self):
"""Format current document or selected text."""
# Save current cursor position to restore it after the current text has
# been replaced by the auto-formatted one.
self.__cursor_position_before_format = self.textCursor().position()

if self.has_selected_text() and self.range_formatting_enabled:
self.format_document_range()
else:
Expand All @@ -1793,6 +1789,8 @@ def format_document_or_range(self):
@schedule_request(method=CompletionRequestTypes.DOCUMENT_FORMATTING)
def format_document(self):
"""Format current document."""
self.__line_number_before_format = self.textCursor().blockNumber()

if not self.formatting_enabled:
return
if self.formatting_in_progress:
Expand Down Expand Up @@ -1826,6 +1824,8 @@ def format_document(self):
@schedule_request(method=CompletionRequestTypes.DOCUMENT_RANGE_FORMATTING)
def format_document_range(self):
"""Format selected text."""
self.__line_number_before_format = self.textCursor().blockNumber()

if not self.range_formatting_enabled or not self.has_selected_text():
return
if self.formatting_in_progress:
Expand Down Expand Up @@ -1984,18 +1984,22 @@ def _apply_document_edits(self, edits):
# Insert formatted text in place of the previous one
cursor.insertText(merged_text)

# Don't run the lines below when testing because they give
# segfaults.
if not running_under_pytest():
# Restore previous cursor position and center it.
# Fixes spyder-ide/spyder#19958
cursor.setPosition(self.__cursor_position_before_format)
self.setTextCursor(cursor)
self.centerCursor()

# End text insertion
cursor.endEditBlock()

# Restore previous cursor line and center it.
# Fixes spyder-ide/spyder#19958
if self.__line_number_before_format < self.blockCount():
self.moveCursor(QTextCursor.Start)
cursor = self.textCursor()
cursor.movePosition(
QTextCursor.Down,
QTextCursor.MoveAnchor,
self.__line_number_before_format
)
self.setTextCursor(cursor)
self.centerCursor()

# ---- LSP: Code folding
# -------------------------------------------------------------------------
def compute_whitespace(self, line):
Expand Down
59 changes: 59 additions & 0 deletions spyder/plugins/editor/widgets/tests/test_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
# Standard library imports
import os
import os.path as osp
import random

# Third party imports
import pytest
from qtpy.QtCore import Qt
from qtpy.QtGui import QTextCursor
from qtpy.QtWidgets import QMessageBox
import yapf
Expand Down Expand Up @@ -257,3 +259,60 @@ def test_closing_document_formatting(
code_editor = editorstack.load(str(file_path)).editor

assert code_editor.get_text_with_eol() == expected


@pytest.mark.order(1)
@pytest.mark.parametrize('formatter', [autopep8, black])
def test_formatting_on_save(completions_editor, formatter, qtbot):
"""
Check that auto-formatting on save works as expected and that we restore
the current line after doing it.
This includes a regression test for issue spyder-ide/spyder#19958
"""
file_path, editorstack, code_editor, completion_plugin = completions_editor
text, expected = get_formatter_values(formatter, newline='\n')

# Set formatter
editorstack.set_format_on_save(True)
CONF.set(
'completions',
('provider_configuration', 'lsp', 'values', 'formatting'),
formatter
)

with qtbot.waitSignal(completion_plugin.sig_editor_rpc):
completion_plugin.after_configuration_update([])
qtbot.wait(2000)

# Set text in editor
code_editor.set_text(text)

# Notify changes
with qtbot.waitSignal(
code_editor.completions_response_signal, timeout=30000):
code_editor.document_did_change()

# Set a random current line
current_line = random.randint(0, code_editor.blockCount())
code_editor.moveCursor(QTextCursor.Start)
cursor = code_editor.textCursor()
cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor, current_line)
code_editor.setTextCursor(cursor)
qtbot.wait(500)

# Make a simple change to the file
code_editor.moveCursor(QTextCursor.EndOfLine)
qtbot.keyPress(code_editor, Qt.Key_Space)
qtbot.wait(500)

# Save the file
with qtbot.waitSignal(
code_editor.completions_response_signal, timeout=30000):
editorstack.save(force=True)
qtbot.wait(500)

# Check that auto-formatting was applied on save and that we restored the
# previous line.
assert code_editor.get_text_with_eol() == expected
assert code_editor.textCursor().blockNumber() == current_line

0 comments on commit 2e9c380

Please sign in to comment.