will vi ever work right?

This commit is contained in:
Lisa Milne 2025-09-01 16:09:26 +10:00
parent 219d7455dd
commit 662f4b736a
2 changed files with 158 additions and 36 deletions

View file

@ -106,6 +106,16 @@ return Object.create({
clite.io.vfprintf(io.pid,io.stdout,fmt,args);
},
addstr:function(str) {
clite.io.write(io.pid,io.stdout,str);
},
addch:function(ch,opts) {
if (!this.isinit)
return;
this.addstr(ch);
},
getch:function(cb) {
if (!this.isinit)
return false;

View file

@ -6,11 +6,17 @@ clite.commands.load('vi',function(args,env,io) {
var curses = io.include('curses'); // definitely not dark magic
var term = io.include('term');
const VIMODE_VIEW = 0;
const VIMODE_CMD = 1;
const VIMODE_EDIT = 2;
var cmd_buff = '';
var file = null;
var mode = 0; // 0 view mode, 1 command mode, 2 edit mode
var mode = VIMODE_VIEW; // 0 view mode, 1 command mode, 2 edit mode
var cursor_line = 0;
var cursor_col = 0;
var cursor_line_real = 0;
var cursor_col_real = 0;
var changed = false;
var num = false;
var message = '';
@ -20,10 +26,6 @@ clite.commands.load('vi',function(args,env,io) {
var topLine = 0;
var bottomLine = 0;
const VIMODE_VIEW = 0;
const VIMODE_CMD = 1;
const VIMODE_EDIT = 2;
function switchMode(m) {
if (m == mode)
return;
@ -68,7 +70,7 @@ Options:
var i = lines.length-1;
for (; i>-1; i--) {
r -= lines[i][1];
r -= lines[i].rows;
if (r<0)
i++;
if (r <= 0)
@ -78,6 +80,60 @@ Options:
bottomLine = i;
}
function drawCursorLine(line) {
var cl = 0;
var s = -1;
var disp = '';
var rows = 0;
for (var i=0; i<line.length; i++) {
if (i == cursor_col) {
cursor_line_real = rows;
cursor_col_real = cl;
}
if (cl > cols) {
var b = '';
var e = '';
if (s > -1) {
b = disp.substring(0,s);
e = l.disp.substring(s);
}else{
b = disp.substring(0,disp.length-1);
e = disp.substring(disp.length-1);
}
disp = b+'\n'+e;
cl = e.length;
rows++;
s = -1;
}
switch (line[i]) {
case '\t':
{
if (cl > (cols-4)) {
disp += '\n';
cl = 0;
rows++;
s = -1;
break;
}
s = disp.length;
var c = 4-(s%4);
for (var j=0; j<c; j++) {
disp += ' ';
cl++;
}
break;
}
case ' ':
s = disp.length;
default:
disp += line[i];
cl++;
}
}
curses.addstr(disp+'\n');
}
function showAt(line) {
if (line > lines.length)
line = lines.length;
@ -88,20 +144,28 @@ Options:
if (end > lines.length)
end = lines.length;
curses.clear();
var cursor_screen = [0,cursor_col+1];
var cursor_line_screen = 0;
var k = 0;
if (num) {
cursor_screen[1] += 4;
for (var i=start; i<end; i++,k++) {
if (i == cursor_line)// {
cursor_screen[0] = k;
curses.printw('% 4d %s\n',i+1,lines[i][0]);
if (i == cursor_line) {
cursor_line_screen = k;
curses.printw('% 4d ',i+1);
drawCursorLine(lines[i].real);
}else{
curses.printw('% 4d %s\n',i+1,lines[i].disp);
}
}
}else{
for (var i=start; i<end; i++,k++) {
if (i == cursor_line)// {
cursor_screen[0] = k;
curses.printw(' %s\n',lines[i][0]);
if (i == cursor_line) {
cursor_line_screen = k;
curses.addch(' ');
drawCursorLine(lines[i].real);
}else{
curses.printw(' %s\n',lines[i].disp);
}
}
}
curses.move(rows-2,0);
@ -112,8 +176,61 @@ Options:
curses.move(rows-1,0);
if (cmd_buff != '')
curses.printw('%s',cmd_buff);
if (mode != 1)
curses.move(cursor_screen[0],cursor_screen[1]);
if (mode != VIMODE_CMD)
curses.move(cursor_line_real+cursor_line_screen,cursor_col_real+1);
}
function prepLine(line) {
var l = Object.create({
real:line,
disp:'',
rows:1
});
var cl = 0;
var s = -1;
for (var i=0; i<line.length; i++) {
if (cl > cols) {
var b = '';
var e = '';
if (s > -1) {
b = l.disp.substring(0,s);
e = l.disp.substring(s);
}else{
b = l.disp.substring(0,l.disp.length-1);
e = l.disp.substring(l.disp.length-1);
}
l.disp = b+'\n'+e;
cl = e.length;
l.rows++;
s = -1;
}
switch (line[i]) {
case '\t':
{
if (cl > (cols-4)) {
l.disp += '\n';
cl = 0;
l.rows++;
s = -1;
break;
}
s = l.disp.length;
var c = 4-(s%4);
for (var j=0; j<c; j++) {
l.disp += ' ';
cl++;
}
break;
}
case ' ':
s = l.disp.length;
default:
l.disp += line[i];
cl++;
}
}
return l;
}
function prepFile(fd) {
@ -133,21 +250,16 @@ Options:
var parts = txt.split('\n');
parts.forEach(function(line) {
if (line.length > cols) {
var count = Math.ceil(line.length/cols);
lines.push([line,count]);
return;
}
lines.push([line,1]);
lines.push(prepLine(line));
});
if (lines.length < 1)
lines.push(['',0]);
lines.push(prepLine(''));
cursor_line = lines.length-1;
cursor_line = 0;
topLine = 0;
calculateBottomLine();
topLine = bottomLine;
showAt(topLine);
}
@ -158,7 +270,7 @@ Options:
return;
var data = '';
lines.forEach(function(l) {
data += l[0]+'\n';
data += l.real+'\n';
});
stdio.write(fd,data);
stdio.close(fd);
@ -205,6 +317,8 @@ Options:
}
}
switchMode(VIMODE_VIEW);
return true;
}
@ -232,20 +346,18 @@ Options:
showAt(topLine);
}
function cursorRt() {
if (cursor_col < lines[cursor_line][0].length)
if (cursor_col < lines[cursor_line].real.length)
cursor_col++;
showAt(topLine);
}
function setLine(str) {
lines[cursor_line][0] = str;
var count = Math.ceil(lines[cursor_line][0].length/cols);
lines[cursor_line][1] = count;
lines[cursor_line] = prepLine(str);
calculateBottomLine();
changed = true;
}
function insertLine(str) {
var l = [str,str.length];
var l = prepLine(str);
lines.splice(cursor_line+1,0,l);
cursor_col = 0;
cursorDn();
@ -325,7 +437,7 @@ Options:
break;
case curses.key.KEY_BACKSPACE:
if (cursor_col > 0) {
var l = lines[cursor_line][0];
var l = lines[cursor_line].real;
var b = l.substring(0,cursor_col-1);
var e = l.substring(cursor_col);
setLine(b+e);
@ -334,7 +446,7 @@ Options:
}
break;
case curses.key.KEY_ENTER:
var l = lines[cursor_line][0];
var l = lines[cursor_line].real;
var b = l.substring(0,cursor_col);
var e = l.substring(cursor_col);
setLine(b);
@ -343,17 +455,17 @@ Options:
showAt(topLine);
break;
case curses.key.KEY_DL:
if (cursor_col < lines[cursor_line][1]) {
var l = lines[cursor_line][0];
if (cursor_col < lines[cursor_line].real.length) {
var l = lines[cursor_line].real;
var b = l.substring(0,cursor_col);
var e = l.substring(cursor_col+1);
setLine(b+key+e);
setLine(b+e);
showAt(topLine);
}
break;
default:
if (typeof key === 'string' && key.length == 1) {
var l = lines[cursor_line][0];
var l = lines[cursor_line].real;
var b = l.substring(0,cursor_col);
var e = l.substring(cursor_col);
setLine(b+key+e);