added g8, v ( hightlight only )

Some structural changes on VimControls
This commit is contained in:
斟酌 鵬兄 2016-03-22 02:08:07 +08:00
parent 8769e69f35
commit e52c312af5
8 changed files with 307 additions and 138 deletions

View File

@ -33,6 +33,8 @@
this.__rec( "", true ); this.__rec( "", true );
}; };
INSERT.prototype.allowMovement = false;
INSERT.prototype.__saveCur = function() INSERT.prototype.__saveCur = function()
{ {
var c = this.__cursor; var c = this.__cursor;
@ -80,7 +82,8 @@
insertLength = contentUndo.length; insertLength = contentUndo.length;
contentUndo = contentRedo; contentUndo = contentRedo;
cur.P = st.p; cur.PStart = st.p;
cur.PEnd = st.p + 1;
cur.X = st.x; cur.X = st.x;
cur.Y = st.y; cur.Y = st.y;
feeder.panX = st.px; feeder.panX = st.px;

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,67 @@
(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" );
var Mesg = __import( "Components.Vim.Message" );
/** @type {Components.Vim.Cursor.IAction} */
var VISUAL = function( Cursor )
{
/** @type {Components.Vim.Cursor} */
this.__cursor = Cursor;
this.__startaP = Cursor.aPos;
this.__start = Cursor.PStart;
this.__selStart = Cursor.PStart;
Cursor.blink = false;
};
VISUAL.prototype.allowMovement = true;
VISUAL.prototype.dispose = function()
{
this.__cursor.blink = true;
this.__cursor.PStart = this.__selStart;
this.__cursor.PEnd = this.__selStart + 1;
};
VISUAL.prototype.handler = function( e )
{
e.preventDefault();
if( [ 16, 17, 18 ].indexOf( e.keyCode ) != -1 ) return;
var cur = this.__cursor;
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()
{
var msg = Mesg( "VISUAL" );
return msg;
};
ns[ NS_EXPORT ]( EX_CLASS, "VISUAL", VISUAL );
})();

View File

@ -7,6 +7,10 @@
var SHIFT = 1 << 9; var SHIFT = 1 << 9;
var CTRL = 1 << 10; var CTRL = 1 << 10;
var KEY_SHIFT = 16;
var KEY_CTRL = 17;
var KEY_ALT = 18;
var BACKSPACE = 8; var BACKSPACE = 8;
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;
@ -29,132 +33,62 @@
{ {
/** @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();
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, kCode )
Controls.prototype.__comboD = function( e ) { return false; };
// <
Controls.prototype.__comboLeftShift = function( e ) { return false; };
// >
Controls.prototype.__comboRightShift = function( e ) { return false; };
Controls.prototype.__comboKey = function( e )
{ {
return this.__comboG( e )
|| this.__comboD( e )
|| this.__comboT( e )
|| this.__comboLeftShift( e )
|| this.__comboRightShift( e );
};
Controls.prototype.handler = function( sender, e )
{
// Neve capture these keys
if( e.altKey
// F2 - F12
|| ( F1 < 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 == ESC || ( e.ctrlKey && e.keyCode == C );
// 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;
ccur.moveX( a, b, c );
if( ccur.X == x ) beep();
};
var cMoveY = function( a )
{
var y = ccur.Y + cfeeder.panY;
ccur.moveY( a );
if( y == ( ccur.Y + cfeeder.panY ) )
{
if( 0 < a && !cfeeder.EOF ) return;
beep();
}
};
var ActionHandled = true; var ActionHandled = true;
// Action Commands var ccur = this.__ccur;
// Action Command
switch( kCode ) switch( kCode )
{ {
case SHIFT + A: // Append at the line end case SHIFT + A: // Append at the line end
ccur.lineEnd(); ccur.lineEnd();
case A: // Append case A: // Append
cMoveX( 1, true, true ); this.__cMoveX( 1, true, true );
case I: // Insert case I: // Insert
ccur.openAction( "INSERT" ); ccur.openAction( "INSERT" );
break; break;
@ -177,22 +111,67 @@
case SHIFT + K: // Find the manual entry case SHIFT + K: // Find the manual entry
break; break;
case V: // Visual
ccur.openAction( "VISUAL" );
break;
case SHIFT + V: // Visual line
ccur.openAction( "VISUAL_LINE" );
break;
case F1: // F1, help case F1: // F1, help
break; break;
default: default:
ActionHandled = false; ActionHandled = false;
} }
if( ActionHandled ) return; return ActionHandled;
};
// Cursor Commands Controls.prototype.__cMoveX = function( a, b, c )
{
var ccur = this.__ccur;
var x = ccur.X;
ccur.moveX( a, b, c );
if( ccur.X == x ) beep();
};
Controls.prototype.__cMoveY = function( a )
{
var ccur = this.__ccur;
var cfeeder = this.__cfeeder;
var y = ccur.Y + cfeeder.panY;
ccur.moveY( a );
if( y == ( ccur.Y + cfeeder.panY ) )
{
if( 0 < a && !cfeeder.EOF ) return;
beep();
}
};
Controls.prototype.__cursorCommand = function( e, kCode )
{
if( this.__cMovement && this.__comp )
{
var k = e.keyCode;
if(!( k == KEY_SHIFT || k == KEY_CTRL || k == KEY_ALT ))
{
this.__comp( kCode );
return true;
}
}
var ccur = this.__ccur;
var cursorHandled = true;
switch( kCode ) switch( kCode )
{ {
case BACKSPACE: cMoveX( -1, true ); break; // Backspace, go back 1 char, regardless of line case BACKSPACE: this.__cMoveX( -1, true ); break; // Backspace, go back 1 char, regardless of line
case H: cMoveX( -1 ); break; // Left case H: this.__cMoveX( -1 ); break; // Left
case L: cMoveX( 1 ); break; // Right case L: this.__cMoveX( 1 ); break; // Right
case K: cMoveY( -1 ); break; // Up case K: this.__cMoveY( -1 ); break; // Up
case J: cMoveY( 1 ); break; // Down case J: this.__cMoveY( 1 ); break; // Down
case SHIFT + H: // First line buffer case SHIFT + H: // First line buffer
break; break;
@ -207,24 +186,78 @@
case SHIFT + G: // Goto last line case SHIFT + G: // Goto last line
ccur.moveY( Number.MAX_VALUE ); ccur.moveY( Number.MAX_VALUE );
ccur.moveX( Number.MAX_VALUE, true ); ccur.moveX( Number.MAX_VALUE, true );
break; break
case SHIFT + _5: // %, Find next item case SHIFT + _5: // %, Find next item
break; 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;
};
// Integrated commands Controls.prototype.handler = function( sender, e )
switch( kCode )
{ {
case V: // Visual // Neve capture these keys
ccur.openAction( "VISUAL" ); if( e.altKey
break; // F2 - F12
case SHIFT + V: // Visual line || ( F1 < e.keyCode && e.keyCode < 124 )
ccur.openAction( "VISUAL_LINE" ); ) return;
break;
// Esc OR Ctrl + c
var Escape = e.keyCode == ESC || ( e.ctrlKey && e.keyCode == C );
// Clear composite command
if( Escape && this.__compReg )
{
this.__compReg = null;
this.__cMovement = false;
beep();
return;
} }
var cfeeder = this.__cfeeder;
var ccur = this.__ccur;
var kCode = e.keyCode
+ ( e.shiftKey || e.getModifierState( "CapsLock" ) ? SHIFT : 0 )
+ ( e.ctrlKey ? CTRL : 0 );
// Action commands are handled by the actions themselves
if( ccur.action )
{
if( Escape )
{
e.preventDefault();
ccur.closeAction();
}
else
{
if( ccur.action.allowMovement )
this.__cursorCommand( e, kCode );
ccur.action.handler( e );
}
return;
}
e.preventDefault();
if( this.__cursorCommand( e, kCode ) ) return;
if( this.__actionCommand( e, kCode ) ) return;
}; };
ns[ NS_EXPORT ]( EX_CLASS, "Controls", Controls ); ns[ NS_EXPORT ]( EX_CLASS, "Controls", Controls );

View File

@ -71,12 +71,15 @@
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;
}; };
// Can only be 1, -1 // Can only be 1, -1
@ -147,7 +150,11 @@
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.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) ); this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
}; };
@ -383,8 +390,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

@ -53,12 +53,6 @@
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; } );
@ -141,11 +135,17 @@
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.prototype, "content", function() { __readOnly( VimArea.prototype, "content", function() {

View File

@ -25,12 +25,16 @@ Components.Vim.Cursor.openRunAction;
/** @type Function */ /** @type Function */
Components.Vim.Cursor.closeAction; Components.Vim.Cursor.closeAction;
/** @type {Boolean} */
Components.Vim.Cursor.blink;
/** @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;