Skip to content

Commit

Permalink
improve: show diff.
Browse files Browse the repository at this point in the history
- use __future__ to solve some compation with python2.
- compat get_terminal_size.
  • Loading branch information
zlj-zz committed Aug 10, 2021
1 parent 748164a commit 17a4fd3
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ __pycache__/

ignore_files/
log
*.pyc

*.tmp

Expand Down
163 changes: 110 additions & 53 deletions pigit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from __future__ import print_function, division, absolute_import


__project__ = "pigit"
__version__ = "1.0.7.bate.1"
Expand Down Expand Up @@ -69,6 +71,36 @@
import urllib.request

urlopen = urllib.request.urlopen

def get_terminal_size(fallback=(80, 24)):
# fork from shutil.get_terminal_size()
# columns, lines are the working values
try:
columns = int(os.environ["COLUMNS"])
except (KeyError, ValueError):
columns = 0

try:
lines = int(os.environ["LINES"])
except (KeyError, ValueError):
lines = 0

# only query if necessary
if columns <= 0 or lines <= 0:
try:
size = os.get_terminal_size(sys.__stdout__.fileno())
except (AttributeError, ValueError, OSError):
# stdout is None, closed, detached, or not a terminal, or
# os.get_terminal_size() is unsupported
size = fallback
if columns <= 0:
columns = size[0]
if lines <= 0:
lines = size[1]

return columns, lines


else:
input = raw_input
range = xrange
Expand All @@ -78,6 +110,34 @@

urlopen = urllib2.urlopen

def get_terminal_size(fallback=(80, 24)):
# reason: python2 not support get_terminal_size().
# columns, lines are the working values
try:
columns = int(os.environ["COLUMNS"])
except (KeyError, ValueError):
columns = 0

try:
lines = int(os.environ["LINES"])
except (KeyError, ValueError):
lines = 0

# only query if necessary
if columns <= 0 or lines <= 0:
try:
size = subprocess.check_output(["stty", "size"]).split()
size = [int(i) for i in size[::-1]]
except (AttributeError, ValueError, OSError):
size = fallback
if columns <= 0:
columns = size[0]
if lines <= 0:
lines = size[1]

return columns, lines


# For windows.
IS_WIN = sys.platform.lower().startswith("win")
if IS_WIN:
Expand Down Expand Up @@ -526,6 +586,9 @@ def load_config(self):
)
if type(getattr(self, key)) == bool:
try:
# True values are y, yes, t, true, on and 1;
# false values are n, no, f, false, off and 0.
# Raises ValueError if val is anything else.
new_config[key] = bool(strtobool(line))
except ValueError:
self.warnings.append(
Expand Down Expand Up @@ -1084,7 +1147,7 @@ def err_echo(msg, nl=True):
class InteractiveAdd(object):
"""Interactive operation git tree status."""

def __init__(self, use_color=True, cursor=None, help_wait=1.5):
def __init__(self, use_color=True, cursor=None, help_wait=1.5, debug=False):
super(InteractiveAdd, self).__init__()
self.use_color = use_color
if not cursor:
Expand All @@ -1097,18 +1160,7 @@ def __init__(self, use_color=True, cursor=None, help_wait=1.5):
self.help_wait = help_wait
self._min_height = 8
self._min_width = 60

def get_terminal_size(self, fallback=(80, 24)):
try:
width, height = os.get_terminal_size()
except AttributeError:
try:
width = int(os.environ["COLUMNS"])
height = int(os.environ["LINES"])
except (KeyError, ValueError):
width, height = fallback

return width, height
self._debug = debug

def get_status(self, max_width, ident=2):
"""Get the file tree status of GIT for processing and encapsulation.
Expand Down Expand Up @@ -1262,21 +1314,45 @@ def show_diff(self, file_obj):
TermError: terminal size not enough.
"""

width, height = self.get_terminal_size()
width, height = get_terminal_size()

# Initialize.
cursor_row = 1
display_range = [1, height - 1]

stopping = False # exit signal.

def _process_diff(diff_list, term_width):
"""Process diff raw list.
Generate a new list, in which each element is a tuple in the shape of (str, int).
The first parameter is the displayed string, and the second is the additional
row to be occupied under the current width.
"""
new_list = []
for line in diff_list:
text = Fx.uncolor(line)
count = 0
for ch in text:
count += get_width(ord(ch))
# [float] is to solve the division of python2 without retaining decimal places.
new_list.append((line, ceil(count / term_width) - 1))
return new_list

# only need get once.
diff_ = self.diff(
diff_raw = self.diff(
file_obj.name,
file_obj.tracked,
file_obj.has_staged_change,
not self.use_color,
).split("\n")

diff_ = _process_diff(diff_raw, width)
if self._debug: # debug mode print all occupied line num.
echo(Fx.clear_)
print(str([i[1] for i in diff_]))
input()

extra = 0 # Extra occupied row.
while not stopping:
echo(Fx.clear_)
Expand All @@ -1288,13 +1364,14 @@ def show_diff(self, file_obj):

extra = 0 # Return to zero and accumulate again.
# Terminal outputs the text to be displayed.
for index, line in enumerate(diff_, start=1):
for index, data in enumerate(diff_, start=1):
line, each_extra = data
if display_range[0] <= index <= display_range[1] - extra:
if index == cursor_row:
print("{}{}{}".format(Color.bg("#6495ED"), line, Fx.reset))
else:
print(line)
extra += self.extra_occupied_rows(Fx.uncolor(line), width)
extra += each_extra

# TODO(zachary): sometime bug -- scroll with flash.
input_key = KeyEvent.sync_get_input()
Expand All @@ -1319,16 +1396,17 @@ def show_diff(self, file_obj):
cursor_row = cursor_row if cursor_row > 1 else 1
elif input_key == "windows resize":
# get new term height.
new_width, new_height = self.get_terminal_size()
new_width, new_height = get_terminal_size()
if new_height < self._min_height or new_width < self._min_width:
raise TermError("The minimum size of terminal should be 60 x 5.")
# get size diff, reassign.
line_diff = new_height - height
height = new_height
width = new_width
width, height = new_width, new_height
# get new display range.
display_range[1] += line_diff
diff_ = _process_diff(diff_raw, width)
elif input_key == "?":
# show help messages.
echo(Fx.clear_)
echo(
(
Expand Down Expand Up @@ -1366,10 +1444,15 @@ def add_interactive(self, *args):
if not TERM_CONTROL:
raise TermError("This behavior is not supported in the current system.")

width, height = self.get_terminal_size()
width, height = get_terminal_size()
if height < self._min_height or width < self._min_width:
raise TermError("The minimum size of terminal should be 60 x 5.")

if self._debug: # debug show.
echo(Fx.clear_)
print(width, height)
time.sleep(1.5)

# Initialize.
cursor_row = 1
cursor_icon = self.cursor
Expand Down Expand Up @@ -1438,7 +1521,7 @@ def add_interactive(self, *args):
self.show_diff(file_items[cursor_row - 1])
elif input_key == "windows resize":
# get new term height.
new_width, new_height = self.get_terminal_size()
new_width, new_height = get_terminal_size()
if new_height < self._min_height or new_width < self._min_width:
raise TermError(
"The minimum size of terminal should be 60 x 5."
Expand Down Expand Up @@ -3189,15 +3272,7 @@ def count(cls, root_path=".", use_ignore=True, progress=True):
"""

if progress:
try:
import shutil

width = shutil.get_terminal_size().columns
except:
try:
width = int(os.environ["COLUMNS"])
except (KeyError, ValueError):
width = 80
width, _ = get_terminal_size()
if width > 55:
_msg = "\rValid files found: {:,}, Invalid files found: {:,}"
else:
Expand Down Expand Up @@ -3311,15 +3386,7 @@ def format_print(cls, new, old=None, result_format="simple"):
"""

needed_width = 67
try:
import shutil

width = shutil.get_terminal_size().columns
except:
try:
width = int(os.environ["COLUMNS"])
except (KeyError, ValueError):
width = 80
width, _ = get_terminal_size()
if result_format == "simple" or width < needed_width:
for key, value in new.items():
line = "{}: {:,} | {:,}".format(key, value["files"], value["lines"])
Expand Down Expand Up @@ -3399,10 +3466,8 @@ def format_print(cls, new, old=None, result_format="simple"):
echo(" Total: {}".format(sum))
if additions > 0 or deletions > 0:
echo(" Altered: ", nl=False)
echo(
"+" * int(ceil(additions / 10)), color=CommandColor.Green, nl=False
)
echo("-" * int(ceil(deletions / 10)), color=CommandColor.Red)
echo("+" * ceil(additions / 10), color=CommandColor.Green, nl=False)
echo("-" * ceil(deletions / 10), color=CommandColor.Red)

@classmethod
def count_and_format_print(
Expand Down Expand Up @@ -3476,15 +3541,7 @@ def __init__(
self, prog, indent_increment=2, max_help_position=24, width=90, colors=[]
):
width = CONFIG.help_max_line_width
try:
import shutil

max_width = shutil.get_terminal_size().columns
except:
try:
max_width = int(os.environ["COLUMNS"])
except (KeyError, ValueError):
max_width = 90
max_width, _ = get_terminal_size()

width = width if width < max_width else max_width - 2
super(CustomHelpFormatter, self).__init__(
Expand Down
9 changes: 9 additions & 0 deletions tests/interactive_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import sys

sys.path.insert(0, ".")

from pigit import InteractiveAdd

# Initialize to debug mode.
i = InteractiveAdd(debug=True)
i.add_interactive()

0 comments on commit 17a4fd3

Please sign in to comment.