EM

From Pickwiki
Revision as of 23:48, 26 February 2015 by Conversion script (talk) (link fix)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

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