在 CodeMirror 中查找 {line, ch} 对象的绝对起始索引
Finding the absolute start index of a {line, ch} object in CodeMirror
我试图在保留原始文本的同时替换 codemirror 中突出显示的文本。假设您在 codemirror
中有以下文本
Hi I'm 22
我想用 21 替换 22。我的函数会 return Hi I'm 21
,而 codemirror 仍然读取原文 Hi I'm 22
。我有可用的 21 作为标记,所以我有一个可用的开始和结束索引。
我最终得到了以下代码
cm.replaceRange(..)
value = cm.getValue()
cm.undo()
这很好,只是对于我的用例来说它有点太慢,浏览器花费大量时间来执行 dom 以及用户不可见的 replaceRange 和撤消的样式操作, 浪费周期:(
所以我想出了一个替代方法,使用cm.getValue(),计算标记的绝对开始和结束索引,将cm.getValue()拆分为夹在中间的前后部分21他们之间。
我编写了以下函数来执行此操作,大部分 都很好。有时它会变坏,我真的不知道为什么,我已经调试了 3 个多小时了。
function getIndexOfLineColumn(lineCh) {
var lines = editor.doc.children[0].lines;
// Take all the lines, sum up their lengths up to but NOT including the line the character lies on
// then add the column (lineCh.ch)
var index = lines.slice(0, lineCh.line).reduce(function (index, lineObj) {return index + lineObj.text.length + 1;}, 0) + lineCh.ch;
return index;
}
我正在使用的一个字符串如下
// "Seascape" by Alexander Alekseev aka TDM - 2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
const int NUM_STEPS = 8;
const float PI = 3.1415;
const float EPSILON = 1e-3;
float EPSILON_NRM = 0.1 / iResolution.x;
// sea
const int ITER_GEOMETRY = 3;
const int ITER_FRAGMENT = 5;
const float SEA_HEIGHT = 0.6;
const float SEA_CHOPPY = 4.0;
const float SEA_SPEED = 0.8;
const float SEA_FREQ = 0.16;
const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
float SEA_TIME = iGlobalTime * SEA_SPEED;
mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);
// math
mat3 fromEuler(vec3 ang) {
vec2 a1 = vec2(sin(ang.x),cos(ang.x));
vec2 a2 = vec2(sin(ang.y),cos(ang.y));
vec2 a3 = vec2(sin(ang.z),cos(ang.z));
mat3 m;
m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
return m;
}
float hash( vec2 p ) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)*43758.5453123);
}
float noise( in vec2 p ) {
1.0;
vec2 i = floor( p );
vec2 f = fract( p );
vec2 u = f*f*(3.0-2.0*f);
return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),
hash( i + vec2(1.0,0.0) ), u.x),
mix( hash( i + vec2(0.0,1.0) ),
hash( i + vec2(1.0,1.0) ), u.x), u.y);
}
如果我在行 mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);
中标记数字 1.6
,则它会正确报告起始索引为 598
。但是,如果我在行 vec2 u = f*f*(3.0-2.0*f);
中标记数字 301
,它会错误地将索引报告为 1153
,即使索引应该是 1204
,它也会被关闭将近 50 个!
有没有人知道为什么我的方法没有按预期工作,或者有没有人编写自己的方法来查找绝对索引?
您看到 indexFromPos
和 posFromIndex
方法了吗?
我试图在保留原始文本的同时替换 codemirror 中突出显示的文本。假设您在 codemirror
中有以下文本Hi I'm 22
我想用 21 替换 22。我的函数会 return Hi I'm 21
,而 codemirror 仍然读取原文 Hi I'm 22
。我有可用的 21 作为标记,所以我有一个可用的开始和结束索引。
我最终得到了以下代码
cm.replaceRange(..)
value = cm.getValue()
cm.undo()
这很好,只是对于我的用例来说它有点太慢,浏览器花费大量时间来执行 dom 以及用户不可见的 replaceRange 和撤消的样式操作, 浪费周期:(
所以我想出了一个替代方法,使用cm.getValue(),计算标记的绝对开始和结束索引,将cm.getValue()拆分为夹在中间的前后部分21他们之间。
我编写了以下函数来执行此操作,大部分 都很好。有时它会变坏,我真的不知道为什么,我已经调试了 3 个多小时了。
function getIndexOfLineColumn(lineCh) {
var lines = editor.doc.children[0].lines;
// Take all the lines, sum up their lengths up to but NOT including the line the character lies on
// then add the column (lineCh.ch)
var index = lines.slice(0, lineCh.line).reduce(function (index, lineObj) {return index + lineObj.text.length + 1;}, 0) + lineCh.ch;
return index;
}
我正在使用的一个字符串如下
// "Seascape" by Alexander Alekseev aka TDM - 2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
const int NUM_STEPS = 8;
const float PI = 3.1415;
const float EPSILON = 1e-3;
float EPSILON_NRM = 0.1 / iResolution.x;
// sea
const int ITER_GEOMETRY = 3;
const int ITER_FRAGMENT = 5;
const float SEA_HEIGHT = 0.6;
const float SEA_CHOPPY = 4.0;
const float SEA_SPEED = 0.8;
const float SEA_FREQ = 0.16;
const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
float SEA_TIME = iGlobalTime * SEA_SPEED;
mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);
// math
mat3 fromEuler(vec3 ang) {
vec2 a1 = vec2(sin(ang.x),cos(ang.x));
vec2 a2 = vec2(sin(ang.y),cos(ang.y));
vec2 a3 = vec2(sin(ang.z),cos(ang.z));
mat3 m;
m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
return m;
}
float hash( vec2 p ) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)*43758.5453123);
}
float noise( in vec2 p ) {
1.0;
vec2 i = floor( p );
vec2 f = fract( p );
vec2 u = f*f*(3.0-2.0*f);
return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),
hash( i + vec2(1.0,0.0) ), u.x),
mix( hash( i + vec2(0.0,1.0) ),
hash( i + vec2(1.0,1.0) ), u.x), u.y);
}
如果我在行 mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);
中标记数字 1.6
,则它会正确报告起始索引为 598
。但是,如果我在行 vec2 u = f*f*(3.0-2.0*f);
中标记数字 301
,它会错误地将索引报告为 1153
,即使索引应该是 1204
,它也会被关闭将近 50 个!
有没有人知道为什么我的方法没有按预期工作,或者有没有人编写自己的方法来查找绝对索引?
您看到 indexFromPos
和 posFromIndex
方法了吗?