Add static typing for widgets
This commit is contained in:
parent
e660acdc48
commit
e975f66fde
|
@ -333,6 +333,7 @@ class LineEnding(IntFlag):
|
||||||
|
|
||||||
Values can be used as flags in bitwise operations.'''
|
Values can be used as flags in bitwise operations.'''
|
||||||
|
|
||||||
|
NO_FORMAT = 0
|
||||||
DOS_FORMAT = 1
|
DOS_FORMAT = 1
|
||||||
MAC_FORMAT = 2
|
MAC_FORMAT = 2
|
||||||
UNIX_FORMAT = 4
|
UNIX_FORMAT = 4
|
||||||
|
|
|
@ -21,8 +21,9 @@ import difflib
|
||||||
import os
|
import os
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
|
from enum import IntFlag
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from diffuse import utils
|
from diffuse import utils
|
||||||
from diffuse.resources import theResources
|
from diffuse.resources import theResources
|
||||||
|
@ -38,7 +39,7 @@ from gi.repository import GObject, Gdk, Gtk, Pango, PangoCairo # type: ignore #
|
||||||
|
|
||||||
|
|
||||||
# mapping to column width of a character (tab will never be in this map)
|
# mapping to column width of a character (tab will never be in this map)
|
||||||
_char_width_cache: Dict[str, str] = {}
|
_char_width_cache: Dict[str, int] = {}
|
||||||
|
|
||||||
# the file diff viewer is always in one of these modes defining the cursor,
|
# the file diff viewer is always in one of these modes defining the cursor,
|
||||||
# and hotkey behavior
|
# and hotkey behavior
|
||||||
|
@ -151,7 +152,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
class Pane:
|
class Pane:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
# list of lines displayed in this pane (including spacing lines)
|
# list of lines displayed in this pane (including spacing lines)
|
||||||
self.lines: List[FileDiffViewerBase.Line] = []
|
self.lines: List[Optional[FileDiffViewerBase.Line]] = []
|
||||||
# high water mark for line length in Pango units (used to determine
|
# high water mark for line length in Pango units (used to determine
|
||||||
# the required horizontal scroll range)
|
# the required horizontal scroll range)
|
||||||
self.line_lengths = 0
|
self.line_lengths = 0
|
||||||
|
@ -167,7 +168,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# portion of the cache are cleared by setting entries to None
|
# portion of the cache are cleared by setting entries to None
|
||||||
self.diff_cache: List[List[Any]] = []
|
self.diff_cache: List[List[Any]] = []
|
||||||
# mask indicating the type of line endings present
|
# mask indicating the type of line endings present
|
||||||
self.format = 0
|
self.format: LineEnding = LineEnding.NO_FORMAT
|
||||||
# number of lines with edits
|
# number of lines with edits
|
||||||
self.num_edits = 0
|
self.num_edits = 0
|
||||||
|
|
||||||
|
@ -407,7 +408,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# returns the 'column width' for a string -- used to help position
|
# returns the 'column width' for a string -- used to help position
|
||||||
# characters when tabs and other special characters are present
|
# characters when tabs and other special characters are present
|
||||||
# This is an inline loop over self.characterWidth() for performance reasons.
|
# This is an inline loop over self.characterWidth() for performance reasons.
|
||||||
def stringWidth(self, s):
|
def stringWidth(self, s: str) -> int:
|
||||||
if not self.prefs.getBool('display_show_whitespace'):
|
if not self.prefs.getBool('display_show_whitespace'):
|
||||||
s = utils.strip_eol(s)
|
s = utils.strip_eol(s)
|
||||||
col = 0
|
col = 0
|
||||||
|
@ -436,7 +437,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return col
|
return col
|
||||||
|
|
||||||
# returns the 'column width' for a single character created at column 'i'
|
# returns the 'column width' for a single character created at column 'i'
|
||||||
def characterWidth(self, i, c):
|
def characterWidth(self, i: int, c: str) -> int:
|
||||||
try:
|
try:
|
||||||
return _char_width_cache[c]
|
return _char_width_cache[c]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -458,13 +459,13 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# translates a string into an array of the printable representation for
|
# translates a string into an array of the printable representation for
|
||||||
# each character
|
# each character
|
||||||
def expand(self, s):
|
def expand(self, s: str) -> List[str]:
|
||||||
visible = self.prefs.getBool('display_show_whitespace')
|
visible = self.prefs.getBool('display_show_whitespace')
|
||||||
if not visible:
|
if not visible:
|
||||||
s = utils.strip_eol(s)
|
s = utils.strip_eol(s)
|
||||||
tab_width = self.prefs.getInt('display_tab_width')
|
tab_width = self.prefs.getInt('display_tab_width')
|
||||||
col = 0
|
col = 0
|
||||||
result = []
|
result: List[str] = []
|
||||||
for c in s:
|
for c in s:
|
||||||
v = ord(c)
|
v = ord(c)
|
||||||
if v <= 32:
|
if v <= 32:
|
||||||
|
@ -493,7 +494,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# changes the viewer's mode to LINE_MODE
|
# changes the viewer's mode to LINE_MODE
|
||||||
def setLineMode(self):
|
def setLineMode(self) -> None:
|
||||||
if self.mode != LINE_MODE:
|
if self.mode != LINE_MODE:
|
||||||
if self.mode == CHAR_MODE:
|
if self.mode == CHAR_MODE:
|
||||||
self._im_focus_out()
|
self._im_focus_out()
|
||||||
|
@ -512,7 +513,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.emit('mode_changed')
|
self.emit('mode_changed')
|
||||||
|
|
||||||
# changes the viewer's mode to CHAR_MODE
|
# changes the viewer's mode to CHAR_MODE
|
||||||
def setCharMode(self):
|
def setCharMode(self) -> None:
|
||||||
if self.mode != CHAR_MODE:
|
if self.mode != CHAR_MODE:
|
||||||
if self.mode == LINE_MODE:
|
if self.mode == LINE_MODE:
|
||||||
self.cursor_column = -1
|
self.cursor_column = -1
|
||||||
|
@ -546,7 +547,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return self.syntax
|
return self.syntax
|
||||||
|
|
||||||
# returns True if any pane contains edits
|
# returns True if any pane contains edits
|
||||||
def hasEdits(self):
|
def hasEdits(self) -> bool:
|
||||||
for pane in self.panes:
|
for pane in self.panes:
|
||||||
if pane.num_edits > 0:
|
if pane.num_edits > 0:
|
||||||
return True
|
return True
|
||||||
|
@ -561,7 +562,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# openUndoBlock() should be called when the action from a user, like a
|
# openUndoBlock() should be called when the action from a user, like a
|
||||||
# mouse button press, menu item, etc. may cause change to the diff viewer's
|
# mouse button press, menu item, etc. may cause change to the diff viewer's
|
||||||
# state
|
# state
|
||||||
def openUndoBlock(self):
|
def openUndoBlock(self) -> None:
|
||||||
self.undoblock = []
|
self.undoblock = []
|
||||||
|
|
||||||
# all changes to the diff viewer's state should create an Undo object and
|
# all changes to the diff viewer's state should create an Undo object and
|
||||||
|
@ -574,14 +575,14 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# all openUndoBlock() calls should also have a matching closeUndoBlock()
|
# all openUndoBlock() calls should also have a matching closeUndoBlock()
|
||||||
# this method collects all Undos created since the openUndoBlock() call
|
# this method collects all Undos created since the openUndoBlock() call
|
||||||
# and pushes them onto the undo stack as a single unit
|
# and pushes them onto the undo stack as a single unit
|
||||||
def closeUndoBlock(self):
|
def closeUndoBlock(self) -> None:
|
||||||
if len(self.undoblock) > 0:
|
if len(self.undoblock) > 0:
|
||||||
self.redos = []
|
self.redos = []
|
||||||
self.undos.append(self.undoblock)
|
self.undos.append(self.undoblock)
|
||||||
self.undoblock = None
|
self.undoblock = None
|
||||||
|
|
||||||
# 'undo' action
|
# 'undo' action
|
||||||
def undo(self):
|
def undo(self) -> None:
|
||||||
self.undoblock, old_block = None, self.undoblock
|
self.undoblock, old_block = None, self.undoblock
|
||||||
if self.mode == CHAR_MODE:
|
if self.mode == CHAR_MODE:
|
||||||
# avoid implicit preedit commit when an undo changes the mode
|
# avoid implicit preedit commit when an undo changes the mode
|
||||||
|
@ -597,7 +598,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.undoblock = old_block
|
self.undoblock = old_block
|
||||||
|
|
||||||
# 'redo' action
|
# 'redo' action
|
||||||
def redo(self):
|
def redo(self) -> None:
|
||||||
self.undoblock, old_block = None, self.undoblock
|
self.undoblock, old_block = None, self.undoblock
|
||||||
if self.mode in (LINE_MODE, CHAR_MODE):
|
if self.mode in (LINE_MODE, CHAR_MODE):
|
||||||
if self.mode == CHAR_MODE:
|
if self.mode == CHAR_MODE:
|
||||||
|
@ -613,7 +614,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.undoblock = old_block
|
self.undoblock = old_block
|
||||||
|
|
||||||
# returns the width of the viewport's line number column in Pango units
|
# returns the width of the viewport's line number column in Pango units
|
||||||
def getLineNumberWidth(self):
|
def getLineNumberWidth(self) -> int:
|
||||||
# find the maximum number of digits for a line number from all panes
|
# find the maximum number of digits for a line number from all panes
|
||||||
n = 0
|
n = 0
|
||||||
if self.prefs.getBool('display_show_line_numbers'):
|
if self.prefs.getBool('display_show_line_numbers'):
|
||||||
|
@ -624,7 +625,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return n
|
return n
|
||||||
|
|
||||||
# returns the width of a string in Pango units
|
# returns the width of a string in Pango units
|
||||||
def getTextWidth(self, text):
|
def getTextWidth(self, text: str) -> int:
|
||||||
if len(text) == 0:
|
if len(text) == 0:
|
||||||
return 0
|
return 0
|
||||||
layout = self.create_pango_layout(text)
|
layout = self.create_pango_layout(text)
|
||||||
|
@ -635,7 +636,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# set 'compute_width' to False if the high water mark for line length can
|
# set 'compute_width' to False if the high water mark for line length can
|
||||||
# be used to determine the required width for the viewport, use True for
|
# be used to determine the required width for the viewport, use True for
|
||||||
# this value otherwise
|
# this value otherwise
|
||||||
def updateSize(self, compute_width, f=None):
|
def updateSize(self, compute_width: bool, f: Optional[int] = None) -> None:
|
||||||
digit_width, stringWidth = self.digit_width, self.stringWidth
|
digit_width, stringWidth = self.digit_width, self.stringWidth
|
||||||
string_width_cache = self.string_width_cache
|
string_width_cache = self.string_width_cache
|
||||||
if compute_width:
|
if compute_width:
|
||||||
|
@ -685,14 +686,14 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.vadj.step_increment = self.font_height
|
self.vadj.step_increment = self.font_height
|
||||||
|
|
||||||
# returns a line from the specified pane and offset
|
# returns a line from the specified pane and offset
|
||||||
def getLine(self, f, i):
|
def getLine(self, f: int, i: int) -> Optional[Line]:
|
||||||
lines = self.panes[f].lines
|
lines = self.panes[f].lines
|
||||||
if i < len(lines):
|
if i < len(lines):
|
||||||
return lines[i]
|
return lines[i]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# returns the text for the specified line
|
# returns the text for the specified line
|
||||||
def getLineText(self, f, i):
|
def getLineText(self, f: int, i: int) -> Optional[str]:
|
||||||
line = self.getLine(f, i)
|
line = self.getLine(f, i)
|
||||||
if line is not None:
|
if line is not None:
|
||||||
return line.getText()
|
return line.getText()
|
||||||
|
@ -700,7 +701,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# Undo for changes to the cached line ending style
|
# Undo for changes to the cached line ending style
|
||||||
class SetFormatUndo:
|
class SetFormatUndo:
|
||||||
def __init__(self, f, fmt, old_format):
|
def __init__(self, f: int, fmt: LineEnding, old_format: LineEnding) -> None:
|
||||||
self.data = (f, fmt, old_format)
|
self.data = (f, fmt, old_format)
|
||||||
|
|
||||||
def undo(self, viewer):
|
def undo(self, viewer):
|
||||||
|
@ -712,7 +713,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
viewer.setFormat(f, fmt)
|
viewer.setFormat(f, fmt)
|
||||||
|
|
||||||
# sets the cached line ending style
|
# sets the cached line ending style
|
||||||
def setFormat(self, f, fmt):
|
def setFormat(self, f: int, fmt: LineEnding) -> None:
|
||||||
pane = self.panes[f]
|
pane = self.panes[f]
|
||||||
if self.undoblock is not None:
|
if self.undoblock is not None:
|
||||||
# create an Undo object for the action
|
# create an Undo object for the action
|
||||||
|
@ -722,7 +723,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# Undo for the creation of Line objects
|
# Undo for the creation of Line objects
|
||||||
class InstanceLineUndo:
|
class InstanceLineUndo:
|
||||||
def __init__(self, f, i, reverse):
|
def __init__(self, f: int, i: int, reverse: bool) -> None:
|
||||||
self.data = (f, i, reverse)
|
self.data = (f, i, reverse)
|
||||||
|
|
||||||
def undo(self, viewer):
|
def undo(self, viewer):
|
||||||
|
@ -735,7 +736,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# creates an instance of a Line object for the specified pane and offset
|
# creates an instance of a Line object for the specified pane and offset
|
||||||
# deletes an instance when 'reverse' is set to True
|
# deletes an instance when 'reverse' is set to True
|
||||||
def instanceLine(self, f, i, reverse=False):
|
def instanceLine(self, f: int, i: int, reverse: bool = False) -> None:
|
||||||
if self.undoblock is not None:
|
if self.undoblock is not None:
|
||||||
# create an Undo object for the action
|
# create an Undo object for the action
|
||||||
self.addUndo(FileDiffViewerBase.InstanceLineUndo(f, i, reverse))
|
self.addUndo(FileDiffViewerBase.InstanceLineUndo(f, i, reverse))
|
||||||
|
@ -759,7 +760,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
f, i, _, _, is_modified, text = self.data
|
f, i, _, _, is_modified, text = self.data
|
||||||
viewer.updateLineText(f, i, is_modified, text)
|
viewer.updateLineText(f, i, is_modified, text)
|
||||||
|
|
||||||
def getMapFlags(self, f, i):
|
def getMapFlags(self, f: int, i: int) -> int:
|
||||||
flags = 0
|
flags = 0
|
||||||
compare_text = self.getCompareString(f, i)
|
compare_text = self.getCompareString(f, i)
|
||||||
if f > 0 and self.getCompareString(f - 1, i) != compare_text:
|
if f > 0 and self.getCompareString(f - 1, i) != compare_text:
|
||||||
|
@ -822,7 +823,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# Undo for inserting a spacing line in a single pane
|
# Undo for inserting a spacing line in a single pane
|
||||||
class InsertNullUndo:
|
class InsertNullUndo:
|
||||||
def __init__(self, f, i, reverse):
|
def __init__(self, f: int, i: int, reverse: bool) -> None:
|
||||||
self.data = (f, i, reverse)
|
self.data = (f, i, reverse)
|
||||||
|
|
||||||
def undo(self, viewer):
|
def undo(self, viewer):
|
||||||
|
@ -836,7 +837,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# insert a spacing line at line 'i' in pane 'f'
|
# insert a spacing line at line 'i' in pane 'f'
|
||||||
# this caller must ensure the blocks and number of lines in each pane
|
# this caller must ensure the blocks and number of lines in each pane
|
||||||
# are valid again
|
# are valid again
|
||||||
def insertNull(self, f, i, reverse):
|
def insertNull(self, f: int, i: int, reverse: bool) -> None:
|
||||||
if self.undoblock is not None:
|
if self.undoblock is not None:
|
||||||
# create an Undo object for the action
|
# create an Undo object for the action
|
||||||
self.addUndo(FileDiffViewerBase.InsertNullUndo(f, i, reverse))
|
self.addUndo(FileDiffViewerBase.InsertNullUndo(f, i, reverse))
|
||||||
|
@ -885,7 +886,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# Undo for alignment changes
|
# Undo for alignment changes
|
||||||
class AlignmentChangeUndo:
|
class AlignmentChangeUndo:
|
||||||
def __init__(self, finished):
|
def __init__(self, finished: bool) -> None:
|
||||||
self.data = finished
|
self.data = finished
|
||||||
|
|
||||||
def undo(self, viewer):
|
def undo(self, viewer):
|
||||||
|
@ -897,7 +898,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
viewer.alignmentChange(finished)
|
viewer.alignmentChange(finished)
|
||||||
|
|
||||||
# update viewer in response to alignment changes
|
# update viewer in response to alignment changes
|
||||||
def alignmentChange(self, finished):
|
def alignmentChange(self, finished: bool) -> None:
|
||||||
if self.undoblock is not None:
|
if self.undoblock is not None:
|
||||||
# create an Undo object for the action
|
# create an Undo object for the action
|
||||||
self.addUndo(FileDiffViewerBase.AlignmentChangeUndo(finished))
|
self.addUndo(FileDiffViewerBase.AlignmentChangeUndo(finished))
|
||||||
|
@ -947,7 +948,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.blocks = blocks
|
self.blocks = blocks
|
||||||
|
|
||||||
# insert 'n' blank lines in all panes
|
# insert 'n' blank lines in all panes
|
||||||
def insertLines(self, i, n):
|
def insertLines(self, i: int, n: int) -> None:
|
||||||
# insert lines
|
# insert lines
|
||||||
self.updateAlignment(i, 0, [n * [None] for pane in self.panes])
|
self.updateAlignment(i, 0, [n * [None] for pane in self.panes])
|
||||||
pre, post = _cut_blocks(i, self.blocks)
|
pre, post = _cut_blocks(i, self.blocks)
|
||||||
|
@ -966,7 +967,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.diffmap.queue_draw()
|
self.diffmap.queue_draw()
|
||||||
|
|
||||||
# remove a line
|
# remove a line
|
||||||
def removeSpacerLines(self, i, n, skip=-1):
|
def removeSpacerLines(self, i: int, n: int, skip: int = -1) -> int:
|
||||||
npanes, removed = len(self.panes), []
|
npanes, removed = len(self.panes), []
|
||||||
for j in range(i, i + n):
|
for j in range(i, i + n):
|
||||||
for f in range(npanes):
|
for f in range(npanes):
|
||||||
|
@ -1055,7 +1056,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.diffmap.queue_draw()
|
self.diffmap.queue_draw()
|
||||||
|
|
||||||
# create a hash for a line to use for line matching
|
# create a hash for a line to use for line matching
|
||||||
def _alignmentHash(self, line):
|
def _alignmentHash(self, line: Line) -> Optional[str]:
|
||||||
text = line.getText()
|
text = line.getText()
|
||||||
if text is None:
|
if text is None:
|
||||||
return None
|
return None
|
||||||
|
@ -1076,15 +1077,14 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
if pref('align_ignore_whitespace_changes'):
|
if pref('align_ignore_whitespace_changes'):
|
||||||
# replace all blocks of white space with a single space
|
# replace all blocks of white space with a single space
|
||||||
pc = True
|
pc = True
|
||||||
r = []
|
r: List[str] = []
|
||||||
append = r.append
|
|
||||||
for c in text:
|
for c in text:
|
||||||
if c in utils.whitespace:
|
if c in utils.whitespace:
|
||||||
if pc:
|
if pc:
|
||||||
append(' ')
|
r.append(' ')
|
||||||
pc = False
|
pc = False
|
||||||
else:
|
else:
|
||||||
append(c)
|
r.append(c)
|
||||||
pc = True
|
pc = True
|
||||||
text = ''.join(r)
|
text = ''.join(r)
|
||||||
if pref('align_ignore_case'):
|
if pref('align_ignore_case'):
|
||||||
|
@ -1110,9 +1110,8 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
s1, s2 = mlines
|
s1, s2 = mlines
|
||||||
n1, n2 = 0, 0
|
n1, n2 = 0, 0
|
||||||
# hash lines according to the alignment preferences
|
# hash lines according to the alignment preferences
|
||||||
a = self._alignmentHash
|
t1 = [self._alignmentHash(s) for s in s1]
|
||||||
t1 = [a(s) for s in s1]
|
t2 = [self._alignmentHash(s) for s in s2]
|
||||||
t2 = [a(s) for s in s2]
|
|
||||||
# align s1 and s2 by inserting spacer lines
|
# align s1 and s2 by inserting spacer lines
|
||||||
# this will be used to determine which lines from the inner lists of
|
# this will be used to determine which lines from the inner lists of
|
||||||
# lines should be neighbours
|
# lines should be neighbours
|
||||||
|
@ -1253,8 +1252,9 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# refresh the lines to contain new objects with updated line numbers and
|
# refresh the lines to contain new objects with updated line numbers and
|
||||||
# no local edits
|
# no local edits
|
||||||
def bakeEdits(self, f):
|
def bakeEdits(self, f: int) -> None:
|
||||||
pane, lines, line_num = self.panes[f], [], 0
|
lines: List[Optional[FileDiffViewerBase.Line]] = []
|
||||||
|
pane, line_num = self.panes[f], 0
|
||||||
for i in range(len(pane.lines)):
|
for i in range(len(pane.lines)):
|
||||||
s = self.getLineText(f, i)
|
s = self.getLineText(f, i)
|
||||||
if s is None:
|
if s is None:
|
||||||
|
@ -1267,7 +1267,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.replaceLines(f, pane.lines, lines, pane.max_line_number, line_num)
|
self.replaceLines(f, pane.lines, lines, pane.max_line_number, line_num)
|
||||||
|
|
||||||
# update the contents for a line, creating the line if necessary
|
# update the contents for a line, creating the line if necessary
|
||||||
def updateText(self, f, i, text, is_modified=True):
|
def updateText(self, f: int, i: int, text: Optional[str], is_modified: bool = True) -> None:
|
||||||
if self.panes[f].lines[i] is None:
|
if self.panes[f].lines[i] is None:
|
||||||
self.instanceLine(f, i)
|
self.instanceLine(f, i)
|
||||||
self.updateLineText(f, i, is_modified, text)
|
self.updateLineText(f, i, is_modified, text)
|
||||||
|
@ -1533,7 +1533,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.dareas[old_f].queue_draw()
|
self.dareas[old_f].queue_draw()
|
||||||
|
|
||||||
# queue a range of lines for redrawing
|
# queue a range of lines for redrawing
|
||||||
def _queue_draw_lines(self, f, line0, line1=None):
|
def _queue_draw_lines(self, f: int, line0: int, line1: Optional[int] = None) -> None:
|
||||||
if line1 is None:
|
if line1 is None:
|
||||||
line1 = line0
|
line1 = line0
|
||||||
elif line0 > line1:
|
elif line0 > line1:
|
||||||
|
@ -1543,7 +1543,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
darea.queue_draw_area(0, line0 * h - int(self.vadj.get_value()), w, (line1 - line0 + 1) * h)
|
darea.queue_draw_area(0, line0 * h - int(self.vadj.get_value()), w, (line1 - line0 + 1) * h)
|
||||||
|
|
||||||
# scroll vertically to ensure the current line is visible
|
# scroll vertically to ensure the current line is visible
|
||||||
def _ensure_line_is_visible(self, i):
|
def _ensure_line_is_visible(self, i: int) -> None:
|
||||||
h = self.font_height
|
h = self.font_height
|
||||||
lower = i * h
|
lower = i * h
|
||||||
upper = lower + h
|
upper = lower + h
|
||||||
|
@ -1557,7 +1557,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# change the current selection in LINE_MODE
|
# change the current selection in LINE_MODE
|
||||||
# use extend=True to extend the selection
|
# use extend=True to extend the selection
|
||||||
def setCurrentLine(self, f, i, selection=None):
|
def setCurrentLine(self, f: int, i: int, selection: Optional[int] = None) -> None:
|
||||||
# remember old cursor position so we can just redraw what is necessary
|
# remember old cursor position so we can just redraw what is necessary
|
||||||
old_f = self.current_pane
|
old_f = self.current_pane
|
||||||
line0, line1 = self.current_line, self.selection_line
|
line0, line1 = self.current_line, self.selection_line
|
||||||
|
@ -1569,10 +1569,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# update cursor
|
# update cursor
|
||||||
self.current_pane = f
|
self.current_pane = f
|
||||||
self.current_line = i
|
self.current_line = i
|
||||||
if selection is None:
|
self.selection_line = selection if selection is not None else i
|
||||||
self.selection_line = i
|
|
||||||
else:
|
|
||||||
self.selection_line = selection
|
|
||||||
|
|
||||||
self.emit('cursor_changed')
|
self.emit('cursor_changed')
|
||||||
|
|
||||||
|
@ -1585,7 +1582,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self._ensure_line_is_visible(i)
|
self._ensure_line_is_visible(i)
|
||||||
|
|
||||||
# returns True if the line has preedit text
|
# returns True if the line has preedit text
|
||||||
def hasPreedit(self, f, i):
|
def hasPreedit(self, f: int, i: int) -> bool:
|
||||||
return (
|
return (
|
||||||
self.mode == CHAR_MODE and
|
self.mode == CHAR_MODE and
|
||||||
self.current_pane == f and
|
self.current_pane == f and
|
||||||
|
@ -1626,15 +1623,17 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.im_context.set_cursor_location(rect)
|
self.im_context.set_cursor_location(rect)
|
||||||
|
|
||||||
# get the position of the cursor in Pango units
|
# get the position of the cursor in Pango units
|
||||||
def _get_cursor_x_offset(self):
|
def _get_cursor_x_offset(self) -> int:
|
||||||
j = self.current_char
|
j = self.current_char
|
||||||
if j > 0:
|
if j > 0:
|
||||||
text = self.getLineText(self.current_pane, self.current_line)[:j]
|
text = self.getLineText(self.current_pane, self.current_line)
|
||||||
return self.getTextWidth(''.join(self.expand(text)))
|
if text is not None:
|
||||||
|
text = text[:j]
|
||||||
|
return self.getTextWidth(''.join(self.expand(text)))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# scroll to ensure the current cursor position is visible
|
# scroll to ensure the current cursor position is visible
|
||||||
def _ensure_cursor_is_visible(self):
|
def _ensure_cursor_is_visible(self) -> None:
|
||||||
current_line = self.current_line
|
current_line = self.current_line
|
||||||
|
|
||||||
# find the cursor's horizontal range
|
# find the cursor's horizontal range
|
||||||
|
@ -1722,7 +1721,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return ''.join([s for s in ss if s is not None])
|
return ''.join([s for s in ss if s is not None])
|
||||||
|
|
||||||
# expands the selection to include everything
|
# expands the selection to include everything
|
||||||
def select_all(self):
|
def select_all(self) -> None:
|
||||||
if self.mode in (LINE_MODE, CHAR_MODE):
|
if self.mode in (LINE_MODE, CHAR_MODE):
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
self.selection_line = 0
|
self.selection_line = 0
|
||||||
|
@ -1735,7 +1734,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# returns the index of the last character in text that should be left of
|
# returns the index of the last character in text that should be left of
|
||||||
# 'x' _pixels from the edge of the darea widget
|
# 'x' _pixels from the edge of the darea widget
|
||||||
# if partial=True, include characters only partially to the left of 'x'
|
# if partial=True, include characters only partially to the left of 'x'
|
||||||
def _getPickedCharacter(self, text, x, partial):
|
def _getPickedCharacter(self, text: Optional[str], x: int, partial: bool) -> int:
|
||||||
if text is None:
|
if text is None:
|
||||||
return 0
|
return 0
|
||||||
n = len(text)
|
n = len(text)
|
||||||
|
@ -1945,7 +1944,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# returns a hash of a string that can be used to quickly compare strings
|
# returns a hash of a string that can be used to quickly compare strings
|
||||||
# according to the display preferences
|
# according to the display preferences
|
||||||
def getCompareString(self, f, i):
|
def getCompareString(self, f: int, i: int) -> Optional[str]:
|
||||||
line = self.getLine(f, i)
|
line = self.getLine(f, i)
|
||||||
if line is None:
|
if line is None:
|
||||||
return None
|
return None
|
||||||
|
@ -2553,7 +2552,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.setCurrentLine(self.current_pane, self.current_line - delta, selection)
|
self.setCurrentLine(self.current_pane, self.current_line - delta, selection)
|
||||||
|
|
||||||
# 'extend_page_up' keybinding action
|
# 'extend_page_up' keybinding action
|
||||||
def _line_mode_extend_page_up(self):
|
def _line_mode_extend_page_up(self) -> None:
|
||||||
self._line_mode_page_up(self.selection_line)
|
self._line_mode_page_up(self.selection_line)
|
||||||
|
|
||||||
# 'page_down' keybinding action
|
# 'page_down' keybinding action
|
||||||
|
@ -2562,20 +2561,20 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.setCurrentLine(self.current_pane, self.current_line + delta, selection)
|
self.setCurrentLine(self.current_pane, self.current_line + delta, selection)
|
||||||
|
|
||||||
# 'extend_page_down' keybinding action
|
# 'extend_page_down' keybinding action
|
||||||
def _line_mode_extend_page_down(self):
|
def _line_mode_extend_page_down(self) -> None:
|
||||||
self._line_mode_page_down(self.selection_line)
|
self._line_mode_page_down(self.selection_line)
|
||||||
|
|
||||||
# 'delete_text' keybinding action
|
# 'delete_text' keybinding action
|
||||||
def _delete_text(self):
|
def _delete_text(self) -> None:
|
||||||
self.replaceText('')
|
self.replaceText('')
|
||||||
|
|
||||||
# 'enter_line_mode' keybinding action
|
# 'enter_line_mode' keybinding action
|
||||||
def _align_mode_enter_line_mode(self):
|
def _align_mode_enter_line_mode(self) -> None:
|
||||||
self.selection_line = self.current_line
|
self.selection_line = self.current_line
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
|
|
||||||
# 'align' keybinding action
|
# 'align' keybinding action
|
||||||
def _align_text(self):
|
def _align_text(self) -> None:
|
||||||
f1 = self.align_pane
|
f1 = self.align_pane
|
||||||
line1 = self.align_line
|
line1 = self.align_line
|
||||||
line2 = self.current_line
|
line2 = self.current_line
|
||||||
|
@ -2587,12 +2586,12 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.align(self.current_pane, line2, line1)
|
self.align(self.current_pane, line2, line1)
|
||||||
|
|
||||||
# give the input method focus
|
# give the input method focus
|
||||||
def _im_focus_in(self):
|
def _im_focus_in(self) -> None:
|
||||||
if self.has_focus:
|
if self.has_focus:
|
||||||
self.im_context.focus_in()
|
self.im_context.focus_in()
|
||||||
|
|
||||||
# remove input method focus
|
# remove input method focus
|
||||||
def _im_focus_out(self):
|
def _im_focus_out(self) -> None:
|
||||||
if self.has_focus:
|
if self.has_focus:
|
||||||
self.im_context.focus_out()
|
self.im_context.focus_out()
|
||||||
|
|
||||||
|
@ -2762,7 +2761,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
if text is not None and j < len(text):
|
if text is not None and j < len(text):
|
||||||
c = _get_character_class(text[j])
|
c = _get_character_class(text[j])
|
||||||
if (
|
if (
|
||||||
c != WHITESPACE_CLASS and
|
c != CharacterClass.WHITESPACE and
|
||||||
(j < 1 or j - 1 >= len(text) or _get_character_class(text[j - 1]) != c)
|
(j < 1 or j - 1 >= len(text) or _get_character_class(text[j - 1]) != c)
|
||||||
):
|
):
|
||||||
break
|
break
|
||||||
|
@ -2929,12 +2928,12 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
# 'copy' action
|
# 'copy' action
|
||||||
def copy(self):
|
def copy(self) -> None:
|
||||||
if self.mode in (LINE_MODE, CHAR_MODE):
|
if self.mode in (LINE_MODE, CHAR_MODE):
|
||||||
self._set_clipboard_text(Gdk.SELECTION_CLIPBOARD, self.getSelectedText())
|
self._set_clipboard_text(Gdk.SELECTION_CLIPBOARD, self.getSelectedText())
|
||||||
|
|
||||||
# 'cut' action
|
# 'cut' action
|
||||||
def cut(self):
|
def cut(self) -> None:
|
||||||
if self.mode in (LINE_MODE, CHAR_MODE):
|
if self.mode in (LINE_MODE, CHAR_MODE):
|
||||||
self.copy()
|
self.copy()
|
||||||
self.replaceText('')
|
self.replaceText('')
|
||||||
|
@ -2952,13 +2951,13 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.closeUndoBlock()
|
self.closeUndoBlock()
|
||||||
|
|
||||||
# 'paste' action
|
# 'paste' action
|
||||||
def paste(self):
|
def paste(self) -> None:
|
||||||
Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD).request_text(
|
Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD).request_text(
|
||||||
self.receive_clipboard_text_cb,
|
self.receive_clipboard_text_cb,
|
||||||
None)
|
None)
|
||||||
|
|
||||||
# 'clear_edits' action
|
# 'clear_edits' action
|
||||||
def clear_edits(self):
|
def clear_edits(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
|
@ -2977,7 +2976,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
|
||||||
# 'dismiss_all_edits' action
|
# 'dismiss_all_edits' action
|
||||||
def dismiss_all_edits(self):
|
def dismiss_all_edits(self) -> None:
|
||||||
if self.mode in (LINE_MODE, CHAR_MODE):
|
if self.mode in (LINE_MODE, CHAR_MODE):
|
||||||
self.bakeEdits(self.current_pane)
|
self.bakeEdits(self.current_pane)
|
||||||
|
|
||||||
|
@ -3038,7 +3037,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# move cursor to a given line
|
# move cursor to a given line
|
||||||
def go_to_line(self, i):
|
def go_to_line(self, i: int) -> None:
|
||||||
f, idx = self.current_pane, 0
|
f, idx = self.current_pane, 0
|
||||||
if i > 0:
|
if i > 0:
|
||||||
# search for a line matching that number
|
# search for a line matching that number
|
||||||
|
@ -3057,7 +3056,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# recompute viewport size and redraw as the display preferences may have
|
# recompute viewport size and redraw as the display preferences may have
|
||||||
# changed
|
# changed
|
||||||
def prefsUpdated(self):
|
def prefsUpdated(self) -> None:
|
||||||
# clear cache as tab width may have changed
|
# clear cache as tab width may have changed
|
||||||
self.string_width_cache = {}
|
self.string_width_cache = {}
|
||||||
self.setFont(
|
self.setFont(
|
||||||
|
@ -3075,12 +3074,12 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.diffmap.queue_draw()
|
self.diffmap.queue_draw()
|
||||||
|
|
||||||
# 'realign_all' action
|
# 'realign_all' action
|
||||||
def realign_all(self):
|
def realign_all(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
lines = []
|
lines: List[List[FileDiffViewerBase.Line]] = []
|
||||||
blocks = []
|
blocks: List[int] = []
|
||||||
for pane in self.panes:
|
for pane in self.panes:
|
||||||
# create a new list of lines with no spacers
|
# create a new list of lines with no spacers
|
||||||
newlines = [[line for line in pane.lines if line is not None]]
|
newlines = [[line for line in pane.lines if line is not None]]
|
||||||
|
@ -3114,7 +3113,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.closeUndoBlock()
|
self.closeUndoBlock()
|
||||||
|
|
||||||
# 'isolate' action
|
# 'isolate' action
|
||||||
def isolate(self):
|
def isolate(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
|
@ -3157,7 +3156,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
|
|
||||||
# returns True if line 'i' in pane 'f' has an edit or is different from its
|
# returns True if line 'i' in pane 'f' has an edit or is different from its
|
||||||
# neighbour
|
# neighbour
|
||||||
def hasEditsOrDifference(self, f, i):
|
def hasEditsOrDifference(self, f: int, i: int) -> bool:
|
||||||
line = self.getLine(f, i)
|
line = self.getLine(f, i)
|
||||||
if line is not None and line.is_modified:
|
if line is not None and line.is_modified:
|
||||||
return True
|
return True
|
||||||
|
@ -3167,7 +3166,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
(f + 1 < len(self.panes) and text != self.getCompareString(f + 1, i)))
|
(f + 1 < len(self.panes) and text != self.getCompareString(f + 1, i)))
|
||||||
|
|
||||||
# returns True if there are any differences
|
# returns True if there are any differences
|
||||||
def hasDifferences(self):
|
def hasDifferences(self) -> bool:
|
||||||
n = len(self.panes)
|
n = len(self.panes)
|
||||||
nlines = len(self.panes[0].lines)
|
nlines = len(self.panes[0].lines)
|
||||||
for i in range(nlines):
|
for i in range(nlines):
|
||||||
|
@ -3178,13 +3177,13 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# scroll the viewport so _pixels at position 'y' are centred
|
# scroll the viewport so _pixels at position 'y' are centred
|
||||||
def centre_view_about_y(self, y):
|
def centre_view_about_y(self, y: int) -> None:
|
||||||
vadj = self.vadj
|
vadj = self.vadj
|
||||||
y = min(max(0, y - vadj.get_page_size() / 2), vadj.get_upper() - vadj.get_page_size())
|
y = min(max(0, y - vadj.get_page_size() / 2), vadj.get_upper() - vadj.get_page_size())
|
||||||
vadj.set_value(y)
|
vadj.set_value(y)
|
||||||
|
|
||||||
# move the cursor from line 'i' to the next difference in direction 'delta'
|
# move the cursor from line 'i' to the next difference in direction 'delta'
|
||||||
def go_to_difference(self, i, delta):
|
def go_to_difference(self, i: int, delta: int) -> None:
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
nlines = len(self.panes[f].lines)
|
nlines = len(self.panes[f].lines)
|
||||||
# back up to beginning of difference
|
# back up to beginning of difference
|
||||||
|
@ -3210,31 +3209,31 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.setCurrentLine(f, start, i)
|
self.setCurrentLine(f, start, i)
|
||||||
|
|
||||||
# 'first_difference' action
|
# 'first_difference' action
|
||||||
def first_difference(self):
|
def first_difference(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.go_to_difference(0, 1)
|
self.go_to_difference(0, 1)
|
||||||
|
|
||||||
# 'previous_difference' action
|
# 'previous_difference' action
|
||||||
def previous_difference(self):
|
def previous_difference(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
i = min(self.current_line, self.selection_line) - 1
|
i = min(self.current_line, self.selection_line) - 1
|
||||||
self.go_to_difference(i, -1)
|
self.go_to_difference(i, -1)
|
||||||
|
|
||||||
# 'next_difference' action
|
# 'next_difference' action
|
||||||
def next_difference(self):
|
def next_difference(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
i = max(self.current_line, self.selection_line) + 1
|
i = max(self.current_line, self.selection_line) + 1
|
||||||
self.go_to_difference(i, 1)
|
self.go_to_difference(i, 1)
|
||||||
|
|
||||||
# 'last_difference' action
|
# 'last_difference' action
|
||||||
def last_difference(self):
|
def last_difference(self) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
i = len(self.panes[self.current_pane].lines)
|
i = len(self.panes[self.current_pane].lines)
|
||||||
self.go_to_difference(i, -1)
|
self.go_to_difference(i, -1)
|
||||||
|
|
||||||
# Undo for changes to the pane ordering
|
# Undo for changes to the pane ordering
|
||||||
class SwapPanesUndo:
|
class SwapPanesUndo:
|
||||||
def __init__(self, f_dst, f_src):
|
def __init__(self, f_dst: int, f_src: int) -> None:
|
||||||
self.data = (f_dst, f_src)
|
self.data = (f_dst, f_src)
|
||||||
|
|
||||||
def undo(self, viewer):
|
def undo(self, viewer):
|
||||||
|
@ -3246,7 +3245,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
viewer.swapPanes(f_dst, f_src)
|
viewer.swapPanes(f_dst, f_src)
|
||||||
|
|
||||||
# swap the contents of two panes
|
# swap the contents of two panes
|
||||||
def swapPanes(self, f_dst, f_src):
|
def swapPanes(self, f_dst: int, f_src: int) -> None:
|
||||||
if self.undoblock is not None:
|
if self.undoblock is not None:
|
||||||
self.addUndo(FileDiffViewerBase.SwapPanesUndo(f_dst, f_src))
|
self.addUndo(FileDiffViewerBase.SwapPanesUndo(f_dst, f_src))
|
||||||
self.current_pane = f_dst
|
self.current_pane = f_dst
|
||||||
|
@ -3267,7 +3266,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.emit('swapped_panes', f_dst, f_src)
|
self.emit('swapped_panes', f_dst, f_src)
|
||||||
|
|
||||||
# swap the contents of two panes
|
# swap the contents of two panes
|
||||||
def swap_panes(self, f_dst, f_src):
|
def swap_panes(self, f_dst: int, f_src: int) -> None:
|
||||||
if 0 <= f_dst < len(self.panes):
|
if 0 <= f_dst < len(self.panes):
|
||||||
if self.mode == ALIGN_MODE:
|
if self.mode == ALIGN_MODE:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
|
@ -3282,17 +3281,17 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.closeUndoBlock()
|
self.closeUndoBlock()
|
||||||
|
|
||||||
# 'shift_pane_left' action
|
# 'shift_pane_left' action
|
||||||
def shift_pane_left(self):
|
def shift_pane_left(self) -> None:
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
self.swap_panes(f - 1, f)
|
self.swap_panes(f - 1, f)
|
||||||
|
|
||||||
# 'shift_pane_right' action
|
# 'shift_pane_right' action
|
||||||
def shift_pane_right(self):
|
def shift_pane_right(self) -> None:
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
self.swap_panes(f + 1, f)
|
self.swap_panes(f + 1, f)
|
||||||
|
|
||||||
# 'convert_to_upper_case' action
|
# 'convert_to_upper_case' action
|
||||||
def _convert_case(self, to_upper):
|
def _convert_case(self, to_upper: bool) -> None:
|
||||||
# find range of characters to operate upon
|
# find range of characters to operate upon
|
||||||
if self.mode == CHAR_MODE:
|
if self.mode == CHAR_MODE:
|
||||||
start, end = self.current_line, self.selection_line
|
start, end = self.current_line, self.selection_line
|
||||||
|
@ -3333,15 +3332,15 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.updateText(f, i, s)
|
self.updateText(f, i, s)
|
||||||
|
|
||||||
# 'convert_to_upper_case' action
|
# 'convert_to_upper_case' action
|
||||||
def convert_to_upper_case(self):
|
def convert_to_upper_case(self) -> None:
|
||||||
self._convert_case(True)
|
self._convert_case(True)
|
||||||
|
|
||||||
# 'convert_to_lower_case' action
|
# 'convert_to_lower_case' action
|
||||||
def convert_to_lower_case(self):
|
def convert_to_lower_case(self) -> None:
|
||||||
self._convert_case(False)
|
self._convert_case(False)
|
||||||
|
|
||||||
# sort lines
|
# sort lines
|
||||||
def _sort_lines(self, descending):
|
def _sort_lines(self, descending: bool) -> None:
|
||||||
if self.mode != CHAR_MODE:
|
if self.mode != CHAR_MODE:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
@ -3353,7 +3352,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
# get set of lines
|
# get set of lines
|
||||||
ss = [self.getLineText(f, i) for i in range(start, end + 1)]
|
ss = [self.getLineText(f, i) for i in range(start, end + 1)]
|
||||||
# create sorted list, removing any nulls
|
# create sorted list, removing any nulls
|
||||||
temp = [s for s in ss if s is not None]
|
temp: List[Optional[str]] = [s for s in ss if s is not None]
|
||||||
temp.sort()
|
temp.sort()
|
||||||
if descending:
|
if descending:
|
||||||
temp.reverse()
|
temp.reverse()
|
||||||
|
@ -3369,15 +3368,15 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
|
||||||
# 'sort_lines_in_ascending_order' action
|
# 'sort_lines_in_ascending_order' action
|
||||||
def sort_lines_in_ascending_order(self):
|
def sort_lines_in_ascending_order(self) -> None:
|
||||||
self._sort_lines(False)
|
self._sort_lines(False)
|
||||||
|
|
||||||
# 'sort_lines_in_descending_order' action
|
# 'sort_lines_in_descending_order' action
|
||||||
def sort_lines_in_descending_order(self):
|
def sort_lines_in_descending_order(self) -> None:
|
||||||
self._sort_lines(True)
|
self._sort_lines(True)
|
||||||
|
|
||||||
# 'remove_trailing_white_space' action
|
# 'remove_trailing_white_space' action
|
||||||
def remove_trailing_white_space(self):
|
def remove_trailing_white_space(self) -> None:
|
||||||
if self.mode != CHAR_MODE:
|
if self.mode != CHAR_MODE:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
@ -3403,7 +3402,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
|
||||||
# 'convert_tabs_to_spaces' action
|
# 'convert_tabs_to_spaces' action
|
||||||
def convert_tabs_to_spaces(self):
|
def convert_tabs_to_spaces(self) -> None:
|
||||||
# find range of characters to operate upon
|
# find range of characters to operate upon
|
||||||
if self.mode == CHAR_MODE:
|
if self.mode == CHAR_MODE:
|
||||||
start, end = self.current_line, self.selection_line
|
start, end = self.current_line, self.selection_line
|
||||||
|
@ -3456,7 +3455,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
|
||||||
# 'convert_leading_spaces_to_tabs' action
|
# 'convert_leading_spaces_to_tabs' action
|
||||||
def convert_leading_spaces_to_tabs(self):
|
def convert_leading_spaces_to_tabs(self) -> None:
|
||||||
if self.mode != CHAR_MODE:
|
if self.mode != CHAR_MODE:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
@ -3486,7 +3485,7 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
|
||||||
# adjust indenting of the selected lines by 'offset' soft tabs
|
# adjust indenting of the selected lines by 'offset' soft tabs
|
||||||
def _adjust_indenting(self, offset):
|
def _adjust_indenting(self, offset: int) -> None:
|
||||||
if self.mode != CHAR_MODE:
|
if self.mode != CHAR_MODE:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
# find range of lines to operate upon
|
# find range of lines to operate upon
|
||||||
|
@ -3519,14 +3518,14 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
|
|
||||||
# 'increase_indenting' action
|
# 'increase_indenting' action
|
||||||
def increase_indenting(self):
|
def increase_indenting(self) -> None:
|
||||||
self._adjust_indenting(1)
|
self._adjust_indenting(1)
|
||||||
|
|
||||||
# 'decrease_indenting' action
|
# 'decrease_indenting' action
|
||||||
def decrease_indenting(self):
|
def decrease_indenting(self) -> None:
|
||||||
self._adjust_indenting(-1)
|
self._adjust_indenting(-1)
|
||||||
|
|
||||||
def convert_format(self, fmt):
|
def convert_format(self, fmt: LineEnding) -> None:
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
|
@ -3539,19 +3538,19 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.setFormat(f, fmt)
|
self.setFormat(f, fmt)
|
||||||
|
|
||||||
# 'convert_to_dos' action
|
# 'convert_to_dos' action
|
||||||
def convert_to_dos(self):
|
def convert_to_dos(self) -> None:
|
||||||
self.convert_format(LineEnding.DOS_FORMAT)
|
self.convert_format(LineEnding.DOS_FORMAT)
|
||||||
|
|
||||||
# 'convert_to_mac' action
|
# 'convert_to_mac' action
|
||||||
def convert_to_mac(self):
|
def convert_to_mac(self) -> None:
|
||||||
self.convert_format(LineEnding.MAC_FORMAT)
|
self.convert_format(LineEnding.MAC_FORMAT)
|
||||||
|
|
||||||
# 'convert_to_unix' action
|
# 'convert_to_unix' action
|
||||||
def convert_to_unix(self):
|
def convert_to_unix(self) -> None:
|
||||||
self.convert_format(LineEnding.UNIX_FORMAT)
|
self.convert_format(LineEnding.UNIX_FORMAT)
|
||||||
|
|
||||||
# copies the selected range of lines from pane 'f_src' to 'f_dst'
|
# copies the selected range of lines from pane 'f_src' to 'f_dst'
|
||||||
def merge_lines(self, f_dst, f_src):
|
def merge_lines(self, f_dst: int, f_src: int) -> None:
|
||||||
self.recordEditMode()
|
self.recordEditMode()
|
||||||
self.setLineMode()
|
self.setLineMode()
|
||||||
pane = self.panes[f_dst]
|
pane = self.panes[f_dst]
|
||||||
|
@ -3581,25 +3580,25 @@ class FileDiffViewerBase(Gtk.Grid):
|
||||||
self.closeUndoBlock()
|
self.closeUndoBlock()
|
||||||
|
|
||||||
# 'copy_selection_right' action
|
# 'copy_selection_right' action
|
||||||
def copy_selection_right(self):
|
def copy_selection_right(self) -> None:
|
||||||
f = self.current_pane + 1
|
f = self.current_pane + 1
|
||||||
if 0 < f < len(self.panes):
|
if 0 < f < len(self.panes):
|
||||||
self.merge_lines(f, f - 1)
|
self.merge_lines(f, f - 1)
|
||||||
|
|
||||||
# 'copy_selection_left' action
|
# 'copy_selection_left' action
|
||||||
def copy_selection_left(self):
|
def copy_selection_left(self) -> None:
|
||||||
f = self.current_pane - 1
|
f = self.current_pane - 1
|
||||||
if f >= 0 and f + 1 < len(self.panes):
|
if f >= 0 and f + 1 < len(self.panes):
|
||||||
self.merge_lines(f, f + 1)
|
self.merge_lines(f, f + 1)
|
||||||
|
|
||||||
# 'copy_left_into_selection' action
|
# 'copy_left_into_selection' action
|
||||||
def copy_left_into_selection(self):
|
def copy_left_into_selection(self) -> None:
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
if 0 < f < len(self.panes):
|
if 0 < f < len(self.panes):
|
||||||
self.merge_lines(f, f - 1)
|
self.merge_lines(f, f - 1)
|
||||||
|
|
||||||
# 'copy_right_into_selection' action
|
# 'copy_right_into_selection' action
|
||||||
def copy_right_into_selection(self):
|
def copy_right_into_selection(self) -> None:
|
||||||
f = self.current_pane
|
f = self.current_pane
|
||||||
if f >= 0 and f + 1 < len(self.panes):
|
if f >= 0 and f + 1 < len(self.panes):
|
||||||
self.merge_lines(f, f + 1)
|
self.merge_lines(f, f + 1)
|
||||||
|
@ -3740,18 +3739,19 @@ def createMenu(specs, radio=None, accel_group=None):
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
|
|
||||||
ALPHANUMERIC_CLASS = 0
|
class CharacterClass(IntFlag):
|
||||||
WHITESPACE_CLASS = 1
|
ALPHANUMERIC = 0
|
||||||
OTHER_CLASS = 2
|
WHITESPACE = 1
|
||||||
|
OTHER = 2
|
||||||
|
|
||||||
|
|
||||||
# maps similar types of characters to a group
|
# maps similar types of characters to a group
|
||||||
def _get_character_class(c):
|
def _get_character_class(c: str) -> CharacterClass:
|
||||||
if c.isalnum() or c == '_':
|
if c.isalnum() or c == '_':
|
||||||
return ALPHANUMERIC_CLASS
|
return CharacterClass.ALPHANUMERIC
|
||||||
if c.isspace():
|
if c.isspace():
|
||||||
return WHITESPACE_CLASS
|
return CharacterClass.WHITESPACE
|
||||||
return OTHER_CLASS
|
return CharacterClass.OTHER
|
||||||
|
|
||||||
|
|
||||||
# patience diff with difflib-style fallback
|
# patience diff with difflib-style fallback
|
||||||
|
@ -3966,36 +3966,36 @@ def _lcs_approx(a, b):
|
||||||
|
|
||||||
|
|
||||||
# True if the string ends with '\r\n'
|
# True if the string ends with '\r\n'
|
||||||
def _has_dos_line_ending(s):
|
def _has_dos_line_ending(s: str) -> bool:
|
||||||
return s.endswith('\r\n')
|
return s.endswith('\r\n')
|
||||||
|
|
||||||
|
|
||||||
# True if the string ends with '\r'
|
# True if the string ends with '\r'
|
||||||
def _has_mac_line_ending(s):
|
def _has_mac_line_ending(s: str) -> bool:
|
||||||
return s.endswith('\r')
|
return s.endswith('\r')
|
||||||
|
|
||||||
|
|
||||||
# True if the string ends with '\n' but not '\r\n'
|
# True if the string ends with '\n' but not '\r\n'
|
||||||
def _has_unix_line_ending(s):
|
def _has_unix_line_ending(s: str) -> bool:
|
||||||
return s.endswith('\n') and not s.endswith('\r\n')
|
return s.endswith('\n') and not s.endswith('\r\n')
|
||||||
|
|
||||||
|
|
||||||
# returns the format mask for a list of strings
|
# returns the format mask for a list of strings
|
||||||
def _get_format(ss):
|
def _get_format(lines: List[Optional[str]]) -> LineEnding:
|
||||||
flags = 0
|
flags: LineEnding = LineEnding.NO_FORMAT
|
||||||
for s in ss:
|
for line in lines:
|
||||||
if s is not None:
|
if line is not None:
|
||||||
if _has_dos_line_ending(s):
|
if _has_dos_line_ending(line):
|
||||||
flags |= LineEnding.DOS_FORMAT
|
flags |= LineEnding.DOS_FORMAT
|
||||||
elif _has_mac_line_ending(s):
|
elif _has_mac_line_ending(line):
|
||||||
flags |= LineEnding.MAC_FORMAT
|
flags |= LineEnding.MAC_FORMAT
|
||||||
elif _has_unix_line_ending(s):
|
elif _has_unix_line_ending(line):
|
||||||
flags |= LineEnding.UNIX_FORMAT
|
flags |= LineEnding.UNIX_FORMAT
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
|
|
||||||
# convenience method to change the line ending of a string
|
# convenience method to change the line ending of a string
|
||||||
def _convert_to_format(s, fmt):
|
def _convert_to_format(s: Optional[str], fmt: LineEnding) -> Optional[str]:
|
||||||
if s is not None and fmt != 0:
|
if s is not None and fmt != 0:
|
||||||
old_format = _get_format([s])
|
old_format = _get_format([s])
|
||||||
if old_format != 0 and (old_format & fmt) == 0:
|
if old_format != 0 and (old_format & fmt) == 0:
|
||||||
|
@ -4025,14 +4025,14 @@ def _convert_to_format(s, fmt):
|
||||||
# in this array so 'blocks' will be an empty array when there are no lines. A
|
# in this array so 'blocks' will be an empty array when there are no lines. A
|
||||||
# 'cut' at location 'i' means a line 'i-1' and line 'i' belong to different
|
# 'cut' at location 'i' means a line 'i-1' and line 'i' belong to different
|
||||||
# sections
|
# sections
|
||||||
def _create_block(n):
|
def _create_block(n: int) -> List[int]:
|
||||||
if n > 0:
|
if n > 0:
|
||||||
return [n]
|
return [n]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# returns the two sets of blocks after cutting at 'i'
|
# returns the two sets of blocks after cutting at 'i'
|
||||||
def _cut_blocks(i, blocks):
|
def _cut_blocks(i: int, blocks: List[int]) -> Tuple[List[int], List[int]]:
|
||||||
pre, post, nlines = [], [], 0
|
pre, post, nlines = [], [], 0
|
||||||
for b in blocks:
|
for b in blocks:
|
||||||
if nlines >= i:
|
if nlines >= i:
|
||||||
|
@ -4048,7 +4048,7 @@ def _cut_blocks(i, blocks):
|
||||||
|
|
||||||
|
|
||||||
# returns a set of blocks containing all of the cuts in the inputs
|
# returns a set of blocks containing all of the cuts in the inputs
|
||||||
def _merge_blocks(leftblocks, rightblocks):
|
def _merge_blocks(leftblocks: List[int], rightblocks: List[int]) -> List[int]:
|
||||||
leftblocks, rightblocks, b = leftblocks[:], rightblocks[:], []
|
leftblocks, rightblocks, b = leftblocks[:], rightblocks[:], []
|
||||||
while len(leftblocks) > 0:
|
while len(leftblocks) > 0:
|
||||||
nleft, nright = leftblocks[0], rightblocks[0]
|
nleft, nright = leftblocks[0], rightblocks[0]
|
||||||
|
@ -4122,14 +4122,14 @@ def _remove_null_lines(blocks, lines_set):
|
||||||
|
|
||||||
|
|
||||||
# returns true if the string only contains whitespace characters
|
# returns true if the string only contains whitespace characters
|
||||||
def _is_blank(s):
|
def _is_blank(s: str) -> bool:
|
||||||
for c in utils.whitespace:
|
for c in utils.whitespace:
|
||||||
s = s.replace(c, '')
|
s = s.replace(c, '')
|
||||||
return len(s) == 0
|
return len(s) == 0
|
||||||
|
|
||||||
|
|
||||||
# use Pango.SCALE instead of Pango.PIXELS to avoid overflow exception
|
# use Pango.SCALE instead of Pango.PIXELS to avoid overflow exception
|
||||||
def _pixels(size):
|
def _pixels(size: int) -> int:
|
||||||
return int(size / Pango.SCALE + 0.5)
|
return int(size / Pango.SCALE + 0.5)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue