From 372e983459168e04fef0e9d419fb388caf752108 Mon Sep 17 00:00:00 2001 From: lovedboy Date: Thu, 22 Oct 2015 19:25:00 +0800 Subject: [PATCH 1/5] add THEFUCK_HISTORY_LIMIT, my machine is so slow --- README.md | 3 ++- thefuck/conf.py | 4 +++- thefuck/shells.py | 11 +++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 199f37b8..9f3b2168 100644 --- a/README.md +++ b/README.md @@ -302,7 +302,8 @@ Or via environment variables: * `THEFUCK_NO_COLORS` – disable colored output, `true/false`; * `THEFUCK_PRIORITY` – priority of the rules, like `no_command=9999:apt_get=100`, rule with lower `priority` will be matched first; -* `THEFUCK_DEBUG` – enables debug output, `true/false`. +* `THEFUCK_DEBUG` – enables debug output, `true/false`; +* `THEFUCK_HISTORY_LIMIT` – how many history commands will be scanned, like `2000`. For example: diff --git a/thefuck/conf.py b/thefuck/conf.py index 3e6e55f5..47eaf34c 100644 --- a/thefuck/conf.py +++ b/thefuck/conf.py @@ -24,7 +24,8 @@ ENV_TO_ATTR = {'THEFUCK_RULES': 'rules', 'THEFUCK_REQUIRE_CONFIRMATION': 'require_confirmation', 'THEFUCK_NO_COLORS': 'no_colors', 'THEFUCK_PRIORITY': 'priority', - 'THEFUCK_DEBUG': 'debug'} + 'THEFUCK_DEBUG': 'debug', + 'THEFUCK_HISTORY_LIMIT': 'history_limit'} SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file # @@ -125,3 +126,4 @@ class Settings(dict): settings = Settings(DEFAULT_SETTINGS) +settings.init() diff --git a/thefuck/shells.py b/thefuck/shells.py index 97d51a43..d82a88ba 100644 --- a/thefuck/shells.py +++ b/thefuck/shells.py @@ -10,6 +10,7 @@ from time import time import io import os from .utils import DEVNULL, memoize, cache +from .conf import settings class Generic(object): @@ -59,10 +60,16 @@ class Generic(object): def get_history(self): """Returns list of history entries.""" + tail_num = settings.get("history_limit", None) history_file_name = self._get_history_file_name() if os.path.isfile(history_file_name): - with io.open(history_file_name, 'r', - encoding='utf-8', errors='ignore') as history: + if tail_num is not None: + _, f = os.popen2("tail -n {} {}".format(tail_num, history_file_name)) + _.close() + else: + f = io.open(history_file_name, 'r', + encoding='utf-8', errors='ignore') + with f as history: for line in history: prepared = self._script_from_history(line)\ .strip() From b3a19fe439c095e8116f76521e287a1d24af7829 Mon Sep 17 00:00:00 2001 From: lovedboy Date: Thu, 29 Oct 2015 10:14:34 +0800 Subject: [PATCH 2/5] history limit from settings --- README.md | 1 + thefuck/conf.py | 2 +- thefuck/shells.py | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9f3b2168..082a1f33 100644 --- a/README.md +++ b/README.md @@ -314,6 +314,7 @@ export THEFUCK_REQUIRE_CONFIRMATION='true' export THEFUCK_WAIT_COMMAND=10 export THEFUCK_NO_COLORS='false' export THEFUCK_PRIORITY='no_command=9999:apt_get=100' +export THEFUCK_HISTORY_LIMIT='2000' ``` ## Developing diff --git a/thefuck/conf.py b/thefuck/conf.py index 47eaf34c..21a17753 100644 --- a/thefuck/conf.py +++ b/thefuck/conf.py @@ -16,6 +16,7 @@ DEFAULT_SETTINGS = {'rules': DEFAULT_RULES, 'no_colors': False, 'debug': False, 'priority': {}, + 'history_limit': None, 'env': {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'}} ENV_TO_ATTR = {'THEFUCK_RULES': 'rules', @@ -126,4 +127,3 @@ class Settings(dict): settings = Settings(DEFAULT_SETTINGS) -settings.init() diff --git a/thefuck/shells.py b/thefuck/shells.py index d82a88ba..a7037800 100644 --- a/thefuck/shells.py +++ b/thefuck/shells.py @@ -60,10 +60,10 @@ class Generic(object): def get_history(self): """Returns list of history entries.""" - tail_num = settings.get("history_limit", None) + tail_num = settings.history_limit history_file_name = self._get_history_file_name() if os.path.isfile(history_file_name): - if tail_num is not None: + if tail_num is not None and tail_num.isdigit(): _, f = os.popen2("tail -n {} {}".format(tail_num, history_file_name)) _.close() else: From bd6ee68c03891999bf91bfd30aa05070f911da70 Mon Sep 17 00:00:00 2001 From: nvbn Date: Thu, 29 Oct 2015 20:17:17 +0800 Subject: [PATCH 3/5] #394: Try simpler solution to limit lines count --- tests/test_shells.py | 2 +- thefuck/shells.py | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/test_shells.py b/tests/test_shells.py index cd98a909..413bdef7 100644 --- a/tests/test_shells.py +++ b/tests/test_shells.py @@ -18,7 +18,7 @@ def history_lines(mocker): def aux(lines): mock = mocker.patch('io.open') mock.return_value.__enter__\ - .return_value.__iter__.return_value = lines + .return_value.readlines.return_value = lines return aux diff --git a/thefuck/shells.py b/thefuck/shells.py index 6ae306cb..b469c1d5 100644 --- a/thefuck/shells.py +++ b/thefuck/shells.py @@ -60,19 +60,29 @@ class Generic(object): """ return '' + def _get_history_lines(self, history_file): + """Returns all history lines. + + If `settings.history_limit` defined, limits result to `settings.history_limit`. + + """ + if not settings.history_limit: + return history_file.readlines() + + buffer = [] + for line in history_file.readlines(): + if len(buffer) > settings.history_limit: + buffer.pop(0) + buffer.append(line) + return buffer + def get_history(self): """Returns list of history entries.""" - tail_num = settings.history_limit history_file_name = self._get_history_file_name() if os.path.isfile(history_file_name): - if tail_num is not None and tail_num.isdigit(): - _, f = os.popen2("tail -n {} {}".format(tail_num, history_file_name)) - _.close() - else: - f = io.open(history_file_name, 'r', - encoding='utf-8', errors='ignore') - with f as history: - for line in history: + with io.open(history_file_name, 'r', + encoding='utf-8', errors='ignore') as history_file: + for line in self._get_history_lines(history_file): prepared = self._script_from_history(line)\ .strip() if prepared: From 8c8abca8d504cf06da9e0dd1143f920566e067e1 Mon Sep 17 00:00:00 2001 From: nvbn Date: Thu, 29 Oct 2015 22:51:30 +0800 Subject: [PATCH 4/5] #394: `readlines` isn't lazy --- thefuck/shells.py | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/thefuck/shells.py b/thefuck/shells.py index b469c1d5..0555b3c7 100644 --- a/thefuck/shells.py +++ b/thefuck/shells.py @@ -52,37 +52,18 @@ class Generic(object): with open(history_file_name, 'a') as history: history.write(self._get_history_line(command_script)) - def _script_from_history(self, line): - """Returns prepared history line. - - Should return a blank line if history line is corrupted or empty. - - """ - return '' - - def _get_history_lines(self, history_file): - """Returns all history lines. - - If `settings.history_limit` defined, limits result to `settings.history_limit`. - - """ - if not settings.history_limit: - return history_file.readlines() - - buffer = [] - for line in history_file.readlines(): - if len(buffer) > settings.history_limit: - buffer.pop(0) - buffer.append(line) - return buffer - def get_history(self): """Returns list of history entries.""" history_file_name = self._get_history_file_name() if os.path.isfile(history_file_name): with io.open(history_file_name, 'r', encoding='utf-8', errors='ignore') as history_file: - for line in self._get_history_lines(history_file): + + lines = history_file.readlines() + if settings.history_limit: + lines = lines[-settings.history_limit:] + + for line in lines: prepared = self._script_from_history(line)\ .strip() if prepared: From 2fea0d4c6006a47b19b749248d7df15bc63e0979 Mon Sep 17 00:00:00 2001 From: nvbn Date: Fri, 30 Oct 2015 16:23:19 +0800 Subject: [PATCH 5/5] #394: Force `history_limit` to be int --- README.md | 3 ++- thefuck/conf.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f5e95542..3f0565bf 100644 --- a/README.md +++ b/README.md @@ -280,7 +280,8 @@ The Fuck has a few settings parameters which can be changed in `$XDG_CONFIG_HOME * `wait_command` – max amount of time in seconds for getting previous command output; * `no_colors` – disable colored output; * `priority` – dict with rules priorities, rule with lower `priority` will be matched first; -* `debug` – enables debug output, by default `False`. +* `debug` – enables debug output, by default `False`; +* `history_limit` &ndash numeric value of how many history commands will be scanned, like `2000`; Example of `settings.py`: diff --git a/thefuck/conf.py b/thefuck/conf.py index 64944838..bab990dc 100644 --- a/thefuck/conf.py +++ b/thefuck/conf.py @@ -128,6 +128,8 @@ class Settings(dict): return int(val) elif attr in ('require_confirmation', 'no_colors', 'debug'): return val.lower() == 'true' + elif attr == 'history_limit': + return int(val) else: return val