parent
45039d3e43
commit
c4a4687f58
|
@ -164,8 +164,8 @@ whitespace = ' \t\n\r\x0b\x0c'
|
||||||
|
|
||||||
# escape special glob characters
|
# escape special glob characters
|
||||||
def globEscape(s):
|
def globEscape(s):
|
||||||
m = dict([ (c, f'[{c}]') for c in u'[]?*' ])
|
m = dict([ (c, f'[{c}]') for c in '[]?*' ])
|
||||||
return u''.join([ m.get(c, c) for c in s ])
|
return ''.join([ m.get(c, c) for c in s ])
|
||||||
|
|
||||||
# associate our icon with all of our windows
|
# associate our icon with all of our windows
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -289,7 +289,7 @@ def readlines(fd):
|
||||||
return strip_eols(splitlines(fd.read()))
|
return strip_eols(splitlines(fd.read()))
|
||||||
|
|
||||||
def readconfiglines(fd):
|
def readconfiglines(fd):
|
||||||
return fd.read().replace(u'\r', u'').split(u'\n')
|
return fd.read().replace('\r', '').split('\n')
|
||||||
|
|
||||||
# This class to hold all customisable behaviour not exposed in the preferences
|
# This class to hold all customisable behaviour not exposed in the preferences
|
||||||
# dialogue: hotkey assignment, colours, syntax highlighting, etc.
|
# dialogue: hotkey assignment, colours, syntax highlighting, etc.
|
||||||
|
@ -605,7 +605,7 @@ class Resources:
|
||||||
try:
|
try:
|
||||||
# eg. add Python syntax highlighting:
|
# eg. add Python syntax highlighting:
|
||||||
# import /usr/share/diffuse/syntax/python.syntax
|
# import /usr/share/diffuse/syntax/python.syntax
|
||||||
if args[0] == u'import' and len(args) == 2:
|
if args[0] == 'import' and len(args) == 2:
|
||||||
path = os.path.expanduser(args[1])
|
path = os.path.expanduser(args[1])
|
||||||
# relative paths are relative to the parsed file
|
# relative paths are relative to the parsed file
|
||||||
path = os.path.join(globEscape(os.path.dirname(file_name)), path)
|
path = os.path.join(globEscape(os.path.dirname(file_name)), path)
|
||||||
|
@ -619,28 +619,28 @@ class Resources:
|
||||||
self.parse(os.path.abspath(path))
|
self.parse(os.path.abspath(path))
|
||||||
# eg. make Ctrl+o trigger the open_file menu item
|
# eg. make Ctrl+o trigger the open_file menu item
|
||||||
# keybinding menu open_file Ctrl+o
|
# keybinding menu open_file Ctrl+o
|
||||||
elif args[0] == u'keybinding' and len(args) == 4:
|
elif args[0] == 'keybinding' and len(args) == 4:
|
||||||
self.setKeyBinding(args[1], args[2], args[3])
|
self.setKeyBinding(args[1], args[2], args[3])
|
||||||
# eg. set the regular background colour to white
|
# eg. set the regular background colour to white
|
||||||
# colour text_background 1.0 1.0 1.0
|
# colour text_background 1.0 1.0 1.0
|
||||||
elif args[0] in [ u'colour', u'color' ] and len(args) == 5:
|
elif args[0] in [ 'colour', 'color' ] and len(args) == 5:
|
||||||
self.colours[args[1]] = Colour(float(args[2]), float(args[3]), float(args[4]))
|
self.colours[args[1]] = Colour(float(args[2]), float(args[3]), float(args[4]))
|
||||||
# eg. set opacity of the line_selection colour
|
# eg. set opacity of the line_selection colour
|
||||||
# float line_selection_opacity 0.4
|
# float line_selection_opacity 0.4
|
||||||
elif args[0] == u'float' and len(args) == 3:
|
elif args[0] == 'float' and len(args) == 3:
|
||||||
self.floats[args[1]] = float(args[2])
|
self.floats[args[1]] = float(args[2])
|
||||||
# eg. set the help browser
|
# eg. set the help browser
|
||||||
# string help_browser gnome-help
|
# string help_browser gnome-help
|
||||||
elif args[0] == u'string' and len(args) == 3:
|
elif args[0] == 'string' and len(args) == 3:
|
||||||
self.strings[args[1]] = args[2]
|
self.strings[args[1]] = args[2]
|
||||||
if args[1] == u'difference_colours':
|
if args[1] == 'difference_colours':
|
||||||
self.setDifferenceColours(args[2])
|
self.setDifferenceColours(args[2])
|
||||||
# eg. start a syntax specification for Python
|
# eg. start a syntax specification for Python
|
||||||
# syntax Python normal text
|
# syntax Python normal text
|
||||||
# where 'normal' is the name of the default state and
|
# where 'normal' is the name of the default state and
|
||||||
# 'text' is the classification of all characters not
|
# 'text' is the classification of all characters not
|
||||||
# explicitly matched by a syntax highlighting rule
|
# explicitly matched by a syntax highlighting rule
|
||||||
elif args[0] == u'syntax' and (len(args) == 2 or len(args) == 4):
|
elif args[0] == 'syntax' and (len(args) == 2 or len(args) == 4):
|
||||||
key = args[1]
|
key = args[1]
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
# remove file pattern for a syntax specification
|
# remove file pattern for a syntax specification
|
||||||
|
@ -666,10 +666,10 @@ class Resources:
|
||||||
# the pattern '#' is matched and classify the matched
|
# the pattern '#' is matched and classify the matched
|
||||||
# characters as 'python_comment'
|
# characters as 'python_comment'
|
||||||
# syntax_pattern normal comment python_comment '#'
|
# syntax_pattern normal comment python_comment '#'
|
||||||
elif args[0] == u'syntax_pattern' and self.current_syntax is not None and len(args) >= 5:
|
elif args[0] == 'syntax_pattern' and self.current_syntax is not None and len(args) >= 5:
|
||||||
flags = 0
|
flags = 0
|
||||||
for arg in args[5:]:
|
for arg in args[5:]:
|
||||||
if arg == u'ignorecase':
|
if arg == 'ignorecase':
|
||||||
flags |= re.IGNORECASE
|
flags |= re.IGNORECASE
|
||||||
else:
|
else:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
|
@ -677,7 +677,7 @@ class Resources:
|
||||||
# eg. default to the Python syntax rules when viewing
|
# eg. default to the Python syntax rules when viewing
|
||||||
# a file ending with '.py' or '.pyw'
|
# a file ending with '.py' or '.pyw'
|
||||||
# syntax_files Python '\.pyw?$'
|
# syntax_files Python '\.pyw?$'
|
||||||
elif args[0] == u'syntax_files' and (len(args) == 2 or len(args) == 3):
|
elif args[0] == 'syntax_files' and (len(args) == 2 or len(args) == 3):
|
||||||
key = args[1]
|
key = args[1]
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
# remove file pattern for a syntax specification
|
# remove file pattern for a syntax specification
|
||||||
|
@ -693,7 +693,7 @@ class Resources:
|
||||||
# eg. default to the Python syntax rules when viewing
|
# eg. default to the Python syntax rules when viewing
|
||||||
# a files starting with patterns like #!/usr/bin/python
|
# a files starting with patterns like #!/usr/bin/python
|
||||||
# syntax_magic Python '^#!/usr/bin/python$'
|
# syntax_magic Python '^#!/usr/bin/python$'
|
||||||
elif args[0] == u'syntax_magic' and len(args) > 1:
|
elif args[0] == 'syntax_magic' and len(args) > 1:
|
||||||
key = args[1]
|
key = args[1]
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
# remove magic pattern for a syntax specification
|
# remove magic pattern for a syntax specification
|
||||||
|
@ -704,7 +704,7 @@ class Resources:
|
||||||
else:
|
else:
|
||||||
flags = 0
|
flags = 0
|
||||||
for arg in args[3:]:
|
for arg in args[3:]:
|
||||||
if arg == u'ignorecase':
|
if arg == 'ignorecase':
|
||||||
flags |= re.IGNORECASE
|
flags |= re.IGNORECASE
|
||||||
else:
|
else:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
|
@ -1138,7 +1138,7 @@ class Preferences:
|
||||||
return str(s, encoding=encoding), encoding
|
return str(s, encoding=encoding), encoding
|
||||||
except (UnicodeDecodeError, LookupError):
|
except (UnicodeDecodeError, LookupError):
|
||||||
pass
|
pass
|
||||||
return u''.join([ chr(ord(c)) for c in s ]), None
|
return ''.join([ chr(ord(c)) for c in s ]), None
|
||||||
|
|
||||||
# cygwin and native applications can be used on windows, use this method
|
# cygwin and native applications can be used on windows, use this method
|
||||||
# to convert a path to the usual form expected on sys.platform
|
# to convert a path to the usual form expected on sys.platform
|
||||||
|
@ -2396,14 +2396,14 @@ class _Svn:
|
||||||
# FIXME: verify this
|
# FIXME: verify this
|
||||||
# merge conflict
|
# merge conflict
|
||||||
escaped_name = globEscape(name)
|
escaped_name = globEscape(name)
|
||||||
left = glob.glob(escaped_name + u'.merge-left.r*')
|
left = glob.glob(escaped_name + '.merge-left.r*')
|
||||||
right = glob.glob(escaped_name + u'.merge-right.r*')
|
right = glob.glob(escaped_name + '.merge-right.r*')
|
||||||
if len(left) > 0 and len(right) > 0:
|
if len(left) > 0 and len(right) > 0:
|
||||||
return [ (left[-1], None), (name, None), (right[-1], None) ]
|
return [ (left[-1], None), (name, None), (right[-1], None) ]
|
||||||
# update conflict
|
# update conflict
|
||||||
left = sorted(glob.glob(escaped_name + u'.r*'))
|
left = sorted(glob.glob(escaped_name + '.r*'))
|
||||||
right = glob.glob(escaped_name + u'.mine')
|
right = glob.glob(escaped_name + '.mine')
|
||||||
right.extend(glob.glob(escaped_name + u'.working'))
|
right.extend(glob.glob(escaped_name + '.working'))
|
||||||
if len(left) > 0 and len(right) > 0:
|
if len(left) > 0 and len(right) > 0:
|
||||||
return [ (left[-1], None), (name, None), (right[0], None) ]
|
return [ (left[-1], None), (name, None), (right[0], None) ]
|
||||||
# default case
|
# default case
|
||||||
|
@ -2936,7 +2936,7 @@ OTHER_CLASS = 2
|
||||||
|
|
||||||
# maps similar types of characters to a group
|
# maps similar types of characters to a group
|
||||||
def getCharacterClass(c):
|
def getCharacterClass(c):
|
||||||
if c.isalnum() or c == u'_':
|
if c.isalnum() or c == '_':
|
||||||
return ALPHANUMERIC_CLASS
|
return ALPHANUMERIC_CLASS
|
||||||
elif c.isspace():
|
elif c.isspace():
|
||||||
return WHITESPACE_CLASS
|
return WHITESPACE_CLASS
|
||||||
|
@ -3471,22 +3471,22 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
if c == ' ':
|
if c == ' ':
|
||||||
if visible:
|
if visible:
|
||||||
# show spaces using a centre-dot
|
# show spaces using a centre-dot
|
||||||
result.append(u'\u00b7')
|
result.append('\u00b7')
|
||||||
else:
|
else:
|
||||||
result.append(c)
|
result.append(c)
|
||||||
elif c == '\t':
|
elif c == '\t':
|
||||||
width = tab_width - col % tab_width
|
width = tab_width - col % tab_width
|
||||||
if visible:
|
if visible:
|
||||||
# show tabs using a right double angle quote
|
# show tabs using a right double angle quote
|
||||||
result.append(u'\u00bb' + (width - 1) * u' ')
|
result.append('\u00bb' + (width - 1) * ' ')
|
||||||
else:
|
else:
|
||||||
result.append(width * u' ')
|
result.append(width * ' ')
|
||||||
elif c == '\n' and visible:
|
elif c == '\n' and visible:
|
||||||
# show newlines using a pilcrow
|
# show newlines using a pilcrow
|
||||||
result.append(u'\u00b6')
|
result.append('\u00b6')
|
||||||
else:
|
else:
|
||||||
# prefix with a ^
|
# prefix with a ^
|
||||||
result.append(u'^' + chr(v + 64))
|
result.append('^' + chr(v + 64))
|
||||||
else:
|
else:
|
||||||
result.append(c)
|
result.append(c)
|
||||||
col += self.characterWidth(col, c)
|
col += self.characterWidth(col, c)
|
||||||
|
@ -5704,10 +5704,10 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
width = self.prefs.getInt('editor_soft_tab_width')
|
width = self.prefs.getInt('editor_soft_tab_width')
|
||||||
w = (w - 1) // width * width
|
w = (w - 1) // width * width
|
||||||
if self.prefs.getBool('editor_expand_tabs'):
|
if self.prefs.getBool('editor_expand_tabs'):
|
||||||
s = u' ' * w
|
s = ' ' * w
|
||||||
else:
|
else:
|
||||||
width = self.prefs.getInt('display_tab_width')
|
width = self.prefs.getInt('display_tab_width')
|
||||||
s = u'\t' * (w // width) + u' ' * (w % width)
|
s = '\t' * (w // width) + ' ' * (w % width)
|
||||||
j = 0
|
j = 0
|
||||||
else:
|
else:
|
||||||
# delete back to an end of line character from the
|
# delete back to an end of line character from the
|
||||||
|
@ -5788,10 +5788,10 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
ws = max(0, w + offset * self.prefs.getInt('editor_soft_tab_width'))
|
ws = max(0, w + offset * self.prefs.getInt('editor_soft_tab_width'))
|
||||||
if ws != w:
|
if ws != w:
|
||||||
if self.prefs.getBool('editor_expand_tabs'):
|
if self.prefs.getBool('editor_expand_tabs'):
|
||||||
s = u' ' * ws
|
s = ' ' * ws
|
||||||
else:
|
else:
|
||||||
tab_width = self.prefs.getInt('display_tab_width')
|
tab_width = self.prefs.getInt('display_tab_width')
|
||||||
s = u'\t' * (ws // tab_width) + u' ' * (ws % tab_width)
|
s = '\t' * (ws // tab_width) + ' ' * (ws % tab_width)
|
||||||
if i == start_i:
|
if i == start_i:
|
||||||
start_j = len(s) + max(0, start_j - j)
|
start_j = len(s) + max(0, start_j - j)
|
||||||
if i == end_i:
|
if i == end_i:
|
||||||
|
@ -5827,11 +5827,11 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
w = 0
|
w = 0
|
||||||
if self.prefs.getBool('editor_expand_tabs'):
|
if self.prefs.getBool('editor_expand_tabs'):
|
||||||
# convert to spaces
|
# convert to spaces
|
||||||
s = u' ' * ws
|
s = ' ' * ws
|
||||||
else:
|
else:
|
||||||
# replace with tab characters where possible
|
# replace with tab characters where possible
|
||||||
s = u'\t' * ((w + ws) // tab_width - w // tab_width)
|
s = '\t' * ((w + ws) // tab_width - w // tab_width)
|
||||||
s += u' ' * ((w + ws) % tab_width)
|
s += ' ' * ((w + ws) % tab_width)
|
||||||
self.replaceText(s)
|
self.replaceText(s)
|
||||||
# handle all other printable characters
|
# handle all other printable characters
|
||||||
elif len(event.string) > 0:
|
elif len(event.string) > 0:
|
||||||
|
@ -6340,7 +6340,7 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
w = self.characterWidth(col, c)
|
w = self.characterWidth(col, c)
|
||||||
# replace tab with spaces
|
# replace tab with spaces
|
||||||
if c == '\t':
|
if c == '\t':
|
||||||
c = w * u' '
|
c = w * ' '
|
||||||
ss.append(c)
|
ss.append(c)
|
||||||
col += w
|
col += w
|
||||||
# determine the range of interest
|
# determine the range of interest
|
||||||
|
@ -6388,7 +6388,7 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
j += 1
|
j += 1
|
||||||
if col >= tab_width:
|
if col >= tab_width:
|
||||||
# convert to tabs
|
# convert to tabs
|
||||||
s = ''.join([ u'\t' * (col // tab_width), u' ' * (col % tab_width), text[j:] ])
|
s = ''.join([ '\t' * (col // tab_width), ' ' * (col % tab_width), text[j:] ])
|
||||||
# update line only if it changed
|
# update line only if it changed
|
||||||
if text != s:
|
if text != s:
|
||||||
self.updateText(f, i, s)
|
self.updateText(f, i, s)
|
||||||
|
@ -6420,10 +6420,10 @@ class FileDiffViewer(Gtk.Grid):
|
||||||
ws = max(0, w + offset * self.prefs.getInt('editor_soft_tab_width'))
|
ws = max(0, w + offset * self.prefs.getInt('editor_soft_tab_width'))
|
||||||
if ws != w:
|
if ws != w:
|
||||||
if self.prefs.getBool('editor_expand_tabs'):
|
if self.prefs.getBool('editor_expand_tabs'):
|
||||||
s = u' ' * ws
|
s = ' ' * ws
|
||||||
else:
|
else:
|
||||||
tab_width = self.prefs.getInt('display_tab_width')
|
tab_width = self.prefs.getInt('display_tab_width')
|
||||||
s = u'\t' * (ws // tab_width) + u' ' * (ws % tab_width)
|
s = '\t' * (ws // tab_width) + ' ' * (ws % tab_width)
|
||||||
self.updateText(f, i, s + text[j:])
|
self.updateText(f, i, s + text[j:])
|
||||||
if self.mode == CHAR_MODE:
|
if self.mode == CHAR_MODE:
|
||||||
# ensure the cursor position is valid
|
# ensure the cursor position is valid
|
||||||
|
@ -7266,7 +7266,7 @@ class Diffuse(Gtk.Window):
|
||||||
s = line.getText()
|
s = line.getText()
|
||||||
if s is not None:
|
if s is not None:
|
||||||
ss.append(s)
|
ss.append(s)
|
||||||
encoded = codecs.encode(u''.join(ss), encoding)
|
encoded = codecs.encode(''.join(ss), encoding)
|
||||||
|
|
||||||
# write file
|
# write file
|
||||||
fd = open(name, 'wb')
|
fd = open(name, 'wb')
|
||||||
|
@ -8321,16 +8321,16 @@ def make_subdirs(p, ss):
|
||||||
# process the command line arguments
|
# process the command line arguments
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# find the config directory and create it if it didn't exist
|
# find the config directory and create it if it didn't exist
|
||||||
rc_dir, subdirs = os.environ.get('XDG_CONFIG_HOME', None), [u'diffuse']
|
rc_dir, subdirs = os.environ.get('XDG_CONFIG_HOME', None), ['diffuse']
|
||||||
if rc_dir is None:
|
if rc_dir is None:
|
||||||
rc_dir = os.path.expanduser(u'~')
|
rc_dir = os.path.expanduser('~')
|
||||||
subdirs.insert(0, u'.config')
|
subdirs.insert(0, '.config')
|
||||||
rc_dir = make_subdirs(rc_dir, subdirs)
|
rc_dir = make_subdirs(rc_dir, subdirs)
|
||||||
# find the local data directory and create it if it didn't exist
|
# find the local data directory and create it if it didn't exist
|
||||||
data_dir, subdirs = os.environ.get('XDG_DATA_HOME', None), [u'diffuse']
|
data_dir, subdirs = os.environ.get('XDG_DATA_HOME', None), ['diffuse']
|
||||||
if data_dir is None:
|
if data_dir is None:
|
||||||
data_dir = os.path.expanduser(u'~')
|
data_dir = os.path.expanduser('~')
|
||||||
subdirs[:0] = [ u'.local', u'share' ]
|
subdirs[:0] = [ '.local', 'share' ]
|
||||||
data_dir = make_subdirs(data_dir, subdirs)
|
data_dir = make_subdirs(data_dir, subdirs)
|
||||||
# load resource files
|
# load resource files
|
||||||
i, rc_files = 1, []
|
i, rc_files = 1, []
|
||||||
|
@ -8343,10 +8343,10 @@ if __name__ == '__main__':
|
||||||
else:
|
else:
|
||||||
# parse system wide then personal initialisation files
|
# parse system wide then personal initialisation files
|
||||||
if isWindows():
|
if isWindows():
|
||||||
rc_file = os.path.join(bin_dir, u'diffuserc')
|
rc_file = os.path.join(bin_dir, 'diffuserc')
|
||||||
else:
|
else:
|
||||||
rc_file = os.path.join(bin_dir, u'../../etc/diffuserc')
|
rc_file = os.path.join(bin_dir, '../../etc/diffuserc')
|
||||||
for rc_file in rc_file, os.path.join(rc_dir, u'diffuserc'):
|
for rc_file in rc_file, os.path.join(rc_dir, 'diffuserc'):
|
||||||
if os.path.isfile(rc_file):
|
if os.path.isfile(rc_file):
|
||||||
rc_files.append(rc_file)
|
rc_files.append(rc_file)
|
||||||
for rc_file in rc_files:
|
for rc_file in rc_files:
|
||||||
|
|
Loading…
Reference in New Issue