Ver código fonte

Add `'context_swap'` in place of display hiding

Display hiding only allowed one alternative set of display values,
context swap now allows multiple and also links displays and prompts
together as sets. Less stuff for the shell to do manually.
Weiyi Lou 10 anos atrás
pai
commit
24e8b1ad12
2 arquivos alterados com 59 adições e 43 exclusões
  1. 7 10
      js/pgsh.js
  2. 52 33
      tags/terminal.tag

+ 7 - 10
js/pgsh.js

@@ -19,12 +19,13 @@ function pgsh(ev) {
 
   this.prompt = '<span style="color:blueviolet">pgs </span>' +
     '<span style="color:green">$ </span>'
-  var welc = 'Linux parsleygardens.net 3.4.5-6-7-i286 #8 PGS Vimputer ' +
+  this.prompt_su = '<span style="color:tomato">root </span>' +
+    '<span style="color:red">% </span>'
+  this.welcome = 'Linux parsleygardens.net 3.4.5-6-7-i286 #8 PGS Vimputer ' +
     '3.4.56-7 i286\n\n' +
     '~ Welcome to Parsley Gardens! ~\n' +
     '"He maketh me to lie down in green pa..."\n\n' +
     'Type `help` for list of commands\n\n'
-  this.welcome = welc
   this.commands = {
     'about': {
       'help': 'Author Information\nUsage: about',
@@ -97,9 +98,7 @@ function pgsh(ev) {
               '    #3) With great power comes great\n\n'
             show(wa)
           }
-          var p = '<span style="color:tomato">root </span>'
-          p += '<span style="color:red">% </span>'
-          ev.trigger('prompt_set', p)
+          ev.trigger('prompt_set', self.prompt_su)
         }
       }
     },
@@ -132,15 +131,13 @@ function pgsh(ev) {
       'run': function(args) {
         if (!self.active) {
           self.active = 'questions'
-          ev.trigger('disp_hide')
-          ev.trigger('prompt_hide')
-          show('Welcome to the questions. Do you want to continue?')
+          ev.trigger('context_swap', 'questions')
+          ev.trigger('disp_set', 'Welcome to the questions. Do you want to continue?')
           return
         }
         if (args == 'exit') {
           self.active = ''
-          ev.trigger('disp_restore')
-          ev.trigger('prompt_show')
+          ev.trigger('context_swap')
           show('Thanks for answering questions!')
           return
         }

+ 52 - 33
tags/terminal.tag

@@ -49,16 +49,26 @@
  *        })
  *     }
  *
- * The observable also provides events to make things happen:
- *
- *     events.trigger('disp_add', text)   // Append `text` to the display
- *     events.trigger('disp_set', text)   // Display only `text`
- *     events.trigger('disp_clear')       // Clear the display
- *     events.trigger('disp_hide')        // Save the display, then clear it
- *     events.trigger('disp_restore')     // Restore the saved display
- *     events.trigger('prompt_set', text) // Change the command prompt to `text`
- *     events.trigger('prompt_hide')      // Hide the command prompt
- *     events.trigger('prompt_show')      // Show the command prompt
+ * ### Events
+ *
+ * The observable provides events to make things happen:
+ *
+ *     events.trigger('disp_add', text)      // Append `text` to the display
+ *     events.trigger('disp_set', text)      // Display only `text`
+ *     events.trigger('disp_clear')          // Clear the display
+ *     events.trigger('prompt_set', text)    // Change the prompt to `text`
+ *     events.trigger('prompt_hide')         // Hide the command prompt
+ *     events.trigger('prompt_show')         // Show the command prompt
+ *
+ * There is also an event to swap between sets of displays and prompts:
+ *
+ *     events.trigger('context_swap', name)
+ *
+ * The starting context name is `'default'`. Calling `'context_swap'` with:
+ *
+ * - a new name initialises a new, empty set.
+ * - an existing name loads that set.
+ * - no name returns to the `'default'` set.
  */
 <terminal>
   <display welcome={ welcome } events={ this } />
@@ -84,7 +94,8 @@
 
   var ev = opts.events
   var self = this
-  this.output = []
+  this.contexts = {}
+  this.output = this.contexts['default'] = []
 
   this.on('mount', function() {
     this.add(opts.welcome)
@@ -105,17 +116,13 @@
     self.clear()
   })
 
-  ev.on('disp_hide', function() {
-    self.saved = self.output.splice(0, self.output.length)
-    self.clear()
-  })
-
-  ev.on('disp_restore', function() {
-    if (self.saved.length > 0) {
-      self.clear()
-      self.output = self.saved.splice(0, self.saved.length)
-      self.update()
+  ev.on('context_swap', function(name) {
+    name = name || 'default'
+    if (!(name in self.contexts)) {
+      self.contexts[name] = []
     }
+    self.update({ output: [] }) // Cleanly disassociate current output first.
+    self.update({ output: self.contexts[name] })
   })
 
   add(text) {
@@ -134,7 +141,8 @@
 
 <commandline>
   <form autocomplete='off' onsubmit={ process }>
-    <raw name='lhs' content={ prompt } show={ visible } /><input type='text' name='command' />
+    <raw name='lhs' content={ prompt.text } show={ prompt.visible }>
+    </raw><input type='text' name='command' />
   </form>
 
   <style>
@@ -151,35 +159,46 @@
 
   var ev = opts.events
   var self = this
-  this.prompt = opts.prompt || '$ '
-  this.visible = true
+  this.contexts = {}
+  this.prompt = this.contexts['default'] = {
+    text: opts.prompt || '$ ',
+    visible: true
+  }
 
   this.on('mount', function() {
-    document.getElementsByName('command')[0].focus()
+    this.command.focus()
   })
 
   ev.on('prompt_set', function(value) {
-    self.prompt = value
+    self.prompt.text = value
     self.tags.lhs.write(value)
   })
 
   ev.on('prompt_hide', function() {
-    self.update({ visible: false })
+    self.prompt.visible = false
   })
 
   ev.on('prompt_show', function() {
-    self.update({ visible: true })
+    self.prompt.visible = true
+  })
+
+  ev.on('context_swap', function(name) {
+    name = name || 'default'
+    if (!(name in self.contexts)) {
+      self.contexts[name] = { text: '', visible: true }
+    }
+    self.prompt = self.contexts[name]
+    self.tags.lhs.write(self.prompt.text)
   })
 
   process() {
-    var prompt = this.visible ? this.prompt : ''
+    var prompt = this.prompt.visible ? this.prompt.text : ''
     var command = this.encode(this.command.value)
-    this.command.value = ''
     ev.trigger('disp_add', prompt + command + '\n')
     ev.trigger('cmd_entered', command)
-    // Refocus on the command input to scroll the display and keep it in view.
+    this.command.value = ''
     this.command.blur()
-    this.command.focus()
+    this.command.focus() // Refocus to scroll display and keep input in view.
   }
 
   encode(text) {
@@ -194,7 +213,7 @@
     raw { white-space: pre-wrap }
   </style>
 
-  // Set the initial html using the `content` option.
+  // Set initial html using `content` option, and...
   this.on('mount', function() {
     this.write(opts.content)
   })