--[[
@title editor
@param a 0=overwrite 1=insert
@default a 0
@param b conwidth 0=default
@default b 0
@param c conheight 0=default
@default c 0
@param f keydelay
@default f 30
@param g LED [0=aus] [1=an]
@default g 1
@param h #Editline [3..conh]
@default h 3
@param m Menu [1..]
@default m 1
@param i Infos [1..]
@default i 1
]]
--- edit Ver 0.2 ---
Buffer_in_lbaselib_restricted_to_127=true
scriptname="edit"
key=""
if a==0 then insmode=false else insmode=true end
if b==0 then conwidth=25
else b=math.max(b,25) conwidth=math.min(b,50) end
if c==0 then conheight=5
else c=math.max(c,5) conheight=math.min(c,14) end
if h<3 then h=3 end
if h>conheight then h=conheight end
edit_line=h
dirwidth = conwidth-8
padheight= conheight-1
use_LED = g==1
init_path = "A/CHDK"
-- DIR> has to be last to enable directory change
files_to_read = ".TXT .BAS .LUA .LOG .GRD .LST DIR> "
MaxFileSizeInKB= 30
MaxPickList = 5
marks = {left="\16",mid="\6",right="\17"}
date = {"%d/%d/%d","%d.%d.%d"}
-- messages
opt={
menheader={"File functions","Dateifunktionen"},
chartab= {" show chars", " Zeichentabelle"},
abort= {" < abort >", " < Abbruch >"},
save= {" save", " Speichern"},
saveas= {" save as", " Speichern unter"},
open= {" open", " Laden"},
leave= {" end edit", " Beenden "},
new= {" new", " Neu"},
ok= {" ok", " Weiter"},
yes= {" yes", " Ja"},
no= {" no", " Nein"},
getname= {"Enter name", "Dateiname ?"},
getsearch={"Enter search", "Suchen ?"},
}
i=math.min(#opt.no,i)
USE_Info=math.max(1,i)
-- %%..%% will be replaced at runtime
info={
SearchEnd={{"Not found until eof", opt.ok[1]},
{"bis Dateiende", "nicht gefunden",opt.ok[2]}},
overwrite={{"Overwrite existing", "%%currentfile%%?",opt.yes[1],opt.no[1]},
{"Bestehende Datei", "%%currentfile%%","überschreiben?",opt.yes[2],opt.no[2]}},
ToBig ={{"ERROR: file to big", opt.ok[1]},
{"Die Datei ist zu groß", opt.ok[2]}},
AskSave ={{"Save current file", "%%currentfile%% to","%%currentpath%%",opt.yes[1],opt.no[1]},
{"Datei %%currentfile%%","sichern nach","%%currentpath%%",opt.yes[2],opt.no[2]}},
InfoExt ={{"With this Extension", "you can't reopen","%%currentfile%% save ?",opt.yes[1],opt.no[1]},
{"Mit dieser Extension kann","die Datei nicht mehr ge-","laden werden. Sichern?",opt.yes[2],opt.no[2]}},
NoFile ={{"Coudn't find", "%%currentfile%%",opt.ok[1]},
{"Datei nicht gefunden", "%%currentfile%%",opt.ok[2]}},
NotSaved ={{"Current file", "%%currentfile%%","not saved Save?",opt.yes[1],opt.no[1]},
{"Aktuelle Datei", "%%currentfile%%","nicht gesichert. Sichern?",opt.yes[2],opt.no[2]}}
}
-- commands: substrings to right may be changed but have to be unic
c={up =" U \24 H ",
down =" D \25 T B ",
left =" L < ",
right =" R > ",
jmp_up =" UU \24\24 ",
jmp_down =" DD \25\25 ",
jmp_left =" LL \171 ",
jmp_right =" RR \187 ",
toggle_ins=" TM EM ",
del_char =" Cd Bl ",
cut_char =" Cc Ba ",
ins_char =" Ci Be ",
cut_word =" Wc Wa ",
del_word =" Wd Wl ",
ins_word =" Wi We ",
paste_word=" Wp Wh ",
cut_line =" Lc Za ",
del_line =" Ld Zl ",
ins_line =" Li Ze ",
new_line =" Ln Zn ",
paste_line=" Lp Zh ",
tab =" TB TA ",
back_space=" BS RS ",
line_feed =" LF ZU ",
search =" S F Src ",
ok =" OK ENDE ",
menu =" File Datei MENU Menü "
}
-- elements are separated by one blank
-- lines starting with " " will be treated as text
-- text included in '' may include blanks. No leading blanks allowed
-- other lines are exspected to contain commands from the list above
-- order and amount of elements are arbitrary
MainMenu={
{
"File Src \24\24 \24 \25 \25\25 \171 < > \187 TM TB BS LF Cd Cc Ci Ld Lp Lc Li Ln Wp Wc Wi Wd ",
" A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Ä Ö Ü ",
" a b c d e f g h i j k l m n o p q r s t u v w x y z ä ö ü ß ",
" '' \32 1 2 3 4 5 6 7 8 9 0 . _ ~ = > < , ; : - + * \\ \" ' / { } ( ) [ ] % & # ! $ ? @ \9 "
},
{
"Datei S \24\24 \24 \25 \25\25 \171 < > \187 EM TA ZU RS Bl Ba Be Zl Zh Za Ze Zn Wh Wa We Wl ",
" A B C D E F G H I J K L M N O P Q R S T U V W X Y T Ä Ö Ü ",
" a b c d e f g h i j k l m n o p q r s t u v w x y z ä ö ü ß ",
" '' \32 1 2 3 4 5 6 7 8 9 0 . \9 _ ~ = > < , ; : - + * \\ \" ' / { } ( ) [ ] € @ % & # ! ? "
},
{
"MENU F TM TB LF BS Cd Cc Ci Ld Lc Li Wp Wc Wi Wd ",
"\24\24 U D \25\25 \171 < > \187 ",
" A B C D E F G H I J K L M N O P Q R S T U V W X Y T Ä Ö Ü ",
" a b c d e f g h i j k l m n o p q r s t u v w x y z ",
" \32 1 2 3 4 5 6 7 8 9 0 . \9 _ ~ = > < , ; : - + * \\ \" \' / { } ( ) [ ] % & # ! ? ",
" 'then ' else 'if ' end 'for ' 'while ' 'do ' 'repeat ' 'until ' 'goto ' ",
" \192 \193 \194 \195 \196 \197 \198 \199 \200 \201 \202 \203 \204 \205 \206 \207 \208 \209 \210 \211 \212 \213 \214 \215 \216 \217 \218 \219 \220 \221 \222 \223 ",
" \224 \225 \226 \227 \228 \229 \230 \231 \232 \233 \234 \235 \236 \237 \238 \239 \240 \241 \242 \243 \244 \245 \246 \247 \248 \249 \250 \251 \252 \253 \254 \255 "
}
}
m=math.min(#MainMenu,m)
USE_menu=math.max(1,m)
-- for use with inputs don't touch
InputMenu={
"OK > BS Cd < ",
" A B C D E F G H I J K L M N O P Q R S T U V W X Y T ",
" a b c d e f g h i j k l m n o p q r s t u v w x y z ",
" '' 1 2 3 4 5 6 7 8 9 0 . _ "
}
function button(allowed)
lastkey=key
repeat
sleep(f)
test=string.lower(key)
if test~="" and is_pressed(test) then
else
key=""
--wait_click(f)
end
if is_pressed "set" then key = "SET"
elseif is_pressed "erase" then key = "ERASE"
elseif is_pressed "display" then key = "DISPLAY"
elseif is_pressed "menu" then key = "MENU"
elseif is_pressed "up" then key = "UP"
elseif is_pressed "down" then key = "DOWN"
elseif is_pressed "left" then key = "LEFT"
elseif is_pressed "right" then key = "RIGHT"
elseif is_pressed "zoom_in" then key = "ZOOM_IN"
elseif is_pressed "zoom_out" then key = "ZOOM_OUT"
end
if allowed~=nil then if not string.find(allowed,key) then key="" end end
until key~=""
if use_LED then
set_led (8,1)
sleep (5)
set_led (8,0)
end
sleep(5)
end
function waitpress()
keysav,lastsav=key,lastkey
button()
key,lastkey=keysav,lastsav
end
function msg(title)
local m,i={}
for i=1,#title[USE_Info] do m[i]=string.gsub(title[USE_Info][i],"%%%%currentfile%%%%",text.f.fname) end
for i=1,#title[USE_Info] do m[i]=string.gsub(m[i],"%%%%currentpath%%%%",text.f.fpath) end
return selection(m)
end
function get_state(file_name)
state_is = {}
if string.sub(file_name,-2,-1)==".." then return nil end
local r = os.stat(file_name)
if r then
local keys={ "dev", "mode", "size", "atime", "mtime",
"ctime", "blksize", "blocks", "attrib","is_dir","is_file",}
for k,v in ipairs(keys) do
state_is[v] = r[v]
end
end
return state_is
end
function exists_file(name)
return get_state(name).is_file == true
end
function read_dir(path,files_to_find)
local dir,state_is,ii,hs={},{},1
dir = os.listdir(path, true)
table.sort(dir)
while ii<=#dir do
name = dir[ii]
test = name
state_is=get_state(path.."/"..name)
if name=="." or state_is==nil then
table.remove(dir,ii)
ii=ii-1
else
if state_is.is_dir then
size = "
"
test = size
elseif state_is.is_file then
size = state_is.size
if size <1000 then hs=" B"
else size=size/1024
if size <1000 then hs=" k"
else size=size/1024
if size <1000 then hs=" m"
else size=size/1024 hs =" g"
end
end
end
size=string.sub(" "..tostring(size),-3)..hs
else
size = "???"
end
if files_to_find~=nil and (string.find(files_to_find,string.sub(string.upper(test),-4,-1))==nil) then
table.remove(dir,ii)
ii=ii-1
else
dir[ii]=" "..string.sub(name..string.rep(" ",50),1,dirwidth)..marks.mid..size
end
end
ii=ii+1
end
-- old vxworks(digic II) returns .. as real directory with flags
-- newer and DryOs doesn´t at least return no flags
if string.sub(files_to_find,-5)=="DIR> "
and #path>2
and (#dir==0 or string.sub(dir[1],2,3) ~="..") then
table.insert(dir,1," .."..string.rep(" ",dirwidth-2)..marks.mid.."")
end
return dir
end
function setidx(val,min,max,step)
if step>=0 then
if val+stepmax then return val+step end
end
if val==max then return min end
return max
end
function selection(selection_table)
local pad,size,Buffer,ii,index,top,start={},#selection_table
start=1
for ii=1,size do
table.insert(pad,string.sub(selection_table[ii]..string.rep(" ",50),1,conwidth))
if string.sub( selection_table[ii],1,1)~=" " then start=start+1 end
end
top=start
index=top
repeat
Buffer=""
for ii=1,start-1 do Buffer=Buffer..pad[ii] end
for ii=top,top+conheight-start do
if Buffer_in_lbaselib_restricted_to_127 then
if #Buffer+conwidth>127 then print(Buffer) Buffer="" end
end
if ii==index then Buffer=Buffer..marks.left..string.sub(pad[ii],2,-2)..marks.right
elseif ii>size then Buffer=Buffer..string.sub(string.rep(" ",conwidth),1,conwidth)
else Buffer=Buffer..pad[ii] end
end
print(Buffer)
button()
if key == "UP" then index=setidx(index,start,size,-1)
elseif key == "DOWN" then index=setidx(index,start,size, 1)
elseif key == "LEFT" then index=setidx(index,start,size,-padheight)
elseif key == "RIGHT" then index=setidx(index,start,size, padheight)
end
top=index-(conheight-start)
if top",dirwidth)~=nil then
if subdir==".." then
while string.sub(path,-1,-1) ~= "/" do
path=string.sub(path,1,-2)
end
path=string.sub(path,1,-2)
else
path=path.."/"..subdir
end
else
return path,subdir,get_state(path.."/"..subdir).size/1024
end
until idx== -1
end
function init_doc(start,for_input)
local doc={}
doc.f={
cr_used=false,
fname="",
fpath="",
wrap=true,
changed=false,
insmode=insmode}
doc.t={}
doc.idx={x=1,y=1,editline=start}
if for_input then
doc.t[1]="-----------------"
doc.t[3]=doc.t[1] doc.idx.y=2
doc.f.wrap=false
doc.f.insmode=false
end
return doc
end
function Read_file(fpath,fname)
local content=init_doc(edit_line,false)
content.f.fname=fname
content.f.fpath=fpath
if exists_file(fpath..fname) then
io.input(fpath..fname)
for line in io.lines() do
if line~=nil then
if line.byte(line,-1)==13 then
content.f.cr_used=true
line=line.sub(line,1,-2)
end
table.insert(content.t,line)
end
end
end
return content
end
function save_file(content,Check_OverWrite)
if Check_OverWrite and exists_file(content.f.fpath..content.f.fname) then
if msg(info.overwrite)~=1 then return end
end
-- print(content.f.fpath,content.f.fname,content.t[1]) button()
-- print(content.f.fpath..content.f.fname,content.t[1],#content.t) button()
local f,cr=io.open(content.f.fpath..content.f.fname,"wb")
-- print("opend") button()
if content.f.cr_used then cr="\13" else cr="" end
for i,v in ipairs(content.t) do f:write(trim(v),cr,"\n") end
f:close()
content.f.changed=false
return content
end
function print_chars()
local kk,hs,ii,jj=1," "
print(" 01234567 89ABCDEF")
for ii=0,15 do
for jj=kk,15 do hs=hs..string.char(ii*16+jj)
if jj==7 then hs=hs.." " end
end
print(string.format("%03d %02X",ii*16,ii*16),hs)
kk,hs=0,""
button()
end
end
fpad = {
opt.open[USE_Info],
opt.save[USE_Info],
opt.saveas[USE_Info],
opt.chartab[USE_Info],
opt.abort[USE_Info],
opt.leave[USE_Info]
}
function filemenue(t)
local pad,lp,ln,ls,idx={}
local picklist=Read_file("A/CHDK/DATA/",scriptname..".DTA")
lp = #picklist.t
for idx=1,#fpad do table.insert(pad,idx,fpad[idx]) end
local function setpick(lp,ln)
local n=#picklist.t
table.insert(picklist.t,1,lp.." "..ln)
while n>1 do
if picklist.t[n]==picklist.t[1] then table.remove(picklist.t,n) end
n=n-1
end
if #picklist.t>MaxPickList then table.remove(picklist.t) end
end
local function open(lp,ln)
local menu=t.men
if exists_file(lp.."/"..ln) then
t=Read_file(lp.."/",ln)
t.men=menu
setpick(lp,ln)
end
return t
end
while lp>0 do table.insert(pad,2," "..string.sub(string.gsub(picklist.t[lp]," ","/"),-(conwidth-2))) lp=lp-1 end
idx=selection(pad)
if idx==1 then --open
lp,ln,ls=fileselection(init_path,files_to_read)
if lp~="" then
if tonumber(ls)>MaxFileSizeInKB then
msg(info.ToBig)
return
else
idx=101
end
end
elseif idx==#pad-4 then -- save
if msg(info.AskSave)==1 then save_file(t) end
elseif idx==#pad-3 then --save as
local menu=InputMenu
table.insert(menu," "..string.sub(files_to_read,1,-6))
search=init_doc(4,true)
search.t[2]=t.f.fname
search=string.gsub(edit(search,menu,opt.getname[USE_Info]).t[2]," ","")
if not string.find(files_to_read,string.upper(string.sub(search,-4))) then
t.f.fname,search=search,t.f.fname
if msg(info.InfoExt)==1 then idx=100
else t.f.fname,search=search,t.f.fname end
else t.f.fname=search idx= 100 end
table.remove(menu)
elseif idx==#pad-2 then print_chars()
elseif idx==#pad-1 then return
elseif idx==#pad then
else
lp=string.find(picklist.t[idx-1]," ")
while string.find(picklist.t[idx-1]," ",lp+1) do lp=string.find(picklist.t[idx-1]," ",lp+1) end
ln=string.sub(picklist.t[idx-1],lp+1) lp=string.sub(picklist.t[idx-1],1, lp-1) idx=101
end
if idx==100 then setpick(t.f.fname,t.f.fpath) save_file(t,true) end
if idx==101 then
if t.f.changed and msg(info.NotSaved)==1 then save_file(t) end
t=open(lp,ln)
end
if idx==#pad then cmd=setfield(c.ok)[2]
else save_file(picklist,false) cmd="nothing" end
return t
end
function setfield(str)
local res,s,i,j={},""
if string.sub(str,-1)~=" " then str=str.." " end
while string.len(str) > 0 do
i,j=string.find(str," ")
if string.sub(str,1,1)=="'" and string.sub(str,j-1,j-1)~="'" then
l,j=string.find(str,"'",j)
j=j+1
end
if i~=1 then i=1 j=j-1 end
s=string.sub(str,i,j)
if #s > 1 then s=string.gsub(s,"'","") end
table.insert(res,s)
str=string.sub(str,j+1,#str)
end
return res
end
function edit(doc,men,Titel)
words,lines,chars={},{},{}
bool={[true]=1,[false]=0}
chd ={[true]="*",[false]=""}
ins ={[true]="I",[false]="O"}
local ms,mstart,zoom_used,jmp_on_mnu=1,1,false,false
doc.msg=Titel
doc.men={}
for mstart=1,#men do
doc.men[mstart] = {mIt=setfield(men[mstart]),idx=1}
doc.men[mstart].is_cmd=doc.men[mstart].mIt[1]~=" "
if doc.men[mstart].is_cmd then table.insert(doc.men[mstart].mIt,1," ") end
end
local function draw_screen(doc)
local line,Buffer,hs,i,lpad,xl={},""
function formatline(tline,ls)
local lin,start=tline
if ls>(conwidth-3) then start=ls-(conwidth-6) else start=1 end
tline=string.sub(tline,start)
if Buffer_in_lbaselib_restricted_to_127 then
if #Buffer+conwidth>127 then print(Buffer) Buffer="" end
end
if #tline>conwidth then Buffer=Buffer..string.sub(tline,1,conwidth-1)..">"
else Buffer=Buffer..string.sub(tline..string.rep(" ",conwidth),1,conwidth) end
end
-- status
if doc.msg~=nil then hs=doc.msg..string.rep(" ",50)
else
if zoom_used then hs="Z" else if jmp_on_mnu then hs="J" else hs="S" end end
hs=string.format("%d:%d:%d %d-%d "..ins[doc.f.insmode]..hs.." "..chd[doc.f.changed]..doc.f.fname.."%50d",
#doc.t,doc.idx.y,doc.idx.x,menl,doc.men[menl].idx,0)
end
Buffer=string.sub(hs,1,
conwidth-(#doc.men[menl].mIt[doc.men[menl].idx*2]+1)).." "..
doc.men[menl].mIt[doc.men[menl].idx*2]
-- menue
line=doc.men[menl].mIt
if mode=="UPPER" then
line[doc.men[menl].idx*2+1]=marks.right
hs=table.concat(line)
mstart=string.find(hs,marks.right)
line[doc.men[menl].idx*2-1],line[doc.men[menl].idx*2+1]=marks.left,marks.right
hs=table.concat(line)
formatline(hs,mstart)
line[doc.men[menl].idx*2-1],line[doc.men[menl].idx*2+1]=" "," "
end
-- edit
hs=doc.t[doc.idx.y]
if hs==nil then hs="" end
hs=replace(hs,doc.idx.x,marks.left..string.sub(hs,doc.idx.x,doc.idx.x)..marks.right)
if #doc.t==0 then xl=0 else xl = math.min(doc.idx.x,#doc.t[doc.idx.y]) end
Startline=doc.idx.y-(doc.idx.editline-3)
Deltaline=doc.idx.editline-4
if mode ~= "UPPER" then Startline=Startline-1 Deltaline=Deltaline+1 end
for i=Startline,Startline+Deltaline do
if i >0 then
formatline(doc.t[i],xl)
else formatline("",0) end
end
formatline(hs,xl)
-- rest
for i=1,(padheight-doc.idx.editline)+1 do
if doc.idx.y+i<=#doc.t then
formatline(doc.t[doc.idx.y+i],xl)
else formatline("",0) end
end
print(Buffer)
end --draw_screen
local function match(s)
return string.find(s," "..cmd.." ")
end
local function setVal(doc,what,insmode)
if insmode then nofchar=-1 else nofchar=0 end
if doc.idx.x==#doc.t[doc.idx.y] then nofchar =0 end
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],doc.idx.x,what,nofchar)
doc.idx.x=doc.idx.x+#what
if #doc.t[doc.idx.y]1 and string.sub(str,wleft,wleft)~=" " do wleft=wleft-1 end
while x<#str and string.sub(str,x,x)~=" " do x=x+1 end
if string.sub(str,wleft,wleft)==" " and wleft~=x then
wleft=wleft+1
end
return string.sub(str,wleft,x),wleft,x
end
local function search_doc(doc,where,line)
while line<#doc.t do
if string.find(doc.t[line],doc.search,where,true) then
return true,line,string.find(doc.t[line],doc.search,where)
end
where=1 line=line+1
end
return false
end
mode="UPPER"
menl=1
loaded=true
repeat
draw_screen(doc)
button()
menItems=(#doc.men[menl].mIt-1)/2
cmd=doc.men[menl].mIt[doc.men[menl].idx*2]
is_cmd=doc.men[menl].is_cmd
savekey=key
if key=="ZOOM_IN" or key=="ZOOM_OUT" or is_pressed("flash") then zoom_used = true jmp_on_mnu=false end
if key=="ERASE" and mode~="LOWER" and is_cmd then key="SET" cmd=setfield(c.del_char)[2] end
if key=="MENU" and not zoom_used then
jmp_on_mnu=not jmp_on_mnu
elseif key=="DISPLAY" then
if mode=="UPPER" then mode="LOWER" else mode="UPPER" end
else
if is_pressed("flash") and cmd~=setfield(c.del_char)[2] then mode="lower" end -- S-Series
if mode=="UPPER" then -- move in menu
if jmp_on_mnu then stepw = 5 else stepw=1 end
if key == "UP" then menl=setidx(menl,1,#men,-1)
elseif key == "DOWN" then menl=setidx(menl,1,#men, 1)
elseif key == "LEFT" then doc.men[menl].idx=setidx(doc.men[menl].idx,1,menItems,-stepw)
elseif key == "RIGHT" then doc.men[menl].idx=setidx(doc.men[menl].idx,1,menItems, stepw)
elseif key == "ZOOM_OUT" then doc.men[menl].idx=setidx(doc.men[menl].idx,1,menItems,-5)
elseif key == "ZOOM_IN" then doc.men[menl].idx=setidx(doc.men[menl].idx,1,menItems, 5)
elseif key == "SET" then
if is_cmd then -- handle menucommands
if match(c.up ) then mode="lower" key="UP"
elseif match(c.down ) then mode="lower" key="DOWN"
elseif match(c.left ) then mode="lower" key="LEFT"
elseif match(c.right ) then mode="lower" key="RIGHT"
elseif match(c.jmp_up ) then mode="lower" key="SET"
elseif match(c.jmp_down ) then mode="lower" key="MENU"
elseif match(c.jmp_left ) then mode="lower" key="ZOOM_OUT"
elseif match(c.jmp_right ) then mode="lower" key="ZOOM_IN"
elseif match(c.toggle_ins) then doc.f.insmode = not doc.f.insmode
elseif match(c.menu) then
t=filemenue(doc)
if t~=nil then doc=t end
else
doc.f.changed=true
if match(c.tab ) then setVal(doc,string.char(9),doc.f.insmode)
elseif match(c.del_word..c.cut_word) and doc.idx.x<#doc.t[doc.idx.y] and string.sub(doc.t[doc.idx.y],doc.idx.x,doc.idx.x)~=" " then
hs,wleft,wright=word_at(doc.t[doc.idx.y],doc.idx.x)
if match(c.cut_word) then table.insert(words,hs) end
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],wleft,"",wright-wleft)
doc.idx.x=wleft
elseif match(c.ins_word..c.paste_word) and #words>0 then
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],doc.idx.x,words[#words],-1)
if match(c.ins_word) then table.remove(words) end
elseif match(c.cut_line..c.del_line) and #doc.t>0 then
if #doc.t>1 or (#doc.t==1 and #doc.t[1]>0) then
if match(c.cut_line) then table.insert(lines,doc.t[doc.idx.y]) end
table.remove(doc.t,doc.idx.y)
end
if #doc.t==0 then doc.t[1]="" end
doc.idx.y=math.min(#doc.t,doc.idx.y)
elseif match(c.ins_line..c.paste_line) and #lines>0 then
table.insert(doc.t,doc.idx.y,lines[#lines])
if match(c.ins_line) then table.remove(lines) end
elseif match(c.new_line) then table.insert(doc.t,doc.idx.y,"")
elseif match(c.back_space) then
if doc.idx.x == 1 then
if doc.idx.y == 1 or not doc.f.wrap then
else
doc.idx.x = #doc.t[doc.idx.y-1]+1
doc.t[doc.idx.y-1]= doc.t[doc.idx.y-1]..doc.t[doc.idx.y]
table.remove(doc.t,doc.idx.y)
doc.idx.y=doc.idx.y-1
end
else
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],doc.idx.x-1,"")
doc.idx.x=doc.idx.x-1
end
elseif match(c.ins_char) and #chars>0 then
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],doc.idx.x,chars[#chars],-1)
table.remove(chars)
elseif match(c.line_feed) then
table.insert(doc.t,doc.idx.y+1,string.sub(doc.t[doc.idx.y],doc.idx.x))
doc.t[doc.idx.y ]=string.sub(doc.t[doc.idx.y],1,doc.idx.x-1)
doc.idx.y=doc.idx.y+1 doc.idx.x=1
end
if match(c.del_char..c.cut_char..c.back_space) then
if doc.idx.x > #doc.t[doc.idx.y] then
if doc.t[doc.idx.y+1] ~= nil and doc.f.wrap then
doc.idx.x=#doc.t[doc.idx.y]+1
doc.t[doc.idx.y]= doc.t[doc.idx.y].." "..doc.t[doc.idx.y+1]
table.remove(doc.t,doc.idx.y+1)
end
end
if match(c.back_space) then lll=-1 else lll=0 end
if #doc.t[doc.idx.y]>=doc.idx.x then
if match(c.cut_char) then table.insert(chars,string.sub(doc.t[doc.idx.y],doc.idx.x,doc.idx.x)) end
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],doc.idx.x,"",lll)
end
end
if match(c.search) then
hss,wStart,wEnd=word_at(doc.t[doc.idx.y],doc.idx.x)
hss=string.sub(trim(hss),1,conwidth-5)
if doc.search~=nil then hs =doc.search else hs=hss end
search=init_doc(4,true)
search.t[2]=hs
if #hss > 1 then hss=" "..hss else hss="" end
InputMenu[4]=hss..InputMenu[4]
doc.search=string.gsub(edit(search,InputMenu,opt.getsearch[USE_Info]).t[2]," ","")
InputMenu[4]=string.sub(InputMenu[4],#hss+1)
if #doc.search>1 then
found,lin,pos=search_doc(doc,wEnd,doc.idx.y)
else found=false end
if found then
doc.idx.y=lin doc.idx.x=pos
else msg(info.SearchEnd) end
cmd = "Nothing"
end
end
if match(c.ok) then cmd="$#FINISH" end
else -- handle char
setVal(doc,cmd,doc.f.insmode)
end
end --set
end -- upper
if mode~="UPPER" then -- move in doc
if jmp_on_mnu then steph=conwidth/2 stepv=padheight-1
else steph=1 stepv=1 end
if key == "LEFT" then doc.idx.x=setidx(math.min(doc.idx.x,#doc.t[doc.idx.y]+1),1,#doc.t[doc.idx.y]+1,-steph)
elseif key == "RIGHT" then doc.idx.x=setidx(math.min(doc.idx.x,#doc.t[doc.idx.y]+1),1,#doc.t[doc.idx.y]+1, steph)
elseif key == "ZOOM_OUT" then doc.idx.x=setidx(math.min(doc.idx.x,#doc.t[doc.idx.y]+1),1,#doc.t[doc.idx.y]+1,-conwidth/2)
elseif key == "ZOOM_IN" then doc.idx.x=setidx(math.min(doc.idx.x,#doc.t[doc.idx.y]+1),1,#doc.t[doc.idx.y]+1, conwidth/2)
elseif key == "UP" then doc.idx.y=setidx(doc.idx.y,1,#doc.t,-stepv)
elseif key == "DOWN" then doc.idx.y=setidx(doc.idx.y,1,#doc.t, stepv)
elseif key == "SET" then doc.idx.y=setidx(doc.idx.y,1,#doc.t,-padheight)
elseif key == "MENU" then doc.idx.y=setidx(doc.idx.y,1,#doc.t, padheight)
elseif key == "ERASE" then
if doc.idx.x > #doc.t[doc.idx.y] then
if doc.t[doc.idx.y+1] ~= nil then
doc.idx.x=#doc.t[doc.idx.y]+1
doc.t[doc.idx.y]= doc.t[doc.idx.y].." "..doc.t[doc.idx.y+1]
table.remove(doc.t,doc.idx.y+1)
end
end
if match(c.back_space) then lll=-1 else lll=0 end
if #doc.t[doc.idx.y]>=doc.idx.x then
doc.t[doc.idx.y]=replace(doc.t[doc.idx.y],doc.idx.x,"",lll)
end
doc.f.changed=true
end
end
if mode=="lower" then mode="UPPER" end
if match(c.ok) then cmd="$#FINISH" end
end
key=savekey
until cmd=="$#FINISH"
return doc
end --edit
text,search={},{}
text=init_doc(edit_line,false)
-- may be deleted
text.f.fname="edit.txt"
text.f.fpath="A/CHDK/BOOKS/"
text.t={"[DISP] to move in Text",
"[DISP] again returns",
"to menu. press \24\25\26\27 to move Cursor",
"[ZOOM_IN/OUT] move in line by jumps",
"If you don't have [ZOOM_IN/OUT]",
"press [MENU] to switch to jumps",
"[MENU] again returns to steps",
"Once ZOOM used moving in text",
"[SET] will jump up [MENU] down",
"If you have [FLASH], holding",
"this will affekt lower cursor.",
"[ERASE] deletes current char in text.",
"------- Commands --------",
"Commands are as follows:",
"(C)aracter (L)line (W)ord",
"(d)elete (c)ut",
"(i)insert(p)aste",
"Ld will cut line",
"Lc same but stores cutted line",
"Li will insert cutted line",
"Lp same but keeps line in buffer",
"TM toggles insert/overwrite",
"TB writes tabulator as char",
"LF line feed at current position",
"BS back space",
"(S)rc search",
"------- Indications -----",
"1st: lines total:actual line:position in line",
"2nd: menu line-menu position",
"3rd: I/O insert/overwrite Mode",
" Z/S/J jumps by (Z)oom",
" (S)single (J)ump=MENUE active",
"4th: filename if present",
" with asterix if changed",
"last: current menu selection"
}
edit(text,MainMenu[USE_menu])
cls()
exit_alt()