Skip to content

Commit

Permalink
Cleanup: typing, PEP 8, unused code
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewshadura committed Mar 24, 2022
1 parent 3190b68 commit 55919d4
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 83 deletions.
150 changes: 74 additions & 76 deletions git_crecord/chunk_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
# Much of this extension is based on Bryan O'Sullivan's record extension.
#
# SPDX-License-Identifier: GPL-2.0-or-later
from __future__ import annotations

from collections.abc import MutableSequence, Sequence
from gettext import gettext as _

from . import util

from . import encoding
Expand All @@ -22,32 +25,15 @@

from .crpatch import PatchRoot, Header, Hunk, HunkLine

try:
import curses
import fcntl
import termios
curses.error
fcntl.ioctl
termios.TIOCGWINSZ
except ImportError:
# I have no idea if wcurses works with crecord...
try:
import wcurses as curses
curses.error
except ImportError:
# wcurses is not shipped on Windows by default
pass

try:
curses
except NameError:
raise util.Abort(
_('the python curses/wcurses module is not available/installed'))


_origstdout = sys.__stdout__ # used by gethw()

def gethw():
import curses
import fcntl
import termios


_origstdout = sys.__stdout__ # used by gethw()


def gethw() -> tuple[int, int]:
"""
Magically get the current height and width of the window (without initscr)
Expand All @@ -57,7 +43,7 @@ def gethw():
"""
h, w = struct.unpack(
"hhhh", fcntl.ioctl(_origstdout, termios.TIOCGWINSZ, "\000"*8))[0:2]
"hhhh", fcntl.ioctl(_origstdout, termios.TIOCGWINSZ, b"\0"*8))[0:2]
return h, w


Expand All @@ -73,13 +59,14 @@ def chunkselector(opts, headerlist, ui):
import locale
locale.setlocale(locale.LC_ALL, '')

class dummystdscr:
class DummyStdscr:
def clear(self):
pass

def refresh(self):
pass

chunkselector.stdscr = dummystdscr()
chunkselector.stdscr = DummyStdscr()

f = signal.getsignal(signal.SIGTSTP)
curses.wrapper(chunkselector.main, opts)
Expand All @@ -88,7 +75,9 @@ def refresh(self):
# ncurses does not restore signal handler for SIGTSTP
signal.signal(signal.SIGTSTP, f)

_headermessages = { # {operation: text}

_headermessages = {
# {operation: text}
'crecord': _('Select hunks to commit'),
'cstage': _('Select hunks to stage'),
'cunstage': _('Select hunks to keep'),
Expand All @@ -100,6 +89,7 @@ def refresh(self):
'cunstage': _('Are you sure you want to unstage the unselected changes [Yn]?'),
}


class CursesChunkSelector:
def __init__(self, headerlist, ui):
# put the headers into a patch object
Expand Down Expand Up @@ -342,7 +332,7 @@ def leftarrowshiftevent(self):
self.recenterdisplayedarea()

def updatescroll(self):
"Scroll the screen to fully show the currently-selected"
"""Scroll the screen to fully show the currently-selected"""
selstart = self.selecteditemstartline
selend = self.selecteditemendline
#selnumlines = selend - selstart
Expand All @@ -359,9 +349,8 @@ def updatescroll(self):
# negative values scroll in pgup direction
self.scrolllines(selstart - padstartbuffered)


def scrolllines(self, numlines):
"Scroll the screen up (down) by numlines when numlines >0 (<0)."
"""Scroll the screen up (down) by numlines when numlines >0 (<0)."""
self.firstlineofpadtoprint += numlines
if self.firstlineofpadtoprint < 0:
self.firstlineofpadtoprint = 0
Expand Down Expand Up @@ -416,10 +405,10 @@ def toggleapply(self, item=None):
if not item.header.special():
item.header.applied = False
item.header.partial = False
else: # some/all parent siblings are applied
else: # some/all parent siblings are applied
item.header.applied = True
item.header.partial = (somesiblingspartial or
not allsiblingsapplied)
not allsiblingsapplied)

elif isinstance(item, HunkLine):
siblingappliedstatus = [ln.applied for ln in item.hunk.changedlines]
Expand All @@ -433,7 +422,7 @@ def toggleapply(self, item=None):
elif allsiblingsapplied:
item.hunk.applied = True
item.hunk.partial = False
else: # some siblings applied
else: # some siblings applied
item.hunk.applied = True
item.hunk.partial = True

Expand All @@ -452,14 +441,14 @@ def toggleapply(self, item=None):
item.hunk.header.applied = False
item.hunk.header.partial = False
# set the applied and partial status of the header if needed
else: # some/all parent siblings are applied
else: # some/all parent siblings are applied
item.hunk.header.applied = True
item.hunk.header.partial = (someparentsiblingspartial or
not allparentsiblingsapplied)

def toggleall(self):
"Toggle the applied flag of all items."
if self.waslasttoggleallapplied: # then unapply them this time
"""Toggle the applied flag of all items."""
if self.waslasttoggleallapplied: # then unapply them this time
for item in self.headerlist:
if item.applied:
self.toggleapply(item)
Expand All @@ -470,7 +459,7 @@ def toggleall(self):
self.waslasttoggleallapplied = not self.waslasttoggleallapplied

def togglefolded(self, item=None, foldparent=False):
"Toggle folded flag of specified item (defaults to currently selected)"
"""Toggle folded flag of specified item (defaults to currently selected)"""
if item is None:
item = self.currentselecteditem
if foldparent or (isinstance(item, Header) and item.neverunfolded):
Expand All @@ -481,7 +470,7 @@ def togglefolded(self, item=None, foldparent=False):
item.neverunfolded = False

# also fold any foldable children of the parent/current item
if isinstance(item, Header): # the original OR 'new' item
if isinstance(item, Header): # the original OR 'new' item
for child in item.allchildren():
child.folded = not item.folded

Expand Down Expand Up @@ -529,8 +518,10 @@ def printstring(self, window, text, fgcolor=None, bgcolor=None, pair=None,
# preprocess the text, converting tabs to spaces
text = text.expandtabs(4)
# Strip \n, and convert control characters to ^[char] representation
text = re.sub(r'[\x00-\x08\x0a-\x1f]',
lambda m:'^' + chr(ord(m.group()) + 64), text.strip('\n'))
text = re.sub(
r'[\x00-\x08\x0a-\x1f]',
lambda m: '^' + chr(ord(m.group()) + 64), text.strip('\n')
)

if pair is not None:
colorpair = pair
Expand Down Expand Up @@ -559,11 +550,11 @@ def printstring(self, window, text, fgcolor=None, bgcolor=None, pair=None,
colorpair |= textattr

y, xstart = self.chunkpad.getyx()
t = "" # variable for counting lines printed
t = "" # variable for counting lines printed
# if requested, show trailing whitespace
if showwhtspc:
origlen = len(text)
text = text.rstrip(' \n') # tabs have already been expanded
text = text.rstrip(' \n') # tabs have already been expanded
strippedlen = len(text)
numtrailingspaces = origlen - strippedlen

Expand All @@ -572,11 +563,11 @@ def printstring(self, window, text, fgcolor=None, bgcolor=None, pair=None,
t += text

if showwhtspc:
wscolorpair = colorpair | curses.A_REVERSE
if towin:
for i in range(numtrailingspaces):
window.addch(curses.ACS_CKBOARD, wscolorpair)
t += " " * numtrailingspaces
wscolorpair = colorpair | curses.A_REVERSE
if towin:
for i in range(numtrailingspaces):
window.addch(curses.ACS_CKBOARD, wscolorpair)
t += " " * numtrailingspaces

if align:
if towin:
Expand Down Expand Up @@ -608,7 +599,7 @@ def _getstatuslinesegments(self):
]
return segments

def _getstatuslines(self):
def _getstatuslines(self) -> Sequence[str]:
"""() -> [str]. return short help used in the top status window"""
if self.errorstr is not None:
lines = [self.errorstr, _('Press any key to continue')]
Expand All @@ -630,7 +621,7 @@ def _getstatuslines(self):
if len(lines) != self.numstatuslines:
self.numstatuslines = len(lines)
self.statuswin.resize(self.numstatuslines, self.xscreensize)
return [util.ellipsis(l, self.xscreensize - 1) for l in lines]
return [util.ellipsis(line, self.xscreensize - 1) for line in lines]

def updatescreen(self):
self.statuswin.erase()
Expand Down Expand Up @@ -687,7 +678,7 @@ def getstatusprefixstring(self, item):
if isinstance(item, Header):
# add two more spaces for headers
checkbox += " "
except AttributeError: # not foldable
except AttributeError: # not foldable
checkbox += " "

return checkbox
Expand Down Expand Up @@ -734,7 +725,7 @@ def printheader(self, header: Header, selected=False, towin=True,

def printhunklinesbefore(self, hunk: Hunk, selected=False, towin=True,
ignorefolding=False):
"includes start/end line indicator"
"""includes start/end line indicator"""
outstr = ""
# where hunk is in list of siblings
hunkindex = hunk.header.hunks.index(hunk)
Expand Down Expand Up @@ -800,15 +791,15 @@ def printhunkchangedline(self, hunkline: HunkLine, selected=False, towin=True):

lineprefix = " "*self.hunklineindentnumchars + checkbox
outstr += self.printstring(self.chunkpad, lineprefix, towin=towin,
align=False) # add uncolored checkbox/indent
align=False) # add uncolored checkbox/indent
outstr += self.printstring(self.chunkpad, linestr, pair=colorpair,
towin=towin, showwhtspc=True)
return outstr

def printitem(self, item=None, ignorefolding=False, recursechildren=True,
towin=True):
"""
Use __printitem() to print the the specified item.applied.
Use __printitem() to print the specified item.applied.
If item is not specified, then print the entire patch.
(hiding folded elements, etc. -- see __printitem() docstring)
"""
Expand All @@ -818,12 +809,13 @@ def printitem(self, item=None, ignorefolding=False, recursechildren=True,
self.linesprintedtopadsofar = 0

outstr = []
self.__printitem(item, ignorefolding, recursechildren, outstr,
towin=towin)
self.__printitem(
item, ignorefolding, recursechildren, outstr, towin=towin
)
return ''.join(outstr)

def outofdisplayedarea(self):
y, _ = self.chunkpad.getyx() # cursor location
y, _ = self.chunkpad.getyx() # cursor location
# * 2 here works but an optimization would be the max number of
# consecutive non selectable lines
# i.e the max number of context line for any hunk in the patch
Expand All @@ -842,8 +834,14 @@ def handleselection(self, item, recursechildren):
selecteditemlines - 1)
return selected

def __printitem(self, item, ignorefolding, recursechildren, outstr,
towin=True):
def __printitem(
self,
item: PatchRoot | Header | Hunk | HunkLine,
ignorefolding: bool,
recursechildren: bool,
outstr: MutableSequence[str],
towin: bool = True,
):
"""
Recursive method for printing out patch/header/hunk/hunk-line data to
screen. Also returns a string with all of the content of the displayed
Expand Down Expand Up @@ -880,8 +878,8 @@ def __printitem(self, item, ignorefolding, recursechildren, outstr,
outstr.append(self.printhunklinesbefore(item, selected, towin=towin,
ignorefolding=ignorefolding))
if recursechildren:
for l in item.changedlines:
self.__printitem(l, ignorefolding,
for line in item.changedlines:
self.__printitem(line, ignorefolding,
recursechildren, outstr, towin)
outstr.append(self.printhunklinesafter(item, towin=towin,
ignorefolding=ignorefolding))
Expand Down Expand Up @@ -910,7 +908,7 @@ def getnumlinesdisplayed(self, item=None, ignorefolding=False,
return numlines

def sigwinchhandler(self, n, frame):
"Handle window resizing"
"""Handle window resizing"""
try:
curses.endwin()
self.yscreensize, self.xscreensize = gethw()
Expand Down Expand Up @@ -979,11 +977,11 @@ def getcolorpair(self, fgcolor=None, bgcolor=None, name=None,
return colorpair

def initcolorpair(self, *args, **kwargs):
"Same as getcolorpair."
"""Same as getcolorpair."""
self.getcolorpair(*args, **kwargs)

def helpwindow(self):
"Print a help window to the screen. Exit after any keypress."
"""Print a help window to the screen. Exit after any keypress."""
helptext = """ [press any key to return to the patch-display]
crecord allows you to interactively choose among the changes you have made,
Expand Down Expand Up @@ -1028,7 +1026,7 @@ def helpwindow(self):
pass

def confirmationwindow(self, windowtext):
"Display an informational window, then wait for and return a keypress."
"""Display an informational window, then wait for and return a keypress."""

lines = windowtext.split("\n")
confirmwin = curses.newwin(len(lines), 0, 0, 0)
Expand Down Expand Up @@ -1087,21 +1085,21 @@ def recenterdisplayedarea(self):
def toggleamend(self):
"""Toggle the amend flag.
When the amend flag is set, a commit will modify the most recently
committed changeset, instead of creating a new changeset. Otherwise, a
new changeset will be created (the normal commit behavior).
When the amend flag is set, a commit will modify the most recent
commit, instead of creating a new commit. Otherwise, a
new commit will be created (the normal commit behavior).
"""
if self.opts.get('amend') is False:
if not self.opts.get('amend'):
self.opts['amend'] = True
msg = ("Amend option is turned on -- committing the currently "
"selected changes will not create a new changeset, but "
"instead update the most recently committed changeset.\n\n"
"selected changes will not create a new commit, but "
"instead update the most recent commit.\n\n"
"Press any key to continue.")
elif self.opts.get('amend') is True:
else:
self.opts['amend'] = False
msg = ("Amend option is turned off -- committing the currently "
"selected changes will create a new changeset.\n\n"
"selected changes will create a new commit.\n\n"
"Press any key to continue.")

self.confirmationwindow(msg)
Expand Down Expand Up @@ -1229,7 +1227,7 @@ def _main(self, stdscr):
self.initcolorpair(curses.COLOR_WHITE, curses.COLOR_BLUE, name="legend")
# newwin([height, width,] begin_y, begin_x)
self.statuswin = curses.newwin(self.numstatuslines, 0, 0, 0)
self.statuswin.keypad(1) # interpret arrow-key, etc. ESC sequences
self.statuswin.keypad(True) # interpret arrow-key, etc. ESC sequences

# figure out how much space to allocate for the chunk-pad which is
# used for displaying the patch
Expand Down
Loading

0 comments on commit 55919d4

Please sign in to comment.