1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 06:47:58 +01:00

removed block cursor, it is just too unreliable :(

Many improvments in textarea mode with support for motion commands like c or d;
initial f,F,t and T support (only textarea + visual mode, no motion yet);
This commit is contained in:
Martin Stubenschrott
2007-09-12 05:43:11 +00:00
parent c9865eba27
commit 9a7ecb0f5c
5 changed files with 462 additions and 124 deletions

View File

@@ -19,6 +19,10 @@
function Editor() //{{{ function Editor() //{{{
{ {
// store our last search with f,F,t or T
var last_findChar = null;
var last_findChar_func = null;
function editor() function editor()
{ {
return window.document.commandDispatcher.focusedElement; return window.document.commandDispatcher.focusedElement;
@@ -33,6 +37,29 @@ function Editor() //{{{
return el.controllers.getControllerAt(0); return el.controllers.getControllerAt(0);
} }
this.line = function()
{
var line = 1;
var text = editor().value;
for (var i = 0; i < editor().selectionStart; i++)
if (text[i] == "\n")
line++;
return line;
}
this.col = function()
{
var col = 1;
var text = editor().value;
for (var i = 0; i < editor().selectionStart; i++)
{
col++;
if (text[i] == "\n")
col = 1;
}
return col;
}
this.unselectText = function() this.unselectText = function()
{ {
var elt = window.document.commandDispatcher.focusedElement; var elt = window.document.commandDispatcher.focusedElement;
@@ -40,6 +67,12 @@ function Editor() //{{{
return true; return true;
} }
this.selectedText = function()
{
var text = editor().value;
return text.substring(editor().selectionStart, editor().selectionEnd);
}
this.pasteClipboard = function() this.pasteClipboard = function()
{ {
var elt = window.document.commandDispatcher.focusedElement; var elt = window.document.commandDispatcher.focusedElement;
@@ -86,9 +119,6 @@ function Editor() //{{{
{ {
controller.doCommand(cmd); controller.doCommand(cmd);
did_command = true; did_command = true;
if (vimperator.hasMode(vimperator.modes.TEXTAREA))
this.moveCaret();
} }
catch(e) catch(e)
{ {
@@ -101,47 +131,195 @@ function Editor() //{{{
return true; return true;
} }
// cmd = y, d, c
// motion = b, 0, gg, G, etc.
this.executeCommandWithMotion = function(cmd, motion, count)
{
if (!typeof count == "number" || count < 1)
count = 1;
if (cmd == motion)
{
motion = "j";
count--;
}
switch (motion)
{
case "j":
this.executeCommand("cmd_beginLine", 1);
this.executeCommand("cmd_selectLineNext", count+1);
break;
case "k":
this.executeCommand("cmd_beginLine", 1);
this.executeCommand("cmd_lineNext", 1);
this.executeCommand("cmd_selectLinePrevious", count+1);
break;
case "h":
this.executeCommand("cmd_selectCharPrevious", count);
break;
case "l":
this.executeCommand("cmd_selectCharNext", count);
break;
case "e":
case "w":
this.executeCommand("cmd_selectWordNext", count);
break;
case "b":
this.executeCommand("cmd_selectWordPrevious", count);
break;
case "0":
case "^":
this.executeCommand("cmd_selectBeginLine", 1);
break;
case "$":
this.executeCommand("cmd_selectEndLine", 1);
break;
case "gg":
this.executeCommand("cmd_endLine", 1);
this.executeCommand("cmd_selectTop", 1);
this.executeCommand("cmd_selectBeginLine", 1);
break;
case "G":
this.executeCommand("cmd_beginLine", 1);
this.executeCommand("cmd_selectBottom", 1);
this.executeCommand("cmd_selectEndLine", 1);
break;
default:
vimperator.beep();
return false;
}
switch (cmd)
{
case "d":
this.executeCommand("cmd_delete", 1);
// need to reset the mode as the visual selection changes it
vimperator.setMode(vimperator.modes.TEXTAREA);
break;
case "c":
this.executeCommand("cmd_delete", 1);
this.startInsert();
break;
case "y":
this.executeCommand("cmd_copy", 1);
this.unselectText();
break;
default:
vimperator.beep();
return false;
}
return true;
}
this.startNormal = function() this.startNormal = function()
{ {
vimperator.setMode(vimperator.modes.TEXTAREA); vimperator.setMode(vimperator.modes.TEXTAREA);
this.moveCaret();
}
this.startVisual = function() //var self = this;
{ //editor().addEventListener("mouseclick", function() {
vimperator.setMode(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA); // setTimeout(function() {
// pos = editor().selectionStart;
// self.moveCaret(pos);
// }, 10);
//}, false);
} }
this.startInsert = function() this.startInsert = function()
{ {
vimperator.setMode(vimperator.modes.INSERT, vimperator.modes.TEXTAREA); vimperator.setMode(vimperator.modes.INSERT, vimperator.modes.TEXTAREA);
this.moveCaret();
} }
this.stopInsert = function() // This function will move/select up to given "pos"
// Simple setSelectionRange() would be better, but we want to maintain the correct
// order of selectionStart/End (a firefox bug always makes selectionStart <= selectionEnd)
// Use only for small movements!
this.moveToPosition = function(pos, forward, select)
{ {
vimperator.setMode(vimperator.modes.TEXTAREA); if (!select)
this.moveCaret(); {
}
// very rudimentary testing code
this.moveCaret = function(pos)
{
if (!pos)
pos = editor().selectionStart - 1;
if (!vimperator.hasMode(vimperator.modes.INSERT))
editor().setSelectionRange(pos, pos+1);
else if (!vimperator.hasMode(vimperator.modes.VISUAL))
editor().setSelectionRange(pos, pos); editor().setSelectionRange(pos, pos);
return;
}
if (forward)
{
if (pos <= editor().selectionEnd || pos > editor().value.length)
return false;
do // TODO: test code for endless loops
{
this.executeCommand("cmd_selectCharNext", 1);
}
while ( editor().selectionEnd != pos );
}
else
{
if (pos >= editor().selectionStart || pos < 0)
return false;
do // TODO: test code for endless loops
{
this.executeCommand("cmd_selectCharPrevious", 1);
}
while ( editor().selectionStart != pos );
}
} }
// cmd = y, d, c // returns the position of char
// motion = b, 0, gg, G, etc. this.findCharForward = function(char, count)
this.executeCommandWithMotion = function(cmd, motion)
{ {
if (!editor())
return -1;
last_findChar = char;
last_findChar_func = this.findCharForward;
var text = editor().value;
if (!typeof count == "number" || count < 1)
count = 1;
for (var i = editor().selectionEnd + 1; i < text.length; i++)
{
if (text[i] == "\n")
break;
if (text[i] == char)
count--;
if (count == 0)
return i + 1; // always position the cursor after the char
}
vimperator.beep();
return -1;
} }
// returns the position of char
this.findCharBackward = function(char, count)
{
if (!editor())
return -1;
last_findChar = char;
last_findChar_func = this.findCharBackward;
var text = editor().value;
if (!typeof count == "number" || count < 1)
count = 1;
for (var i = editor().selectionStart - 1; i >= 0; i--)
{
if (text[i] == "\n")
break;
if (text[i] == char)
count--;
if (count == 0)
return i;
}
vimperator.beep();
return -1;
}
} //}}} } //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -64,9 +64,6 @@ function Events() //{{{
// this adds an event which is is called on each page load, even if the // this adds an event which is is called on each page load, even if the
// page is loaded in a background tab // page is loaded in a background tab
getBrowser().addEventListener("load", onPageLoad, true); getBrowser().addEventListener("load", onPageLoad, true);
// to keep track if we are in a text field
//getBrowser().addEventListener("focus", onFocus, true);
//getBrowser().addEventListener("focus", onFocus, true);
// called when the active document is scrolled // called when the active document is scrolled
getBrowser().addEventListener("scroll", function (event) getBrowser().addEventListener("scroll", function (event)
@@ -75,12 +72,10 @@ function Events() //{{{
vimperator.setMode(); // trick to reshow the mode in the command line vimperator.setMode(); // trick to reshow the mode in the command line
}, null); }, null);
//
/////////////////////////////////////////////////////////
// track if a popup is open or the menubar is active // track if a popup is open or the menubar is active
//
var active_menubar = false; var active_menubar = false;
function enterPopupMode(event) function enterPopupMode(event)
{ {
if (event.originalTarget.localName == "tooltip" || event.originalTarget.id == "vimperator-visualbell") if (event.originalTarget.localName == "tooltip" || event.originalTarget.id == "vimperator-visualbell")
@@ -88,35 +83,31 @@ function Events() //{{{
vimperator.addMode(null, vimperator.modes.MENU); vimperator.addMode(null, vimperator.modes.MENU);
} }
function exitPopupMode() function exitPopupMode()
{ {
// gContextMenu is set to NULL by firefox, when a context menu is closed // gContextMenu is set to NULL by firefox, when a context menu is closed
if (!gContextMenu && !active_menubar) if (!gContextMenu && !active_menubar)
vimperator.removeMode(null, vimperator.modes.MENU); vimperator.removeMode(null, vimperator.modes.MENU);
} }
function enterMenuMode() function enterMenuMode()
{ {
active_menubar = true; active_menubar = true;
vimperator.addMode(null, vimperator.modes.MENU) vimperator.addMode(null, vimperator.modes.MENU)
} }
function exitMenuMode() function exitMenuMode()
{ {
active_menubar = false; active_menubar = false;
vimperator.removeMode(null, vimperator.modes.MENU); vimperator.removeMode(null, vimperator.modes.MENU);
} }
window.addEventListener("popupshown", enterPopupMode, true); window.addEventListener("popupshown", enterPopupMode, true);
window.addEventListener("popuphidden", exitPopupMode, true); window.addEventListener("popuphidden", exitPopupMode, true);
window.addEventListener("DOMMenuBarActive", enterMenuMode, true); window.addEventListener("DOMMenuBarActive", enterMenuMode, true);
window.addEventListener("DOMMenuBarInactive", exitMenuMode, true); window.addEventListener("DOMMenuBarInactive", exitMenuMode, true);
window.document.addEventListener("DOMTitleChanged", function(event) // window.document.addEventListener("DOMTitleChanged", function(event)
{ // {
//alert("titlechanged"); // vimperator.log("titlechanged");
}, null); // }, null);
// NOTE: the order of ["Esc", "Escape"] or ["Escape", "Esc"] // NOTE: the order of ["Esc", "Escape"] or ["Escape", "Esc"]
// matters, so use that string as the first item, that you // matters, so use that string as the first item, that you
@@ -381,7 +372,8 @@ function Events() //{{{
return (key == "<Esc>" || key == "<C-[>" || key == "<C-c>"); return (key == "<Esc>" || key == "<C-[>" || key == "<C-c>");
} }
// event is delibarately not used, as i don't seem to have access to the really focus target // argument "event" is delibarately not used, as i don't seem to have
// access to the real focus target
this.onFocusChange = function(event) this.onFocusChange = function(event)
{ {
if (vimperator.hasMode(vimperator.modes.COMMAND_LINE)) if (vimperator.hasMode(vimperator.modes.COMMAND_LINE))
@@ -397,16 +389,43 @@ function Events() //{{{
else if (elem && elem instanceof HTMLTextAreaElement) else if (elem && elem instanceof HTMLTextAreaElement)
{ {
if (elem.selectionEnd - elem.selectionStart > 0) if (elem.selectionEnd - elem.selectionStart > 0)
vimperator.editor.startVisual(); vimperator.setMode(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA);
else else
vimperator.editor.startNormal(); vimperator.editor.startNormal();
vimperator.buffer.lastInputField = elem; vimperator.buffer.lastInputField = elem;
} }
else else if //(vimperator.hasMode(vimperator.modes.VISUAL) ||
{ (vimperator.hasMode(vimperator.modes.INSERT) ||
if (vimperator.hasMode(vimperator.modes.INSERT) ||
vimperator.hasMode(vimperator.modes.TEXTAREA)) vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.setMode(vimperator.modes.NORMAL); // FIXME: remember previous mode vimperator.setMode(vimperator.modes.NORMAL);
}
this.onSelectionChange = function(event)
{
vimperator.log("onselection");
var could_copy = false;
var controller = document.commandDispatcher.getControllerForCommand("cmd_copy");
if (controller && controller.isCommandEnabled("cmd_copy"))
could_copy = true;
var extended = vimperator.modes.NONE;
if (vimperator.hasMode(vimperator.modes.TEXTAREA))
extended = vimperator.modes.TEXTAREA;
else if (vimperator.hasMode(vimperator.modes.CARET))
extended = vimperator.modes.CARET;
if (could_copy && !vimperator.hasMode(vimperator.modes.VISUAL) &&
(vimperator.hasMode(vimperator.modes.NORMAL) ||
vimperator.hasMode(vimperator.modes.TEXTAREA) ||
vimperator.hasMode(vimperator.modes.CARET)))
{
vimperator.setMode(vimperator.modes.VISUAL, extended);
}
else if (vimperator.hasMode(vimperator.modes.VISUAL))
{
if (!could_copy && !vimperator.hasMode(vimperator.modes.CARET) &&
!vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.setMode(extended || vimperator.modes.NORMAL);
} }
} }
@@ -416,16 +435,23 @@ function Events() //{{{
{ {
if (!vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY)) if (!vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY))
{ {
// clear any selection made
// FIXME: need to make more general to allow caret/visual mode also for text fields
var selection = window.content.getSelection();
selection.collapseToStart();
if (vimperator.hasMode(vimperator.modes.VISUAL)) if (vimperator.hasMode(vimperator.modes.VISUAL))
{ {
if (vimperator.hasMode(vimperator.modes.TEXTAREA)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
{
vimperator.editor.unselectText(); vimperator.editor.unselectText();
vimperator.setMode(vimperator.getMode()[1], vimperator.modes.NONE); vimperator.setMode(vimperator.modes.TEXTAREA, vimperator.modes.NONE);
}
else
{
// clear any selection made
var selection = window.content.getSelection();
selection.collapseToStart();
if (vimperator.hasMode(vimperator.modes.CARET)) // set as an extended mode
vimperator.setMode(vimperator.modes.CARET);
else
vimperator.setMode(vimperator.modes.NORMAL);
}
} }
else if (vimperator.hasMode(vimperator.modes.CARET)) else if (vimperator.hasMode(vimperator.modes.CARET))
{ {
@@ -436,7 +462,7 @@ function Events() //{{{
else if (vimperator.hasMode(vimperator.modes.INSERT)) else if (vimperator.hasMode(vimperator.modes.INSERT))
{ {
if(vimperator.hasMode(vimperator.modes.TEXTAREA)) if(vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.editor.stopInsert(); vimperator.setMode(vimperator.modes.TEXTAREA);
else else
{ {
vimperator.editor.unselectText(); vimperator.editor.unselectText();
@@ -452,8 +478,6 @@ function Events() //{{{
vimperator.statusline.updateUrl(); vimperator.statusline.updateUrl();
vimperator.focusContent(); vimperator.focusContent();
} }
} }
} }
@@ -491,7 +515,8 @@ function Events() //{{{
// FIXME: proper way is to have a better onFocus handler which also handles events for the XUL // FIXME: proper way is to have a better onFocus handler which also handles events for the XUL
if (!vimperator.hasMode(vimperator.modes.TEXTAREA) && if (!vimperator.hasMode(vimperator.modes.TEXTAREA) &&
!vimperator.hasMode(vimperator.modes.INSERT) && !vimperator.hasMode(vimperator.modes.INSERT) &&
isFormElemFocused()) // non insert mode, but e.g. the location bar has focus !vimperator.hasMode(vimperator.modes.COMMAND_LINE) &&
isFormElemFocused()) // non insert mode, but e.g. the location bar has focus
return false; return false;
// XXX: ugly hack for now pass certain keys to firefox as they are without beeping // XXX: ugly hack for now pass certain keys to firefox as they are without beeping
@@ -607,16 +632,20 @@ function Events() //{{{
// counts must be at the start of a complete mapping (10j -> go 10 lines down) // counts must be at the start of a complete mapping (10j -> go 10 lines down)
if ((vimperator.input.buffer + key).match(/^[1-9][0-9]*$/)) if ((vimperator.input.buffer + key).match(/^[1-9][0-9]*$/))
{ {
vimperator.input.buffer += key; // no count for insert mode mappings
if (vimperator.hasMode(vimperator.modes.INSERT))
stop = false;
else
vimperator.input.buffer += key;
} }
else if (vimperator.input.pendingMap) else if (vimperator.input.pendingArgMap)
{ {
vimperator.input.buffer = ""; vimperator.input.buffer = "";
if (key != "<Esc>" && key != "<C-[>") if (key != "<Esc>" && key != "<C-[>")
vimperator.input.pendingMap.execute(null, vimperator.input.count, key); vimperator.input.pendingArgMap.execute(null, vimperator.input.count, key);
vimperator.input.pendingMap = null; vimperator.input.pendingArgMap = null;
} }
else if (map = vimperator.mappings.get(mode, candidate_command)) else if (map = vimperator.mappings.get(mode, candidate_command))
{ {
@@ -625,9 +654,24 @@ function Events() //{{{
vimperator.input.count = -1; vimperator.input.count = -1;
if (map.flags & Mappings.flags.ARGUMENT) if (map.flags & Mappings.flags.ARGUMENT)
{ {
vimperator.input.pendingMap = map; vimperator.input.pendingArgMap = map;
vimperator.input.buffer += key; vimperator.input.buffer += key;
} }
else if (vimperator.input.pendingMotionMap)
{
if (key != "<Esc>" && key != "<C-[>")
{
vimperator.input.pendingMotionMap.execute(candidate_command, vimperator.input.count, null);
}
vimperator.input.pendingMotionMap = null;
vimperator.input.buffer = "";
}
// no count support for these commands yet
else if (map.flags & Mappings.flags.MOTION)
{
vimperator.input.pendingMotionMap = map;
vimperator.input.buffer = "";
}
else else
{ {
vimperator.input.buffer = ""; vimperator.input.buffer = "";
@@ -642,7 +686,8 @@ function Events() //{{{
else else
{ {
vimperator.input.buffer = ""; vimperator.input.buffer = "";
vimperator.input.pendingMap = null; vimperator.input.pendingArgMap = null;
vimperator.input.pendingMotionMap = null;
if (vimperator.hasMode(vimperator.modes.INSERT) || if (vimperator.hasMode(vimperator.modes.INSERT) ||
vimperator.hasMode(vimperator.modes.COMMAND_LINE)) vimperator.hasMode(vimperator.modes.COMMAND_LINE))
@@ -657,7 +702,8 @@ function Events() //{{{
event.stopPropagation(); event.stopPropagation();
} }
vimperator.statusline.updateInputBuffer(vimperator.input.buffer); var motion_map = (vimperator.input.pendingMotionMap && vimperator.input.pendingMotionMap.names[0]) || "";
vimperator.statusline.updateInputBuffer(motion_map + vimperator.input.buffer);
return false; return false;
} }
window.addEventListener("keypress", this.onKeyPress, true); window.addEventListener("keypress", this.onKeyPress, true);

View File

@@ -1333,7 +1333,7 @@ function Mappings() //{{{
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
addDefaultMap(new Map([vimperator.modes.CARET], ["w", "W", "<C-Right>"], addDefaultMap(new Map([vimperator.modes.CARET], ["w", "W", "e", "<C-Right>"],
function(count) function(count)
{ {
if (count < 1) count = 1; if (count < 1) count = 1;
@@ -1406,10 +1406,14 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().lineMove(true, true); {
else
vimperator.editor.executeCommand("cmd_selectLineNext"); vimperator.editor.executeCommand("cmd_selectLineNext");
if (vimperator.hasMode(vimperator.modes.LINE) && !vimperator.editor.selectedText())
vimperator.editor.executeCommand("cmd_selectLineNext");
}
else
getSelectionController().lineMove(true, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1420,10 +1424,14 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().lineMove(false, true); {
else
vimperator.editor.executeCommand("cmd_selectLinePrevious"); vimperator.editor.executeCommand("cmd_selectLinePrevious");
if (vimperator.hasMode(vimperator.modes.LINE) && !vimperator.editor.selectedText())
vimperator.editor.executeCommand("cmd_selectLinePrevious");
}
else
getSelectionController().lineMove(false, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1434,10 +1442,10 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().characterMove(false, true);
else
vimperator.editor.executeCommand("cmd_selectCharPrevious"); vimperator.editor.executeCommand("cmd_selectCharPrevious");
else
getSelectionController().characterMove(false, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1448,10 +1456,10 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().characterMove(true, true);
else
vimperator.editor.executeCommand("cmd_selectCharNext"); vimperator.editor.executeCommand("cmd_selectCharNext");
else
getSelectionController().characterMove(true, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1462,24 +1470,24 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().wordMove(false, true);
else
vimperator.editor.executeCommand("cmd_selectWordPrevious"); vimperator.editor.executeCommand("cmd_selectWordPrevious");
else
getSelectionController().wordMove(false, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["w", "W"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["w", "W", "e"],
function(count) function(count)
{ {
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().wordMove(true, true);
else
vimperator.editor.executeCommand("cmd_selectWordNext"); vimperator.editor.executeCommand("cmd_selectWordNext");
else
getSelectionController().wordMove(true, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1490,10 +1498,10 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().pageMove(true, true); ;//vimperator.editor.executeCommand("cmd_selectPageNext");
else else
;//vimperator.editor.executeCommand("cmd_selectWordNext"); getSelectionController().pageMove(true, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1504,10 +1512,10 @@ function Mappings() //{{{
if (count < 1) count = 1; if (count < 1) count = 1;
while(count--) while(count--)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().pageMove(false, true);
else
;//vimperator.editor.executeCommand("cmd_selectWordNext"); ;//vimperator.editor.executeCommand("cmd_selectWordNext");
else
getSelectionController().pageMove(false, true);
} }
}, },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
@@ -1515,93 +1523,95 @@ function Mappings() //{{{
addDefaultMap(new Map([vimperator.modes.VISUAL], ["gg", "<C-Home>"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["gg", "<C-Home>"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().completeMove(false, true);
else
vimperator.editor.executeCommand("cmd_selectTop"); vimperator.editor.executeCommand("cmd_selectTop");
else
getSelectionController().completeMove(false, true);
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["G", "<C-End>"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["G", "<C-End>"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().completeMove(true, true);
else
vimperator.editor.executeCommand("cmd_selectBottom"); vimperator.editor.executeCommand("cmd_selectBottom");
else
getSelectionController().completeMove(true, true);
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["0", "^", "<Home>"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["0", "^", "<Home>"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().intraLineMove(false, true);
else
vimperator.editor.executeCommand("cmd_selectBeginLine"); vimperator.editor.executeCommand("cmd_selectBeginLine");
else
getSelectionController().intraLineMove(false, true);
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["$", "<End>"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["$", "<End>"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
getSelectionController().intraLineMove(true, true);
else
vimperator.editor.executeCommand("cmd_selectEndLine"); vimperator.editor.executeCommand("cmd_selectEndLine");
else
getSelectionController().intraLineMove(true, true);
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["c", "s"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["c", "s"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.beep();
else
{ {
vimperator.editor.executeCommand("cmd_cut"); vimperator.editor.executeCommand("cmd_cut");
vimperator.setMode(vimperator.modes.INSERT, vimperator.modes.TEXTAREA); vimperator.setMode(vimperator.modes.INSERT, vimperator.modes.TEXTAREA);
} }
else
vimperator.beep();
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["d"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["d"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.beep();
else
{ {
vimperator.editor.executeCommand("cmd_cut"); vimperator.editor.executeCommand("cmd_cut");
vimperator.setMode(vimperator.modes.TEXTAREA); vimperator.setMode(vimperator.modes.TEXTAREA);
} }
else
vimperator.beep();
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL], ["y"], addDefaultMap(new Map([vimperator.modes.VISUAL], ["y"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.beep(); // TODO: yanking is possible for caret mode
else
{ {
vimperator.editor.executeCommand("cmd_copy"); vimperator.editor.executeCommand("cmd_copy");
vimperator.editor.unselectText(); // vimperator.editor.unselectText();
vimperator.setMode(vimperator.modes.TEXTAREA); vimperator.setMode(vimperator.modes.TEXTAREA);
} }
else
vimperator.beep(); // TODO: yanking is possible for caret mode
}, },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.VISUAL, vimperator.modes.TEXTAREA], ["p"], addDefaultMap(new Map([vimperator.modes.VISUAL, vimperator.modes.TEXTAREA], ["p"],
function(count) function(count)
{ {
if (vimperator.hasMode(vimperator.modes.CARET)) if (vimperator.hasMode(vimperator.modes.TEXTAREA))
vimperator.beep(); // TODO: yanking is possible for caret mode
else
{ {
vimperator.editor.executeCommand("cmd_paste"); if (!count) count = 1;
while (count--)
vimperator.editor.executeCommand("cmd_paste");
vimperator.setMode(vimperator.modes.TEXTAREA); vimperator.setMode(vimperator.modes.TEXTAREA);
} }
else
vimperator.beep();
}, },
{ } { }
)); ));
@@ -1668,12 +1678,21 @@ function Mappings() //{{{
function(count) { vimperator.setMode(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA); }, function(count) { vimperator.setMode(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA); },
{ } { }
)); ));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["V"],
function(count)
{
vimperator.editor.executeCommand("cmd_beginLine", 1);
vimperator.editor.executeCommand("cmd_selectLineNext", 1);
vimperator.setMode(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA | vimperator.modes.LINE);
},
{ }
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["u"], addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["u"],
function(count) { vimperator.editor.executeCommand("cmd_undo", count); }, function(count) { vimperator.editor.executeCommand("cmd_undo", count); vimperator.setMode(vimperator.modes.TEXTAREA); },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["<C-r>"], addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["<C-r>"],
function(count) { vimperator.editor.executeCommand("cmd_redo", count); }, function(count) { vimperator.editor.executeCommand("cmd_redo", count); vimperator.setMode(vimperator.modes.TEXTAREA); },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["j", "<Down>", "<Return>"], addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["j", "<Down>", "<Return>"],
@@ -1692,7 +1711,7 @@ function Mappings() //{{{
function(count) { vimperator.editor.executeCommand("cmd_charNext", count); }, function(count) { vimperator.editor.executeCommand("cmd_charNext", count); },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["w", "W", "<C-Right>"], addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["w", "W", "e", "<C-Right>"],
function(count) { vimperator.editor.executeCommand("cmd_wordNext", count); }, function(count) { vimperator.editor.executeCommand("cmd_wordNext", count); },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
@@ -1724,6 +1743,86 @@ function Mappings() //{{{
function(count) { vimperator.editor.executeCommand("cmd_movePageUp", count); }, function(count) { vimperator.editor.executeCommand("cmd_movePageUp", count); },
{ flags: Mappings.flags.COUNT } { flags: Mappings.flags.COUNT }
)); ));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["o"],
function(count)
{
vimperator.editor.executeCommand("cmd_endLine", 1);
vimperator.editor.startInsert();
vimperator.events.feedkeys("<Return>");
},
{ }
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["O"],
function(count)
{
vimperator.editor.executeCommand("cmd_beginLine", 1);
vimperator.editor.startInsert();
vimperator.events.feedkeys("<Return>");
vimperator.editor.executeCommand("cmd_linePrevious", 1);
},
{ }
));
// no need to check if we are really in TEXTAREA mode, as findCharForward/Backward will return -1 otherwise
addDefaultMap(new Map([vimperator.modes.TEXTAREA, vimperator.modes.VISUAL], ["f"],
function(count, arg)
{
var pos = vimperator.editor.findCharForward(arg, count);
if (pos >= 0)
vimperator.editor.moveToPosition(pos, true, vimperator.hasMode(vimperator.modes.VISUAL));
},
{ flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT}
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA, vimperator.modes.VISUAL], ["F"],
function(count, arg)
{
var pos = vimperator.editor.findCharBackward(arg, count);
if (pos >= 0)
vimperator.editor.moveToPosition(pos, false, vimperator.hasMode(vimperator.modes.VISUAL));
},
{ flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT}
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA, vimperator.modes.VISUAL], ["t"],
function(count, arg)
{
var pos = vimperator.editor.findCharForward(arg, count);
if (pos >= 0)
vimperator.editor.moveToPosition(pos - 1, true, vimperator.hasMode(vimperator.modes.VISUAL));
},
{ flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT}
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA, vimperator.modes.VISUAL], ["T"],
function(count, arg)
{
var pos = vimperator.editor.findCharBackward(arg, count);
if (pos >= 0)
vimperator.editor.moveToPosition(pos + 1, false, vimperator.hasMode(vimperator.modes.VISUAL));
},
{ flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT}
));
// addDefaultMap(new Map([vimperator.modes.TEXTAREA, vimperator.modes.VISUAL], [";"],
// function(count, arg)
// {
// var pos = vimperator.editor.findCharBackward(null, count);
// if (pos >= 0)
// vimperator.editor.moveToPosition(pos + 1, false, vimperator.hasMode(vimperator.modes.VISUAL));
// },
// { flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT}
// ));
// commands which require a motion
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["d"],
function(motion, count) { vimperator.editor.executeCommandWithMotion("d", motion, count); },
{ flags: Mappings.flags.MOTION | Mappings.flags.COUNT }
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["c"],
function(motion, count) { vimperator.editor.executeCommandWithMotion("c", motion, count); },
{ flags: Mappings.flags.MOTION | Mappings.flags.COUNT }
));
addDefaultMap(new Map([vimperator.modes.TEXTAREA], ["y"],
function(motion, count) { vimperator.editor.executeCommandWithMotion("y", motion, count); },
{ flags: Mappings.flags.MOTION | Mappings.flags.COUNT }
));
// }}} // }}}
// INSERT mode // INSERT mode

View File

@@ -52,7 +52,8 @@ const vimperator = (function() //{{{
QUICK_HINT: 1 << 16, QUICK_HINT: 1 << 16,
EXTENDED_HINT: 1 << 17, EXTENDED_HINT: 1 << 17,
ALWAYS_HINT: 1 << 18, ALWAYS_HINT: 1 << 18,
MENU: 1 << 19 // a popupmenu is active MENU: 1 << 19, // a popupmenu is active
LINE: 1 << 20 // linewise visual mode
} }
var mode_messages = {}; var mode_messages = {};
@@ -60,8 +61,9 @@ const vimperator = (function() //{{{
mode_messages[modes.INSERT] = "INSERT"; mode_messages[modes.INSERT] = "INSERT";
mode_messages[modes.VISUAL] = "VISUAL"; mode_messages[modes.VISUAL] = "VISUAL";
mode_messages[modes.HINTS] = "HINTS"; mode_messages[modes.HINTS] = "HINTS";
mode_messages[modes.CARET] = "CARET"; // XXX: not a perfect name mode_messages[modes.CARET] = "CARET";
mode_messages[modes.TEXTAREA] = "TEXTAREA"; // XXX: not a perfect name mode_messages[modes.TEXTAREA] = "TEXTAREA";
mode_messages[modes.TEXTAREA | modes.LINE] = "line"; // used in visual mode
mode_messages[modes.ESCAPE_ONE_KEY] = "escape one key"; mode_messages[modes.ESCAPE_ONE_KEY] = "escape one key";
mode_messages[modes.ESCAPE_ALL_KEYS] = "escape all keys"; mode_messages[modes.ESCAPE_ALL_KEYS] = "escape all keys";
mode_messages[modes.ESCAPE_ONE_KEY | modes.ESCAPE_ALL_KEYS] = "pass one key"; mode_messages[modes.ESCAPE_ONE_KEY | modes.ESCAPE_ALL_KEYS] = "pass one key";
@@ -202,7 +204,8 @@ const vimperator = (function() //{{{
input: { input: {
buffer: "", // partial command storage buffer: "", // partial command storage
pendingMap: null, // pending map storage pendingMotionMap: null, // e.g. "d{motion}" if we wait for a motion of the "d" command
pendingArgMap: null, // pending map storage for commands like m{a-z}
count: -1 // parsed count from the input buffer count: -1 // parsed count from the input buffer
}, },
@@ -244,6 +247,14 @@ const vimperator = (function() //{{{
{ {
mode = main; mode = main;
extended_mode = vimperator.modes.NONE; extended_mode = vimperator.modes.NONE;
// TODO: also fix the other modes!!
switch (main)
{
case vimperator.modes.TEXTAREA:
vimperator.editor.unselectText();
break;
}
} }
if (typeof extended === "number") if (typeof extended === "number")
extended_mode = extended; extended_mode = extended;

View File

@@ -127,10 +127,14 @@ the terms of any one of the MPL, the GPL or the LGPL.
<!--this notifies us also of focus events in the XUL <!--this notifies us also of focus events in the XUL
from: http://developer.mozilla.org/en/docs/XUL_Tutorial:Updating_Commands !--> from: http://developer.mozilla.org/en/docs/XUL_Tutorial:Updating_Commands !-->
<commandset id="updateVimperatorFocus" <commandset id="onVimperatorFocus"
commandupdater="true" commandupdater="true"
events="focus" events="focus"
oncommandupdate="vimperator.events.onFocusChange(event);"/> oncommandupdate="vimperator.events.onFocusChange(event);"/>
<commandset id="onVimperatorSelect"
commandupdater="true"
events="select"
oncommandupdate="vimperator.events.onSelectionChange(event);"/>
</window> </window>
</overlay> </overlay>