forked from Botanical/BotanJS
Some drafts
This commit is contained in:
commit
d6bbf245c6
195
botanjs/src/Components/Vim/LineFeeder.js
Normal file
195
botanjs/src/Components/Vim/LineFeeder.js
Normal file
@ -0,0 +1,195 @@
|
||||
(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 Line = function( cols, nextLine )
|
||||
{
|
||||
this.cols = cols;
|
||||
this.next = nextLine;
|
||||
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 lines = [];
|
||||
|
||||
// Last line
|
||||
lines[ rows - 1 ] = new Line( cols );
|
||||
|
||||
for( var i = rows - 2; 0 <= i; i -- )
|
||||
{
|
||||
lines[i] = new Line( cols, lines[ i + 1 ] );
|
||||
}
|
||||
|
||||
this.lines = lines;
|
||||
this.setRender();
|
||||
};
|
||||
|
||||
Feeder.prototype.init = function( content, wrap )
|
||||
{
|
||||
if( wrap == undefined ) wrap = true;
|
||||
if( this.lines.length )
|
||||
{
|
||||
this.lines[0].Push( content, wrap );
|
||||
}
|
||||
};
|
||||
|
||||
// Advance the text to number of lines
|
||||
Feeder.prototype.feed = function( num )
|
||||
{
|
||||
};
|
||||
|
||||
Feeder.prototype.wrap = function( setwrap )
|
||||
{
|
||||
};
|
||||
|
||||
Feeder.prototype.setRender = function( placeholder )
|
||||
{
|
||||
if( placeholder == undefined ) placeholder = true;
|
||||
|
||||
if( placeholder )
|
||||
{
|
||||
this.__render = function( line, steps )
|
||||
{
|
||||
var display = ( line == undefined ? "" : line ) + "";
|
||||
|
||||
for( var i = 0;
|
||||
line && i < steps && ( line = line.next );
|
||||
i ++ )
|
||||
{
|
||||
display += "\n" + line;
|
||||
}
|
||||
|
||||
return display;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
this.__render = function( line, steps )
|
||||
{
|
||||
var display = ( line == undefined ? "" : line ) + "";
|
||||
|
||||
for( var i = 0;
|
||||
line && i < steps && ( line = line.next ) && !line.placeholder;
|
||||
i ++ )
|
||||
{
|
||||
display += "\n" + line;
|
||||
}
|
||||
|
||||
return display;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Feeder.prototype.cursor = function( direction )
|
||||
{
|
||||
switch( direction )
|
||||
{
|
||||
case 0:
|
||||
return { start: 0, end: 1 };
|
||||
}
|
||||
};
|
||||
|
||||
Feeder.prototype.render = function( start, length )
|
||||
{
|
||||
if( start == undefined ) start = 0;
|
||||
else if( this.lines.length < start ) return "";
|
||||
|
||||
if( length == undefined || ( this.lines.length - start ) < length )
|
||||
length = this.lines.length - start;
|
||||
|
||||
if( length == 0 ) return "";
|
||||
|
||||
return this.__render( this.lines[ start ], length - 1 );
|
||||
};
|
||||
|
||||
__readOnly( Feeder.prototype, "linesOccupied", function() {
|
||||
var line = this.lines[0];
|
||||
if( line.placeholder ) return 0;
|
||||
|
||||
var i = 0;
|
||||
do i ++;
|
||||
while( ( line = line.next ) && !line.placeholder );
|
||||
return i;
|
||||
} );
|
||||
|
||||
ns[ NS_EXPORT ]( EX_CLASS, "LineFeeder", Feeder );
|
||||
})();
|
50
botanjs/src/Components/Vim/StatusBar.js
Normal file
50
botanjs/src/Components/Vim/StatusBar.js
Normal file
@ -0,0 +1,50 @@
|
||||
(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" );
|
||||
|
||||
/** @type {Components.VimArea.LineFeeder} */
|
||||
var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
|
||||
|
||||
var StatusBar = function( cols )
|
||||
{
|
||||
this.cols = cols;
|
||||
this.statStamp = {};
|
||||
};
|
||||
|
||||
StatusBar.prototype.stamp = function( pos, func )
|
||||
{
|
||||
this.statStamp[ pos ] = func;
|
||||
};
|
||||
|
||||
__readOnly( StatusBar.prototype, "statusText", function()
|
||||
{
|
||||
var display = "";
|
||||
var l = this.cols;
|
||||
|
||||
for( var i = 0; i < l; i ++ )
|
||||
{
|
||||
var avail = l - i;
|
||||
var text = this.statStamp[ i ] || this.statStamp[ - avail ];
|
||||
if( text )
|
||||
{
|
||||
text = text();
|
||||
display += text.substr( 0, avail );
|
||||
i = display.length - 1;
|
||||
}
|
||||
else display += " ";
|
||||
}
|
||||
|
||||
return display;
|
||||
} );
|
||||
|
||||
ns[ NS_EXPORT ]( EX_CLASS, "StatusBar", StatusBar );
|
||||
})();
|
163
botanjs/src/Components/Vim/VimArea.js
Normal file
163
botanjs/src/Components/Vim/VimArea.js
Normal file
@ -0,0 +1,163 @@
|
||||
(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.utils.DataKey} */
|
||||
var DataKey = __import( "System.utils.DataKey" );
|
||||
/** @type {System.Cycle} */
|
||||
var Cycle = __import( "System.Cycle" );
|
||||
/** @type {System.Debug} */
|
||||
var debug = __import( "System.Debug" );
|
||||
|
||||
/** @type {Components.VimArea.LineFeeder} */
|
||||
var LineFeeder = ns[ NS_INVOKE ]( "LineFeeder" );
|
||||
var StatusBar = ns[ NS_INVOKE ]( "StatusBar" );
|
||||
|
||||
var KeyHandler = function( sender, handler )
|
||||
{
|
||||
return function( e )
|
||||
{
|
||||
e = e || window.event;
|
||||
if ( e.keyCode ) code = e.keyCode;
|
||||
else if ( e.which ) code = e.which;
|
||||
|
||||
handler( sender, e );
|
||||
};
|
||||
};
|
||||
|
||||
var VimControls = function( sender, e )
|
||||
{
|
||||
e.preventDefault();
|
||||
if( e.ctrlKey )
|
||||
{
|
||||
VimComboFunc( sender, e );
|
||||
return;
|
||||
}
|
||||
|
||||
var kCode = e.KeyCode + ( e.shiftKey ? 1000 : 0 );
|
||||
switch( e.KeyCode )
|
||||
{
|
||||
case 65: // a
|
||||
case 1065: // A
|
||||
break;
|
||||
case 72: // h
|
||||
case 1072: // H
|
||||
break;
|
||||
case 74: // j
|
||||
case 1074: // J
|
||||
break;
|
||||
case 75: // k
|
||||
case 1075: // K
|
||||
break;
|
||||
case 76: // l
|
||||
case 1076: // L
|
||||
break;
|
||||
case 1053: // %
|
||||
case 1054: // ^
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/* stage @param {Dandelion.IDOMElement} */
|
||||
var VimArea = function( stage )
|
||||
{
|
||||
if( !stage ) return;
|
||||
|
||||
var element = stage.element;
|
||||
|
||||
if( element.nodeName != "TEXTAREA" )
|
||||
{
|
||||
debug.Error( "Element is not compatible for VimArea" );
|
||||
return;
|
||||
}
|
||||
|
||||
stage.setAttribute( new DataKey( "vimarea", 1 ) );
|
||||
|
||||
this.stage = stage;
|
||||
this.rows = element.rows;
|
||||
this.cols = element.cols;
|
||||
|
||||
this.PosX = 1;
|
||||
this.PosY = 1;
|
||||
|
||||
stage.addEventListener( "KeyDown", KeyHandler( this, VimControls ) );
|
||||
|
||||
// Init
|
||||
this.content = element.value;
|
||||
this.VisualizeVimFrame();
|
||||
};
|
||||
|
||||
VimArea.prototype.startInput = function( mode )
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
VimArea.prototype.cursor = function( x, y )
|
||||
{
|
||||
return this.__cursor();
|
||||
};
|
||||
|
||||
VimArea.prototype.flashCursor = function()
|
||||
{
|
||||
var _self = this;
|
||||
var textarea = this.stage.element;
|
||||
Cycle.perma( "VimCursorFlashCycle", function()
|
||||
{
|
||||
var cursor = _self.cursor();
|
||||
if( cursor )
|
||||
{
|
||||
textarea.selectionStart = cursor.start;
|
||||
textarea.selectionEnd = cursor.end;
|
||||
}
|
||||
}, 600 );
|
||||
};
|
||||
|
||||
VimArea.prototype.VisualizeVimFrame = function()
|
||||
{
|
||||
var element = this.stage.element;
|
||||
var r = this.rows;
|
||||
var c = this.cols;
|
||||
|
||||
// Content feeder
|
||||
var cfeeder = new LineFeeder( r, c );
|
||||
|
||||
cfeeder.init( this.content );
|
||||
|
||||
// Status feeder
|
||||
sfeeder = new LineFeeder( r, c );
|
||||
sfeeder.setRender( false );
|
||||
|
||||
var statusBar = new StatusBar( c );
|
||||
statusBar.stamp( -18, function(){
|
||||
return "1,1-1";
|
||||
});
|
||||
|
||||
statusBar.stamp( -3, function(){
|
||||
return "All";
|
||||
});
|
||||
|
||||
sfeeder.init( statusBar.statusText );
|
||||
|
||||
element.value = cfeeder.render( 0, r - sfeeder.linesOccupied ) + "\n" + sfeeder.render();
|
||||
|
||||
this.contentFeeder = cfeeder;
|
||||
this.statusFeeder = sfeeder;
|
||||
|
||||
var f = true;
|
||||
this.__cursor = function()
|
||||
{
|
||||
if( f = !f )
|
||||
return this.contentFeeder.cursor( 0 );
|
||||
else return { start: 0, end: 0 };
|
||||
}
|
||||
|
||||
this.flashCursor();
|
||||
};
|
||||
|
||||
ns[ NS_EXPORT ]( EX_CLASS, "VimArea", VimArea );
|
||||
})();
|
4
botanjs/src/Components/Vim/_this.css
Normal file
4
botanjs/src/Components/Vim/_this.css
Normal file
@ -0,0 +1,4 @@
|
||||
textarea[data-vimarea="1"] {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 #000;
|
||||
}
|
42
botanjs/src/Components/Vim/_this.js
Normal file
42
botanjs/src/Components/Vim/_this.js
Normal file
@ -0,0 +1,42 @@
|
||||
(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 messages = {
|
||||
"INSERT": "-- INSERT --"
|
||||
, "MORE": "-- MORE --"
|
||||
, "WRITE": "\"%1\" %2L, %3C written"
|
||||
, "CONTINUE": "Press ENTER or type command to continue"
|
||||
, "SEARCH_HIT_BOTTOM": "Seach hit BOTTOM, contining at TOP"
|
||||
, "TOP": "Top"
|
||||
, "BOTTOM": "Bot"
|
||||
, "ALL": "All"
|
||||
, "EXIT": "Type :quit<Enter> to exit Vim"
|
||||
};
|
||||
|
||||
var errors = {
|
||||
"E486": "E486: Pattern not found: %1"
|
||||
};
|
||||
|
||||
var Message = function( key )
|
||||
{
|
||||
var restArgs = Array.prototype.slice.apply( arguments, 1 );
|
||||
var i = 0;
|
||||
return messages[ key ].replace( /%\d+/g, function( e )
|
||||
{
|
||||
return restArgs[ i ++ ];
|
||||
} );
|
||||
};
|
||||
|
||||
ns[ NS_EXPORT ]( EX_FUNC, "Message", Message );
|
||||
})();
|
Loading…
Reference in New Issue
Block a user