Skip to content

Commit

Permalink
Merge from 3.x: PR #4634
Browse files Browse the repository at this point in the history
Fixes #3257
Fixes #2030
Fixes #1049

Conflicts:
- spyder/plugins/explorer.py
- spyder/plugins/ipythonconsole.py
  • Loading branch information
ccordoba12 committed Jul 9, 2017
2 parents e4a25d4 + 0718935 commit f8c988b
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 188 deletions.
45 changes: 45 additions & 0 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,51 @@ def test_change_types_in_varexp(main_window, qtbot):
assert shell.get_value('a') == 10


@flaky(max_runs=3)
def test_change_cwd_ipython_console(main_window, qtbot, tmpdir):
"""
Test synchronization with working directory and File Explorer when
changing cwd in the IPython console.
"""
# Wait until the window is fully up
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)

# Change directory in ipython console using %cd
temp_dir = str(tmpdir.mkdir("test_dir"))
with qtbot.waitSignal(shell.executed):
shell.execute("%cd {}".format(temp_dir))
qtbot.wait(1000)

# assert that cwd changed in workingdirectory
assert osp.normpath(main_window.workingdirectory.history[-1]) == osp.normpath(temp_dir)

# assert that cwd changed in explorer
assert osp.normpath(main_window.explorer.fileexplorer.treewidget.get_current_folder()) == osp.normpath(temp_dir)


@flaky(max_runs=3)
def test_change_cwd_explorer(main_window, qtbot, tmpdir):
"""
Test synchronization with working directory and IPython console when
changing directories in the File Explorer.
"""
# Wait until the window is fully up
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)

# Change directory in the explorer widget
temp_dir = str(tmpdir.mkdir("test_dir"))
main_window.explorer.chdir(temp_dir)
qtbot.wait(1000)

# assert that cwd changed in workingdirectory
assert osp.normpath(main_window.workingdirectory.history[-1]) == osp.normpath(temp_dir)

# assert that cwd changed in ipythonconsole
assert osp.normpath(temp_dir) == osp.normpath(shell._cwd)


@flaky(max_runs=3)
@pytest.mark.skipif(os.name == 'nt' or not is_module_installed('Cython'),
reason="It times out sometimes on Windows and Cython is needed")
Expand Down
13 changes: 5 additions & 8 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,15 +281,12 @@
}),
('workingdir',
{
'editor/open/browse_scriptdir': True,
'editor/open/browse_workdir': False,
'editor/new/browse_scriptdir': False,
'editor/new/browse_workdir': True,
'editor/open/auto_set_to_basedir': False,
'editor/save/auto_set_to_basedir': False,
'working_dir_adjusttocontents': False,
'working_dir_history': 20,
'startup/use_last_directory': True,
'startup/use_project_or_home_directory': True,
'console/use_project_or_home_directory': True,
'console/use_cwd': False,
'console/use_fixed_directory': False,
}),
('shortcuts',
{
Expand Down Expand Up @@ -638,7 +635,7 @@
# or if you want to *rename* options, then you need to do a MAJOR update in
# version, e.g. from 3.0.0 to 4.0.0
# 3. You don't need to touch this value if you're just adding a new option
CONF_VERSION = '38.0.0'
CONF_VERSION = '39.0.0'

# Main configuration instance
try:
Expand Down
39 changes: 21 additions & 18 deletions spyder/plugins/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ def get_plugin_actions(self):
self.register_shortcut(run_action, context="_", name="Run",
add_sc_to_tip=True)

configure_action = create_action(self, _("&Configure..."),
configure_action = create_action(self, _("&Configuration per file..."),
icon=ima.icon('run_settings'),
tip=_("Run settings"),
menurole=QAction.NoRole,
Expand Down Expand Up @@ -1756,7 +1756,10 @@ def new(self, fname=None, editorstack=None, text=None):
if not osp.isfile(fname):
break
basedir = getcwd()
if CONF.get('workingdir', 'editor/new/browse_scriptdir'):

if self.main.projects.get_active_project() is not None:
basedir = self.main.projects.get_active_project_path()
else:
c_fname = self.get_current_filename()
if c_fname is not None and c_fname != self.TEMPFILE_PATH:
basedir = osp.dirname(c_fname)
Expand Down Expand Up @@ -1847,10 +1850,10 @@ def load(self, filenames=None, goto=None, word='', editorwindow=None,
self.edit_filetypes = get_edit_filetypes()
if self.edit_filters is None:
self.edit_filters = get_edit_filters()
if CONF.get('workingdir', 'editor/open/browse_scriptdir'):
c_fname = self.get_current_filename()
if c_fname is not None and c_fname != self.TEMPFILE_PATH:
basedir = osp.dirname(c_fname)

c_fname = self.get_current_filename()
if c_fname is not None and c_fname != self.TEMPFILE_PATH:
basedir = osp.dirname(c_fname)
self.redirect_stdio.emit(False)
parent_widget = self.get_current_editorstack()
if filename0 is not None:
Expand All @@ -1874,9 +1877,6 @@ def load(self, filenames=None, goto=None, word='', editorwindow=None,
self.redirect_stdio.emit(True)
if filenames:
filenames = [osp.normpath(fname) for fname in filenames]
if CONF.get('workingdir', 'editor/open/auto_set_to_basedir'):
directory = osp.dirname(filenames[0])
self.open_dir.emit(directory)
else:
return

Expand Down Expand Up @@ -2000,18 +2000,13 @@ def save_as(self):
editorstack = self.get_current_editorstack()
if editorstack.save_as():
fname = editorstack.get_current_filename()
if CONF.get('workingdir', 'editor/save/auto_set_to_basedir'):
self.open_dir.emit(osp.dirname(fname))
self.__add_recent_file(fname)

@Slot()
def save_copy_as(self):
"""Save *copy as* the currently edited file"""
editorstack = self.get_current_editorstack()
if editorstack.save_copy_as():
fname = editorstack.get_current_filename()
if CONF.get('workingdir', 'editor/save/auto_set_to_basedir'):
self.open_dir.emit(osp.dirname(fname))
editorstack.save_copy_as()

@Slot()
def save_all(self):
Expand Down Expand Up @@ -2390,16 +2385,24 @@ def run_file(self, debug=False):
if show_dlg and not dialog.exec_():
return
runconf = dialog.get_configuration()

wdir = runconf.get_working_directory()

args = runconf.get_arguments()
python_args = runconf.get_python_arguments()
interact = runconf.interact
post_mortem = runconf.post_mortem
current = runconf.current
systerm = runconf.systerm
clear_namespace = runconf.clear_namespace


if runconf.file_dir:
wdir = osp.dirname(fname)
elif runconf.cw_dir:
wdir = ''
elif osp.isdir(runconf.dir):
wdir = runconf.dir
else:
wdir = ''

python = True # Note: in the future, it may be useful to run
# something in a terminal instead of a Python interp.
self.__last_ec_exec = (fname, wdir, args, interact, debug,
Expand Down
3 changes: 2 additions & 1 deletion spyder/plugins/explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ def register_plugin(self):
treewidget.sig_open_dir.connect(
lambda dirname:
self.main.workingdirectory.chdir(dirname,
refresh_explorer=False))
refresh_explorer=False,
refresh_console=True))

self.main.editor.open_dir.connect(self.chdir)

Expand Down
36 changes: 36 additions & 0 deletions spyder/plugins/ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ def __init__(self, parent, testing=False):
self.historylog = None # History log plugin
self.variableexplorer = None # Variable explorer plugin
self.editor = None # Editor plugin
self.projects = None # Projects plugin

self.master_clients = 0
self.clients = []
Expand Down Expand Up @@ -802,6 +803,9 @@ def register_plugin(self):
self.main.workingdirectory.set_current_console_wd.connect(
self.set_current_client_working_directory)

self.tabwidget.currentChanged.connect(self.update_working_directory)


#------ Public API (for clients) ------------------------------------------
def get_clients(self):
"""Return clients list"""
Expand Down Expand Up @@ -876,6 +880,20 @@ def set_current_client_working_directory(self, directory):
directory = encoding.to_unicode_from_fs(directory)
shellwidget.set_cwd(directory)

def set_working_directory(self, dirname):
"""Set current working directory.
In the workingdirectory and explorer plugins.
"""
if dirname and not self.testing:
self.main.workingdirectory.chdir(dirname, refresh_explorer=True,
refresh_console=False)

def update_working_directory(self):
"""Update working directory to console cwd."""
shellwidget = self.get_current_shellwidget()
if shellwidget is not None:
shellwidget.get_cwd()

def execute_code(self, lines, current_client=True, clear_variables=False):
"""Execute code instructions."""
sw = self.get_current_shellwidget()
Expand Down Expand Up @@ -1131,6 +1149,22 @@ def register_client(self, client, give_focus=True):
lambda fname, lineno, shellwidget=shellwidget:
self.pdb_has_stopped(fname, lineno, shellwidget))

# Set shell cwd according to preferences
cwd_path = ''
if CONF.get('workingdir', 'console/use_project_or_home_directory'):
cwd_path = get_home_dir()
if (self.projects is not None and
self.projects.get_active_project() is not None):
cwd_path = self.projects.get_active_project_path()
elif CONF.get('workingdir', 'console/use_fixed_directory'):
cwd_path = CONF.get('workingdir', 'console/fixed_directory')

if osp.isdir(cwd_path) and self.main is not None:
shellwidget.set_cwd(cwd_path)
if give_focus:
# Syncronice cwd with explorer and cwd widget
shellwidget.get_cwd()

# Connect text widget to Help
if self.help is not None:
control.set_help(self.help)
Expand All @@ -1147,6 +1181,8 @@ def register_client(self, client, give_focus=True):
# Connect focus signal to client's control widget
control.focus_changed.connect(lambda: self.focus_changed.emit())

shellwidget.sig_change_cwd.connect(self.set_working_directory)

# Update the find widget if focus changes between control and
# page_control
self.find_widget.set_editor(control)
Expand Down
Loading

0 comments on commit f8c988b

Please sign in to comment.