Advertisement
snake5

SGScript | console + autocomplete

Apr 24th, 2014
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. include "string", "re", "math";
  3.  
  4.  
  5. function ConUtil_MatchRank( word, comp )
  6. {
  7.     comp = re_replace( comp, "#[^a-zA-Z-]#", "" );
  8.     rcomp = string_explode( comp, "" );
  9.     rcomp = "#" $ string_implode( rcomp, ".*?" ) $ "#i";
  10.     if( re_match( word, rcomp ) )
  11.     {
  12.         length_rank = 1 / word.length;
  13.         return 1 + length_rank;
  14.     }
  15.     return 0;
  16. }
  17.  
  18. function ConUtil_ArgUnpack( params, argc )
  19. {
  20.     params = array_filter( string_explode( params, " " ) );
  21.     params.resize( argc );
  22.     return params;
  23. }
  24.  
  25.  
  26. global Console =
  27. {
  28.     CR = 13,
  29.     BS = 8,
  30.     SC_PREVIOUS = 1,
  31.     SC_NEXT = 2,
  32.     SC_FINISH = 3,
  33. };
  34.  
  35. function Console.create()
  36. {
  37.     data =
  38.     {
  39.         commands = {},
  40.         buffer = [],
  41.         autocomplete = [],
  42.         history = [],
  43.         history_index = 0,
  44.         history_limit = 50,
  45.     };
  46.     con = class( data, Console );
  47.     con.add_commands
  48.     ({
  49.         "list" = function()use(con){ con.list_commands(); },
  50.     });
  51.     return con;
  52. }
  53.  
  54. function Console.add_commands( cmds )
  55. {
  56.     this.commands = get_merged( this.commands, cmds );
  57. }
  58.  
  59. function Console.list_commands()
  60. {
  61.     foreach( cmd ,: this.commands )
  62.     {
  63.         Console.print( cmd );
  64.     }
  65. }
  66.  
  67. function Console.print( text )
  68. {
  69.     println( text );
  70. }
  71.  
  72. function Console.commit()
  73. {
  74.     if( this.history_index )
  75.         cmd = this.history[ this.history.size + this.history_index ];
  76.     else
  77.     {
  78.         cmd = string_utf8_encode( this.buffer );
  79.         if( this.autocomplete.size )
  80.             cmd = this.ac_apply();
  81.     }
  82.    
  83.     if( !cmd.length )
  84.         return;
  85.    
  86.     while( this.history.size > this.history_limit )
  87.         this.history.shift();
  88.     if( this.history.size == 0 || this.history.last != cmd )
  89.         this.history.push( string_trim( cmd ) );
  90.    
  91.     split = string_explode( cmd, " " );
  92.     action = split.shift();
  93.     params = string_implode( split, " " );
  94.     if( isset( this.commands, action ) )
  95.     {
  96.         Console.print( "> " $ cmd );
  97.         this.commands[ action ]( params, this, cmd );
  98.     }
  99.     else
  100.     {
  101.         Console.print( "Command '"$action$"' was not found" );
  102.     }
  103.    
  104.     this.buffer.clear();
  105.     this.autocomplete.clear();
  106.     this.history_index = 0;
  107. }
  108.  
  109. function Console.ac_apply( nosp )
  110. {
  111.     id = this.history_index;
  112.     if( id < 0 )
  113.     {
  114.         cmd = this.history[ this.history.size + id ];
  115.         this.buffer = string_utf8_decode( cmd );
  116.         this.history_index = 0;
  117.         this.ac_update( true );
  118.         return cmd;
  119.     }
  120.    
  121.     if( id < 1 )
  122.         id = 1;
  123.    
  124.     cmd = string_utf8_encode( this.buffer );
  125.     if( this.autocomplete.size == 0 )
  126.         return cmd;
  127.    
  128.     cmd = string_trim( cmd, " ", STRING_TRIM_LEFT );
  129.     split = string_explode( cmd, " " );
  130.     split[ 0 ] = this.autocomplete[ id - 1 ];
  131.     cmd = string_implode( split, " " );
  132.    
  133.     this.buffer = string_utf8_decode( if( nosp, cmd, cmd $ " " ) );
  134.    
  135.     this.history_index = 0;
  136.     this.ac_update();
  137.     return cmd;
  138. }
  139.  
  140. function Console.ac_update( restart )
  141. {
  142.     if( restart )
  143.         this.autocomplete = get_keys( this.commands );
  144.    
  145.     cmd = string_explode( string_trim( string_utf8_encode( this.buffer ) ), " " )[0];
  146.     ranking = [];
  147.     foreach( acid, item : this.autocomplete )
  148.     {
  149.         rank = ConUtil_MatchRank( item, cmd );
  150.         if( !rank )
  151.             this.autocomplete[ acid ] = null;
  152.         ranking.push( rank );
  153.     }
  154. //  printvar(this.autocomplete,ranking);
  155.     this.autocomplete.sort_mapped( ranking, true );
  156.    
  157.     this.autocomplete = array_filter( this.autocomplete );
  158. }
  159.  
  160. function Console.char_event( code )
  161. {
  162.     if( code == 0 ) ; // invalid code, ignore
  163.     else if( code == Console.BS )
  164.     {
  165.         if( this.history_index != 0 )
  166.             this.ac_apply( true );
  167.         if( this.buffer.size > 0 )
  168.             this.buffer.pop();
  169.         if( this.buffer.size == 0 )
  170.             this.autocomplete.clear();
  171.         else
  172.             this.ac_update( true );
  173.     }
  174.     else if( code == Console.CR )
  175.     {
  176.         this.ac_apply();
  177.         this.commit();
  178.     }
  179.     else
  180.     {
  181.         if( this.history_index != 0 )
  182.             this.ac_apply( true );
  183.         this.buffer.push( code );
  184.         this.ac_update( this.buffer.size == 1 );
  185.     }
  186. }
  187.  
  188. function Console.special_event( which )
  189. {
  190.     if( which == Console.SC_PREVIOUS )
  191.     {
  192.         this.history_index--;
  193.         if( -this.history_index > this.history.size )
  194.             this.history_index = -this.history.size;
  195.         if( !this.history_index )
  196.             this.autocomplete.clear();
  197.     }
  198.     else if( which == Console.SC_NEXT )
  199.     {
  200.         this.history_index++;
  201.         if( this.history_index > this.autocomplete.size )
  202.             this.history_index = this.autocomplete.size;
  203.         if( !this.history_index )
  204.             this.ac_update( true );
  205.     }
  206.     else if( which == Console.SC_FINISH )
  207.     {
  208.         if( this.autocomplete.size )
  209.             this.ac_apply();
  210.     }
  211. }
  212.  
  213.  
  214. function ss_draw_console( con, font, lineheight )
  215. {
  216.     // pick command to display
  217.     if( con.history_index < 0 )
  218.         com2d = con.history[ con.history.size + con.history_index ];
  219.     else if( con.history_index > 0 )
  220.         com2d = con.autocomplete[ con.history_index - 1 ];
  221.     else
  222.         com2d = string_utf8_encode( con.buffer );
  223.    
  224.     // render command
  225.     draw({ preset = "tile", position = [4,5], scale = [9999,lineheight], color = [0,0,0,0.5] });
  226.     draw_text_line( "> " $ com2d $ "_", font, 4, 4, [0.9,0.9,0.9] );
  227.    
  228.     // render autocomplete
  229.     maxcount = 10;
  230.     if( con.autocomplete.size < maxcount )
  231.         maxcount = con.autocomplete.size;
  232.     for( i = 0; i < maxcount; ++i )
  233.     {
  234.         draw({ preset = "tile", position = [36,5 + lineheight * ( i + 1 )], scale = [100,lineheight], color = [0,0,0,0.5] });
  235.         draw_text_line( "- " $ con.autocomplete[ i ], font, 36, 4 + lineheight * ( i + 1 ), [0.5,0.5,0.5] );
  236.     }
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement