📄 spaser.m
字号:
% 用来拆分语句,大致规则如下:
% 0.每次遇到光标移动,就拆段语句
% 1.目前考虑的光标移动包括:
% a.回车造成的
% b.*[A,B,C,D造成的
% c.*[J清屏造成的
% d.*[H造成的
% ??e.*[K-----这个是清楚行尾,不过貌似本身并不移动光标,可能放在这里不太合适,以后有空改改吧。
% By 可爱的 modeman, May.12 2008
% 增加了对*[s/u的处理
% 增加了对\x08(backspace)的处理
% By Kawaii 的 modeman May.18 2008
% Note: \n的问题需要改掉
% 汉字的处理问题,这个里面应该全部作成基于native的来处理----不能作为unicode的来处理
% 如果在pool的末尾出现了半个回车,或者不完整的控制字符,需要弄出来.
function scrBuf=spaser(pool);
if isempty(pool)%如果是空集,regexp会出问题
return
end
global cursor;%暂时放在这个地方,以后可能需要放到init里面去
global scrBuf;
% global waitingList;% 等待处理的半个字串
[start_idx, end_idx, extents, matches] = regexp(pool, '(\x1B\[\d*(;\d+)*[ABCDJHK])|(\xA)|(\xD)|(\x1B\[(s|u))|(\x08)');%这个地方的\n需要改!!!!!
%在这个时候可能需要考虑一下最后一个分段里面是否存在半个控制字符串的问题----暂时还没做
n=length(start_idx);
% 下面这个代码还可以进一步的缩写,不过只怕会影响可读性。暂时就这样吧,调通了再说
if n%如果中间出现过控制字符
writeBuf(pool(1:start_idx(1)-1),false);
% %处理waitingList------如果有必要的话;
% escPos=regexp(exp,'\1B','once');
%
% if escPos>end_idx(n)
% waitingList=pool(escPos:end);
% pool=pool(1:escPos-1);
% else %
%
% end
start_idx(n+1)=length(pool)+1;%为了对于最后一个控制字符能够跟前面一样的处理,做一个小小的准备工作
for i=1:n
execute(matches{i});
writeBuf(pool(end_idx(i)+1:start_idx(i+1)-1),i==n);
end
else% 如果从来没出现过移动光标的情况-----世界真美好:)
writeBuf(pool,true);
end
function writeBuf(content,isEnd);
% isEnd是一个flag,用来表示这个是否是最后一个字段,如果是最后一个,需要考虑waitingList的问题
global scrBuf;
global cursor;
global waitingList;
escPos=regexp(content,'\1B','once');
if ~isempty(escPos)
if isEnd %如果已经是处理最后一个字段了,那么遇到esc是可以理解的,扔到waitingList里面就可以了
if length(content)-escPos>10 %设置waitingList里面的东西不能超过10
saveLog('Emergency');
msgbox('waitingList都被你挤爆了...');
else%如果一切ok,就扔到WL去吧
waitingList=content(escPos:end);
content=content(1:escPos-1);
end
else
saveLog('Emergency');
msgbox('这个地方貌似不该出现esc吧');
end
end
leng=length(content);
scrBuf{cursor(1)}(cursor(2):cursor(2)+leng-1)=content;
cursor(2)=cursor(2)+leng;
function execute(exp)%根据exp中的语句做相关操作
global scrBuf;
global cursor;
global cursor_saved;
leng=length(exp);
%处理删除
if isequal(double(exp),8)
cursor=[cursor(1),cursor(2)-1];
% scrBuf{cursor(1)}(cursor(2))=' ';
return;
end
%处理新行
if isequal(double(exp),10)
cursor=[cursor(1)+1,1];
return;
end
%处理回行首
if isequal(double(exp),13)
cursor=[cursor(1),1];
return;
end
%处理请屏
if exp(leng)=='J'
scrBuf={[]};
% if exp(leng-1)=='2'%貌似水木并不区分2J和J
moveCursor([1 1]);
% end
return;
end
%处理H
if exp(leng)=='H'
pos=regexp(exp,'(\d+);(\d+)H$','tokens','once'); % tokens 表示我只要返回的token值----两个括号括起来的token
% once表示只做一次匹配
if isempty(pos)
moveCursor([1 1]);%对于*[H,直接移动到(1,1)-----也不知道这样处理对不对
else
moveCursor([str2num(pos{1}),str2num(pos{2})]);
end
return;
end
% 处理K
% 把本行自cursor位置起的地方都清空
if exp(leng)=='K'
scrBuf{cursor(1)}=scrBuf{cursor(1)}(1:cursor(2)-1);%
return;
end
% 处理s
if exp(end)=='s'
cursor_saved=cursor;
return;
end
% 处理u
if exp(end)=='u'
cursor=cursor_saved;
return;
end
%处理 ABCD
switch exp(leng)
case 'A'
dir=[-1 0];
case 'B'
dir=[1 0];
case 'C'
dir=[0 1];
case 'D'
dir=[0 -1];
otherwise
msgbox('搞什么东东呀,这又是什么新参数?');
saveLog('Emergency');
return;
end
offset=regexp(exp,['(\d+)',exp(leng),'$'],'tokens','once');
if isempty(offset)
offset=1;
else
offset=str2num(offset{1});
end
moveCursor(cursor+dir*offset);
return;
function moveCursor(newpos)%把光标移动到新位置。单独做出来作为一个函数是为了方便做一些边界检查,开辟空间这类的事情
global cursor;
global scrBuf;
%设定边界
xmin=1;
ymin=1;
xmax=50;
ymax=100;
newpos(1)=min(xmax,max(xmin,newpos(1)));
newpos(2)=min(ymax,max(ymin,newpos(2)));
if newpos(1)>length(scrBuf)
scrBuf{newpos(1)}=[];
end
if newpos(2)>length(scrBuf{newpos(1)})+1
scrBuf{newpos(1)}=[scrBuf{newpos(1)},repmat(' ',1,newpos(2)-1-length(scrBuf{newpos(1)}))];%在后面补“空格”-----不是补0!!!
end
cursor=newpos;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -