Module: command-lines Synopsis: The commands provided by the environment Author: Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Properties define open abstract class () sealed constant slot command-info-type :: false-or() = #f, init-keyword: type:; sealed constant slot command-info-persistent? :: = #f, init-keyword: persistent?:; end class ; define method parameter-type-name (type == ) => (name :: ) "property" end method parameter-type-name; define open generic ensure-property-available (context :: , property :: ) => (); define open generic show-property (context :: , property :: ) => (); define open generic set-property (context :: , property :: , value :: , #key save?) => (); define macro command-property-definer { define command-property ?name:name => ?class:name (?options:*) end } => { define constant "$" ## ?name ## "-command-property" = make(?class, ?options, name: ?#"name", title: as-uppercase(?"name")) } end macro command-property-definer; define method ensure-property-available (context :: , property :: ) => () #f end method ensure-property-available; define function find-named-property (context :: , name :: ) => (property :: ) let group = context.context-command-group; let property = find-command-info(group, name, type: ); property | command-error("No such property '%s'", name) end function find-named-property; define function show-named-property (context :: , name :: ) => () let property = find-named-property(context, name); ensure-property-available(context, property); show-property(context, property) end function show-named-property; define function set-named-property (context :: , name :: , value :: , #key save?) => () let property = find-named-property(context, name); ensure-property-available(context, property); set-property(context, property, value, save?: save?) end function set-named-property; /// Properties define class () end class ; define command-property properties => (summary: "Command-line properties", documentation: "The set of command-line properties.") end command-property properties; define method show-property (context :: , property :: ) => () let group = context.context-command-group; let stream = context.context-server.server-output-stream; let properties = collect-command-info(group, ); print-command-info(stream, properties) end method show-property; /// Commands define class () end class ; define command-property commands => (summary: "Command-line commands", documentation: "The set of commands.") end command-property commands; define method show-property (context :: , property :: ) => () let group = context.context-command-group; let stream = context.context-server.server-output-stream; let commands = collect-command-info(group, ); print-command-info(stream, commands) end method show-property; /// Errors define class (, ) end class ; define method set-error (format-string :: , #rest format-arguments) error(make(, format-string: format-string, format-arguments: format-arguments)) end method set-error; /// Property commands define class () constant slot %property :: , required-init-keyword: property:; end class ; define command-line show => (summary: "shows the specified property", documentation: "Shows the specified property.") argument property :: = "the property to show"; end command-line show; define class () constant slot %property :: , required-init-keyword: property:; constant slot %value :: , required-init-keyword: value:; constant slot %save? :: = #f, init-keyword: save?:; end class ; define command-line set => (summary: "sets the specified property", documentation: "Sets the specified property to a given value.") argument property :: = "the property to set"; argument value :: = "the value to set it to"; flag save = "save the new setting persistently [off by default]"; end command-line set; define sealed method do-execute-command (context :: , command :: ) => () let property = command.%property; ensure-property-available(context, property); show-property(context, property) end method do-execute-command; define method context-property-setter (value :: , context :: , property :: , #key save?) => (value :: ) ensure-property-available(context, property); set-property(context, property, value, save?: save?); show-property(context, property); value end method context-property-setter; define method context-named-property-setter (value :: , context :: , name :: , #key save?) => (value :: ) let property = find-named-property(context, name); context-property(context, property, save?: save?) := value end method context-named-property-setter; define sealed method do-execute-command (context :: , command :: ) => () let property = command.%property; ensure-property-available(context, property); let type = property.command-info-type; if (type) let value-string = command.%value; let save? = command.%save?; block (return) let value = block () parse-next-argument(context, type, value-string); exception (error :: ) display-command-line-server-error(context, error); return(); end; block () if (save? & ~property.command-info-persistent?) message(context, "Setting value, but property cannot be saved") end; context-property(context, property, save?: save?) := value exception (error :: ) message(context, "%s", error) end end else command-error("Property '%s' cannot be changed", property.command-info-title) end end method do-execute-command; /// Property commands define command-group property (summary: "property handling commands", documentation: "Commands to manipulate properties.") property properties; property commands; command set; command show; end command-group property;