diff --git a/spyder/plugins/history.py b/spyder/plugins/history.py index a7e26bffbf7..d423cc0a224 100644 --- a/spyder/plugins/history.py +++ b/spyder/plugins/history.py @@ -9,6 +9,7 @@ # Standard library imports import os.path as osp import sys +import re # Third party imports from qtpy import PYQT5 @@ -18,14 +19,15 @@ # Local imports -from spyder.utils import encoding from spyder.config.base import _ from spyder.plugins import SpyderPluginWidget from spyder.plugins.configdialog import PluginConfigPage from spyder.py3compat import is_text_string, to_text_string +from spyder.utils import encoding from spyder.utils import icon_manager as ima from spyder.utils.qthelpers import (add_actions, create_action, create_toolbutton) +from spyder.utils.sourcecode import normalize_eols from spyder.widgets.tabs import Tabs from spyder.widgets.sourcecode import codeeditor from spyder.widgets.findreplace import FindReplace @@ -230,6 +232,12 @@ def add_history(self, filename): editor.toggle_wrap_mode( self.get_option('wrap') ) text, _ = encoding.read(filename) + text = normalize_eols(text) + linebreaks = [m.start() for m in re.finditer('\n', text)] + maxNline = self.get_option('max_entries') + if len(linebreaks) > maxNline: + text = text[linebreaks[-maxNline - 1] + 1:] + encoding.write(text, filename) editor.set_text(text) editor.set_cursor_position('eof') diff --git a/spyder/plugins/tests/test_history.py b/spyder/plugins/tests/test_history.py new file mode 100644 index 00000000000..0d96027724a --- /dev/null +++ b/spyder/plugins/tests/test_history.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © Spyder Project Contributors +# +# Licensed under the terms of the MIT License +# (see spyder/__init__.py for details) +# ----------------------------------------------------------------------------- + +""" +Tests for the history log +""" + +# Standard library imports +try: + from unittest.mock import Mock +except ImportError: + from mock import Mock + +# Third party imports +from qtpy.QtWidgets import QWidget +import pytest + +# Local imports +from spyder.plugins.history import HistoryLog +from spyder.py3compat import to_text_string + + +# ============================================================================= +# Fixtures +# ============================================================================= +@pytest.fixture +def history_plugin(qtbot): + """History plugin fixture""" + + class MainMock(QWidget): + def __getattr__(self, attr): + return Mock() + + history = HistoryLog(parent=MainMock()) + qtbot.addWidget(history) + return history + + +# ============================================================================= +# Tests +# ============================================================================= +def test_max_entries(history_plugin, tmpdir): + """Test that history is truncated at max_entries.""" + max_entries = history_plugin.get_option('max_entries') + + # Write more than max entries in a test file + history = '' + for i in range(max_entries + 1): + history = history + '{}\n'.format(i) + + history_file = tmpdir.join('history.py') + history_file.write(history) + + # Load test file in plugin + history_plugin.add_history(to_text_string(history_file)) + + # Assert that we have max_entries after loading history and + # that there's no 0 in the first line + assert len(history_file.readlines()) == max_entries + assert '0' not in history_file.readlines()[0] + + +if __name__ == "__main__": + pytest.main() diff --git a/spyder/utils/sourcecode.py b/spyder/utils/sourcecode.py index 337e4f391a0..592fca10562 100644 --- a/spyder/utils/sourcecode.py +++ b/spyder/utils/sourcecode.py @@ -71,6 +71,14 @@ def has_mixed_eol_chars(text): return repr(correct_text) != repr(text) +def normalize_eols(text, eol='\n'): + """Use the same eol's in text""" + for eol_char, _ in EOL_CHARS: + if eol_char != eol: + text = text.replace(eol_char, eol) + return text + + def fix_indentation(text): """Replace tabs by spaces""" return text.replace('\t', ' '*4) diff --git a/spyder/utils/tests/test_sourcecode.py b/spyder/utils/tests/test_sourcecode.py index 2ab19659872..8cb28fe1206 100644 --- a/spyder/utils/tests/test_sourcecode.py +++ b/spyder/utils/tests/test_sourcecode.py @@ -13,6 +13,11 @@ from spyder.utils import sourcecode +def test_normalize_eols(): + text = "a\nb\r\nc\rd" + assert sourcecode.normalize_eols(text) == "a\nb\nc\nd" + + def test_get_primary_at(): code = 'import functools\nfunctools.partial' assert sourcecode.get_primary_at(code, len(code)) == 'functools.partial'