commit 75662e6d0426339b1eff5d1499ca163761840b40
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2016-03-22T09:35:49Z |
| subject | Some placeholder commands in VISUAL |
commit 75662e6d0426339b1eff5d1499ca163761840b40
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2016-03-22T09:35:49Z
Some placeholder commands in VISUAL
---
botanjs/src/Components/Vim/Actions/DELETE.js | 32 ++++++++
botanjs/src/Components/Vim/Actions/VISUAL.js | 44 ++++++++--
botanjs/src/Components/Vim/Actions/YANK.js | 32 ++++++++
botanjs/src/Components/Vim/Controls.js | 96 +++++++++++++++++++++-
botanjs/src/Components/Vim/Cursor.js | 8 +-
botanjs/src/Components/Vim/State/Registers.js | 50 +++++++++++
botanjs/src/Components/Vim/VimArea.js | 34 +++++---
botanjs/src/externs/Components.Vim.Controls.js | 7 ++
botanjs/src/externs/Components.Vim.Cursor.js | 2 +
.../src/externs/Components.Vim.State.Recorder.js | 6 +-
.../src/externs/Components.Vim.State.Registers.js | 9 ++
botanjs/src/externs/Components.Vim.VimArea.js | 2 +
12 files changed, 296 insertions(+), 26 deletions(-)
diff --git a/botanjs/src/Components/Vim/Actions/DELETE.js b/botanjs/src/Components/Vim/Actions/DELETE.js
new file mode 100644
index 0000000..113a417
--- /dev/null
+++ b/botanjs/src/Components/Vim/Actions/DELETE.js
@@ -0,0 +1,32 @@
+(function(){
+ var ns = __namespace( "Components.Vim.Actions" );
+
+ var Mesg = __import( "Components.Vim.Message" );
+
+ /** @type {Components.Vim.Cursor.IAction} */
+ var DELETE = function( Cursor )
+ {
+ /** @type {Components.Vim.Cursor} */
+ this.__cursor = Cursor;
+ };
+
+ DELETE.prototype.allowMovement = true;
+
+ DELETE.prototype.dispose = function()
+ {
+
+ };
+
+ DELETE.prototype.handler = function( e )
+ {
+ e.preventDefault();
+
+ };
+
+ DELETE.prototype.getMessage = function()
+ {
+ return "<TODO> DELETE COMMAND";
+ };
+
+ ns[ NS_EXPORT ]( EX_CLASS, "DELETE", DELETE );
+})();
diff --git a/botanjs/src/Components/Vim/Actions/VISUAL.js b/botanjs/src/Components/Vim/Actions/VISUAL.js
index 752eaec..dad2fbb 100644
--- a/botanjs/src/Components/Vim/Actions/VISUAL.js
+++ b/botanjs/src/Components/Vim/Actions/VISUAL.js
@@ -1,12 +1,17 @@
(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 debug = __import( "System.Debug" );
var Mesg = __import( "Components.Vim.Message" );
+ /** @type {Components.Vim.Controls} */
+ var Controls = __import( "Components.Vim.Controls" );
+
+ /** @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 )
@@ -16,6 +21,8 @@
this.__startaP = Cursor.aPos;
this.__start = Cursor.PStart;
this.__selStart = Cursor.PStart;
+ this.__msg = Mesg( "VISUAL" );
+ this.__leaveMesg = "";
Cursor.blink = false;
};
@@ -24,17 +31,38 @@
VISUAL.prototype.dispose = function()
{
+ this.__msg = this.__leaveMesg;
this.__cursor.blink = true;
this.__cursor.PStart = this.__selStart;
this.__cursor.PEnd = this.__selStart + 1;
};
-
- VISUAL.prototype.handler = function( e )
+ VISUAL.prototype.handler = function( e, done )
{
e.preventDefault();
- if( [ 16, 17, 18 ].indexOf( e.keyCode ) != -1 ) return;
+ if( Controls.ModKeys( e ) ) return;
+
+ var Action = null;
+ switch( true )
+ {
+ case Controls.KMap( e, "y" ):
+ Action = new YANK( this.__cursor );
+ break;
+ case Controls.KMap( e, "d" ):
+ Action = new DELETE( this.__cursor );
+ break;
+ }
+
+ if( Action )
+ {
+ Action.handler( e );
+ this.__leaveMesg = Action.getMessage();
+ Action.dispose();
+
+ return true;
+ }
+
var cur = this.__cursor;
var prevPos = this.__start;
var newPos = cur.PStart;
@@ -58,9 +86,7 @@
VISUAL.prototype.getMessage = function()
{
- var msg = Mesg( "VISUAL" );
-
- return msg;
+ return this.__msg;
};
ns[ NS_EXPORT ]( EX_CLASS, "VISUAL", VISUAL );
diff --git a/botanjs/src/Components/Vim/Actions/YANK.js b/botanjs/src/Components/Vim/Actions/YANK.js
new file mode 100644
index 0000000..ba987d7
--- /dev/null
+++ b/botanjs/src/Components/Vim/Actions/YANK.js
@@ -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 );
+})();
diff --git a/botanjs/src/Components/Vim/Controls.js b/botanjs/src/Components/Vim/Controls.js
index f55181b..918cc41 100644
--- a/botanjs/src/Components/Vim/Controls.js
+++ b/botanjs/src/Components/Vim/Controls.js
@@ -1,6 +1,7 @@
(function(){
var ns = __namespace( "Components.Vim" );
+ /** @type {System.Debug} */
var debug = __import( "System.Debug" );
var beep = ns[ NS_INVOKE ]( "Beep" );
@@ -29,6 +30,81 @@
var F6 = 117; var F7 = 118; var F8 = 119; var F9 = 120; var F10 = 121;
var F11 = 122; var F12 = 123;
+ 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 "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;
+ default:
+ throw new Error( "No such keys: " + str );
+ }
+
+ return __maps[ str ] = kCode;
+ };
+
var Controls = function( vimArea )
{
/** @type {Components.Vim.VimArea} */
@@ -249,7 +325,10 @@
if( ccur.action.allowMovement )
this.__cursorCommand( e, kCode );
- ccur.action.handler( e );
+ if( ccur.action.handler( e ) )
+ {
+ ccur.closeAction();
+ }
}
return;
}
@@ -260,5 +339,20 @@
if( this.__actionCommand( e, kCode ) ) return;
};
+ __static_method( Controls, "ModKeys", function( e )
+ {
+ var c = e.keyCode;
+ return c == KEY_SHIFT || c == KEY_CTRL || c == KEY_ALT;
+ } );
+
+ __static_method( Controls, "KMap", function( e, map )
+ {
+ var kCode = e.keyCode
+ + ( e.shiftKey || e.getModifierState( "CapsLock" ) ? SHIFT : 0 )
+ + ( e.ctrlKey ? CTRL : 0 );
+
+ return kCode == Map( map );
+ } );
+
ns[ NS_EXPORT ]( EX_CLASS, "Controls", Controls );
})();
diff --git a/botanjs/src/Components/Vim/Cursor.js b/botanjs/src/Components/Vim/Cursor.js
index 51377a5..0481f30 100644
--- a/botanjs/src/Components/Vim/Cursor.js
+++ b/botanjs/src/Components/Vim/Cursor.js
@@ -82,6 +82,9 @@
this.blink = true;
};
+ // Set by VimArea
+ Cursor.prototype.Vim;
+
// Can only be 1, -1
// 0 will be treated as undefined
Cursor.prototype.moveX = function( d, penentrate, phantomSpace )
@@ -259,6 +262,8 @@
this.updatePosition();
};
+ // Open an action handler
+ // i.e. YANK, VISUAL, INSERT, UNDO, etc.
Cursor.prototype.openAction = function( name )
{
if( this.action ) this.action.dispose();
@@ -272,12 +277,13 @@
{
if( !this.action ) return;
this.action.dispose();
+ this.__pulseMsg = this.action.getMessage();
this.action = null;
- this.__pulseMsg = null;
this.feeder.dispatcher.dispatchEvent( new BotanEvent( "VisualUpdate" ) );
};
+ // Open, Run, then close an action
Cursor.prototype.openRunAction = function( name, e )
{
/** @type {Components.Vim.IAction} */
diff --git a/botanjs/src/Components/Vim/State/Registers.js b/botanjs/src/Components/Vim/State/Registers.js
new file mode 100644
index 0000000..220fe70
--- /dev/null
+++ b/botanjs/src/Components/Vim/State/Registers.js
@@ -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 );
+})();
diff --git a/botanjs/src/Components/Vim/VimArea.js b/botanjs/src/Components/Vim/VimArea.js
index 8ecb7a9..d02bdf4 100644
--- a/botanjs/src/Components/Vim/VimArea.js
+++ b/botanjs/src/Components/Vim/VimArea.js
@@ -10,6 +10,9 @@
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
+ /** @type {Components.Vim.State.Registers} */
+ var Registers = __import( "Components.Vim.State.Registers" );
+
/** @type {Components.Vim.LineFeeder} */
var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
/** @type {Components.Vim.StatusBar} */
@@ -18,6 +21,8 @@
var VimControls = ns[ NS_INVOKE ]( "Controls" );
var mesg = ns[ NS_INVOKE ]( "Message" );
+ var Insts = [];
+
var KeyHandler = function( sender, handler )
{
return function( e )
@@ -58,6 +63,9 @@
// Init
this.VisualizeVimFrame( element.value );
+
+ // Push this instance
+ Insts.push( this );
};
VimArea.prototype.select = function( sel )
@@ -86,6 +94,7 @@
// Content feeder
var cfeeder = new LineFeeder( cRange, c );
+ // 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" );
@@ -94,19 +103,15 @@
sfeeder = new LineFeeder( r, c );
sfeeder.setRender( false );
- // XXX: Placeholder
- var statusBar = new StatusBar( c );
- statusBar.stamp( -18, function(){
- return cfeeder.lineStat;
- });
-
- statusBar.stamp( -3, function(){
- return mesg( cfeeder.docPos );
- } );
+ // Set the Vim instance
+ cfeeder.cursor.Vim = this;
+ sfeeder.cursor.Vim = this;
- statusBar.stamp( 0, function(){
- return cfeeder.cursor.message;
- } );
+ // Set the stamps
+ var statusBar = new StatusBar( c );
+ statusBar.stamp( -18, function(){ return cfeeder.lineStat; } );
+ statusBar.stamp( -3, function(){ return mesg( cfeeder.docPos ); } );
+ statusBar.stamp( 0, function(){ return cfeeder.cursor.message; } );
sfeeder.init( statusBar.statusText );
@@ -128,6 +133,7 @@
this.contentFeeder = cfeeder;
this.statusFeeder = sfeeder;
this.statusBar = statusBar;
+ this.registers = new Registers();
this.__cursor = cfeeder.cursor;
@@ -148,6 +154,10 @@
);
};
+ __readOnly( VimArea, "Instances", function() {
+ return Insts.slice();
+ } );
+
__readOnly( VimArea.prototype, "content", function() {
return this.contentFeeder.content.slice( 0, -1 );
} );
diff --git a/botanjs/src/externs/Components.Vim.Controls.js b/botanjs/src/externs/Components.Vim.Controls.js
new file mode 100644
index 0000000..6fec2e7
--- /dev/null
+++ b/botanjs/src/externs/Components.Vim.Controls.js
@@ -0,0 +1,7 @@
+/** @constructor */
+Components.Vim.Controls = function(){};
+
+/** @type Function */
+Components.Vim.Controls.ModKeys;
+/** @type Function */
+Components.Vim.Controls.KMap;
diff --git a/botanjs/src/externs/Components.Vim.Cursor.js b/botanjs/src/externs/Components.Vim.Cursor.js
index 0873383..76fef9d 100644
--- a/botanjs/src/externs/Components.Vim.Cursor.js
+++ b/botanjs/src/externs/Components.Vim.Cursor.js
@@ -1,6 +1,8 @@
/** @constructor */
Components.Vim.Cursor = function(){};
+/** @type {Components.Vim.VimArea} */
+Components.Vim.Cursor.Vim;
/** @type {Components.Vim.LineFeeder} */
Components.Vim.Cursor.feeder;
/** @type {Components.Vim.IAction} */
diff --git a/botanjs/src/externs/Components.Vim.State.Recorder.js b/botanjs/src/externs/Components.Vim.State.Recorder.js
index 0303938..b39cbf9 100644
--- a/botanjs/src/externs/Components.Vim.State.Recorder.js
+++ b/botanjs/src/externs/Components.Vim.State.Recorder.js
@@ -2,8 +2,8 @@
Components.Vim.State.Recorder = function(){};
/** @type Function */
-Components.Vim.State.undo;
+Components.Vim.State.Recorder.undo;
/** @type Function */
-Components.Vim.State.redo;
+Components.Vim.State.Recorder.redo;
/** @type Function */
-Components.Vim.State.record;
+Components.Vim.State.Recorder.record;
diff --git a/botanjs/src/externs/Components.Vim.State.Registers.js b/botanjs/src/externs/Components.Vim.State.Registers.js
new file mode 100644
index 0000000..75b9c13
--- /dev/null
+++ b/botanjs/src/externs/Components.Vim.State.Registers.js
@@ -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;
diff --git a/botanjs/src/externs/Components.Vim.VimArea.js b/botanjs/src/externs/Components.Vim.VimArea.js
index e71c020..982acda 100644
--- a/botanjs/src/externs/Components.Vim.VimArea.js
+++ b/botanjs/src/externs/Components.Vim.VimArea.js
@@ -12,3 +12,5 @@ Components.Vim.VimArea.statusBar;
Components.Vim.VimArea.rows;
/** @type {Number} */
Components.Vim.VimArea.cols;
+/** @type {Array} */
+Components.Vim.VimArea.Instances;