edits.next_word.spec = "Move the caret to the end of the first word to the right of the caret"
edits.prev_word = function(state) {
if (state.start == state.end) {
var left_half = state.text.slice(0, state.start);
var m = left_half.replace(/\w+\W*$/g, "");
var new_index = m.length;
return {
text: state.text,
start: new_index,
end: new_index
}
} else {
return {
text: state.text,
start: state.start,
end: state.start
}
}
}
edits.prev_word.desc = "CTRL+←";
edits.prev_word.spec = "Move the caret to the beginning of the first word that's to the left of the caret."
edits.select_prev_word = function(state) {
var prev = edits.prev_word(state);
if(state.direction == "f"){
return {
text: state.text,
start: prev.start,
end: state.start,
direction: "b"
}
}else{
if(state.start != state.end){
prev = edits.prev_word(prev);
}
return {
text: state.text,
start: prev.start,
end: state.end,
direction: "b"
}
}
}
edits.select_prev_word.desc = "CTRL+SHIFT+←"
edits.select_prev_word.spec = "Move the active end of the selection to the beginning of the first word to the left of the active end of the selection."
edits.select_next_word = function(state){
var next = edits.next_word(state);
if(state.direction == "f"){
if(state.start != state.end){
//when you have 1 or more characters selected, ctrl+right only move the pointer to the end of the selection, not to the end of the word boundary
next = edits.next_word(next);
}
return {
text: state.text,
start: state.start,
end: next.start,
direction: "f"
}
}else{
return {
text: state.text,
start: state.end,
end: next.start,
direction: "f"
}
}
}
edits.select_next_word.desc = "CTRL+SHIFT+→";
edits.select_next_word.spec = "Move the active part of the selection to the end of the first word to the right of the active end of the selection"
edits.delete_prev_word = function(state) {
if(state.start == state.end){
state = edits.select_prev_word(state);
}
return edits.backspace(state);
}
edits.delete_prev_word.desc = "CTRL+BACKSPACE";
edits.delete_prev_word.spec = "When any text is selected, remove that text. Otherwise delete all the chars to the left of the caret until the beginning of the first word to the left of the caret."
edits.delete_next_word = function(state){
if(state.start == state.end){
state = edits.select_next_word(state);
}
return edits["delete"](state);
}
edits.delete_next_word.desc = "CTRL+DEL";
edits.delete_next_word.spec = "When any text is selected, remove that text. Otherwise delete all he chars to the right of the caret until the end of the first word to the right of the caret."
edits.shift_home = function(state){
var moving_index = "start";
if(state.direction == "f"){
moving_index = "end";
}
var left_half = state.text.slice(0, state[moving_index]);
edits.select_right.spec = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
edits.control_home = function(state){
return {
text: state.text,
start: 0,
end: 0
}
}
edits.control_home.desc = "CTRL+HOME";
edits.control_home.spec = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
edits.control_end = function(state){
return {
text: state.text,
start: state.text.length,
end: state.text.length
}
}
edits.control_end.desc = "CTRL+END";
edits.control_end.spec = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
function get_h_offset(state){
var moving_index = "end";
if(state.direction == "b"){
moving_index = "start";
}
var left_half = state.text.slice(0, state[moving_index])
if(left_half.lastIndexOf("\n") == "-1"){
return state[moving_index];
}
var ret = left_half.slice(left_half.lastIndexOf("\n"), Infinity).length - 1;
return ret;
}
function get_v_offset(state){
var moving_index = "end";
if(state.direction == "b"){
moving_index = "start";
}
var lines = state.text.split("\n");
var current_index = 0;
var the_line = 0;
for(var i in lines){
var new_index = parseInt(current_index) + lines[i].length + 1;
if(new_index > state[moving_index]){
the_line = i;
break;
}
current_index = new_index;
}
return the_line;
}
function hv2i(state, v, h){
assert(!isNaN(h));
var lines = state.text.split("\n");
var ret = lines
.slice(0, v)
.map(function(a){
return a.length + 1;
})
.reduce(function(a,b){
return a + b;
}, 0) + Math.min(h, lines[v].length);
return ret;
}
edits.shift_up = function(state){
var h_offset;
if(state.h == undefined){
h_offset = get_h_offset(state);
}else{
h_offset = state.h;
}
var v_offset = get_v_offset(state);
var lines = state.text.split("\n");
if(v_offset == 0){
return edits.shift_home(state);
}
var direction;
var new_offset = hv2i(state, v_offset-1, h_offset);
if(state.direction== "f"){
var start = Math.min(new_offset, state.start);
var end = Math.max(new_offset, state.start);
if(new_offset<state.start){
direction = "b";
}else{
direction = "f";
}
}else{
var start = Math.min(new_offset, state.end);
var end = Math.max(new_offset, state.end);
if(new_offset > state.end){
direction = "f";
}else{
direction = "b";
}
}
return {
text: state.text,
start:start,
end: end,
direction: direction,
h: h_offset
}
}
edits.shift_up.desc = "SHIFT+↑";
edits.shift_up.spec = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
edits.shift_down = function(state){
var h_offset;
if(state.h == undefined){
h_offset = get_h_offset(state);
}else{
h_offset = state.h;
}
var v_offset = get_v_offset(state);
var lines = state.text.split("\n");
if(v_offset == lines.length-1){
return edits.shift_end(state);
}
var direction;
var new_offset = hv2i(state, parseInt(v_offset)+1, h_offset);
if(state.direction== "f"){
var start = Math.min(new_offset, state.start);
var end = Math.max(new_offset, state.start);
if(new_offset<state.start){
direction = "b";
}else{
direction = "f";
}
}else{
var start = Math.min(new_offset, state.end);
var end = Math.max(new_offset, state.end);
if(new_offset > state.end){
direction = "f";
}else{
direction = "b";
}
}
return {
text: state.text,
start:start,
end: end,
direction: direction,
h: h_offset
}
}
edits.shift_down.desc = "SHIFT+↓";
edits.shift_down.spec = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
+edits.left = function(state){
+ if(state.start == state.end){
+ return {
+ text: state.text,
+ start: Math.max(state.start - 1, 0),
+ end: Math.max(state.start - 1, 0)
+ }
+ }else{
+ return {
+ text: state.text,
+ start: state.start,
+ end: state.start
+ }
+ }
+}
+
+edits.left.desc ="←";
+edits.left.spec = "If no text is selected, move caret one character to the left. If some text is selected, deselect it and move caret to the left end of the selection."
+edits.right.spec = "If no text is selected, move caret one character to the right. If some text is selected, deselect it and move caret to the right end of the selection."