Skip to content

Commit

Permalink
Merge from 5.x: PR #16509
Browse files Browse the repository at this point in the history
Fixes #16431
  • Loading branch information
ccordoba12 committed Mar 17, 2022
2 parents 4fbfef3 + 232cf14 commit e948501
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 12 deletions.
46 changes: 42 additions & 4 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1441,13 +1441,19 @@ def test_run_code(main_window, qtbot, tmpdir):
main_window.editor.load(filepath)

# Move to the editor's first line
code_editor = main_window.editor.get_focus_widget()
editor = main_window.editor
code_editor = editor.get_focus_widget()
code_editor.setFocus()
qtbot.keyClick(code_editor, Qt.Key_Home, modifier=Qt.ControlModifier)

# Get a reference to the namespace browser widget
nsb = main_window.variableexplorer.current_widget()

# Set modifier for CTRL or darwin Meta
modifier = Qt.ControlModifier
if sys.platform == 'darwin':
modifier = Qt.MetaModifier

# ---- Run file ----
qtbot.keyClick(code_editor, Qt.Key_F5)

Expand Down Expand Up @@ -1481,6 +1487,41 @@ def test_run_code(main_window, qtbot, tmpdir):

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Run to line ----
# Run lines from file start until, but excluding, current cursor line
# Move to line 10 then move one characters into the line and
# run lines above
editor.go_to_line(10)
qtbot.keyClick(code_editor, Qt.Key_Right)
qtbot.keyClick(code_editor, Qt.Key_F9, modifier=Qt.ShiftModifier)
qtbot.wait(500)

assert shell.get_value('a') == 10
assert shell.get_value('li') == [1, 2, 3]
# Test that lines below did not run
assert 'arr' not in nsb.editor.source_model._data.keys()
assert 's' not in nsb.editor.source_model._data.keys()

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Run from line ----
# Move to line 6, run lines from current cursor line to end
# Note that last line (14) will raise a NameError if 'a' is not defined
# Set 'a' to a different value before hand to avoid errors in shell
shell.execute('a = 100')
editor.go_to_line(6)
qtbot.keyClick(code_editor, Qt.Key_Right)
qtbot.keyClick(code_editor, Qt.Key_F9, modifier=modifier)
qtbot.wait(500)

assert shell.get_value('s') == "Z:\\escape\\test\\string\n"
assert shell.get_value('li') == [1, 2, 3]
assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))
# Test that lines above did not run, i.e. a is still 100
assert shell.get_value('a') == 100

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Run cell and advance ----
# Run the five cells present in file
# Add an unnamed cell at the top of the file
Expand Down Expand Up @@ -1525,9 +1566,6 @@ def test_run_code(main_window, qtbot, tmpdir):

# ---- Run cell ----
# Run the first cell in file
modifier = Qt.ControlModifier
if sys.platform == 'darwin':
modifier = Qt.MetaModifier
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=modifier)

# Wait until the object has appeared in the variable explorer
Expand Down
2 changes: 2 additions & 0 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@
'editor/breakpoint': 'F12',
'editor/conditional breakpoint': 'Shift+F12',
'editor/run selection': "F9",
'editor/run to line': 'Shift+F9',
'editor/run from line': CTRL + '+F9',
'editor/go to line': 'Ctrl+L',
'editor/go to previous file': CTRL + '+Shift+Tab',
'editor/go to next file': CTRL + '+Tab',
Expand Down
29 changes: 28 additions & 1 deletion spyder/plugins/editor/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,20 @@ def get_plugin_actions(self):
self.register_shortcut(run_selected_action, context="Editor",
name="Run selection", add_shortcut_to_tip=True)

run_to_line_action = create_action(self, _("Run &to current line"),
tip=_("Run to current line"),
triggered=self.run_to_line,
context=Qt.WidgetShortcut)
self.register_shortcut(run_to_line_action, context="Editor",
name="Run to line", add_shortcut_to_tip=True)

run_from_line_action = create_action(self, _("Run &from current line"),
tip=_("Run from current line"),
triggered=self.run_from_line,
context=Qt.WidgetShortcut)
self.register_shortcut(run_from_line_action, context="Editor",
name="Run from line", add_shortcut_to_tip=True)

run_cell_action = create_action(self,
_("Run cell"),
icon=ima.icon('run_cell'),
Expand Down Expand Up @@ -1106,7 +1120,8 @@ def get_plugin_actions(self):
run_menu_actions = [run_action, run_cell_action,
run_cell_advance_action,
re_run_last_cell_action, MENU_SEPARATOR,
run_selected_action, re_run_action,
run_selected_action, run_to_line_action,
run_from_line_action, re_run_action,
configure_action, MENU_SEPARATOR]
self.main.run_menu_actions = (
run_menu_actions + self.main.run_menu_actions)
Expand Down Expand Up @@ -3014,6 +3029,18 @@ def run_selection(self):
editorstack = self.get_current_editorstack()
editorstack.run_selection()

@Slot()
def run_to_line(self):
"""Run all lines from beginning up to current line"""
editorstack = self.get_current_editorstack()
editorstack.run_to_line()

@Slot()
def run_from_line(self):
"""Run all lines from current line to end"""
editorstack = self.get_current_editorstack()
editorstack.run_from_line()

@Slot()
def run_cell(self):
"""Run current cell"""
Expand Down
14 changes: 13 additions & 1 deletion spyder/plugins/editor/widgets/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ class CodeEditor(TextEditBaseWidget):
go_to_definition = Signal(str, int, int)
sig_show_object_info = Signal(int)
sig_run_selection = Signal()
sig_run_to_line = Signal()
sig_run_from_line = Signal()
sig_run_cell_and_advance = Signal()
sig_run_cell = Signal()
sig_re_run_last_cell = Signal()
Expand Down Expand Up @@ -4389,7 +4391,14 @@ def setup_context_menu(self):
icon=ima.icon('run_selection'),
shortcut=CONF.get_shortcut('editor', 'run selection'),
triggered=self.sig_run_selection.emit)

self.run_to_line_action = create_action(
self, _("Run to current line"),
shortcut=CONF.get_shortcut('editor', 'run to line'),
triggered=self.sig_run_to_line.emit)
self.run_from_line_action = create_action(
self, _("Run from current line"),
shortcut=CONF.get_shortcut('editor', 'run from line'),
triggered=self.sig_run_from_line.emit)
self.debug_cell_action = create_action(
self, _("Debug cell"), icon=ima.icon('debug_cell'),
shortcut=CONF.get_shortcut('editor', 'debug cell'),
Expand Down Expand Up @@ -4434,6 +4443,7 @@ def setup_context_menu(self):
self.menu = QMenu(self)
actions_1 = [self.run_cell_action, self.run_cell_and_advance_action,
self.re_run_last_cell_action, self.run_selection_action,
self.run_to_line_action, self.run_from_line_action,
self.gotodef_action, None, self.undo_action,
self.redo_action, None, self.cut_action,
self.copy_action, self.paste_action, selectall_action]
Expand Down Expand Up @@ -5273,6 +5283,8 @@ def contextMenuEvent(self, event):
self.run_cell_action.setVisible(self.is_python_or_ipython())
self.run_cell_and_advance_action.setVisible(self.is_python_or_ipython())
self.run_selection_action.setVisible(self.is_python_or_ipython())
self.run_to_line_action.setVisible(self.is_python_or_ipython())
self.run_from_line_action.setVisible(self.is_python_or_ipython())
self.re_run_last_cell_action.setVisible(self.is_python_or_ipython())
self.gotodef_action.setVisible(self.go_to_definition_enabled)

Expand Down
59 changes: 53 additions & 6 deletions spyder/plugins/editor/widgets/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from qtpy.compat import getsavefilename
from qtpy.QtCore import (QByteArray, QFileInfo, QPoint, QSize, Qt, QTimer,
Signal, Slot)
from qtpy.QtGui import QFont
from qtpy.QtGui import QFont, QTextCursor
from qtpy.QtWidgets import (QAction, QApplication, QFileDialog, QHBoxLayout,
QLabel, QMainWindow, QMessageBox, QMenu,
QSplitter, QVBoxLayout, QWidget, QListWidget,
Expand Down Expand Up @@ -480,6 +480,18 @@ def create_shortcuts(self):
name='Run selection',
parent=self)

run_to_line = CONF.config_shortcut(
self.run_to_line,
context='Editor',
name='Run to line',
parent=self)

run_from_line = CONF.config_shortcut(
self.run_from_line,
context='Editor',
name='Run from line',
parent=self)

new_file = CONF.config_shortcut(
lambda: self.sig_new_file[()].emit(),
context='Editor',
Expand Down Expand Up @@ -644,11 +656,11 @@ def create_shortcuts(self):

# Return configurable ones
return [inspect, set_breakpoint, set_cond_breakpoint, gotoline, tab,
tabshift, run_selection, new_file, open_file, save_file,
save_all, save_as, close_all, prev_edit_pos, prev_cursor,
next_cursor, zoom_in_1, zoom_in_2, zoom_out, zoom_reset,
close_file_1, close_file_2, run_cell, debug_cell,
run_cell_and_advance,
tabshift, run_selection, run_to_line, run_from_line, new_file,
open_file, save_file, save_all, save_as, close_all,
prev_edit_pos, prev_cursor, next_cursor, zoom_in_1, zoom_in_2,
zoom_out, zoom_reset, close_file_1, close_file_2, run_cell,
debug_cell, run_cell_and_advance,
go_to_next_cell, go_to_previous_cell, re_run_last_cell,
prev_warning, next_warning, split_vertically,
split_horizontally, close_split,
Expand Down Expand Up @@ -2448,6 +2460,8 @@ def create_new_editor(self, fname, enc, txt, set_current, new=False,
finfo.sig_save_bookmarks.connect(lambda s1, s2:
self.sig_save_bookmarks.emit(s1, s2))
editor.sig_run_selection.connect(self.run_selection)
editor.sig_run_to_line.connect(self.run_to_line)
editor.sig_run_from_line.connect(self.run_from_line)
editor.sig_run_cell.connect(self.run_cell)
editor.sig_debug_cell.connect(self.debug_cell)
editor.sig_run_cell_and_advance.connect(self.run_cell_and_advance)
Expand Down Expand Up @@ -2709,6 +2723,39 @@ def format_document_or_selection(self, index=None):
finfo.editor.format_document_or_range()

# ------ Run
def _run_lines_cursor(self, direction):
""" Select and run all lines from cursor in given direction"""
editor = self.get_current_editor()

# Move cursor to start of line then move to beginning or end of
# document with KeepAnchor
cursor = editor.textCursor()
cursor.movePosition(QTextCursor.StartOfLine)

if direction == 'up':
cursor.movePosition(QTextCursor.Start, QTextCursor.KeepAnchor)
elif direction == 'down':
cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)

code_text = editor.get_selection_as_executable_code(cursor)
if code_text:
self.exec_in_extconsole.emit(code_text.rstrip(),
self.focus_to_editor)

def run_to_line(self):
"""
Run all lines from the beginning up to, but not including, current
line.
"""
self._run_lines_cursor(direction='up')

def run_from_line(self):
"""
Run all lines from and including the current line to the end of
the document.
"""
self._run_lines_cursor(direction='down')

def run_selection(self):
"""
Run selected text or current line in console.
Expand Down

0 comments on commit e948501

Please sign in to comment.