1
+ #include <stdio.h>
2
+ #include <stdbool.h>
3
+ #include <string.h>
4
+ #include "tui.c"
5
+ #include "error.c"
6
+ #include "file.c"
7
+
8
+ int filelength ; int buffersize ;
9
+ char * buffer ;
10
+ int edity = 0 ; int editp = 0 ; /* viewport y & file position */
11
+ #define Height 16
12
+ #define Columns 32 /* 3 chars: "00 " */
13
+ #define ScreenFill Height*Columns
14
+ #define version "nex version 0.0.0, https://Modula.dev"
15
+
16
+ void printCommand (char * keys , char * command ) {
17
+ int len = strlen (keys )+ strlen (command );
18
+ printf (txtK bxtW "%s" reset " %s " , keys , command );
19
+ while (len < 20 ) { printf (" " ); len ++ ; }
20
+ }
21
+
22
+ char * insert (int position , char character ){
23
+ if (filelength + 1 >= buffersize ) { buffersize *= 2 ; buffer = realloc (buffer , buffersize ); }
24
+ memcpy (buffer + position + 1 , buffer + position , filelength - position );
25
+ buffer [position ] = character ;
26
+ return buffer ;
27
+ }
28
+
29
+ char * delete (int position ){
30
+ memcpy (buffer + position , buffer + position + 1 , filelength - position );
31
+ if (filelength <= buffersize /2 ) { buffersize /= 2 ; buffer = realloc (buffer , buffersize ); }
32
+ return buffer ;
33
+ }
34
+
35
+ void save (char * filename ) { file_write (filename , buffer , filelength ); }
36
+
37
+ void refresh (){
38
+ tui_clear (); printf (txtK bxtW version reset " File Size %d bytes (%x)\n" , filelength , filelength );
39
+ printf (txtP " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F" reset );
40
+ int c = (edity * Columns ); int end = (edity * Columns )+ ScreenFill ;
41
+ while (c < end && (c < filelength || c == 0 )) {
42
+ if (c % Columns == 0 ) { printf ("\n" txtP "%04x " reset , c ); }
43
+ if (c == editp )
44
+ { printf (txtW bxtB blink ""); }
45
+ else {
46
+ if (buffer [c ]== 0 ) { printf (txtR "" ); }
47
+ else if (buffer [c ]< 32 || buffer [c ]> 126 ) { printf (txtG "" ); }
48
+ }
49
+ int h = (buffer [c ] >> 4 )& 15 ;
50
+ int l = buffer [c ] & 15 ;
51
+ printf ("%1x%1x" reset " " , h , l );
52
+ c ++ ;
53
+ } printf ("\n" );
54
+
55
+ tui_row (20 );
56
+ printCommand ("Arrows" , "Navigate" );
57
+ printCommand ("Space" , "Insert Zeros" );
58
+ printCommand ("Z" , "Delete character" );
59
+ printf ("\n" );
60
+ printCommand ("Ctrl+X" , "Save" );
61
+ printCommand ("Ctrl+C" , "Quit" );
62
+ printf ("\n" );
63
+ }
64
+
65
+ void quit (){
66
+ terminal_reset_terminal_mode (& original_term );
67
+ tui_clear (); tui_col (0 ); tui_row (0 );
68
+ exit (0 );
69
+ }
70
+
71
+ #define initsize 1024 * 1024 * 4
72
+ int main (int argc , char * * argv ) {
73
+
74
+ if (argc != 2 ) { error ("nex" , "expects a filename as input" ); }
75
+ if (argv [1 ][0 ] == '-' ) {
76
+ if (argv [1 ][1 ] == 'v' ) { ok ("nex" , version "\n" ); }
77
+ if (argv [1 ][1 ] == 'h' ) { ok ("nex" , "\n nex (filename) opens and edits a file in hex" ); }
78
+ }
79
+ char * filename = argv [1 ];
80
+ buffer = malloc (sizeof (char )* initsize ); buffersize = initsize ;
81
+ filelength = file_read (filename , buffer , initsize );
82
+ if (filelength == false) { filelength = 1 ; buffer [0 ] = 0 ; }
83
+
84
+ refresh ();
85
+ char charcode ; bool changed = false; int fileheight = (filelength / Height );
86
+ bool escaped = false; bool leftbracket = false; char value = 1 ;
87
+ while (true) {
88
+ charcode = tui_input ();
89
+ /*if (charcode != 0) { printf("[%x] ", (int)(charcode)); fflush(stdout); }*/
90
+ if (charcode == 0 ) { usleep (1000 ); continue ; }
91
+ switch (charcode ) {
92
+ case 0 : break ;
93
+ case CTRL_C : quit (); break ;
94
+ case CTRL_X : save (filename ); break ;
95
+ case '\e' : escaped = true; break ;
96
+ case '[' : leftbracket = true; break ;
97
+ case ' ' : buffer = insert (editp , '\0' ); changed = true; filelength ++ ; break ;
98
+ case 'z' : if (filelength > 0 ) { buffer = delete (editp ); changed = true; filelength -- ; } break ;
99
+ case ARROW_LEFT :
100
+ if (escaped == true && leftbracket == true )
101
+ if (editp > 0 ) { editp -- ; } changed = true; break ;
102
+ case ARROW_RIGHT :
103
+ if (escaped == true && leftbracket == true )
104
+ editp ++ ; if (editp >= filelength ) { editp = filelength - 1 ; } changed = true; break ;
105
+ case ARROW_UP :
106
+ if (escaped == true && leftbracket == true ) {
107
+ if (editp > 31 ) { editp -= 32 ;}
108
+ if ( edity * Columns > editp ) { edity -- ; }
109
+ changed = true;
110
+ } break ;
111
+ case ARROW_DOWN :
112
+ if (escaped == true && leftbracket == true ) {
113
+ if (editp <= filelength - 32 ) { editp += 32 ;}
114
+ if ((edity + Height - 1 ) * Columns < editp ) { edity ++ ; }
115
+ changed = true;
116
+ } break ;
117
+ case '0' : if (value == 1 ) {value = 0x00 ;} else { value += 0x00 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
118
+ case '1' : if (value == 1 ) {value = 0x10 ;} else { value += 0x01 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
119
+ case '2' : if (value == 1 ) {value = 0x20 ;} else { value += 0x02 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
120
+ case '3' : if (value == 1 ) {value = 0x30 ;} else { value += 0x03 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
121
+ case '4' : if (value == 1 ) {value = 0x40 ;} else { value += 0x04 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
122
+ case '5' : if (value == 1 ) {value = 0x50 ;} else { value += 0x05 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
123
+ case '6' : if (value == 1 ) {value = 0x60 ;} else { value += 0x06 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
124
+ case '7' : if (value == 1 ) {value = 0x70 ;} else { value += 0x07 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
125
+ case '8' : if (value == 1 ) {value = 0x80 ;} else { value += 0x08 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
126
+ case '9' : if (value == 1 ) {value = 0x90 ;} else { value += 0x09 ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
127
+ case 'a' : if (value == 1 ) {value = 0xA0 ;} else { value += 0x0A ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
128
+ case 'b' : if (value == 1 ) {value = 0xB0 ;} else { value += 0x0B ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
129
+ case 'c' : if (value == 1 ) {value = 0xC0 ;} else { value += 0x0C ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
130
+ case 'd' : if (value == 1 ) {value = 0xD0 ;} else { value += 0x0D ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
131
+ case 'e' : if (value == 1 ) {value = 0xE0 ;} else { value += 0x0E ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
132
+ case 'f' : if (value == 1 ) {value = 0xF0 ;} else { value += 0x0F ; buffer [editp ]= value ; value = 1 ; editp ++ ; changed = true;} break ;
133
+ default : escaped = false; leftbracket = false; changed = true;
134
+ }
135
+ if (changed == true) { refresh (); changed = false; }
136
+ }
137
+ }
0 commit comments