EM
EM is designed to be used with Emacs, especially under Unix X(-windows) in client-server mode. It enables editing of individual MVdatabase records or a selectlist of records one by one, or a selectlist of records all at once (be careful about the number as records are locked and you can easily fill the lock table). One record can be edited by entering at TCL: "EM <filename> <recordname>", and this will pop the record into a running emacs session buffer. If a select list is active, entertering at TCL: "EM <filename>" will pop the records, one at a time, into a running emacs session buffer. If a select list is active and you want to edit all the records at once, enter at TCL: "EM <filename> *" to get all in one buffer of a running emacs session. In this mode in emacs, the current record (line) can be viewed in formatted form in a window below by entering the appropriate emacs command (see the Emacs Lisp library Wike page for the code).
* -*-mode:unibasic-*- *$Id: EM,v 1.3 2003/12/15 05:30:26 kenf Exp kenf $ * Last updated by klf (klf) at 13:35:20 on 08/02/93 * Modified by Ken Ford for use by TSW - 4th June, 2003. ****************************************************************************** * This program takes the command line arguments entered when executed and * converts the Universe file and item name to be edited into a Unix pathname. * If the file is not a hashed file, the item is first copied to the &UFD& file * with '~' appended. This file is then used by the EMACS editor and deleted, * after it has been copied back to the original item. Otherwise, the item is * edited directly using its Unix pathname. The program will work with a * single item name, a list of item names, '*', or an active select list. * If the item name is '*', with or without a select list, the items concerned * will be formatted into a buffer in virtually raw format, with the items id. * prepended. Items can be edited, deleted or inserted provided they have their * item ids. intact and relevant item, field, value and sub value marks. * * Author: Ken Ford Date: 4th March, 1992. * * Update History: * Modified to use client/server Emacs. Ken Ford 27th June, 2003 * Modified TO enable editting of multiple Ken Ford 26th August, 2003 * items IN a buffer. * ****************************************************************************** $OPTIONS DEFAULT if index(@SENTENCE,'-DEBUG',1) THEN sentence = FIELD(@SENTENCE, '-', 1) DEBUG END ELSE sentence = @sentence END prompt '' execute 'sh -c pwd' capturing output current.account.pathname=output<1> unix.pathname='' option=field(field(sentence,'-',2),' ',1) filename=field(sentence,' ',2) if filename[1,1]='-' or filename='' then print 'Filename? : ' : input filename if filename = '' then stop end itemname = field(sentence, ' ' , 3) if itemname[1,1]='-' or itemname='' then if oconv(filename,'TVOC;X;;0')='' then unix.pathname=filename end else if not(system(11)) then print 'Itemname/s? : ' : input itemname end end end if unix.pathname='' then if filename='DICT' then filename='DICT ':itemname file.id=itemname itemname=field(sentence,' ',4) if itemname[1,1]='-' or itemname='' then if not(system(11)) then print 'Itemname/s? : ' : input itemname if itemname='' then stop end end end else file.id=filename itemlist='' for i=2 to 99 next.itemname=field(itemname,' ',i) if next.itemname#'' then itemlist<-1>=next.itemname else i=99 next i itemname=field(itemname,' ',1) end multiple.items=(itemname='*') mode = '' begin CASE CASE option='V' mode = '--no-wait' case option='WD' execute 'term 132,42,':field(@term.type,'-',1):'-wd' case option='W' execute 'term 132,':field(@term.type,'-',1):'-w' case option='D' execute 'term 80,42,':field(@term.type,'-',1):'-d' end case if unix.pathname#'' then execute 'sh -c "ls -al ':filename:'"' capturing output if not(index(output<1>,'No such file',1)) THEN GOSUB check.for.emacs cmd='sh -c "UWD=':current.account.pathname:';export UWD;' cmd:='exec /usr/local/bin/emacsclient ':change(unix.pathname,'&','\&',-1):'"' execute cmd execute 'term 80,24,':field(@term.type,'-',1) end stop end open '' , 'VOC' to voc.fv else print '*** VOC file cannot be opened.'; stop read voc.ref from voc.fv, file.id then if index( 'FQ' , voc.ref < 1 > [1, 1], 1) = 0 then print '*** File "':filename:'" does not exist.'; stop end end else print '*** File "':filename:'" does not exist.'; stop if multiple.items AND NOT(SYSTEM(11)) then execute 'select ':filename if itemname='' or multiple.items then readnext itemname else itemname = '' end if field(filename,' ',1)='DICT' then m=5 else m=4 if itemlist='' then for i = m to 99 next.itemname = field(sentence, ' ' , i) if next.itemname[1,1] # '-' then if next.itemname # '' then itemlist < - 1 >= next.itemname else i = 99 end next i end itemnames = dcount(itemlist, @FM) read uv.account.item from voc.fv, 'UV.ACCOUNT' else write 'Q':@FM:'uv':@FM:'UV.ACCOUNT' on voc.fv, 'UV.ACCOUNT' end if voc.ref < 1 > [1, 1] = 'Q' then write 'Q':@FM:voc.ref<2>:@FM:'VOC' on voc.fv, 'Q.VOC.EMACS' open '', 'Q.VOC.EMACS' to q.voc.emacs.fv else print '*** VOC file of Account ':voc.ref<2>:' cannot be opened.' delete voc.fv, 'Q.VOC.EMACS' stop end read q.voc.item from q.voc.emacs.fv,voc.ref<3> else print '*** VOC item for Q-pointer file ':filename:' does not exist.' delete voc.fv, 'Q.VOC.EMACS' stop end account.pathname=oconv(voc.ref<2>,'TUV.ACCOUNT;X;;11') if account.pathname='' then print '*** Account "':voc.ref < 2 >:'" does not exist.'; stop if not(index(q.voc.item<2>,'/',1)) and q.voc.item<1>#'Q' then pathname = account.pathname:'/':q.voc.item < 2 > end else if q.voc.item<1># 'Q' then pathname = q.voc.item<2> else print '*** File ':filename:' is a Q-pointer to another Q-pointer. Use correct filename.' delete voc.fv, 'Q.VOC.EMACS' stop end end delete voc.fv, 'Q.VOC.EMACS' end else substring=voc.ref<m-2>[1,2] begin case case substring='.' pathname=current.account.pathname case substring[1,1]='/' pathname=voc.ref<m-2> case 1 pathname = current.account.pathname:'/':voc.ref < m-2 > end case end execute 'SH -c "ls -dl ':change(pathname,'&','\&',-1):'"' capturing output non.hashed.file=(output[1,1]='d') execute 'sh -c "echo $PWD"' capturing output if current.account.pathname#output<1> then pwd.var='PWD=':current.account.pathname:';export PWD;' end else pwd.var='' directory.pathname=pathname loop while itemname # '' do if not(non.hashed.file) THEN IF multiple.items THEN GOSUB get.multiple.items adjusted.itemname=current.account.pathname:"/'":filename:".uv'" END else execute 'COPYI FROM ':filename:' TO &UFD& ':itemname:',':itemname:'~ OVERWRITING' capturing output if itemname[1,1]='.' then itemname='?':itemname if index(output,'1 record copied',1) then execute 'SH -c "ls -ald ':current.account.pathname:'/':itemname:'~"' capturing output if not(index(output,'No such file',1)) and output[1,1]#'d' then adjusted.itemname=current.account.pathname:'/':itemname:'~' end else pathname=current.account.pathname gosub adjust.itemname end if index(sentence,'-R',1) then execute 'sh -c "pr -n: -t ':adjusted.itemname:' > ':adjusted.itemname:'~"' execute 'sh -c "rm ':adjusted.itemname:'"' execute 'sh -c "mv ':adjusted.itemname:'~ ':adjusted.itemname:'"' if itemname[1,1]='?' then itemname=itemname[2,99] data 'i Record Id: ':itemname data 'c/^252/|/g999' data 't' data 'c/^253/}/g999' data 'fi' execute 'ED &UFD& ':itemname:'~' capturing output end end else pathname=current.account.pathname gosub adjust.itemname END end GOSUB check.for.emacs cmd='sh -c "UWD=':current.account.pathname:';export UWD;' cmd := 'exec /usr/local/bin/emacsclient ':mode:' ':change(adjusted.itemname,'&','\&',-1):'"' execute cmd IF multiple.items THEN IF option#'V' THEN PRINT 'Rewrite multiple items to file? : ': INPUT response, 1 IF index( 'yY' , response, 1) and response # '' THEN GOSUB write.multiple.items END itemname = '' END END else if not(index(sentence,'-R',1)) then execute 'sh -c "ls ':adjusted.itemname:'"' capturing output if not(index(output,'No such file',1)) then if itemname[1,1]='?' then itemname=itemname[2,99] execute 'COPYI FROM &UFD& TO ':filename:' ':itemname:'~,':itemname:' OVERWRITING DELETING' capturing output end end execute 'DELETE &UFD& ':itemname:'~' capturing output dirname=itemname:'~' execute \SELECT &UFD& LIKE "':dirname[1,14]:'..."\ rtnlist selected.items capturing output if @selected>0 then data 'Y' execute 'DELETE &UFD&' passlist selected.items capturing output end execute 'SH -c "rm -r ':dirname[1,14]:'"' capturing output end end else execute 'SH -c "ls -adl ':change(directory.pathname,'&','\&',-1):'/':itemname:'"' capturing output if index(output,'No such file',1) or output[1,1]='d' then execute 'sh -c "ls -a ':directory.pathname:'/.Type1"' capturing output if not(index(output,'No such file',1)) then pathname=directory.pathname gosub adjust.itemname end else adjusted.itemname=directory.pathname:'/':itemname end else adjusted.itemname=directory.pathname:'/':itemname pathname=adjusted.itemname if index(sentence,'-R',1) then execute 'sh -c "pr -n: -t ':change(pathname,'&','\&',-1):' > ':change(pathname,'&','\&',-1):'~"' pathname:='~' end filename=change(filename,'&','\&',-1) GOSUB check.for.emacs cmd='sh -c "UWD=':current.account.pathname:';export UWD;':pwd.var cmd:='SRCDIR=':filename:';export SRCDIR;' cmd:='SRCFILE=':itemname:';export SRCFILE;' cmd := 'exec /usr/local/bin/emacsclient ':mode:' ':change(pathname,'&','\&',-1):'"' execute cmd pathname = change(pathname,'&','\&',-1) if index(sentence,'-R',1) then execute 'sh -c "rm ':pathname:'"' capturing output end else execute 'sh -c "ls ':pathname:'"' capturing output if index(output,'No such file',1) then dirpath=pathname[1,index(pathname,itemname[1,14],1)-1]:itemname[1,14] execute 'sh -c "ls -dl ':dirpath:'"' capturing output if output[1,1] = 'd' then execute 'sh -c "ls -l ':dirpath:'"' capturing output if output<1> = 'total 0' then execute 'sh -c "rm -r ':dirpath:'"' capturing output end end end end END * IF NOT(multiple.items) then if itemnames then itemname = itemlist < 1 > itemnames = itemnames - 1 del itemlist < 1 > end else readnext itemname else itemname = '' end if itemname # '' then print 'Continue? (Y=default[[/N]]) : ' : input response, 1 if index( 'nN' , response, 1) and response # '' then itemname = '' END * end repeat execute 'term 80,24,':field(@term.type,'-',1) stop * adjust.itemname: orig.itemname=itemname adjusted.itemname='' if not(non.hashed.file) then itemname=itemname:'~' loop while len(itemname) > 13 do pathname=pathname:'/':itemname[1,14] if adjusted.itemname#'' then adjusted.itemname=adjusted.itemname[1,index(adjusted.itemname,itemname,1)-2] end if len(itemname) = 14 then adjusted.itemname = adjusted.itemname:itemname:'/?' end else if itemname[15, 1] = '.' then adjusted.itemname = adjusted.itemname:itemname[1, 14]:'/?':itemname[15, 99] end else adjusted.itemname = adjusted.itemname:itemname[1, 14]:'/':itemname[15, 99] end execute 'sh -c "ls -dl ':pathname:'"' capturing output if index(output,'No such file',1) then cmd='sh -c "mkdir ':pathname:'"' execute cmd capturing output end itemname=field(adjusted.itemname,'/',count(adjusted.itemname,'/')+1) repeat if adjusted.itemname='' then if non.hashed.file then adjusted.itemname=pathname:'/':itemname else adjusted.itemname = itemname end else adjusted.itemname=pathname:'/':itemname end itemname=orig.itemname return * check.for.emacs: * * Start emacs as a server if it isn't already running. count=0 cmd='sh -c "ps -fu ':@LOGNAME:' | grep emacs | grep -v grep"' EXECUTE cmd CAPTURING output IF output = '' THEN EXECUTE 'sh -c "emacs -u $HOME/.emacs -f server-start &"' SLEEP 5 loop while (output = '' and count < 1000 ) do EXECUTE cmd CAPTURING output sleep 5 count += 1 repeat end RETURN * get.multiple.items: IF SYSTEM(11) THEN itemcount = @SELECTED END ELSE EXECUTE 'COUNT ':filename CAPTURING output itemcount = FIELD(output, @FM, 2) itemcount = FIELD(itemcount, ' ', 1) END DIM multipleitems(itemcount) original.itemcount = itemcount original.items = '' OPEN '',filename TO DATAFILE ELSE STOP itemindex = itemcount LOOP WHILE itemname # '' DO IF option='V' THEN READ @RECORD FROM DATAFILE, itemname ELSE STOP END ELSE READU @RECORD FROM DATAFILE, itemname ELSE STOP END @RECORD = CHANGE(@RECORD, @FM, CHAR(127), -1) multipleitems(itemindex) = itemname:@IM:@RECORD original.items<-1> = itemname itemindex -= 1 READNEXT itemname ELSE itemname='' REPEAT CLOSE DATAFILE IF option#'V' THEN OPEN '','&UFD&' TO DATAFILE ELSE STOP MATWRITE multipleitems TO DATAFILE,filename:'.uv' ELSE STOP CLOSE DATAFILE END return * write.multiple.items: * Back up the original file prior TO writing EXECUTE 'sh -c "cp ':current.account.pathname:'/':filename:' ':current.account.pathname:'/':filename:'~"' OPEN '','&UFD&' TO DATAFILE ELSE STOP MATREAD multipleitems FROM DATAFILE,filename:'.uv' ELSE STOP itemcount = INMAT() DELETE DATAFILE, filename:'.uv' DELETE DATAFILE, filename:'.uv~' CLOSE DATAFILE IF itemcount = 0 THEN itemindex = original.itemcount END else itemindex = itemcount END OPEN '',filename TO DATAFILE ELSE STOP LOOP WHILE itemindex > 0 DO @RECORD = multipleitems(itemindex) itemname = FIELD(@RECORD, @IM, 1) @RECORD = CHANGE(@RECORD, itemname:@IM, '') @RECORD = CHANGE(@RECORD, CHAR(127), @FM, -1) WRITE @RECORD ON DATAFILE, itemname LOCATE itemname IN original.items SETTING pos ELSE pos = 0 IF pos # 0 THEN original.items<pos> = '' itemindex -= 1 REPEAT IF itemcount = 0 THEN LOOP WHILE multipleitems(0) # '' DO @RECORD = FIELD(multipleitems(0), @FM, 1) itemname = FIELD(@RECORD, @IM, 1) @RECORD = CHANGE(@RECORD, itemname:@IM, '') @RECORD = CHANGE(@RECORD, CHAR(127), @FM, -1) WRITE @RECORD ON DATAFILE, itemname LOCATE itemname IN original.items SETTING pos ELSE pos = 0 IF pos # 0 THEN original.items<pos> = '' multipleitems(0) = FIELD(multipleitems(0), @FM, 2, 1000) REPEAT END itemindex = original.itemcount LOOP WHILE itemindex > 0 DO IF original.items<itemindex> # '' THEN DELETE DATAFILE, original.items<itemindex> END itemindex -= 1 REPEAT CLOSE DATAFILE print '*** NOTE: Multiple records edited. A backup, "':itemname:'~", made prior' print ' to updating can be found in the current directory.' return * end