@@ -799,6 +799,27 @@ console_cursor_pos(VALUE io)
799
799
return rb_assoc_new (UINT2NUM (ws .dwCursorPosition .X ), UINT2NUM (ws .dwCursorPosition .Y ));
800
800
}
801
801
802
+ static VALUE
803
+ console_move (VALUE io , int x , int y )
804
+ {
805
+ rb_io_t * fptr ;
806
+ HANDLE h ;
807
+ rb_console_size_t ws ;
808
+ COORD * pos = & ws .dwCursorPosition ;
809
+
810
+ GetOpenFile (io , fptr );
811
+ h = (HANDLE )rb_w32_get_osfhandle (GetWriteFD (fptr ));
812
+ if (!GetConsoleScreenBufferInfo (h , & ws )) {
813
+ rb_syserr_fail (LAST_ERROR , 0 );
814
+ }
815
+ pos -> X += x ;
816
+ pos -> Y += y ;
817
+ if (!SetConsoleCursorPosition (h , * pos )) {
818
+ rb_syserr_fail (LAST_ERROR , 0 );
819
+ }
820
+ return io ;
821
+ }
822
+
802
823
#include "win32_vk.inc"
803
824
804
825
static VALUE
@@ -889,6 +910,19 @@ console_goto(VALUE io, VALUE x, VALUE y)
889
910
rb_io_write (io , rb_sprintf ("\x1b[%d;%dH" , NUM2UINT (y ), NUM2UINT (x )));
890
911
return io ;
891
912
}
913
+
914
+ static VALUE
915
+ console_move (VALUE io , int x , int y )
916
+ {
917
+ if (x || y ) {
918
+ VALUE s = rb_str_new_cstr ("" );
919
+ if (y ) rb_str_catf (s , "\x1b[%d%c" , y < 0 ? - y : y , y < 0 ? 'A' : 'B' );
920
+ if (x ) rb_str_catf (s , "\x1b[%d%c" , x < 0 ? - x : x , x < 0 ? 'D' : 'C' );
921
+ rb_io_write (io , s );
922
+ rb_io_flush (io );
923
+ }
924
+ return io ;
925
+ }
892
926
# define console_key_pressed_p rb_f_notimplement
893
927
#endif
894
928
@@ -900,6 +934,38 @@ console_cursor_set(VALUE io, VALUE cpos)
900
934
return console_goto (io , RARRAY_AREF (cpos , 0 ), RARRAY_AREF (cpos , 1 ));
901
935
}
902
936
937
+ static VALUE
938
+ console_cursor_up (VALUE io , VALUE val )
939
+ {
940
+ return console_move (io , 0 , - NUM2INT (val ));
941
+ }
942
+
943
+ static VALUE
944
+ console_cursor_down (VALUE io , VALUE val )
945
+ {
946
+ return console_move (io , 0 , + NUM2INT (val ));
947
+ }
948
+
949
+ static VALUE
950
+ console_cursor_left (VALUE io , VALUE val )
951
+ {
952
+ return console_move (io , - NUM2INT (val ), 0 );
953
+ }
954
+
955
+ static VALUE
956
+ console_cursor_right (VALUE io , VALUE val )
957
+ {
958
+ return console_move (io , + NUM2INT (val ), 0 );
959
+ }
960
+
961
+ static VALUE
962
+ console_clear_screen (VALUE io )
963
+ {
964
+ console_erase_screen (io , INT2FIX (2 ));
965
+ console_goto (io , INT2FIX (1 ), INT2FIX (1 ));
966
+ return io ;
967
+ }
968
+
903
969
/*
904
970
* call-seq:
905
971
* IO.console -> #<File:/dev/tty>
@@ -1124,6 +1190,10 @@ InitVM_console(void)
1124
1190
rb_define_method (rb_cIO , "goto" , console_goto , 2 );
1125
1191
rb_define_method (rb_cIO , "cursor" , console_cursor_pos , 0 );
1126
1192
rb_define_method (rb_cIO , "cursor=" , console_cursor_set , 1 );
1193
+ rb_define_method (rb_cIO , "cursor_up" , console_cursor_up , 1 );
1194
+ rb_define_method (rb_cIO , "cursor_down" , console_cursor_down , 1 );
1195
+ rb_define_method (rb_cIO , "cursor_left" , console_cursor_left , 1 );
1196
+ rb_define_method (rb_cIO , "cursor_right" , console_cursor_right , 1 );
1127
1197
rb_define_method (rb_cIO , "pressed?" , console_key_pressed_p , 1 );
1128
1198
#if ENABLE_IO_GETPASS
1129
1199
rb_define_method (rb_cIO , "getpass" , console_getpass , -1 );
0 commit comments