def upload_chunk(self): done, chunk = self.up.next() for cmd in chunk: cmd = cmd.rstrip() # convert tabs to spaces if TABSIZE > 0: cmd = cmd.expandtabs(TABSIZE) # /send blank does nothing, so send a space if not cmd: cmd = " " # and send it tf.send(cmd, self.world) self.lines_sent += 1 # clean up and finish, or schedule further upload if done: self.done() del self.up else: # show progress if self.progress_size and (self.lines_sent - self.lines_sent0) >= self.progress_size: tf.out( "- diffedit.upload -> %s %s - %4d cmds sent" % \ ( self.world, self.remote, self.lines_sent ) ) self.lines_sent0 = self.lines_sent - (self.lines_sent % self.progress_size) # schedule a callback in 1 second INPROGRESS[self.keyname] = self tf.eval('/repeat -w%s -1 1 /python_call diffedit.__more %s' % (self.world, self.keyname))
def connect(argstr): cmd, opts, argstr = tfutil.cmd_parse(argstr, "lqxfb") opts['b'] = '' if 'f' in opts: del opts['f'] tf.out(tfutil.cmd_unparse("/@connect", opts, argstr)) tf.eval(tfutil.cmd_unparse("/@connect", opts, argstr))
def dischook(argstr): split = argstr.split(None, 1) name = split[0].lower() reason = len(split) > 1 and split[1] or '' if name in WDICT: WDICT[name].disconnect(reason) if reason != 'tf4': tf.out("%% Connection to %s closed." % name) world("-a")
def dump_buffer(self): # clean out buffer, no longer active world if not self.buffer: return for line in self.buffer: tf.out(line) self.buffer = [] global ACTIVITY if self in ACTIVITY: ACTIVITY.remove(self) _activity_status()
def fg(argstr): cmd, opts, argstr = tfutil.cmd_parse(argstr, "ns<>c:|q") if not opts and not argstr: return # no opts, just a world name if not opts: fg = WDICT.get(argstr.lower()) if fg: fg.activate() else: tf.out("%% fg: not connected to '%s'" % argstr) return # handle opts fg = None # easy, just next activity world if 'a' in opts and ACTIVITY: fg = ACTIVITY[0] fg.activate() return # relative movement c = 0 if 'c' in opts: try: c = int(opts['c']) except: c = 1 elif '<' in opts or 'a' in opts: c = -1 elif '>' in opts: c = 1 if c != 0: if WLIST: if FG in WLIST: fg = WLIST[(WLIST.index(FG) + c) % len(WLIST)] else: fg = WLIST[0] else: fg = WDICT[''] elif 'n' in opts: fg = WDICT[''] if fg: fg.activate()
def help(dummy=None): for line in """ diffedit usage: /python_call diffedit.upload (-<lines>) (-r) <editor> <remote> <filename> Uploads minimal commands necessary to turn centents of <remote> into <filename> by diff-ing against the last version. This is per <remote> per world. options: -<lines> If -S or -0, send all commands immediately. Otherwise sends <lines> per second. Default: 50. -r Just upload the entire thing. Useful if you think things might be out of sync, or to start fresh. The first time you edit a <remote> for a specific world -r is implied. -p(<n>) Show progress every <n> lines. Default 100 if -p present. arguments: <editor> Which editor class to upload with. Current choices are: ( lsedit | muf ) <remote> Which 'thing' to upload it to. lsedit: <dbref>=<list name> ex: #1234=mydesc muf: <dbref> ex: #1234 <fname> The filename that contains the content you want on the object. Example: To work on my huge scream.muf progam I use: /python_call diffedit.upload muf -p scream.muf ~/muf/scream.muf Since this would be annoying to type every time I'd really use: /def scream=/python_call diffedit.upload muf -p scream.muf ~/muf/scream.muf so I can just type '/scream' in TF after I make local changes. Other functions: /python_call diffedit.abort Emergency abort all in-progress uploads. /python_call diffedit.lastdir <directory> Set where the diffedit keeps the last known version of each file for a <world>_<remote> to compare new versions against. Default: /tmp/diffedit /python_call diffedit.tabsize 8 Set the tab to space expansion size. 0 means no expansion. Default: 4 /python_call diffedit.lines_per_second 100 Set lines per second to send if no -<size>. Default: 50 """.split("\n"): tf.out(line)
def rx(self, text): global FG, MODE # just accumulate in buffer if MODE == MODE_ON and FG != self: if not self.buffer: tf.out("%% Activity in world %s" % self.name) ACTIVITY.append(self) _activity_status() self.buffer.append(text) return if MODE == MODE_SWITCH: self.activate() elif MODE == MODE_MIX: self.check_last() tf.out(text)
def dc(argstr): argstr = argstr.lower().strip() # do them all if argstr == "-all": for world in WLIST: tf.out("/@dc %s" % world.name) tf.eval("/@dc %s" % world.name) dischook(world.name + " tf4") return # otherwise do foreground world if argstr: world = WDICT.get(argstr) else: world = FG if world: tf.eval("/@dc %s" % world.name) dischook(world.name + " tf4")
def myhelp(): for line in """ /tf4 (ON|mix|switch|off) on: Turns on TinyFugue 4 emulation mode where all world activity is shown in a single world separated by ---- World Foo ---- markers. This is emulated with hooks and scripts, so if your own scripts get too fancy it will break, but it seems to work pretty well with mine. mix: Like 'on', but output in background worlds will be immediately shown (with a divider) so you can just watch the output of all worlds scroll by. However the world does not become the foreground world! Without /visual on you won't really have any indication of what the foreground world is so you won't know where you're sending text. switch: Like 'mix' but immediately switches you to whatever world has output. Obviously this makes it tough to guarantee that any text you're sending will go to the right world unless you do a /send -wfoo text, since it could switch just before you hit enter. off: Turn off TinyFugue 4 emulation mode, revert all your keybindings and macro definitions back to the way they were. """.split("\n"): tf.out(line)
def abort(argstr): tf.out("* diffedit.abort - aborting all in progress uploads") global INPROGRESS INPROGRESS = {}
def debug(str): global ECHO if ECHO: tf.out("::::: DEBUG ::::: %s" % str)
def divider(self): # show divider if self.name: tf.out("---- World %s ----" % self.name) else: tf.out("---- No world ----")
def tf4(argstr): # Create a new base state if we don't have one state = getstate() # Just parse the command global MODE argstr = argstr.lower() if not argstr or 'on' in argstr: newmode = MODE_ON elif 'help' in argstr: return myhelp() elif 'off' in argstr: newmode = MODE_OFF elif 'mix' in argstr: newmode = MODE_MIX elif 'switch' in argstr: newmode = MODE_SWITCH else: return myhelp() # Now do what we need to if newmode == MODE_OFF: if newmode != MODE: state.revert() tf.eval("/dc _tf4") tf.eval("/unworld _tf4") sockets = tfutil.listsockets() for name in sockets: tf.eval("/@fg -q " + name) MODE = MODE_OFF tf.out("% tf4 mode is now off. '/tf4' to re-enable it") return if MODE == MODE_OFF: # Create a virtual world to hold our text sockets = tfutil.listsockets() if not "_tf4" in sockets: tf.eval("/addworld _tf4") tf.eval("/connect _tf4") # We want background processing and triggers state.setvar('background', 'on') state.setvar('bg_output', 'off') state.setvar('borg', 'on') state.setvar('gag', 'on') state.setvar('hook', 'on') # change the status bar state.setvar('_tf4world', tf.eval('/test fg_world()')) state.setvar('_tf4activity', '') state.status("rm @world") state.status("add -A@more _tf4world") state.status("rm @active") state.status("add -A@read _tf4activity:11") # Grab text from any world except our dummy world - we use a regexp instead of a glob # because the glob does not preserve the spacing state.define(flags="-p99999 -w_tf4 -ag -mglob -t*") state.define(body="/python_call tf4.rx $[world_info()] %P1", flags="-Fpmaxpri -q -mregexp -t(.*)") # add a trigger for anything being sent to the generic world, so we can reroute # it to the right world state.define(body="/python_call tf4.tx %{*}", flags="-pmaxpri -w_tf4 -hSEND") # Add our hooks state.define(body="/python_call tf4.dischook %{*}", flags="-Fpmaxpri -ag -msimple -hDISCONNECT") state.define(body="/python_call tf4.conhook %{*}", flags="-Fpmaxpri -ag -msimple -hCONNECT") state.define( body="/python_call tf4.otherhook %{*}", flags='-p999 -ag -msimple -hCONFAIL|ICONFAIL|PENDING|DISCONNECT' ) state.define(body="", flags="-pmaxpri -ag -msimple -hBGTRIG") state.define(body="", flags="-pmaxpri -ag -msimple -hACTIVITY") # Bind Esc-b, Esc-f to call us instead state.bind(key="^[b", body="/python_call tf4.fg -<", flags="i") state.bind(key="^[f", body="/python_call tf4.fg ->", flags="i") state.bind(key="^[w", body="/python_call tf4.fg -a", flags="i") # def these commands to go to us state.define("bg", "/python_call tf4.fg -n") state.define("connect", "/python_call tf4.connect %{*}") state.define("dc", "/python_call tf4.dc") state.define("fg", "/python_call tf4.fg %{*}") state.define("quit", "/python_call tf4.quit ${*}") state.define("recall", "/python_call tf4.recall %{*}") state.define("to_active_or_prev_world", "/python_call tf4.fg -a") state.define("to_active_world", "/python_call tf4.fg -a") # close enough state.define("world", "/python_call tf4.world %{*}") MODE = newmode if newmode == MODE_SWITCH: tf.out("% TinyFugue 4 emulation mode with autoswitch to output world.") elif newmode == MODE_MIX: tf.out("% TinyFugue 4 emulation mode with background output shown.") else: tf.out("% TinyFugue 4 emulation mode is on.") tf.out("% '/tf4 off' to disable, '/tf4 help' for help.")
def otherhook(argstr): tf.out(argstr)
if not written: written = _save_worlds2(fout, wdict) continue # write, converting line endings fout.write(line) fin.close() # write all the worlds to the end of the file if haven't done it yet if not written: written = _save_worlds2(fout, wdict) fout.close() # move the new file over the old one os.rename(fin.name, fin.name + ".bak") os.rename(fout.name, fin.name) tf.out("- saved /worlds to %s" % fin.name) return True, None # This is the real worlds function, invoked by curses safety wrapper def _worlds(stdscr): # get dictionary of current worlds wdict = tfutil.listworlds(asdict=True) cols, lines = tfutil.screensize() colors = curses.can_change_color() # Draw the border and create a world window stdscr.clear()
# def these commands to go to us state.define("bg", "/python_call tf4.fg -n") state.define("connect", "/python_call tf4.connect %{*}") state.define("dc", "/python_call tf4.dc") state.define("fg", "/python_call tf4.fg %{*}") state.define("quit", "/python_call tf4.quit ${*}") state.define("recall", "/python_call tf4.recall %{*}") state.define("to_active_or_prev_world", "/python_call tf4.fg -a") state.define("to_active_world", "/python_call tf4.fg -a") # close enough state.define("world", "/python_call tf4.world %{*}") MODE = newmode if newmode == MODE_SWITCH: tf.out("% TinyFugue 4 emulation mode with autoswitch to output world.") elif newmode == MODE_MIX: tf.out("% TinyFugue 4 emulation mode with background output shown.") else: tf.out("% TinyFugue 4 emulation mode is on.") tf.out("% '/tf4 off' to disable, '/tf4 help' for help.") # ------------------------------------- # When first loaded # ------------------------------------- # register ourself state = getstate() state.define(name="tf4", body="/python_call tf4.tf4 %*", flags="-q") tf.out("% '/tf4 help' for how to invoke TinyFugue 4 emulation mode.")