Merge remote-tracking branches 'origin/master' and 'vim/master' into Astro

This commit is contained in:
斟酌 鵬兄 2016-03-29 03:54:22 +08:00
commit c6e4bdc509
21 changed files with 1038 additions and 302 deletions

View File

@ -0,0 +1,112 @@
(function(){
var ns = __namespace( "Components.Vim.Actions" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {Components.Vim.State.Stator} */
var Stator = __import( "Components.Vim.State.Stator" );
/** @type {Components.Vim.State.Stack} */
var Stack = __import( "Components.Vim.State.Stack" );
var Mesg = __import( "Components.Vim.Message" );
var occurence = __import( "System.utils.Perf.CountSubstr" );
/** @type {Components.Vim.Cursor.IAction} */
var DELETE = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
this.__nline = 0;
this.__startX = Cursor.aPos;
};
DELETE.prototype.allowMovement = true;
DELETE.prototype.dispose = function()
{
};
DELETE.prototype.handler = function( e, sp )
{
e.preventDefault();
/** @type {Components.Vim.State.Registers} */
var reg = e.target.registers;
var cur = this.__cursor;
var feeder = cur.feeder;
var Triggered = false;
if( sp == undefined && this.__startX != cur.aPos )
{
Triggered = true;
if( e.kMap( "l" ) )
{
cur.moveX( -1 );
}
sp = this.__startX;
}
else if( sp == undefined ) return;
var c = feeder.content;
var s = sp;
var e = cur.aPos;
if( e < s )
{
s = cur.aPos;
e = sp;
}
var removed = c.substring( s, e + 1 );
reg.change( removed );
this.__nline = occurence( removed, "\n" );
feeder.content = c.substring( 0, s ) + c.substring( e + 1 );
var stator = new Stator( cur, s );
var stack = new Stack();
c = c[ e + 1 ];
if( c == "\n" || c == undefined )
{
cur.suppressEvent();
cur.moveX( -1 );
cur.unsuppressEvent();
}
var f = stator.save( 0, removed );
stack.store( function() {
f();
// Offset correction after REDO / UNDO
cur.moveX( 1 );
} );
cur.rec.record( stack );
feeder.pan();
return Triggered;
};
DELETE.prototype.getMessage = function()
{
if( this.__nline )
{
return Mesg( "LINE_FEWER", this.__nline );
}
return "";
};
ns[ NS_EXPORT ]( EX_CLASS, "DELETE", DELETE );
})();

View File

@ -3,6 +3,8 @@
/** @type {Components.Vim.State.Stack} */ /** @type {Components.Vim.State.Stack} */
var Stack = __import( "Components.Vim.State.Stack" ); var Stack = __import( "Components.Vim.State.Stack" );
/** @type {Components.Vim.State.Stator} */
var Stator = __import( "Components.Vim.State.Stator" );
/** @type {System.Debug} */ /** @type {System.Debug} */
var debug = __import( "System.Debug" ); var debug = __import( "System.Debug" );
@ -27,40 +29,20 @@
/** @type {Components.Vim.Cursor} */ /** @type {Components.Vim.Cursor} */
this.__cursor = Cursor; this.__cursor = Cursor;
this.__startX = Cursor.aPos; this.__Stator = new Stator( Cursor );
// Initialize this stack // Initialize this stack
this.__rec( "", true ); this.__rec( "", true );
}; };
INSERT.prototype.allowMovement = false;
INSERT.prototype.dispose = function() INSERT.prototype.dispose = function()
{ {
this.__cursor.moveX( -1 ); this.__cursor.moveX( -1 );
this.__rec( "", true ); this.__rec( "", true );
}; };
INSERT.prototype.__storeState = function()
{
var cur = this.__cursor;
var feeder = cur.feeder;
var insertLength = this.__insertLength;
var contentUndo = this.__contentUndo;
var startPos = this.__startPosition;
var startX = this.__startX;
return function() {
var contentRedo = feeder.content.substr( startPos, insertLength );
feeder.content =
feeder.content.substring( 0, startPos )
+ contentUndo
+ feeder.content.substring( startPos + insertLength );
insertLength = contentUndo.length;
contentUndo = contentRedo;
feeder.pan();
};
};
INSERT.prototype.__rec = function( c, newRec ) INSERT.prototype.__rec = function( c, newRec )
{ {
if( newRec || !this.__stack ) if( newRec || !this.__stack )
@ -73,7 +55,7 @@
) return; ) return;
this.__stack.store( this.__stack.store(
this.__storeState() this.__Stator.save( this.__insertLength, this.__contentUndo )
); );
this.__cursor.rec.record( this.__stack ); this.__cursor.rec.record( this.__stack );
@ -82,7 +64,6 @@
this.__insertLength = 0; this.__insertLength = 0;
this.__contentUndo = ""; this.__contentUndo = "";
this.__stack = new Stack(); this.__stack = new Stack();
this.__startPosition = this.__cursor.aPos;
} }
if( c == "\n" ) if( c == "\n" )
@ -98,9 +79,9 @@
var cur = this.__cursor; var cur = this.__cursor;
var feeder = cur.feeder; var feeder = cur.feeder;
switch( e.keyCode ) // Backspace
if( e.kMap( "BS" ) )
{ {
case 8: // Backspace
var oY = feeder.panY + cur.Y; var oY = feeder.panY + cur.Y;
if( cur.X == 0 && feeder.panY == 0 && cur.Y == 0 ) return; if( cur.X == 0 && feeder.panY == 0 && cur.Y == 0 ) return;
@ -111,19 +92,15 @@
if( this.__insertLength <= 0 ) if( this.__insertLength <= 0 )
{ {
this.__contentUndo = feeder.content.substr( f, 1 ) + this.__contentUndo; this.__contentUndo = feeder.content.substr( f, 1 ) + this.__contentUndo;
this.__startPosition --;
}
else
{
this.__insertLength --; this.__insertLength --;
} }
feeder.content = feeder.content =
feeder.content.substring( 0, f ) feeder.content.substring( 0, f )
+ feeder.content.substring( f + 1 ); + feeder.content.substring( f + 1 );
}
break; else if( e.kMap( "Del" ) )
case 46: // Delete {
var f = cur.aPos; var f = cur.aPos;
this.__contentUndo += feeder.content.substr( f, 1 ); this.__contentUndo += feeder.content.substr( f, 1 );
@ -131,12 +108,8 @@
feeder.content = feeder.content =
feeder.content.substring( 0, f ) feeder.content.substring( 0, f )
+ feeder.content.substring( f + 1 ); + feeder.content.substring( f + 1 );
break;
default:
// Do nothing
return;
} }
else return;
feeder.pan(); feeder.pan();
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
@ -163,12 +136,23 @@
+ inputChar + inputChar
+ feeder.content.substring( f ); + feeder.content.substring( f );
if( inputChar == "\n" )
{
feeder.softReset();
feeder.pan(); feeder.pan();
cur.moveY( 1 );
cur.lineStart();
}
else
{
feeder.pan();
cur.moveX( 1, false, true );
}
feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
this.__rec( inputChar ); this.__rec( inputChar );
cur.moveX( 1 );
}; };
INSERT.prototype.getMessage = function() INSERT.prototype.getMessage = function()

View File

@ -0,0 +1,52 @@
(function(){
var ns = __namespace( "Components.Vim.Actions" );
/** @type {Components.Vim.State.Stack} */
var Stack = __import( "Components.Vim.State.Stack" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {Components.Vim.Cursor.IAction} */
var PRINT_HEX = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
};
PRINT_HEX.prototype.dispose = function()
{
};
PRINT_HEX.prototype.handler = function( e )
{
e.preventDefault();
var str = unescape( encodeURIComponent( this.__cursor.feeder.content[ this.__cursor.aPos ] ) );
var l = str.length;
var msg = [];
for( var i = 0; i < l; i ++ )
{
msg[i] = str[i] == "\n"
? "a"
: str.charCodeAt( i ).toString( 16 )
;
if( msg[i].length == 1 )
{
msg[i] = "0" + msg[i];
}
else if( msg[i].length == 0 )
{
msg[i] = "00";
}
}
this.__msg = msg.join( " " );
};
PRINT_HEX.prototype.getMessage = function()
{
return this.__msg;
};
ns[ NS_EXPORT ]( EX_CLASS, "PRINT_HEX", PRINT_HEX );
})();

View File

@ -0,0 +1,114 @@
(function(){
var ns = __namespace( "Components.Vim.Actions" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
var Mesg = __import( "Components.Vim.Message" );
/** @type {Components.Vim.Cursor.IAction} */
var YANK = ns[ NS_INVOKE ]( "YANK" );
/** @type {Components.Vim.Cursor.IAction} */
var DELETE = ns[ NS_INVOKE ]( "DELETE" );
/** @type {Components.Vim.Cursor.IAction} */
var VISUAL = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
this.__startaP = Cursor.aPos;
this.__startP = { x: Cursor.X, y: Cursor.Y, p: Cursor.P };
this.__start = Cursor.PStart;
this.__selStart = Cursor.PStart;
this.__msg = Mesg( "VISUAL" );
this.__leaveMesg = "";
Cursor.blink = false;
Cursor.pSpace = true;
};
VISUAL.prototype.allowMovement = true;
VISUAL.prototype.dispose = function()
{
this.__msg = this.__leaveMesg;
this.__cursor.blink = true;
this.__cursor.pSpace = false;
this.__cursor.PStart = this.__selStart;
this.__cursor.PEnd = this.__selStart + 1;
};
VISUAL.prototype.handler = function( e, done )
{
e.preventDefault();
if( e.ModKeys ) return;
var cur = this.__cursor;
var Action = null;
if( e.kMap( "y" ) )
{
Action = new YANK( cur );
}
else if( e.kMap( "d" ) )
{
Action = new DELETE( cur );
}
if( Action )
{
cur.suppressEvent();
// Low-level cursor position adjustment
// this swap the cursor direction from LTR to RTL
// i.e. treat all delete as "e<----s" flow
// to keep the cursor position as the top on UNDO / REDO
if( Action.constructor == DELETE && this.__startaP < cur.aPos )
{
this.__startaP = cur.aPos;
cur.X = this.__startP.x;
cur.Y = this.__startP.y;
cur.P = this.__startP.p;
}
Action.handler( e, this.__startaP );
this.__leaveMesg = Action.getMessage();
Action.dispose();
cur.unsuppressEvent();
this.__selStart = cur.PStart;
return true;
}
else
{
var prevPos = this.__start;
var newPos = cur.PStart;
var posDiff = newPos - prevPos;
if( 0 <= posDiff )
{
this.__selStart = newPos;
newPos = newPos + 1;
}
else if( posDiff < 0 )
{
prevPos += posDiff;
newPos = this.__start + 1;
this.__selStart = prevPos;
}
cur.PStart = prevPos;
cur.PEnd = newPos;
}
};
VISUAL.prototype.getMessage = function()
{
return this.__msg;
};
ns[ NS_EXPORT ]( EX_CLASS, "VISUAL", VISUAL );
})();

View File

@ -0,0 +1,32 @@
(function(){
var ns = __namespace( "Components.Vim.Actions" );
var Mesg = __import( "Components.Vim.Message" );
/** @type {Components.Vim.Cursor.IAction} */
var YANK = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
};
YANK.prototype.allowMovement = true;
YANK.prototype.dispose = function()
{
};
YANK.prototype.handler = function( e )
{
e.preventDefault();
};
YANK.prototype.getMessage = function()
{
return "<TODO> YANK COMMAND";
};
ns[ NS_EXPORT ]( EX_CLASS, "YANK", YANK );
})();

View File

@ -1,13 +1,20 @@
(function(){ (function(){
var ns = __namespace( "Components.Vim" ); var ns = __namespace( "Components.Vim" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" ); var debug = __import( "System.Debug" );
var beep = ns[ NS_INVOKE ]( "Beep" ); var beep = ns[ NS_INVOKE ]( "Beep" );
var SHIFT = 1 << 9; var SHIFT = 1 << 9;
var CTRL = 1 << 10; var CTRL = 1 << 10;
var ALT = 1 << 11;
var KEY_SHIFT = 16;
var KEY_CTRL = 17;
var KEY_ALT = 18;
var BACKSPACE = 8; var BACKSPACE = 8;
var DELETE = 46;
var _0 = 48; var _1 = 49; var _2 = 50; var _3 = 51; var _4 = 52; var _0 = 48; var _1 = 49; var _2 = 50; var _3 = 51; var _4 = 52;
var _5 = 53; var _6 = 54; var _7 = 55; var _8 = 56; var _9 = 57; var _5 = 53; var _6 = 54; var _7 = 55; var _8 = 56; var _9 = 57;
@ -19,117 +26,212 @@
var U = 85; var V = 86; var W = 87; var X = 88; var Y = 89; var U = 85; var V = 86; var W = 87; var X = 88; var Y = 89;
var Z = 90; var Z = 90;
var S_BRACKET_L = 219; var S_BRACKET_R = 221;
var ESC = 27;
var F1 = 112; var F2 = 113; var F3 = 114; var F4 = 115; var F5 = 116;
var F6 = 117; var F7 = 118; var F8 = 119; var F9 = 120; var F10 = 121;
var F11 = 122; var F12 = 123;
var COMMA = 188; var FULLSTOP = 190;
var __maps = {};
var Map = function( str )
{
if( __maps[ str ] ) return __maps[ str ];
// C-Left, A-Up ...
var Code = str.split( "-" );
var sCode = Code[0];
var Mod = 0;
if( Code.length == 2 )
{
var m = true;
switch( Code[0] )
{
case "C": Mod = CTRL; break;
case "A": Mod = ALT; break;
case "S": Mod = SHIFT; break;
default:
m = false;
}
if( m )
{
sCode = Code[1];
}
}
var kCode;
switch( sCode )
{
case "BS": kCode = Mod + BACKSPACE; break;
case "Del": kCode = Mod + DELETE; break;
case "A": Mod = SHIFT; case "a": kCode = Mod + A; break;
case "B": Mod = SHIFT; case "b": kCode = Mod + B; break;
case "C": Mod = SHIFT; case "c": kCode = Mod + C; break;
case "D": Mod = SHIFT; case "d": kCode = Mod + D; break;
case "E": Mod = SHIFT; case "e": kCode = Mod + E; break;
case "F": Mod = SHIFT; case "f": kCode = Mod + F; break;
case "G": Mod = SHIFT; case "g": kCode = Mod + G; break;
case "H": Mod = SHIFT; case "h": kCode = Mod + H; break;
case "I": Mod = SHIFT; case "i": kCode = Mod + I; break;
case "J": Mod = SHIFT; case "j": kCode = Mod + J; break;
case "K": Mod = SHIFT; case "k": kCode = Mod + K; break;
case "L": Mod = SHIFT; case "l": kCode = Mod + L; break;
case "M": Mod = SHIFT; case "m": kCode = Mod + M; break;
case "N": Mod = SHIFT; case "n": kCode = Mod + N; break;
case "O": Mod = SHIFT; case "o": kCode = Mod + O; break;
case "P": Mod = SHIFT; case "p": kCode = Mod + P; break;
case "Q": Mod = SHIFT; case "q": kCode = Mod + Q; break;
case "R": Mod = SHIFT; case "r": kCode = Mod + R; break;
case "S": Mod = SHIFT; case "s": kCode = Mod + S; break;
case "T": Mod = SHIFT; case "t": kCode = Mod + T; break;
case "U": Mod = SHIFT; case "u": kCode = Mod + U; break;
case "V": Mod = SHIFT; case "v": kCode = Mod + V; break;
case "W": Mod = SHIFT; case "w": kCode = Mod + W; break;
case "X": Mod = SHIFT; case "x": kCode = Mod + X; break;
case "Y": Mod = SHIFT; case "y": kCode = Mod + Y; break;
case "Z": Mod = SHIFT; case "z": kCode = Mod + Z; break;
case "!": Mod = SHIFT; case "1": kCode = Mod + _1; break;
case "@": Mod = SHIFT; case "2": kCode = Mod + _2; break;
case "#": Mod = SHIFT; case "3": kCode = Mod + _3; break;
case "$": Mod = SHIFT; case "4": kCode = Mod + _4; break;
case "%": Mod = SHIFT; case "5": kCode = Mod + _5; break;
case "^": Mod = SHIFT; case "6": kCode = Mod + _6; break;
case "&": Mod = SHIFT; case "7": kCode = Mod + _7; break;
case "*": Mod = SHIFT; case "8": kCode = Mod + _8; break;
case "(": Mod = SHIFT; case "9": kCode = Mod + _9; break;
case ")": Mod = SHIFT; case "0": kCode = Mod + _0; break;
case "<": Mod = SHIFT; case ",": kCode = Mod + COMMA; break;
case ">": Mod = SHIFT; case ".": kCode = Mod + FULLSTOP; break;
default:
throw new Error( "Unsupport keys: " + str );
}
return __maps[ str ] = kCode;
};
var Controls = function( vimArea ) var Controls = function( vimArea )
{ {
/** @type {Components.Vim.VimArea} */ /** @type {Components.Vim.VimArea} */
this.__vimArea = vimArea this.__vimArea = vimArea
this.__keyChains = [];
this.__cfeeder = vimArea.contentFeeder;
this.__sfeeder = vimArea.statusFeeder;
this.__ccur = this.__cfeeder.cursor;
}; };
Controls.prototype.__comboG = function( keyCode ) Controls.prototype.__comp = function( kCode, handler )
{ {
var keyON = this.__keyChains[ 0 ] == G; if( handler )
if( keyON )
{ {
var cursor = this.__vimArea.contentFeeder.cursor; if( !this.__compReg ) this.__compReg = [];
switch( keyCode ) this.__compReg.push({
{ keys: Array.prototype.slice.call( arguments, 2 )
case G: , handler: handler
cursor.moveY( -Number.MAX_VALUE ); , i: 0
cursor.moveX( -Number.MAX_VALUE, true ); });
this.__keyChains = [];
return true;
default:
this.__keyChains = [];
beep();
return true;
}
}
else if( keyCode == G )
{
this.__keyChains[ 0 ] = G;
return true; return true;
} }
for( var i = 0; i < this.__compReg.length; i ++ )
{
var compReg = this.__compReg[i];
var keys = compReg.keys;
if( keys[ compReg.i ++ ] == kCode )
{
if( compReg.i == keys.length )
{
compReg.handler();
this.__compReg = null;
this.__cMovement = false;
}
return true;
}
}
if( this.__compReg ) beep();
this.__compReg = null;
this.__cMovement = false;
return false; return false;
}; };
Controls.prototype.__comboT = function( e ) { return false; }; Controls.prototype.__actionCommand = function( e )
// <
Controls.prototype.__comboLeftShift = function( e ) { return false; };
// >
Controls.prototype.__comboRightShift = function( e ) { return false; };
Controls.prototype.__comboKey = function( e )
{ {
return this.__comboG( e ) var ActionHandled = true;
|| this.__comboT( e ) var ccur = this.__ccur;
|| this.__comboLeftShift( e )
|| this.__comboRightShift( e ); // Action Command
switch( e.keyCode )
{
case SHIFT + A: // Append at the line end
ccur.lineEnd();
case A: // Append
this.__cMoveX( 1, true, true );
case I: // Insert
ccur.openAction( "INSERT" );
break;
case U: // Undo
ccur.openRunAction( "UNDO", e );
break;
case CTRL + R: // Redo
ccur.openRunAction( "REDO", e );
break;
case D: // Del with motion
ccur.openAction( "DELETE" );
break;
case X: // Del
break;
case SHIFT + X: // Delete before
break;
case SHIFT + U: // Undo previous changes in oneline
break;
case SHIFT + I: // Append before the line start, after spaces
break;
case SHIFT + J: // Join lines
break;
case SHIFT + K: // Find the manual entry
break;
case V: // Visual
ccur.openAction( "VISUAL" );
break;
case SHIFT + V: // Visual line
ccur.openAction( "VISUAL_LINE" );
break;
case F1: // F1, help
break;
default:
ActionHandled = false;
}
return ActionHandled;
}; };
Controls.prototype.handler = function( sender, e ) Controls.prototype.__cMoveX = function( a, b, c )
{ {
// Neve capture these keys var ccur = this.__ccur;
if( e.altKey
// F2 - F12
|| ( 112 < e.keyCode && e.keyCode < 124 )
) return;
var vArea = this.__vimArea;
// Action Mode handled by the actions themselves
var cfeeder = vArea.contentFeeder;
// Esc OR Ctrl + c
var Escape = e.keyCode == 27 || ( e.ctrlKey && e.keyCode == 67 );
// Clear the keychains in combo commands
if( Escape && this.__keyChains.length )
{
this.__keyChains = [];
beep();
return;
}
if( cfeeder.cursor.action )
{
if( Escape )
{
e.preventDefault();
cfeeder.cursor.closeAction();
}
else
{
cfeeder.cursor.action.handler( e );
}
return;
}
e.preventDefault();
var kCode = e.keyCode
+ ( e.shiftKey || e.getModifierState( "CapsLock" ) ? SHIFT : 0 )
+ ( e.ctrlKey ? CTRL : 0 );
// Handles long commands
if( this.__comboKey( kCode ) ) return;
var cfeeder = vArea.contentFeeder;
var sfeeder = vArea.statusFeeder;
var ccur = cfeeder.cursor;
var cMoveX = function( a, b, c )
{
var x = ccur.X; var x = ccur.X;
ccur.moveX( a, b, c ); ccur.moveX( a, b, c || ccur.pSpace );
if( ccur.X == x ) beep(); if( ccur.X == x ) beep();
}; };
var cMoveY = function( a ) Controls.prototype.__cMoveY = function( a )
{ {
var ccur = this.__ccur;
var cfeeder = this.__cfeeder;
var y = ccur.Y + cfeeder.panY; var y = ccur.Y + cfeeder.panY;
ccur.moveY( a ); ccur.moveY( a );
if( y == ( ccur.Y + cfeeder.panY ) ) if( y == ( ccur.Y + cfeeder.panY ) )
@ -139,79 +241,179 @@
} }
}; };
Controls.prototype.__cursorCommand = function( e )
{
var kCode = e.keyCode;
if( this.__cMovement && this.__comp )
{
if( !e.ModKeys )
{
this.__comp( kCode );
return true;
}
}
var ccur = this.__ccur;
var cursorHandled = true;
switch( kCode ) switch( kCode )
{ {
// Cursor movements case BACKSPACE: this.__cMoveX( -1, true ); break; // Backspace, go back 1 char
case BACKSPACE: // Backspace, go back 1 char, regardless of line case H: this.__cMoveX( -1 ); break; // Left
cMoveX( -1, true ); case L: this.__cMoveX( 1 ); break; // Right
break; case K: this.__cMoveY( -1 ); break; // Up
case H: // Left case J: this.__cMoveY( 1 ); break; // Down
cMoveX( -1 );
break;
case L: // Right
cMoveX( 1 );
break;
case K: // Up
cMoveY( -1 );
break;
case J: // Down
cMoveY( 1 );
break;
// Insert
case A: // Append
cMoveX( 1, true, true );
ccur.openAction( "INSERT" );
break;
case I: // Insert
break;
case U: // Undo
ccur.openRunAction( "UNDO", e );
break;
case CTRL + R: // Redo
ccur.openRunAction( "REDO", e );
break;
case X: // Del
break;
case SHIFT + A: // Append at the line end
break;
case SHIFT + X: // Delete before
break;
case SHIFT + U: // Undo previous changes in oneline
break;
case SHIFT + I: // Append before the line start, after spaces
break;
case SHIFT + G: // Goto last line
ccur.moveY( Number.MAX_VALUE );
ccur.moveX( Number.MAX_VALUE, true );
break;
// remove characters
case X: // Remove in cursor
break;
case SHIFT + X: // Remove before cursor
break;
case SHIFT + H: // First line buffer case SHIFT + H: // First line buffer
break; break;
case SHIFT + L: // Last line buffer case SHIFT + L: // Last line buffer
break; break;
case SHIFT + _4: // $, End
ccur.lineEnd();
break;
case SHIFT + _5: // %, Find next item
break;
case SHIFT + _6: // ^, Start case SHIFT + _6: // ^, Start
ccur.lineStart(); ccur.lineStart();
break; break;
case SHIFT + J: // Join lines case SHIFT + _4: // $, End
ccur.lineEnd( ccur.pSpace );
break; break;
case SHIFT + K: // manual entry case SHIFT + G: // Goto last line
ccur.moveY( Number.MAX_VALUE );
ccur.moveX( Number.MAX_VALUE, true );
break
case SHIFT + _5: // %, Find next item
break;
case T: // To
break;
case I: // In between boundary
if( !ccur.action )
{
cursorHandled = false;
break; break;
case 112: // F1, help
} }
this.__cMovement = true;
// Word boundary
this.__comp( kCode, function(){
debug.Info( "Word boundary" );
}, W );
this.__comp( kCode, function(){
debug.Info( "Bracket boundary [" );
}, S_BRACKET_L );
this.__comp( kCode, function(){
debug.Info( "Bracket boundary ]" );
}, S_BRACKET_R );
this.__comp( kCode, function(){
debug.Info( "Bracket boundary {" );
}, SHIFT + S_BRACKET_L );
this.__comp( kCode, function(){
debug.Info( "Bracket boundary }" );
}, SHIFT + S_BRACKET_R );
break;
case G: // Go to top
this.__cMovement = true;
this.__comp( kCode, function(){
ccur.moveY( -Number.MAX_VALUE );
ccur.moveX( -Number.MAX_VALUE, true );
}, G );
this.__comp( kCode, function(){
ccur.openRunAction( "PRINT_HEX", e );
}, _8 );
break;
default:
cursorHandled = false;
}
return cursorHandled;
};
/**
* sender @param {Components.Vim.VimArea}
* e @param {Components.Vim.Controls.InputEvent}
* */
Controls.prototype.handler = function( sender, e )
{
// Never capture these keys
if( e.keyCode == ( ALT + D )
// F2 - F12
|| ( F1 < e.keyCode && e.keyCode <= F12 )
) return;
// Clear composite command
if( e.Escape && this.__compReg )
{
this.__compReg = null;
this.__cMovement = false;
beep();
return;
}
var cfeeder = this.__cfeeder;
var ccur = this.__ccur;
var kCode = e.keyCode;
// Action commands are handled by the actions themselves
if( ccur.action )
{
if( e.Escape )
{
e.preventDefault();
ccur.closeAction();
}
else
{
if( ccur.action.allowMovement )
this.__cursorCommand( e, kCode );
if( ccur.action.handler( e ) )
{
ccur.closeAction();
}
}
return;
}
e.preventDefault();
if( this.__cursorCommand( e ) ) return;
if( this.__actionCommand( e ) ) return;
};
var InputEvent = function( sender, e )
{
this.__e = e;
this.__target = sender;
var c = this.__e.keyCode;
this.__escape = c == ESC || ( e.ctrlKey && c == C );
this.__kCode = c
+ ( e.shiftKey || e.getModifierState( "CapsLock" ) ? SHIFT : 0 )
+ ( e.ctrlKey ? CTRL : 0 )
+ ( e.altKey ? ALT : 0 );
this.__modKeys = c == KEY_SHIFT || c == KEY_CTRL || c == KEY_ALT;
this.__key = e.key;
};
__readOnly( InputEvent.prototype, "target", function() { return this.__target; } );
__readOnly( InputEvent.prototype, "key", function() { return this.__key; } );
__readOnly( InputEvent.prototype, "keyCode", function() { return this.__kCode; } );
__readOnly( InputEvent.prototype, "ModKeys", function() { return this.__modKeys; } );
__readOnly( InputEvent.prototype, "Escape", function() { return this.__escape; } );
InputEvent.prototype.kMap = function( map )
{
return this.__kCode == Map( map );
};
InputEvent.prototype.preventDefault = function()
{
if( this.__e ) this.__e.preventDefault();
}; };
ns[ NS_EXPORT ]( EX_CLASS, "Controls", Controls ); ns[ NS_EXPORT ]( EX_CLASS, "Controls", Controls );
ns[ NS_EXPORT ]( EX_CLASS, "InputEvent", InputEvent );
})(); })();

View File

@ -9,26 +9,6 @@
var Actions = __import( "Components.Vim.Actions.*" ); var Actions = __import( "Components.Vim.Actions.*" );
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 ) var LineOffset = function( buffs, l )
{ {
/** @type {Components.Vim.LineBuffer} */ /** @type {Components.Vim.LineBuffer} */
@ -55,6 +35,25 @@
return offset; return offset;
}; };
// Rush cursor to wanted position "d" then get the actual position
var GetRushPos = function( c, d )
{
var line = c.getLine();
var l = c.Y + d;
var i = c.Y;
// First line ( visual ) does not count
if( line != c.feeder.firstBuffer ) i --;
for( ; i < l; line = line.nextLine )
{
if( line.placeholder ) break;
if( line.br ) i ++;
}
return i;
};
var Cursor = function( feeder ) var Cursor = function( feeder )
{ {
/** @type {Components.Vim.LineFeeder} */ /** @type {Components.Vim.LineFeeder} */
@ -72,14 +71,23 @@
this.Y = 0; this.Y = 0;
// The resulting position // The resulting position
this.P = 0; this.PStart = 0;
this.PEnd = 1;
// State recorder // State recorder
this.rec = new Recorder(); this.rec = new Recorder();
this.action = null; this.action = null;
this.blink = true;
this.pSpace = false;
this.__suppEvt = 0;
}; };
// Set by VimArea
Cursor.prototype.Vim;
// Can only be 1, -1 // Can only be 1, -1
// 0 will be treated as undefined // 0 will be treated as undefined
Cursor.prototype.moveX = function( d, penentrate, phantomSpace ) Cursor.prototype.moveX = function( d, penentrate, phantomSpace )
@ -93,15 +101,18 @@
var buffs = this.feeder.lineBuffers; var buffs = this.feeder.lineBuffers;
if( penentrate && x < 0 && ( 0 < this.feeder.panY || 0 < this.Y ) ) if( penentrate )
{
if( x < 0 && ( 0 < this.feeder.panY || 0 < this.Y ) )
{ {
this.moveY( -1 ); this.moveY( -1 );
this.lineEnd( phantomSpace ); this.lineEnd( phantomSpace );
return; return;
} }
}
/** @type {Components.Vim.LineBuffer} */ /** @type {Components.Vim.LineBuffer} */
var line = GetLine( buffs, this.Y ); var line = this.getLine();
var content = line.visualLines.join( "\n" ); var content = line.visualLines.join( "\n" );
var cLen = content.length; var cLen = content.length;
@ -110,12 +121,12 @@
// Include empty lines befor cursor end // Include empty lines befor cursor end
if( ( phantomSpace && cLen - 1 <= x ) || ( cLen == 1 && c == undefined ) ) if( ( phantomSpace && cLen - 1 <= x ) || ( cLen == 1 && c == undefined ) )
{ {
x = d > 0 ? cLen - 1 : 0; x = 0 < d ? cLen - 1 : 0;
} }
// ( 2 < cLen ) Exclude empty lines at cursor end // ( 2 < cLen ) Exclude empty lines at cursor end
else if( ( 2 < cLen && x == cLen - 1 && c == " " ) || c == undefined ) else if( ( 2 <= cLen && x == cLen - 1 && c == " " ) || c == undefined )
{ {
x = d > 0 ? cLen - 2 : 0; x = 0 < d ? cLen - 2 : 0;
} }
else if( c == "\n" ) else if( c == "\n" )
{ {
@ -145,58 +156,98 @@
Cursor.prototype.updatePosition = function() Cursor.prototype.updatePosition = function()
{ {
this.P = this.X + LineOffset( this.feeder.lineBuffers, this.Y ); var P = this.X + LineOffset( this.feeder.lineBuffers, this.Y );
this.PStart = P;
this.PEnd = P + 1;
this.__p = P;
this.__fireUpdate();
};
Cursor.prototype.__fireUpdate = function()
{
if( 0 < this.__suppEvt )
{
debug.Info( "Event suppressed, suppression level is: " + this.__suppEvt );
return;
}
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
}; };
Cursor.prototype.moveY = function( d, penentrate ) Cursor.prototype.moveY = function( d, penentrate )
{ {
var i;
var Y = this.Y + d; var Y = this.Y + d;
var feeder = this.feeder;
var line; var line;
if( Y < 0 ) if( Y < 0 )
{ {
this.feeder.pan( undefined, d ); feeder.pan( undefined, d );
this.Y = 0; this.Y = 0;
this.moveX(); this.moveX();
this.updatePosition(); this.updatePosition();
this.feeder.softReset(); feeder.softReset();
return; return;
} }
else if( this.feeder.moreAt < Y ) // More at bottom, start panning
else if( !feeder.EOF && feeder.moreAt < Y )
{ {
var feeder = this.feeder; var feeder = this.feeder;
var lastLine = feeder.lastBuffer.lineNum;
var lineShift = Y - feeder.moreAt;
var i = 0; if( penentrate )
{
feeder.pan( undefined, Y - moreAt );
}
else if( feeder.linesTotal < Y )
{
while( !feeder.EOF ) while( !feeder.EOF )
{ {
feeder.pan( undefined, lineShift + i ); feeder.pan( undefined, 1 );
}
i = GetRushPos( this, d );
}
else
{
var lastLine = feeder.lastBuffer.lineNum;
var lineShift = Y - feeder.moreAt;
var thisLine = this.getLine().lineNum;
if( !feeder.EOF )
feeder.pan( undefined, lineShift );
// if it turns out to be the same line // if it turns out to be the same line
// before after panning // before after panning
// we keep scrolling it ( panning ) // we keep scrolling it ( panning )
// until the entire line cosumes the screen // until the entire line cosumes the screen
if( feeder.lastBuffer.lineNum == lastLine ) while( !feeder.EOF && feeder.lastBuffer.lineNum == lastLine )
{ {
i ++; feeder.pan( undefined, 1 );
}
else break;
} }
// The line number cursor need to be in // The line number cursor need to be in
Y = lastLine + lineShift; Y = thisLine + d;
// Calculate the visual line position i = this.Y;
for( i = 0, line = feeder.firstBuffer; this.Y = 0;
line != feeder.lastBuffer; // Calculate the visual line position "i"
line = line.next ) for( var line = this.getLine();
line && line.lineNum != Y && !line.placeholder;
this.Y ++, line = this.getLine() )
{ {
if( line.br ) i ++; }
if( line.lineNum == Y || line.next.placeholder ) break;
i = this.Y;
// Check if this line is collapsed
if( !feeder.EOF && feeder.lastBuffer.next.lineNum == line.lineNum )
{
// If yes, step back to last visible line
i --;
}
} }
this.Y = i; this.Y = i;
@ -204,20 +255,18 @@
this.moveX(); this.moveX();
this.updatePosition(); this.updatePosition();
// Because it is panned, soft reset is needed
feeder.softReset(); feeder.softReset();
return; return;
} }
else if ( 0 < d ) else if ( 0 < d )
{ {
// If panning is forward var line = this.getLine();
// and next line does not exists // If already at bottom
line = this.getLine().nextLine; if( line.nextLine.placeholder ) return;
if( !line || line.placeholder )
{ Y = GetRushPos( this, d );
// do nothing
return;
}
} }
this.Y = Y; this.Y = Y;
@ -226,25 +275,28 @@
this.updatePosition(); this.updatePosition();
}; };
// Open an action handler
// i.e. YANK, VISUAL, INSERT, UNDO, etc.
Cursor.prototype.openAction = function( name ) Cursor.prototype.openAction = function( name )
{ {
if( this.action ) this.action.dispose(); if( this.action ) this.action.dispose();
this.action = new (Actions[ name ])( this ); this.action = new (Actions[ name ])( this );
this.__pulseMsg = null; this.__pulseMsg = null;
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); this.__fireUpdate();
}; };
Cursor.prototype.closeAction = function() Cursor.prototype.closeAction = function()
{ {
if( !this.action ) return; if( !this.action ) return;
this.action.dispose(); this.action.dispose();
this.__pulseMsg = this.action.getMessage();
this.action = null; this.action = null;
this.__pulseMsg = null;
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); this.__fireUpdate();
}; };
// Open, Run, then close an action
Cursor.prototype.openRunAction = function( name, e ) Cursor.prototype.openRunAction = function( name, e )
{ {
/** @type {Components.Vim.IAction} */ /** @type {Components.Vim.IAction} */
@ -253,22 +305,26 @@
this.__pulseMsg = action.getMessage(); this.__pulseMsg = action.getMessage();
action.dispose(); action.dispose();
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); this.__fireUpdate();
}; };
Cursor.prototype.suppressEvent = function() { ++ this.__suppEvt; };
Cursor.prototype.unsuppressEvent = function() { -- this.__suppEvt; };
Cursor.prototype.getLine = function() Cursor.prototype.getLine = function()
{ {
var feeder = this.feeder; var feeder = this.feeder;
var line = feeder.firstBuffer; var line = feeder.firstBuffer;
var eBuffer = feeder.lastBuffer.next;
for( var i = 0; for( var i = 0;
line != feeder.lastBuffer; line != eBuffer;
line = line.next ) line = line.next )
{ {
if( line.br ) i ++; if( line.br ) i ++;
if( this.Y == i ) break; if( this.Y == i ) return line;
} }
return line; return null;
}; };
// The absX for current Line // The absX for current Line
@ -356,8 +412,8 @@
__readOnly( Cursor.prototype, "position", function() __readOnly( Cursor.prototype, "position", function()
{ {
return { return {
start: this.P start: this.PStart
, end: this.P + 1 , end: this.PEnd
}; };
} ); } );

View File

@ -9,6 +9,8 @@
/** @type {Components.Vim.Cursor} */ /** @type {Components.Vim.Cursor} */
var Cursor = ns[ NS_INVOKE ]( "Cursor" ); var Cursor = ns[ NS_INVOKE ]( "Cursor" );
var occurence = __import( "System.utils.Perf.CountSubstr" );
var Feeder = function( rows, cols ) var Feeder = function( rows, cols )
{ {
var lineBuffers = []; var lineBuffers = [];
@ -92,7 +94,7 @@
this.__softRender = function() this.__softRender = function()
{ {
var line = _self.lineBuffers[ _self.__rStart ]; var line = _self.lineBuffers[ _self.__rStart ];
var steps = _self.__rLength; var steps = _self.__rLength + 1;
for( var i = 0; for( var i = 0;
line && i < steps && ( line = line.next ) && placeholdCond( line ); line && i < steps && ( line = line.next ) && placeholdCond( line );
@ -170,7 +172,7 @@
}; };
__readOnly( Feeder.prototype, "linesTotal", function() { __readOnly( Feeder.prototype, "linesTotal", function() {
return this.content.match( "\n" ); return occurence( this.content, "\n" );
} ); } );
__readOnly( Feeder.prototype, "firstBuffer", function() { __readOnly( Feeder.prototype, "firstBuffer", function() {

View File

@ -0,0 +1,50 @@
(function(){
/* From Vim, :help registers
There are ten types of registers:
1. The unnamed register ""
2. 10 numbered registers "0 to "9
3. The small delete register "-
4. 26 named registers "a to "z or "A to "Z
5. three read-only registers ":, "., "%
6. alternate buffer register "#
7. the expression register "=
8. The selection and drop registers "*, "+ and "~
9. The black hole register "_
10. Last search pattern register "/
i.e. 0123456789-abcdefghijklmnopqrstuvwxyz:.%$=*+~_/
*/
var ns = __namespace( "Components.Vim.State" );
var Registers = function()
{
this.__registers = {};
};
Registers.prototype.unnamed = function( str )
{
this.__registers[ "\"" ] = str;
};
Registers.prototype.yank = function( str )
{
this.unnamed( str );
this.__registers[ 0 ] = str;
};
Registers.prototype.change = function( str )
{
this.unnamed( str );
var r = this.__registers;
for( var i = 9; 1 < i; i -- )
{
if( r[ i - 1 ] != undefined )
{
r[ i ] = r[ i - 1 ];
}
}
r[ 1 ] = str;
};
ns[ NS_EXPORT ]( EX_CLASS, "Registers", Registers );
})();

View File

@ -0,0 +1,71 @@
(function(){
var ns = __namespace( "Components.Vim.State" );
var Stator = function( cur, start )
{
this.__cursor = cur;
this.__startPosition = start == undefined ? cur.aPos : start;
this.__startState = this.__saveCur();
};
Stator.prototype.save = function( insertLength, contentUndo )
{
var cur = this.__cursor;
var feeder = cur.feeder;
var startPos = this.__startPosition;
if( insertLength < 0 )
{
startPos += insertLength;
insertLength = 0;
}
var sSt = this.__startState;
var eSt = this.__saveCur();
var st = sSt;
// Calling this repeatedly will swap between UNDO / REDO state
return function() {
var contentRedo = feeder.content.substr( startPos, insertLength );
feeder.content =
feeder.content.substring( 0, startPos )
+ contentUndo
+ feeder.content.substring( startPos + insertLength );
insertLength = contentUndo.length;
contentUndo = contentRedo;
cur.PStart = st.p;
cur.PEnd = st.p + 1;
cur.X = st.x;
cur.Y = st.y;
feeder.panX = st.px;
feeder.panY = st.py;
feeder.pan();
st = ( st == sSt ) ? eSt : sSt;
};
};
Stator.prototype.__saveCur = function()
{
var c = this.__cursor;
var obj = {
p: c.PStart
, x: c.X
, y: c.Y
, px: c.feeder.panX
, py: c.feeder.panY
};
if( 0 < obj.x )
{
obj.p -= 1;
obj.x -= 1;
}
return obj;
};
ns[ NS_EXPORT ]( EX_CLASS, "Stator", Stator );
})();

View File

@ -10,14 +10,20 @@
/** @type {System.Debug} */ /** @type {System.Debug} */
var debug = __import( "System.Debug" ); var debug = __import( "System.Debug" );
/** @type {Components.Vim.State.Registers} */
var Registers = __import( "Components.Vim.State.Registers" );
/** @type {Components.Vim.LineFeeder} */ /** @type {Components.Vim.LineFeeder} */
var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" ); var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
/** @type {Components.Vim.StatusBar} */ /** @type {Components.Vim.StatusBar} */
var StatusBar = ns[ NS_INVOKE ]( "StatusBar" ); var StatusBar = ns[ NS_INVOKE ]( "StatusBar" );
var VimControls = ns[ NS_INVOKE ]( "Controls" ); var VimControls = ns[ NS_INVOKE ]( "Controls" );
var InputEvent = ns[ NS_INVOKE ]( "InputEvent" );
var mesg = ns[ NS_INVOKE ]( "Message" ); var mesg = ns[ NS_INVOKE ]( "Message" );
var Insts = [];
var KeyHandler = function( sender, handler ) var KeyHandler = function( sender, handler )
{ {
return function( e ) return function( e )
@ -26,7 +32,7 @@
if ( e.keyCode ) code = e.keyCode; if ( e.keyCode ) code = e.keyCode;
else if ( e.which ) code = e.which; else if ( e.which ) code = e.which;
handler( sender, e ); handler( sender, new InputEvent( sender, e ) );
}; };
}; };
@ -53,17 +59,14 @@
var _self = this; var _self = this;
var controls = new VimControls( this );
stage.addEventListener(
"KeyDown"
, KeyHandler( this, controls.handler.bind( controls ) )
);
stage.addEventListener( "Focus", function() { _self.__active = true; } ); stage.addEventListener( "Focus", function() { _self.__active = true; } );
stage.addEventListener( "Blur", function() { _self.__active = false; } ); stage.addEventListener( "Blur", function() { _self.__active = false; } );
// Init // Init
this.VisualizeVimFrame( element.value ); this.VisualizeVimFrame( element.value );
// Push this instance
Insts.push( this );
}; };
VimArea.prototype.select = function( sel ) VimArea.prototype.select = function( sel )
@ -92,25 +95,24 @@
// Content feeder // Content feeder
var cfeeder = new LineFeeder( cRange, c ); var cfeeder = new LineFeeder( cRange, c );
cfeeder.init( content ); // Feed the contents to content feeder
// This "\n" fixes the last line "\n" not displaying
// it will be trimmed after saving
cfeeder.init( content + "\n" );
// Status can consumes up to full screen, I think // Status can consumes up to full screen, I think
sfeeder = new LineFeeder( r, c ); sfeeder = new LineFeeder( r, c );
sfeeder.setRender( false ); sfeeder.setRender( false );
// XXX: Placeholder // Set the Vim instance
cfeeder.cursor.Vim = this;
sfeeder.cursor.Vim = this;
// Set the stamps
var statusBar = new StatusBar( c ); var statusBar = new StatusBar( c );
statusBar.stamp( -18, function(){ statusBar.stamp( -18, function(){ return cfeeder.lineStat; } );
return cfeeder.lineStat; statusBar.stamp( -3, function(){ return mesg( cfeeder.docPos ); } );
}); statusBar.stamp( 0, function(){ return cfeeder.cursor.message; } );
statusBar.stamp( -3, function(){
return mesg( cfeeder.docPos );
} );
statusBar.stamp( 0, function(){
return cfeeder.cursor.message;
} );
sfeeder.init( statusBar.statusText ); sfeeder.init( statusBar.statusText );
@ -132,6 +134,7 @@
this.contentFeeder = cfeeder; this.contentFeeder = cfeeder;
this.statusFeeder = sfeeder; this.statusFeeder = sfeeder;
this.statusBar = statusBar; this.statusBar = statusBar;
this.registers = new Registers();
this.__cursor = cfeeder.cursor; this.__cursor = cfeeder.cursor;
@ -139,15 +142,25 @@
Cycle.perma( "VimCursorBlinkCycle" + element.id, function() Cycle.perma( "VimCursorBlinkCycle" + element.id, function()
{ {
_self.select( _self.select(
( _self.__blink = !_self.__blink ) !_self.__cursor.blink || ( _self.__blink = !_self.__blink )
? _self.__cursor.position ? _self.__cursor.position
: { start: 0, end: 0 } : { start: 0, end: 0 }
); );
}, 600 ); }, 600 );
var controls = new VimControls( this );
this.stage.addEventListener(
"KeyDown"
, KeyHandler( this, controls.handler.bind( controls ) )
);
}; };
__readOnly( VimArea, "Instances", function() {
return Insts.slice();
} );
__readOnly( VimArea.prototype, "content", function() { __readOnly( VimArea.prototype, "content", function() {
return this.contentFeeder.content; return this.contentFeeder.content.slice( 0, -1 );
} ); } );
ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea ); ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea );

View File

@ -5,6 +5,7 @@
"INSERT": "-- INSERT --" "INSERT": "-- INSERT --"
, "REPLACE": "-- REPLACE --" , "REPLACE": "-- REPLACE --"
, "MORE": "-- MORE --" , "MORE": "-- MORE --"
, "VISUAL": "-- VISUAL --"
, "VISLINE": "-- VISUAL LINE --" , "VISLINE": "-- VISUAL LINE --"
, "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"
@ -16,6 +17,8 @@
, "UNDO_LIMIT": "Already at oldest change" , "UNDO_LIMIT": "Already at oldest change"
, "REDO_LIMIT": "Already at newest change" , "REDO_LIMIT": "Already at newest change"
, "LINE_FEWER": "%1 fewer lines"
}; };
var errors = { var errors = {

View File

@ -14,10 +14,10 @@
Log.writeLine( e.name + "\n\t" + e.message + "\n\t" + e.stack, Log.ERROR ); Log.writeLine( e.name + "\n\t" + e.message + "\n\t" + e.stack, Log.ERROR );
}; };
var Info = function(e) var Info = function()
{ {
if( st_info ) if( st_info )
Log.writeLine( e, Log.INFO ); Log.writeLine( Array.prototype.join.call( arguments, " " ), Log.INFO );
}; };
var turnOff = function( what ) var turnOff = function( what )

View File

@ -0,0 +1,15 @@
/** @constructor */
Components.Vim.Controls.InputEvent = function(){};
/** @type {Components.Vim.VimArea} */
Components.Vim.Controls.InputEvent.target;
/** @type String */
Components.Vim.Controls.InputEvent.key;
/** @type Boolean */
Components.Vim.Controls.InputEvent.ModKeys;
/** @type Boolean */
Components.Vim.Controls.InputEvent.Escape;
/** @type Number */
Components.Vim.Controls.InputEvent.keyCode;
/** @type Function */
Components.Vim.Controls.InputEvent.kMap;

View File

@ -0,0 +1,2 @@
/** @constructor */
Components.Vim.Controls = function(){};

View File

@ -1,6 +1,8 @@
/** @constructor */ /** @constructor */
Components.Vim.Cursor = function(){}; Components.Vim.Cursor = function(){};
/** @type {Components.Vim.VimArea} */
Components.Vim.Cursor.Vim;
/** @type {Components.Vim.LineFeeder} */ /** @type {Components.Vim.LineFeeder} */
Components.Vim.Cursor.feeder; Components.Vim.Cursor.feeder;
/** @type {Components.Vim.IAction} */ /** @type {Components.Vim.IAction} */
@ -24,13 +26,23 @@ Components.Vim.Cursor.openAction;
Components.Vim.Cursor.openRunAction; Components.Vim.Cursor.openRunAction;
/** @type Function */ /** @type Function */
Components.Vim.Cursor.closeAction; Components.Vim.Cursor.closeAction;
/** @type Function */
Components.Vim.Cursor.suppressEvent;
/** @type Function */
Components.Vim.Cursor.unsuppressEvent;
/** @type {Boolean} */
Components.Vim.Cursor.blink;
/** @type {Boolean} */
Components.Vim.Cursor.pSpace;
/** @type {Array} */ /** @type {Array} */
Components.Vim.Cursor.lineBuffers; Components.Vim.Cursor.lineBuffers;
/** @type Number */ /** @type Number */
Components.Vim.Cursor.pX; Components.Vim.Cursor.pX;
/** @type Number */ /** @type Number */
Components.Vim.Cursor.P; Components.Vim.Cursor.PStart;
/** @type Number */
Components.Vim.Cursor.PEnd;
/** @type Number */ /** @type Number */
Components.Vim.Cursor.aX; Components.Vim.Cursor.aX;
/** @type Number */ /** @type Number */

View File

@ -7,3 +7,6 @@ Components.Vim.IAction.dispose;
Components.Vim.IAction.handler; Components.Vim.IAction.handler;
/** @type Function */ /** @type Function */
Components.Vim.IAction.getMessage; Components.Vim.IAction.getMessage;
/** @type Boolean */
Components.Vim.IAction.allowMovement;

View File

@ -37,6 +37,8 @@ Components.Vim.LineFeeder.panY;
/** @type Number */ /** @type Number */
Components.Vim.LineFeeder.moreAt; Components.Vim.LineFeeder.moreAt;
/** @type Number */ /** @type Number */
Components.Vim.LineFeeder.linesTotal;
/** @type Number */
Components.Vim.LineFeeder.linesOccupied; Components.Vim.LineFeeder.linesOccupied;
/** @type String */ /** @type String */
Components.Vim.LineFeeder.docPos; Components.Vim.LineFeeder.docPos;

View File

@ -2,8 +2,8 @@
Components.Vim.State.Recorder = function(){}; Components.Vim.State.Recorder = function(){};
/** @type Function */ /** @type Function */
Components.Vim.State.undo; Components.Vim.State.Recorder.undo;
/** @type Function */ /** @type Function */
Components.Vim.State.redo; Components.Vim.State.Recorder.redo;
/** @type Function */ /** @type Function */
Components.Vim.State.record; Components.Vim.State.Recorder.record;

View File

@ -0,0 +1,9 @@
/** @constructor */
Components.Vim.State.Registers = function(){};
/** @type Function */
Components.Vim.State.Registers.change;
/** @type Function */
Components.Vim.State.Registers.yank;
/** @type Function */
Components.Vim.State.Registers.unnamed;

View File

@ -12,3 +12,5 @@ Components.Vim.VimArea.statusBar;
Components.Vim.VimArea.rows; Components.Vim.VimArea.rows;
/** @type {Number} */ /** @type {Number} */
Components.Vim.VimArea.cols; Components.Vim.VimArea.cols;
/** @type {Array} */
Components.Vim.VimArea.Instances;