Skip to content

Commit

Permalink
Merge from 3.x: PR #3974
Browse files Browse the repository at this point in the history
Fixes #3959
  • Loading branch information
ccordoba12 committed Mar 4, 2017
2 parents 590bc78 + d870791 commit ca515f4
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 11 deletions.
24 changes: 24 additions & 0 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,30 @@ def test_run_code(main_window, qtbot):
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ControlModifier)
assert nsb.editor.model.rowCount() == 1

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Re-run last cell ----
# Run the first two cells in file
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ShiftModifier)
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ShiftModifier)

# Wait until objects have appeared in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 2, timeout=EVAL_TIMEOUT)

# Clean namespace
shell.execute('%reset -f')

# Wait until there are no objects in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=EVAL_TIMEOUT)

# Re-run last cell
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.AltModifier)

# Wait until the object has appeared in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 1, timeout=EVAL_TIMEOUT)
assert shell.get_value('li') == [1, 2, 3]

# ---- Closing test file ----
main_window.editor.close_file()


Expand Down
3 changes: 3 additions & 0 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@
RUN_CELL_SHORTCUT = 'Meta+Return'
else:
RUN_CELL_SHORTCUT = 'Ctrl+Return'
RE_RUN_LAST_CELL_SHORTCUT = 'Alt+Return'
RUN_CELL_AND_ADVANCE_SHORTCUT = 'Shift+Return'


# =============================================================================
# Defaults
# =============================================================================
Expand Down Expand Up @@ -421,6 +423,7 @@
'editor/close file 2': "Ctrl+F4",
'editor/run cell': RUN_CELL_SHORTCUT,
'editor/run cell and advance': RUN_CELL_AND_ADVANCE_SHORTCUT,
'editor/re-run last cell': RE_RUN_LAST_CELL_SHORTCUT,
# -- In plugins/editor.py
'editor/show/hide outline': "Ctrl+Alt+O",
# -- In Breakpoints
Expand Down
20 changes: 19 additions & 1 deletion spyder/plugins/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,16 @@ def get_plugin_actions(self):
triggered=self.run_cell_and_advance,
context=Qt.WidgetShortcut)

re_run_last_cell_action = create_action(self,
_("Re-run last cell"),
tip=_("Re run last cell "),
triggered=self.re_run_last_cell,
context=Qt.WidgetShortcut)
self.register_shortcut(re_run_last_cell_action,
context="Editor",
name='re-run last cell',
add_sc_to_tip=True)

# --- Source code Toolbar ---
self.todo_list_action = create_action(self,
_("Show todo list"), icon=ima.icon('todo_list'),
Expand Down Expand Up @@ -1043,7 +1053,8 @@ def get_plugin_actions(self):

# ---- Run menu/toolbar construction ----
run_menu_actions = [run_action, run_cell_action,
run_cell_advance_action, MENU_SEPARATOR,
run_cell_advance_action,
re_run_last_cell_action, MENU_SEPARATOR,
run_selected_action, re_run_action,
configure_action, MENU_SEPARATOR]
self.main.run_menu_actions += run_menu_actions
Expand Down Expand Up @@ -1117,6 +1128,7 @@ def get_plugin_actions(self):
debug_action, run_selected_action,
run_cell_action,
run_cell_advance_action,
re_run_last_cell_action,
blockcomment_action,
unblockcomment_action,
self.winpdb_action]
Expand Down Expand Up @@ -2422,6 +2434,12 @@ def run_cell_and_advance(self):
editorstack = self.get_current_editorstack()
editorstack.run_cell_and_advance()

@Slot()
def re_run_last_cell(self):
"""Run last executed cell."""
editorstack = self.get_current_editorstack()
editorstack.re_run_last_cell()

#------ Zoom in/out/reset
def zoom(self, factor):
"""Zoom in/out/reset"""
Expand Down
8 changes: 4 additions & 4 deletions spyder/utils/syntaxhighlighters.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,11 +557,11 @@ class CythonSH(PythonSH):
"""Cython Syntax Highlighter"""
ADDITIONAL_KEYWORDS = [
"cdef", "ctypedef", "cpdef", "inline", "cimport", "extern",
"include", "begin", "end", "by", "gil", "nogil", "const", "public",
"readonly", "fused ", "static", "api", "DEF", "IF", "ELIF", "ELSE"]
"include", "begin", "end", "by", "gil", "nogil", "const", "public",
"readonly", "fused", "static", "api", "DEF", "IF", "ELIF", "ELSE"]

ADDITIONAL_BUILTINS = C_TYPES.split() + [
"array", "bint", "Py_ssize_t", "intern", "reload", "sizeof"]
"array", "bint", "Py_ssize_t", "intern", "reload", "sizeof", "NULL"]
PROG = re.compile(make_python_patterns(ADDITIONAL_KEYWORDS,
ADDITIONAL_BUILTINS), re.S)
IDPROG = re.compile(r"\s+([\w\.]+)", re.S)
Expand Down
14 changes: 13 additions & 1 deletion spyder/widgets/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,18 @@ def create_shortcuts(self):
context="Editor",
name="run cell and advance",
parent=self)
re_run_last_cell = config_shortcut(self.re_run_last_cell,
context="Editor",
name="re-run last cell",
parent=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, run_cell_and_advance]
close_file_1, close_file_2, run_cell, run_cell_and_advance,
re_run_last_cell]

def get_shortcut_data(self):
"""
Expand Down Expand Up @@ -1736,6 +1741,7 @@ def create_new_editor(self, fname, enc, txt, set_current, new=False,
editor.run_selection.connect(self.run_selection)
editor.run_cell.connect(self.run_cell)
editor.run_cell_and_advance.connect(self.run_cell_and_advance)
editor.re_run_last_cell.connect(self.re_run_last_cell)
editor.sig_new_file.connect(self.sig_new_file.emit)
language = get_file_language(fname, txt)
editor.setup_editor(
Expand Down Expand Up @@ -1927,6 +1933,12 @@ def run_cell_and_advance(self):
self.get_current_editor().go_to_next_cell()
term.setFocus()

def re_run_last_cell(self):
text = self.get_current_editor().get_last_cell_as_executable_code()
finfo = self.get_current_finfo()
if finfo.editor.is_python() and text:
self.exec_in_extconsole.emit(text, self.focus_to_editor)

#------ Drag and drop
def dragEnterEvent(self, event):
"""Reimplement Qt method
Expand Down
21 changes: 18 additions & 3 deletions spyder/widgets/sourcecode/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ def __init__(self, parent=None):
self.matched_p_color = QColor(Qt.green)
self.unmatched_p_color = QColor(Qt.red)

self.last_cursor_cell = None

def setup_completion(self):
size = CONF.get('main', 'completion/size')
font = get_font()
Expand Down Expand Up @@ -621,18 +623,31 @@ def get_selection_as_executable_code(self):

return ls.join(lines)

def get_cell_as_executable_code(self):
"""Return cell contents as executable code"""
def __exec_cell(self):
init_cursor = QTextCursor(self.textCursor())
start_pos, end_pos = self.__save_selection()
cursor, whole_file_selected = self.select_current_cell()
if not whole_file_selected:
self.setTextCursor(cursor)
text = self.get_selection_as_executable_code()
self.last_cursor_cell = init_cursor
self.__restore_selection(start_pos, end_pos)
if text is not None:
text = text.rstrip()
return text

def get_cell_as_executable_code(self):
"""Return cell contents as executable code"""
return self.__exec_cell()

def get_last_cell_as_executable_code(self):
text = None
if self.last_cursor_cell:
self.setTextCursor(self.last_cursor_cell)
self.highlight_current_cell()
text = self.__exec_cell()
return text

def is_cell_separator(self, cursor=None, block=None):
"""Return True if cursor (or text block) is on a block separator"""
assert cursor is not None or block is not None
Expand Down Expand Up @@ -691,7 +706,7 @@ def select_current_cell(self):
prev_pos = cur_pos
cell_at_file_end = cursor.atEnd()
return cursor, cell_at_file_start and cell_at_file_end

def select_current_cell_in_visible_portion(self):
"""Select cell under cursor in the visible portion of the file
cell = group of lines separated by CELL_SEPARATORS
Expand Down
11 changes: 9 additions & 2 deletions spyder/widgets/sourcecode/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class CodeEditor(TextEditBaseWidget):
run_selection = Signal()
run_cell_and_advance = Signal()
run_cell = Signal()
re_run_last_cell = Signal()
go_to_definition_regex = Signal(int)
sig_cursor_position_changed = Signal(int, int)
focus_changed = Signal()
Expand Down Expand Up @@ -2287,6 +2288,10 @@ def setup_context_menu(self):
self, _("Run cell and advance"), icon=ima.icon('run_cell'),
shortcut=QKeySequence(RUN_CELL_AND_ADVANCE_SHORTCUT),
triggered=self.run_cell_and_advance.emit)
self.re_run_last_cell_action = create_action(
self, _("Re-run last cell"), icon=ima.icon('run_cell'),
shortcut=get_shortcut('editor', 're-run last cell'),
triggered=self.re_run_last_cell.emit)
self.run_selection_action = create_action(
self, _("Run &selection or current line"),
icon=ima.icon('run_selection'),
Expand All @@ -2309,8 +2314,9 @@ def setup_context_menu(self):
# Build menu
self.menu = QMenu(self)
actions_1 = [self.run_cell_action, self.run_cell_and_advance_action,
self.run_selection_action, self.gotodef_action, None,
self.undo_action, self.redo_action, None, self.cut_action,
self.re_run_last_cell_action, self.run_selection_action,
self.gotodef_action, None, self.undo_action,
self.redo_action, None, self.cut_action,
self.copy_action, self.paste_action, selectall_action]
actions_2 = [None, zoom_in_action, zoom_out_action, zoom_reset_action,
None, toggle_comment_action]
Expand Down Expand Up @@ -2617,6 +2623,7 @@ def contextMenuEvent(self, event):
self.run_cell_action.setVisible(self.is_python())
self.run_cell_and_advance_action.setVisible(self.is_python())
self.run_selection_action.setVisible(self.is_python())
self.re_run_last_cell_action.setVisible(self.is_python())
self.gotodef_action.setVisible(self.go_to_definition_enabled \
and self.is_python_like())

Expand Down

0 comments on commit ca515f4

Please sign in to comment.