Skip to content

Commit

Permalink
Merge from 3.x: PR #4700
Browse files Browse the repository at this point in the history
Fixes #4694
  • Loading branch information
ccordoba12 committed Jul 6, 2017
2 parents fe001d5 + 9cb8924 commit 2a52085
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 11 deletions.
36 changes: 30 additions & 6 deletions spyder/plugins/ipythonconsole.py
Expand Up @@ -51,7 +51,7 @@
from spyder.utils.ipython.style import create_qss_style
from spyder.utils.qthelpers import create_action, MENU_SEPARATOR
from spyder.utils import icon_manager as ima
from spyder.utils import encoding, programs
from spyder.utils import encoding, programs, sourcecode
from spyder.utils.misc import get_error_match, remove_backslashes
from spyder.widgets.findreplace import FindReplace
from spyder.widgets.ipythonconsole import ClientWidget
Expand Down Expand Up @@ -603,6 +603,7 @@ def __init__(self, parent, testing=False):

self.master_clients = 0
self.clients = []
self.filenames = []
self.mainwindow_close = False
self.create_new_client_if_empty = True
self.testing = testing
Expand Down Expand Up @@ -736,6 +737,7 @@ def refresh_plugin(self):
sw = client.shellwidget
self.variableexplorer.set_shellwidget_from_id(id(sw))
self.help.set_shell(sw)
self.update_tabs_text()
self.sig_update_plugin_title.emit()

def get_plugin_actions(self):
Expand Down Expand Up @@ -901,7 +903,9 @@ def write_to_stdin(self, line):

@Slot()
@Slot(bool)
def create_new_client(self, give_focus=True):
@Slot(str)
@Slot(bool, str)
def create_new_client(self, give_focus=True, filename=''):
"""Create a new client"""
self.master_clients += 1
client_id = dict(int_id=to_text_string(self.master_clients),
Expand All @@ -914,7 +918,7 @@ def create_new_client(self, give_focus=True):
interpreter_versions=self.interpreter_versions(),
connection_file=cf,
menu_actions=self.menu_actions)
self.add_tab(client, name=client.get_name())
self.add_tab(client, name=client.get_name(), filename=filename)

if cf is None:
error_msg = _("The directory {} is not writable and it is "
Expand Down Expand Up @@ -1186,8 +1190,10 @@ def close_client(self, index=None, client=None, force=False):
# Note: client index may have changed after closing related widgets
self.tabwidget.removeTab(self.tabwidget.indexOf(client))
self.clients.remove(client)
self.filenames.pop(index)
if not self.tabwidget.count() and self.create_new_client_if_empty:
self.create_new_client()
self.update_tabs_text()
self.sig_update_plugin_title.emit()

def get_client_index_from_id(self, client_id):
Expand Down Expand Up @@ -1259,15 +1265,16 @@ def create_client_from_path(self, path):
def create_client_for_file(self, filename):
"""Create a client to execute code related to a file."""
# Create client
self.create_new_client()
self.create_new_client(filename=filename)

# Don't increase the count of master clients
self.master_clients -= 1

# Rename client tab with filename
client = self.get_current_client()
client.allow_rename = False
self.rename_client_tab(client, filename)
tab_text = self.disambiguate_fname(filename)
self.rename_client_tab(client, tab_text)

def get_client_for_file(self, filename):
"""Get client associated with a given file."""
Expand Down Expand Up @@ -1349,25 +1356,42 @@ def restart_kernel(self):
client.restart_kernel()

#------ Public API (for tabs) ---------------------------------------------
def add_tab(self, widget, name):
def add_tab(self, widget, name, filename=''):
"""Add tab"""
self.clients.append(widget)
index = self.tabwidget.addTab(widget, name)
self.filenames.insert(index, filename)
self.tabwidget.setCurrentIndex(index)
if self.dockwidget and not self.ismaximized:
self.dockwidget.setVisible(True)
self.dockwidget.raise_()
self.activateWindow()
widget.get_control().setFocus()
self.update_tabs_text()

def move_tab(self, index_from, index_to):
"""
Move tab (tabs themselves have already been moved by the tabwidget)
"""
filename = self.filenames.pop(index_from)
client = self.clients.pop(index_from)
self.filenames.insert(index_to, filename)
self.clients.insert(index_to, client)
self.sig_update_plugin_title.emit()

def disambiguate_fname(self, fname):
"""Generate a file name without ambiguation."""
files_path_list = [filename for filename in self.filenames
if filename]
return sourcecode.disambiguate_fname(files_path_list, fname)

def update_tabs_text(self):
"""Update the text from the tabs."""
for index, fname in enumerate(self.filenames):
if fname:
client = self.clients[index]
self.rename_client_tab(client, self.disambiguate_fname(fname))

def rename_client_tab(self, client, given_name):
"""Rename client's tab"""
index = self.get_client_index_from_id(id(client))
Expand Down
36 changes: 36 additions & 0 deletions spyder/plugins/tests/test_ipythonconsole.py
Expand Up @@ -35,6 +35,7 @@
#==============================================================================
SHELL_TIMEOUT = 20000
PYQT_WHEEL = PYQT_VERSION > '5.6'
TEMP_DIRECTORY = tempfile.gettempdir()


#==============================================================================
Expand Down Expand Up @@ -76,6 +77,40 @@ def close_console():
#==============================================================================
# Tests
#==============================================================================
@flaky(max_runs=3)
def test_console_disambiguation(ipyconsole, qtbot):
"""Test the disambiguation of dedicated consoles."""
# Create directories and file for TEMP_DIRECTORY/a/b/c.py
# and TEMP_DIRECTORY/a/d/c.py
dir_b = osp.join(TEMP_DIRECTORY, 'a', 'b')
filename_b = osp.join(dir_b, 'c.py')
if not osp.isdir(dir_b):
os.makedirs(dir_b)
if not osp.isfile(filename_b):
file_c = open(filename_b, 'w+')
file_c.close()
dir_d = osp.join(TEMP_DIRECTORY, 'a', 'd')
filename_d = osp.join(dir_d, 'c.py')
if not osp.isdir(dir_d):
os.makedirs(dir_d)
if not osp.isfile(filename_d):
file_e = open(filename_d, 'w+')
file_e.close()

# Create new client and assert name without disambiguation
ipyconsole.create_client_for_file(filename_b)
client = ipyconsole.get_current_client()
assert client.get_name() == 'c.py/A'

# Create new client and assert name with disambiguation
ipyconsole.create_client_for_file(filename_d)
client = ipyconsole.get_current_client()
assert client.get_name() == 'c.py - d/A'
ipyconsole.tabwidget.setCurrentIndex(1)
client = ipyconsole.get_current_client()
assert client.get_name() == 'c.py - b/A'


@flaky(max_runs=3)
def test_console_coloring(ipyconsole, qtbot):

Expand All @@ -99,6 +134,7 @@ def test_console_coloring(ipyconsole, qtbot):
assert console_background_color.strip() == editor_background_color.strip()
assert console_font_color.strip() == editor_font_color.strip()


@flaky(max_runs=3)
@pytest.mark.skipif(os.name == 'nt', reason="It doesn't work on Windows")
def test_get_env(ipyconsole, qtbot):
Expand Down
2 changes: 1 addition & 1 deletion spyder/utils/sourcecode.py
Expand Up @@ -183,7 +183,7 @@ def differentiate_prefix(path_components0, path_components1):
path_0 = '/'
return path_0

def get_file_title(files_path_list, filename):
def disambiguate_fname(files_path_list, filename):
"""Get tab title without ambiguation."""
fname = os.path.basename(filename)
same_name_files = get_same_name_files(files_path_list, fname)
Expand Down
6 changes: 3 additions & 3 deletions spyder/utils/tests/test_sourcecode.py
Expand Up @@ -84,7 +84,7 @@ def test_shortest_path():
shortest_path = os.path.join(*['c:','','documents','test','test.py'])
assert sourcecode.shortest_path(files_path_list) == shortest_path

def test_get_file_title():
def test_disambiguate_fname():
files_path_list = []
if sys.platform.startswith('linux'):
fname0 = os.path.join(*['','','documents','test','test.py'])
Expand All @@ -98,8 +98,8 @@ def test_get_file_title():
files_path_list.append(fname1)
title0 = 'test.py - ' + os.path.join(*['test'])
title1 = 'test.py - ' + os.path.join(*['projects','test'])
assert sourcecode.get_file_title(files_path_list, fname0) == title0
assert sourcecode.get_file_title(files_path_list, fname1) == title1
assert sourcecode.disambiguate_fname(files_path_list, fname0) == title0
assert sourcecode.disambiguate_fname(files_path_list, fname1) == title1

if __name__ == '__main__':
pytest.main()
Expand Down
2 changes: 1 addition & 1 deletion spyder/widgets/editor.py
Expand Up @@ -1155,7 +1155,7 @@ def get_tab_text(self, index, is_modified=None, is_readonly=None):
"""Return tab title."""
files_path_list = [finfo.filename for finfo in self.data]
fname = self.data[index].filename
fname = sourcecode.get_file_title(files_path_list, fname)
fname = sourcecode.disambiguate_fname(files_path_list, fname)
return self.__modified_readonly_title(fname,
is_modified, is_readonly)

Expand Down

0 comments on commit 2a52085

Please sign in to comment.