// Emacs Widget library bindings for SCLang EmacsBuffer { // Represents an Emacs buffer classvar all; var onClose, action; *new {|buffer, tag| ^super.new(buffer, 'push-button', ':tag', tag, ':action', [\lambda, [\widget, \event], ['sclang-eval-string', ['sclang-format', "EmacsWidget.idmap[%o].action.value", ['widget-get', \widget, ':id']]]]) } } EmacsEditableField : EmacsWidget { var <>action; *new {|buffer, tag, value=""| ^super.new(buffer, 'editable-field', ':tag', tag, ':format', "%{%t%}: %v", ':action', [\lambda, [\widget, \event], ['sclang-eval-string', ['sclang-format', "EmacsWidget.idmap[%o].action.value(%o)", ['widget-get', \widget, ':id'], ['widget-value', \widget]]]], value) } } EmacsNumber : EmacsWidget { var <>action, <>spec, ', \val, ['widget-get', \widget, ':max']], [\error, "Too much"]], [['<', \val, ['widget-get', \widget, ':min']], [\error, "Too less"]], [\t, ['sclang-eval-string', ['sclang-format', "EmacsWidget.idmap[%o].valueFromEmacs(%o)", ['widget-get', \widget, ':id'], \val]]]]]], value).action_(action).spec_(spec).initValue(value) } valueFromEmacs {|argValue| value = argValue; action.value(value) } value_ {|argValue| Emacs.evalLispExpression( buffer.use( ['save-excursion', ['widget-value-set', [\cdr, [\find, id, 'sclang-widgets', ':key', [\quote, \car]]], argValue], ['widget-setup']], argValue).asLispString, {|result|value=result}) } initValue {|argValue|value=argValue} } EmacsButton : EmacsWidget { var <>action, ', \size, [\length, \string]], [\cond, [[\eq, \align, [\quote, \left]], [\concat, \string, ['make-string', ['-', \size, [\length, \string]], $ ]]], [[\eq, \align, [\quote, \right]], [\concat, ['make-string', ['-', \size, [\length, \string]], $ ], \string]], [[\eq, \align, [\quote, \center]], [\let, [[\half, ['/', ['-', \size, [\length, \string]], 2]]], [\if, ['=', ['+', [\length, \string], ['*', \half, 2]], \size], [\concat, ['make-string', \half, $ ], \string, ['make-string', \half, $ ]], [\concat, ['make-string', \half, $ ], \string, ['make-string', \half, $ ], " "]]]]]]]]]], string).initValue(size?string.size,align,string) } string_ {|argString| string = argString.asString; this.wValueSet(string); } size_ {|argSize| this.wPut(\size, size=argSize, {this.wValueSet(string)}) } align_ {|argAlign| this.wPut(\align, align=argAlign, {this.wValueSet(string)}) } initValue {|argSize,argAlign,argValue|size=argSize;align=argAlign;string=argValue} } EmacsClassTree : EmacsWidget { *new {|buffer, className, open=true| ^super.new(buffer, 'sclang-class-tree', ':tag', className.asString, ':open', if(open){\t}{\nil}, ':node', [\quote, ['sclang-file-position', ':filename', className.asSymbol.asClass.filenameSymbol.asString, ':char-pos', className.asSymbol.asClass.charPos+1, ':tag', className.asString]]) } *dynargs {|className| var class; class = className.asSymbol.asClass; ^(class.subclasses.asArray.copy.sort{|a,b|a.name <= b.name}.collect{|sc| ['sclang-class-tree', ':tag', sc.name.asString, ':node', ['sclang-file-position', ':filename', sc.filenameSymbol.asString, ':char-pos', sc.charPos+1, ':tag', sc.name.asString]]}) ++ (class.class.methods.asArray.copy.sort({|a,b| a.name <= b.name }).collect{|m| ['sclang-file-position', ':filename', m.filenameSymbol.asString, ':char-pos', m.charPos+1, ':tag', "*"++m.name.asString]}) ++ (class.methods.asArray.copy.sort({|a,b| a.name <= b.name }).collect{|m| ['sclang-file-position', ':filename', m.filenameSymbol.asString, ':char-pos', m.charPos+1, ':tag', m.name.asString]}) } } EmacsClassBrowser { var w, classTree; *new {|class| ^super.newCopyArgs(EmacsBuffer("*"++class.asClass.name++"*")).init(class); } init {|class| classTree=EmacsClassTree(w, class); w.gotoBob.front; } }