From d4a7f6fbc97e883adb476845a4d1a60ad0fb46cb Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sun, 2 Aug 2020 13:09:05 -0400 Subject: [PATCH] Implement clipboard --- ansi_cython.pyx | 3 +++ scripting.py | 38 ++++++++++++++++++++++---------------- tpers.py | 13 +++++++++++++ 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/ansi_cython.pyx b/ansi_cython.pyx index 37e4756..136b255 100644 --- a/ansi_cython.pyx +++ b/ansi_cython.pyx @@ -61,6 +61,9 @@ K_END = 261 K_PGUP = 262 K_PGDN = 263 +def K_CTRL(ch): + return chr(ord(ch.upper()) - ord('@')) + def StrKey(ch): if type(ch) == str: return ord(ch) diff --git a/scripting.py b/scripting.py index 9e86fd5..9b97166 100644 --- a/scripting.py +++ b/scripting.py @@ -189,7 +189,7 @@ class Synt(Typeable): return cls() def WithParent(self, syntParent): - assert self.syntParent == None + assert self.syntParent == None or syntParent == None self.syntParent = syntParent return self @@ -344,7 +344,7 @@ class SyntBlock(Synt): with pcur.Indent(2 if pcur.pwHoriz != None else 0): pcur.EndLine() def OnInsertNewLine(syntAfter, psel): - self.InsertLineAfter(syntAfter) + self.InsertLineAt(0) psel.Inc(pcur.Reset().Project().pwVert) PwButtonHidden(pcur.pwVert, "[insert new line]", None, OnInsertNewLine, pcur.dxindent) for syntLine in self.rgsynt: @@ -355,29 +355,34 @@ class SyntBlock(Synt): def StypeForChild(self, syntChild): return StypeStmt() - def InsertLineAfter(self, syntAfter): - syntStmt = SyntHole() - if syntAfter == None: - self.rgsynt.insert(0, syntStmt) - else: - self.rgsynt.insert(self.rgsynt.index(syntAfter) + 1, syntStmt) - syntStmt.syntParent = self + def InsertLineAt(self, isynt, syntStmt = None): + if syntStmt == None: + syntStmt = SyntHole() + syntStmt = syntStmt.WithParent(self) + self.rgsynt.insert(isynt, syntStmt) return syntStmt - def RemoveLine(self, synt): + def RemoveLine(self, synt, psel): + psel.syntClipboard = synt.WithParent(None) self.rgsynt.remove(synt) def HandleKey(self, pwKey, pov, psel, key): if ansi.FEnter(key): - self.InsertLineAfter(pwKey.pwChild.Value()) + isyntInsert = self.rgsynt.index(pwKey.pwChild.Value()) + 1 + self.InsertLineAt(isyntInsert) clevelVert = psel.CLevelChild(pwKey.PwParent()) pwVert = psel.PwSelected(pov.PwProjected(), clevelVert - 1) psel.Inc(pwVert) - return True - elif key == ansi.K_DEL and pwKey.pwChild.RgpwChild()[0] == psel.PwSelected(pwKey): - self.RemoveLine(pwKey.pwChild.Value()) - return True - return False + elif (key == ansi.K_DEL or key == ansi.K_CTRL('x')) and pwKey.pwChild.RgpwChild()[0] == psel.PwSelected(pwKey): + self.RemoveLine(pwKey.pwChild.Value(), psel) + elif key == ansi.K_CTRL('c') and pwKey.pwChild.RgpwChild()[0] == psel.PwSelected(pwKey): + psel.syntClipboard = synt.DeepClone().WithParent(None) + elif key == ansi.K_CTRL('v') and psel.syntClipboard: + isyntInsert = self.rgsynt.index(pwKey.pwChild.Value()) + self.InsertLineAt(isyntInsert, psel.syntClipboard.DeepClone()) + else: + return False + return True def Eval(self, env): for synt in self.rgsynt: @@ -860,6 +865,7 @@ class Psel(TPrs): assert len(pw.RgpwChild()) == 0 #leaf self.rgo_ipw = self.Rgo_ipwFromPw(pw) self.ksel = ksel + self.syntClipboard = None def Rgo_ipwFromPw(self, pw): rgo_ipw = [] diff --git a/tpers.py b/tpers.py index f40a7d9..6fda45e 100644 --- a/tpers.py +++ b/tpers.py @@ -84,6 +84,9 @@ class TPrs(object): def UpgradeFrom(self, versionOld): pass + def DeepClone(self): + return Odb.DeepClone(self) + def __getattr__(self, key): stPersistent = "no persistent yet" if key != "_persistent": @@ -162,6 +165,16 @@ class Odb(object): cls.rgtprsToUpgrade = None cls.rgtprsToInit = None return tprs + + @classmethod + def DeepClone(cls, tprs): + cls.rgtprsToInit = [] + clone = cPickle.loads(cPickle.dumps(tprs)) + for tprsToInit in cls.rgtprsToInit: + with tprsToInit.SetTransiently(): + tprsToInit.InitTransient() + cls.rgtprsToInit = None + return clone clsList = list clsDict = dict