Top

ped_core.changes module

undo module for the ped python editor, implements a simple undo mechanism

# Copyright 2015 James P Goodwin ped tiny python editor
""" undo module for the ped python editor, implements a simple undo mechanism """

import sys


class Change:
    """ Represents one span of lines that have been changed """
    def __init__(self, start_line = 0, end_line = sys.maxsize):
        """ Constructed with the first last lines of span of change and the revision number of the change """
        self.start_line = start_line
        self.end_line = end_line

    def __str__(self):
        return "Change( start_line = %d, end_line = %d )"%(self.start_line,self.end_line)

    def is_changed(self, line):
        """ tests to see if a specified line number is changed """
        if line >= self.start_line and line <= self.end_line:
            return True
        else:
            return False

    def is_equal(self, change ):
        """ tests to see if this change is equal in span to another change """
        if self.start_line == change.start_line and self.end_line == change.end_line:
            return True
        else:
            return False

    def is_overlapped(self, change ):
        """ tests to see if this change overlaps another span """
        if (change.start_line < self.start_line and change.end_line >= self.start_line and change.end_line <= self.end_line) or (change.start_line >= self.start_line and change.start_line <= self.end_line and change.end_line > self.end_line):
            return True
        else:
            return False

    def is_adjacent(self, change ):
        """ tests to see if this change is next to another span """
        if (change.end_line == self.start_line-1 or self.end_line == change.start_line-1):
            return True
        else:
            return False

    def is_contained(self, change ):
        """ tests to see if this change completely contains the change """
        if change.start_line >= self.start_line and change.start_line <= self.end_line and change.end_line <= self.end_line and change.end_line >= self.start_line:
            return True
        else:
            return False

class ChangeManager:
    """ manager for a list of changed lines for a given context so we can use it to do minimal redraw """
    def __init__(self):
        """ construct an ChangeManager, no arguments """
        self.change_list = []
        self.views = {}

    def __del__(self):
        self.change_list = None

    def __str__(self):
        if self.change_list:
            return "["+",".join([str(f) for f in self.change_list])+"]"
        else:
            return "[]"

    def add_view(self,view):
        """ adds a new view to this change manager """
        if view not in self.views:
            self.views[view] = self.change_list

    def remove_view(self,view):
        """ removes a view from this change manager """
        if view in self.views:
            del self.views[view]

    def has_changes(self,view):
        """ returns true if there are pending changes """
        if self.views[view]:
            return True
        else:
            return False

    def is_changed(self, view, line ):
        """ returns true if a line is marked as changed at or after the revNo passed """
        if not self.views[view]:
            return False

        for c in self.views[view]:
            if c.is_changed(line):
                return True
        return False

    def flush(self, view):
        """ reset the change list to empty used when the whole page is going to need refresh no matter what """
        self.views[view] = None
        all_none = True
        for v in self.views:
            if self.views[v]:
                all_none = False
                break
        if all_none:
            self.change_list = []

    def changed(self, start_line = 0, end_line = sys.maxsize ):
        """ mark a range of lines as changed or by default mark them all as changed """
        nc = Change(start_line,end_line)
        new_change_list = []
        for c in self.change_list:
            if nc.is_equal(c) or nc.is_contained(c):
                continue
            elif nc.is_adjacent(c):
                if c.start_line < nc.start_line:
                    nc = Change(c.start_line,end_line)
                else:
                    nc = Change(start_line,c.end_line)
            elif nc.is_overlapped( c ):
                if c.start_line < nc.start_line:
                    nc = Change(c.start_line,nc.end_line)
                else:
                    nc = Change(nc.start_line,c.end_line)
            elif c.is_contained(nc):
                nc = Change(c.start_line,c.end_line)
            else:
                new_change_list.append(Change(c.start_line,c.end_line))
        new_change_list.insert(0,nc)
        self.change_list = new_change_list
        for v in self.views:
            self.views[v] = self.change_list

Classes

class Change

Represents one span of lines that have been changed

class Change:
    """ Represents one span of lines that have been changed """
    def __init__(self, start_line = 0, end_line = sys.maxsize):
        """ Constructed with the first last lines of span of change and the revision number of the change """
        self.start_line = start_line
        self.end_line = end_line

    def __str__(self):
        return "Change( start_line = %d, end_line = %d )"%(self.start_line,self.end_line)

    def is_changed(self, line):
        """ tests to see if a specified line number is changed """
        if line >= self.start_line and line <= self.end_line:
            return True
        else:
            return False

    def is_equal(self, change ):
        """ tests to see if this change is equal in span to another change """
        if self.start_line == change.start_line and self.end_line == change.end_line:
            return True
        else:
            return False

    def is_overlapped(self, change ):
        """ tests to see if this change overlaps another span """
        if (change.start_line < self.start_line and change.end_line >= self.start_line and change.end_line <= self.end_line) or (change.start_line >= self.start_line and change.start_line <= self.end_line and change.end_line > self.end_line):
            return True
        else:
            return False

    def is_adjacent(self, change ):
        """ tests to see if this change is next to another span """
        if (change.end_line == self.start_line-1 or self.end_line == change.start_line-1):
            return True
        else:
            return False

    def is_contained(self, change ):
        """ tests to see if this change completely contains the change """
        if change.start_line >= self.start_line and change.start_line <= self.end_line and change.end_line <= self.end_line and change.end_line >= self.start_line:
            return True
        else:
            return False

Ancestors (in MRO)

Static methods

def __init__(

self, start_line=0, end_line=9223372036854775807)

Constructed with the first last lines of span of change and the revision number of the change

def __init__(self, start_line = 0, end_line = sys.maxsize):
    """ Constructed with the first last lines of span of change and the revision number of the change """
    self.start_line = start_line
    self.end_line = end_line

def is_adjacent(

self, change)

tests to see if this change is next to another span

def is_adjacent(self, change ):
    """ tests to see if this change is next to another span """
    if (change.end_line == self.start_line-1 or self.end_line == change.start_line-1):
        return True
    else:
        return False

def is_changed(

self, line)

tests to see if a specified line number is changed

def is_changed(self, line):
    """ tests to see if a specified line number is changed """
    if line >= self.start_line and line <= self.end_line:
        return True
    else:
        return False

def is_contained(

self, change)

tests to see if this change completely contains the change

def is_contained(self, change ):
    """ tests to see if this change completely contains the change """
    if change.start_line >= self.start_line and change.start_line <= self.end_line and change.end_line <= self.end_line and change.end_line >= self.start_line:
        return True
    else:
        return False

def is_equal(

self, change)

tests to see if this change is equal in span to another change

def is_equal(self, change ):
    """ tests to see if this change is equal in span to another change """
    if self.start_line == change.start_line and self.end_line == change.end_line:
        return True
    else:
        return False

def is_overlapped(

self, change)

tests to see if this change overlaps another span

def is_overlapped(self, change ):
    """ tests to see if this change overlaps another span """
    if (change.start_line < self.start_line and change.end_line >= self.start_line and change.end_line <= self.end_line) or (change.start_line >= self.start_line and change.start_line <= self.end_line and change.end_line > self.end_line):
        return True
    else:
        return False

Instance variables

var end_line

var start_line

class ChangeManager

manager for a list of changed lines for a given context so we can use it to do minimal redraw

class ChangeManager:
    """ manager for a list of changed lines for a given context so we can use it to do minimal redraw """
    def __init__(self):
        """ construct an ChangeManager, no arguments """
        self.change_list = []
        self.views = {}

    def __del__(self):
        self.change_list = None

    def __str__(self):
        if self.change_list:
            return "["+",".join([str(f) for f in self.change_list])+"]"
        else:
            return "[]"

    def add_view(self,view):
        """ adds a new view to this change manager """
        if view not in self.views:
            self.views[view] = self.change_list

    def remove_view(self,view):
        """ removes a view from this change manager """
        if view in self.views:
            del self.views[view]

    def has_changes(self,view):
        """ returns true if there are pending changes """
        if self.views[view]:
            return True
        else:
            return False

    def is_changed(self, view, line ):
        """ returns true if a line is marked as changed at or after the revNo passed """
        if not self.views[view]:
            return False

        for c in self.views[view]:
            if c.is_changed(line):
                return True
        return False

    def flush(self, view):
        """ reset the change list to empty used when the whole page is going to need refresh no matter what """
        self.views[view] = None
        all_none = True
        for v in self.views:
            if self.views[v]:
                all_none = False
                break
        if all_none:
            self.change_list = []

    def changed(self, start_line = 0, end_line = sys.maxsize ):
        """ mark a range of lines as changed or by default mark them all as changed """
        nc = Change(start_line,end_line)
        new_change_list = []
        for c in self.change_list:
            if nc.is_equal(c) or nc.is_contained(c):
                continue
            elif nc.is_adjacent(c):
                if c.start_line < nc.start_line:
                    nc = Change(c.start_line,end_line)
                else:
                    nc = Change(start_line,c.end_line)
            elif nc.is_overlapped( c ):
                if c.start_line < nc.start_line:
                    nc = Change(c.start_line,nc.end_line)
                else:
                    nc = Change(nc.start_line,c.end_line)
            elif c.is_contained(nc):
                nc = Change(c.start_line,c.end_line)
            else:
                new_change_list.append(Change(c.start_line,c.end_line))
        new_change_list.insert(0,nc)
        self.change_list = new_change_list
        for v in self.views:
            self.views[v] = self.change_list

Ancestors (in MRO)

Static methods

def __init__(

self)

construct an ChangeManager, no arguments

def __init__(self):
    """ construct an ChangeManager, no arguments """
    self.change_list = []
    self.views = {}

def add_view(

self, view)

adds a new view to this change manager

def add_view(self,view):
    """ adds a new view to this change manager """
    if view not in self.views:
        self.views[view] = self.change_list

def changed(

self, start_line=0, end_line=9223372036854775807)

mark a range of lines as changed or by default mark them all as changed

def changed(self, start_line = 0, end_line = sys.maxsize ):
    """ mark a range of lines as changed or by default mark them all as changed """
    nc = Change(start_line,end_line)
    new_change_list = []
    for c in self.change_list:
        if nc.is_equal(c) or nc.is_contained(c):
            continue
        elif nc.is_adjacent(c):
            if c.start_line < nc.start_line:
                nc = Change(c.start_line,end_line)
            else:
                nc = Change(start_line,c.end_line)
        elif nc.is_overlapped( c ):
            if c.start_line < nc.start_line:
                nc = Change(c.start_line,nc.end_line)
            else:
                nc = Change(nc.start_line,c.end_line)
        elif c.is_contained(nc):
            nc = Change(c.start_line,c.end_line)
        else:
            new_change_list.append(Change(c.start_line,c.end_line))
    new_change_list.insert(0,nc)
    self.change_list = new_change_list
    for v in self.views:
        self.views[v] = self.change_list

def flush(

self, view)

reset the change list to empty used when the whole page is going to need refresh no matter what

def flush(self, view):
    """ reset the change list to empty used when the whole page is going to need refresh no matter what """
    self.views[view] = None
    all_none = True
    for v in self.views:
        if self.views[v]:
            all_none = False
            break
    if all_none:
        self.change_list = []

def has_changes(

self, view)

returns true if there are pending changes

def has_changes(self,view):
    """ returns true if there are pending changes """
    if self.views[view]:
        return True
    else:
        return False

def is_changed(

self, view, line)

returns true if a line is marked as changed at or after the revNo passed

def is_changed(self, view, line ):
    """ returns true if a line is marked as changed at or after the revNo passed """
    if not self.views[view]:
        return False
    for c in self.views[view]:
        if c.is_changed(line):
            return True
    return False

def remove_view(

self, view)

removes a view from this change manager

def remove_view(self,view):
    """ removes a view from this change manager """
    if view in self.views:
        del self.views[view]

Instance variables

var change_list

var views