Some navigation, but not working:(

This commit is contained in:
斟酌 鵬兄 2016-03-13 08:35:29 +08:00
parent 6ce714be1e
commit 751530b42d
5 changed files with 356 additions and 138 deletions

View File

@ -0,0 +1,162 @@
(function(){
var ns = __namespace( "Components.Vim" );
/** @type {Dandelion} */
var Dand = __import( "Dandelion" );
/** @type {Dandelion.IDOMElement} */
var IDOMElement = __import( "Dandelion.IDOMElement" );
/** @type {Dandelion.IDOMObject} */
var IDOMObject = __import( "Dandelion.IDOMObject" );
/** @type {System.Cycle} */
var Cycle = __import( "System.Cycle" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
var GetLine = function( buffs, l )
{
/** @type {Components.Vim.LineBuffer} */
var LineHead = buffs[0];
l ++;
for( var i = 0, line = LineHead;
line && i < l; i ++ )
{
LineHead = line;
while( line )
{
line = line.next;
if( line.br ) break;
}
}
return LineHead;
};
var LineOffset = function( buffs, l )
{
/** @type {Components.Vim.LineBuffer} */
var offset = 0;
for( var i = 0, line = buffs[0];
line && i < l; i ++ )
{
while( line )
{
if( line.br )
{
offset += line.prev.toString().length + 1;
// Empty line has a special space
if( line.content == "" ) offset ++;
line = line.next;
break;
}
else
{
if( offset == 0 ) offset -= 1;
if( line.next && !line.next.br )
offset += line.cols + 1;
}
line = line.next;
}
}
debug.Info( offset );
return offset;
};
var Cursor = function( buffs )
{
this.buffers = buffs;
this.cols = buffs[0].cols;
// The preferred X position
this.pX = 0;
// The displaying X position
this.X = 0;
// The current line resided
this.Y = 0;
// The resulting position
this.P = 0;
};
// Can only be 1, -1
// 0 will be treated as undefined
Cursor.prototype.moveX = function( d )
{
var x = this.pX;
var updatePx = Boolean( d );
if( updatePx ) x = this.X + d;
if( !d ) d = 1;
var buffs = this.buffers;
/** @type {Components.Vim.LineBuffer} */
var line = GetLine( buffs, this.Y );
var content = line.visualLines.join( "\n" );
var c = content[ x ];
if( c == undefined )
{
x = d > 0 ? content.length - 1 : 0;
}
else if( c == "\n" )
{
x += d;
}
this.X = x;
if( updatePx )
{
this.pX = x;
this.updatePosition();
}
};
Cursor.prototype.lineStart = function()
{
this.pX = 0;
this.moveX();
this.updatePosition();
};
Cursor.prototype.lineEnd = function()
{
/** @type {Components.Vim.LineBuffer} */
this.moveX( Number.MAX_VALUE );
};
Cursor.prototype.updatePosition = function()
{
this.P = this.X + LineOffset( this.buffers, this.Y );
};
Cursor.prototype.moveY = function( d )
{
this.Y += d;
this.moveX();
this.updatePosition();
};
__readOnly( Cursor.prototype, "position", function()
{
return {
start: this.P
, end: this.P + 1
};
} );
ns[ NS_EXPORT ]( EX_CLASS, "Cursor", Cursor );
})();

View File

@ -0,0 +1,111 @@
(function(){
var ns = __namespace( "Components.Vim" );
/** @type {Dandelion} */
var Dand = __import( "Dandelion" );
/** @type {Dandelion.IDOMElement} */
var IDOMElement = __import( "Dandelion.IDOMElement" );
/** @type {Dandelion.IDOMObject} */
var IDOMObject = __import( "Dandelion.IDOMObject" );
/** @type {System.Cycle} */
var Cycle = __import( "System.Cycle" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
var LineBuffer = function( cols, nextLineBuffer )
{
this.prev = null;
this.cols = cols;
this.next = nextLineBuffer;
this.br = false;
this.placeholder = true;
if( nextLineBuffer )
{
nextLineBuffer.prev = this;
}
};
LineBuffer.prototype.Push = function( content, wrap )
{
if( content == undefined || content === "" )
{
this.content = "~";
this.placeholder = true;
if( this.next ) this.next.Push( content, wrap );
return;
}
this.placeholder = false;
var line = "";
var br = false;
if( wrap )
{
for( var i = 0; i < this.cols; i ++ )
{
var c = content[i];
if( c === undefined ) break;
if( c == "\n" )
{
br = true;
i ++;
break;
}
line += c;
}
}
else
{
br = true;
for( var i = 0; true; i ++ )
{
var c = content[i];
if( c === undefined ) break;
if( c == "\n" )
{
i ++;
break;
}
if( i < this.cols )
{
line += c;
}
}
}
if( this.next )
{
this.next.br = br;
this.next.Push( content.substr( i ), wrap );
}
this.content = line;
};
LineBuffer.prototype.toString = function()
{
return this.content || " ";
};
__readOnly( LineBuffer.prototype, "visualLines", function()
{
var lines = [ this ];
var line = this;
while( ( line = line.next ) && !line.br )
{
lines.push( line );
}
return lines;
} );
ns[ NS_EXPORT ]( EX_CLASS, "LineBuffer", LineBuffer );
})();

View File

@ -12,111 +12,38 @@
/** @type {System.Debug} */ /** @type {System.Debug} */
var debug = __import( "System.Debug" ); var debug = __import( "System.Debug" );
var Line = function( cols, nextLine ) /** @type {Components.Vim.LineBuffer} */
{ var LineBuffer = ns[ NS_INVOKE ]( "LineBuffer" );
this.cols = cols; /** @type {Components.Vim.Cursor} */
this.next = nextLine; var Cursor = ns[ NS_INVOKE ]( "Cursor" );
this.br = false;
this.placeholder = true;
};
Line.prototype.Push = function( content, wrap )
{
if( content == undefined || content === "" )
{
this.content = "~";
this.placeholder = true;
if( this.next ) this.next.Push( content, wrap );
return;
}
this.placeholder = false;
var line = "";
var br = false;
if( wrap )
{
for( var i = 0; i < this.cols; i ++ )
{
var c = content[i];
if( c === undefined ) break;
if( c == "\n" )
{
br = true;
i ++;
break;
}
line += c;
}
}
else
{
br = true;
for( var i = 0; true; i ++ )
{
var c = content[i];
if( c === undefined ) break;
if( c == "\n" )
{
i ++;
break;
}
if( i < this.cols )
{
line += c;
}
}
}
if( this.next )
{
this.next.br = br;
this.next.Push( content.substr( i ), wrap );
}
this.content = line;
};
Line.prototype.toString = function()
{
return this.content;
};
var Feeder = function( rows, cols ) var Feeder = function( rows, cols )
{ {
var lines = []; var lineBuffers = [];
// Last line // Last line
lines[ rows - 1 ] = new Line( cols ); lineBuffers[ rows - 1 ] = new LineBuffer( cols );
for( var i = rows - 2; 0 <= i; i -- ) for( var i = rows - 2; 0 <= i; i -- )
{ {
lines[i] = new Line( cols, lines[ i + 1 ] ); lineBuffers[i] = new LineBuffer( cols, lineBuffers[ i + 1 ] );
} }
this.lines = lines; this.cursor = new Cursor( lineBuffers );
this.lineBuffers = lineBuffers;
this.setRender(); this.setRender();
}; };
Feeder.prototype.init = function( content, wrap ) Feeder.prototype.init = function( content, wrap )
{ {
if( wrap == undefined ) wrap = true; if( wrap == undefined ) wrap = true;
if( this.lines.length ) if( this.lineBuffers.length )
{ {
this.lines[0].Push( content, wrap ); this.lineBuffers[0].Push( content, wrap );
} }
}; };
// Advance the text to number of lines
Feeder.prototype.feed = function( num )
{
};
Feeder.prototype.wrap = function( setwrap ) Feeder.prototype.wrap = function( setwrap )
{ {
}; };
@ -159,30 +86,23 @@
} }
} }
Feeder.prototype.cursor = function( direction )
{
switch( direction )
{
case 0:
return { start: 0, end: 1 };
}
};
Feeder.prototype.render = function( start, length ) Feeder.prototype.render = function( start, length )
{ {
if( start == undefined ) start = 0; var buffs = this.lineBuffers;
else if( this.lines.length < start ) return "";
if( length == undefined || ( this.lines.length - start ) < length ) if( start == undefined ) start = 0;
length = this.lines.length - start; else if( buffs.length < start ) return "";
if( length == undefined || ( buffs.length - start ) < length )
length = buffs.length - start;
if( length == 0 ) return ""; if( length == 0 ) return "";
return this.__render( this.lines[ start ], length - 1 ); return this.__render( buffs[ start ], length - 1 );
}; };
__readOnly( Feeder.prototype, "linesOccupied", function() { __readOnly( Feeder.prototype, "linesOccupied", function() {
var line = this.lines[0]; var line = this.lineBuffers[0];
if( line.placeholder ) return 0; if( line.placeholder ) return 0;
var i = 0; var i = 0;

View File

@ -14,8 +14,9 @@
/** @type {System.Debug} */ /** @type {System.Debug} */
var debug = __import( "System.Debug" ); var debug = __import( "System.Debug" );
/** @type {Components.VimArea.LineFeeder} */ /** @type {Components.Vim.LineFeeder} */
var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" ); var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
/** @type {Components.Vim.StatusBar} */
var StatusBar = ns[ NS_INVOKE ]( "StatusBar" ); var StatusBar = ns[ NS_INVOKE ]( "StatusBar" );
var KeyHandler = function( sender, handler ) var KeyHandler = function( sender, handler )
@ -32,6 +33,11 @@
var VimControls = function( sender, e ) var VimControls = function( sender, e )
{ {
if( e.altKey
// F2 - F12
|| ( 112 < e.keyCode && e.keyCode < 124 )
) return;
e.preventDefault(); e.preventDefault();
if( e.ctrlKey ) if( e.ctrlKey )
{ {
@ -39,28 +45,49 @@
return; return;
} }
var kCode = e.KeyCode + ( e.shiftKey ? 1000 : 0 ); var kCode = e.keyCode + ( e.shiftKey ? 1000 : 0 );
switch( e.KeyCode )
var cfeeder = sender.contentFeeder;
switch( kCode )
{ {
// Cursor movements
case 72: // h
cfeeder.cursor.moveX( -1 );
break;
case 74: // j
cfeeder.cursor.moveY( 1 );
break;
case 75: // k
cfeeder.cursor.moveY( -1 );
break;
case 76: // l
cfeeder.cursor.moveX( 1 );
break;
case 65: // a case 65: // a
case 1065: // A case 1065: // A
break; break;
case 72: // h case 1072: // H, First line buffer
case 1072: // H
break; break;
case 74: // j case 1076: // L, Last line buffer
case 1074: // J
break; break;
case 75: // k case 1052: // $
case 1075: // K cfeeder.cursor.lineEnd();
break;
case 76: // l
case 1076: // L
break; break;
case 1053: // % case 1053: // %
case 1054: // ^
break; break;
case 1054: // ^
cfeeder.cursor.lineStart();
break;
case 1074: // J, Join lines
break;
case 1075: // K, manual entry
break;
case 112: // F1, help
} }
sender.__blink = false;
sender.select( cfeeder.cursor.position );
}; };
/* stage @param {Dandelion.IDOMElement} */ /* stage @param {Dandelion.IDOMElement} */
@ -94,31 +121,23 @@
VimArea.prototype.startInput = function( mode ) VimArea.prototype.startInput = function( mode )
{ {
}; };
VimArea.prototype.cursor = function( x, y ) VimArea.prototype.select = function( sel )
{ {
return this.__cursor();
};
VimArea.prototype.flashCursor = function()
{
var _self = this;
var textarea = this.stage.element; var textarea = this.stage.element;
Cycle.perma( "VimCursorFlashCycle", function()
if( sel )
{ {
var cursor = _self.cursor(); textarea.selectionStart = sel.start;
if( cursor ) textarea.selectionEnd = sel.end;
{ }
textarea.selectionStart = cursor.start;
textarea.selectionEnd = cursor.end;
}
}, 600 );
}; };
VimArea.prototype.VisualizeVimFrame = function() VimArea.prototype.VisualizeVimFrame = function()
{ {
var _self = this;
var element = this.stage.element; var element = this.stage.element;
var r = this.rows; var r = this.rows;
var c = this.cols; var c = this.cols;
@ -132,6 +151,7 @@
sfeeder = new LineFeeder( r, c ); sfeeder = new LineFeeder( r, c );
sfeeder.setRender( false ); sfeeder.setRender( false );
// XXX: Placeholder
var statusBar = new StatusBar( c ); var statusBar = new StatusBar( c );
statusBar.stamp( -18, function(){ statusBar.stamp( -18, function(){
return "1,1-1"; return "1,1-1";
@ -143,20 +163,24 @@
sfeeder.init( statusBar.statusText ); sfeeder.init( statusBar.statusText );
element.value = cfeeder.render( 0, r - sfeeder.linesOccupied ) + "\n" + sfeeder.render(); element.value =
cfeeder.render( 0, r - sfeeder.linesOccupied )
+ "\n" + sfeeder.render();
this.contentFeeder = cfeeder; this.contentFeeder = cfeeder;
this.statusFeeder = sfeeder; this.statusFeeder = sfeeder;
var f = true; this.__cursor = cfeeder.cursor;
this.__cursor = function()
{
if( f = !f )
return this.contentFeeder.cursor( 0 );
else return { start: 0, end: 0 };
}
this.flashCursor(); this.__blink = true;
Cycle.perma( "VimCursorBlinkCycle" + element.id, function()
{
_self.select(
( _self.__blink = !_self.__blink )
? _self.__cursor.position
: { start: 0, end: 0 }
);
}, 600 );
}; };
ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea ); ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea );

View File

@ -14,6 +14,7 @@
var messages = { var messages = {
"INSERT": "-- INSERT --" "INSERT": "-- INSERT --"
, "REPLACE": "-- REPLACE --"
, "MORE": "-- MORE --" , "MORE": "-- MORE --"
, "WRITE": "\"%1\" %2L, %3C written" , "WRITE": "\"%1\" %2L, %3C written"
, "CONTINUE": "Press ENTER or type command to continue" , "CONTINUE": "Press ENTER or type command to continue"