''' This file is execfile()'d with a namespace containing: D - the Joy dictionary d - the Display object pt - the PersistTask object log - the log.txt viewer loop - the TheLoop main loop object stack_holder - the Python list object that holds the Joy stack tuple world - the Joy environment ''' from joy.library import ( DefinitionWrapper, FunctionWrapper, SimpleFunctionWrapper, ) from joy.utils.stack import list_to_stack, concat from joy.vui import core, text_viewer, stack_viewer def install(command): D[command.name] = command @install @SimpleFunctionWrapper def list_resources(stack): ''' Put a string on the stack with the names of all the known resources one-per-line. ''' return '\n'.join(pt.scan()), stack @install @SimpleFunctionWrapper def open_stack(stack): ''' Given a coordinate pair [x y] (in pixels) open a StackViewer there. ''' (x, (y, _)), stack = stack V = d.open_viewer(x, y, stack_viewer.StackViewer) V.draw() return stack @install @SimpleFunctionWrapper def open_resource(stack): ''' Given a coordinate pair [x y] (in pixels) and the name of a resource (from list_resources command) open a viewer on that resource at that location. ''' ((x, (y, _)), (name, stack)) = stack om = core.OpenMessage(world, name) d.broadcast(om) if om.status == core.SUCCESS: V = d.open_viewer(x, y, text_viewer.TextViewer) V.content_id, V.lines = om.content_id, om.thing V.draw() return stack @install @SimpleFunctionWrapper def name_viewer(stack): ''' Given a string name on the stack, if the currently focused viewer is anonymous, name the viewer and persist it in the resource store under that name. ''' name, stack = stack assert isinstance(name, str), repr(name) if d.focused_viewer and not d.focused_viewer.content_id: d.focused_viewer.content_id = name pm = core.PersistMessage(world, name, thing=d.focused_viewer.lines) d.broadcast(pm) d.focused_viewer.draw_menu() return stack ##@install ##@SimpleFunctionWrapper ##def persist_viewer(stack): ## if self.focused_viewer: ## ## self.focused_viewer.content_id = name ## self.focused_viewer.draw_menu() ## return stack @install @SimpleFunctionWrapper def inscribe(stack): ''' Create a new Joy function definition in the Joy dictionary. A definition is given as a string with a name followed by a double equal sign then one or more Joy functions, the body. for example: sqr == dup mul If you want the definition to persist over restarts, enter it into the definitions.txt resource. ''' definition, stack = stack DefinitionWrapper.add_def(definition, D) return stack @install @SimpleFunctionWrapper def open_viewer(stack): ''' Given a coordinate pair [x y] (in pixels) and a string, open a new unnamed viewer on that string at that location. ''' ((x, (y, _)), (content, stack)) = stack V = d.open_viewer(x, y, text_viewer.TextViewer) V.lines = content.splitlines() V.draw() return stack @install @SimpleFunctionWrapper def good_viewer_location(stack): ''' Leave a coordinate pair [x y] (in pixels) on the stack that would be a good location at which to open a new viewer. (The heuristic employed is to take up the bottom half of the currently open viewer with the greatest area.) ''' viewers = list(d.iter_viewers()) if viewers: viewers.sort(key=lambda (V, x, y): V.w * V.h) V, x, y = viewers[-1] coords = (x + 1, (y + V.h / 2, ())) else: coords = (0, (0, ())) return coords, stack @install @FunctionWrapper def cmp_(stack, expression, dictionary): ''' The cmp combinator takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values: a b [G] [E] [L] cmp ------------------------- a > b G a b [G] [E] [L] cmp ------------------------- a = b E a b [G] [E] [L] cmp ------------------------- a < b L ''' L, (E, (G, (b, (a, stack)))) = stack expression = concat(G if a > b else L if a < b else E, expression) return stack, expression, dictionary @install @SimpleFunctionWrapper def list_viewers(stack): ''' Put a string on the stack with some information about the currently open viewers, one-per-line. This is kind of a demo function, rather than something really useful. ''' lines = [] for x, T in d.tracks: #lines.append('x: %i, w: %i, %r' % (x, T.w, T)) for y, V in T.viewers: lines.append('x: %i y: %i h: %i %r %r' % (x, y, V.h, V.content_id, V)) return '\n'.join(lines), stack @install @SimpleFunctionWrapper def splitlines(stack): ''' Given a string on the stack replace it with a list of the lines in the string. ''' text, stack = stack assert isinstance(text, str), repr(text) return list_to_stack(text.splitlines()), stack @install @SimpleFunctionWrapper def hiya(stack): ''' Demo function to insert "Hi World!" into the current viewer, if any. ''' if d.focused_viewer: d.focused_viewer.insert('Hi World!') return stack