/*{{{}}}*/
/*{{{  #includes*/
#ifdef CONFIG_H
#   include "config.h"
#endif

#include <sys/types.h>
#include <ctype.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>

#define FOLDFILING_C
#define I_BUFFLOOP_C
#define I_DISPLAY_C
#define I_FINDS_C
#define I_FOLDHELP_C
#define I_FOLDING_C
#define I_GETMSG_C
#define I_GETTK_C
#define I_KEYBOARD_C
#define I_LOOP_C
#define I_MESSAGES_C
#define I_MISC_C
#define I_ORIEDT_C
#define I_PROMPT_C
#define I_READFOLDS_C
#define I_SCREEN_C
#define I_SHELL_C
#define I_SIGNALS_C
#define I_VIRTUAL_C
#define I_WRITEF_C

#include "origami.h"
#include <lib/ori_add_lib.h>
/*}}}  */

/*{{{  type edit_file_buffer*/
typedef struct edit_file_buffer
 { char const *filename;
   int last_line;
   struct edit_file_buffer *next;
 } edit_file_buffer;
/*}}}  */
/*{{{  variable*/
private edit_file_buffer *cmd_last=0;
private edit_file_buffer *current_ring_file=0;
private edit_file_buffer default_ring={ 0,0,&default_ring };
private int ring_size=1;
private edit_file_buffer *file_ring= &default_ring;
/*}}}  */

/*{{{  cut_filename*/
private void cut_filename(unsigned char *buff,unsigned char const *s)
{
  int i;
  unsigned char c;

  for
   ( i=0;
     (c= *s) && c!=' ' && c!='\t' && i<_POSIX_PATH_MAX;
     buff[i++]= c,s++
   );
  buff[i]='\0';
}
/*}}}  */
/*{{{  save_lang*/
public void save_lang(struct lg_dumb * const d)
{
  *d=bd.m.dialect;
  d->lg=dialects[F_C_USER].lg;
}
/*}}}  */
/*{{{  reset_lang*/
public void reset_lang(struct lg_dumb * const d)
{
  bd.m.dialect= *d;
  dialects[F_C_USER].lg=d->lg;
}
/*}}}  */
/*{{{  proc_language*/
public void proc_language(void)
{
  if (bd.m.dialect.typ!=F_C_TDS || yes(get_msg(M_LEAVE_INMOS)))
   /*{{{  get and set new dialect*/
   { struct lg_dumb d;
     unsigned char m_buff[LINELEN+1];

     /*{{{  prepare menu string*/
     { f_c_types i;

       for (i=F_C_NONE,m_buff[0]='\0';i<F_C_SIZE;i++)
        { ustrcat(m_buff,((i>=F_C_USER)?two_space:one_space));
          ustrcat(m_buff,dialects[i].name);
        }
     }
     /*}}}  */
     d.typ=menu_item(m_buff,bd.m.dialect.typ,False,True);
     if (d.typ>=F_C_NONE && d.typ<=F_C_TDS)
      /*{{{  set new dialect*/
      { if (bd.m.dialect.typ!=d.typ || bd.m.dialect.typ==F_C_USER)
         { switch (d.typ)
            { case F_C_USER:
               /*{{{  get user-comments*/
               { s_readprompt(d.lg_u_s,get_msg(M_CO_START),FOLD_COMMENT_LENGTH,no_history);
                 if (aborted)
                    break;
                 s_readprompt(d.lg_u_e,get_msg(M_CO_END),FOLD_COMMENT_LENGTH,no_history);
                 if (aborted)
                    break;
                 d.lg.start=ustrlen(d.lg_u_s);
                 d.lg.end=ustrlen(d.lg_u_e);
                 reset_lang(&d);
               }
               /*}}}  */
              default:
                 title_op(CHGTITLE);
                 bd.m.dialect.typ=d.typ;
                 no_message();
                 return;
            }
         }
      }
      /*}}}  */
   }
   /*}}}  */
  try_unchange();
  no_message();
}
/*}}}  */
/*{{{  file_fold*/
public void file_fold
 ( unsigned char const * const save_name,
   FILE * const read_pipe
 )
{
  msgtyp ff_msg;
  unsigned char newfilename[_POSIX_PATH_MAX+1];
  unsigned char exfilename[_POSIX_PATH_MAX+1];

  ff_msg=M_NO_SIMPLE_FOLD;
  ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  if (normal_att(&(bd.f.current->x.fold),True))
   { switch((bd.f.cur_line_typ=get_linetyp(*bd.f.current)))
      { default:
           goto ff_error;
        case START_FOLD:
         /*{{{  file*/
         { FILE *fp;
           boolean can_open;

           check_fold(bd.f.current);
           if (save_name)
            /*{{{  use given name*/
            { ustrcpy(newfilename,save_name);
              ustrcpy(exfilename,save_name);
            }
            /*}}}  */
           else
            /*{{{  create new name from fold comment*/
            { cut_filename(newfilename,get_data(bd.f.Start_of_fold));
              ustrcpy(exfilename,newfilename);
              home_expand((char*)exfilename);
            }
            /*}}}  */
           if (access((char *)exfilename, F_OK|R_OK|W_OK)==0)
              can_open=yes(get_msg(F_TCFF,newfilename));
           else if ((fp=fopen((char *)exfilename,(char*)"w")))
            { fclose(fp);
              can_open=True;
            }
           else
             can_open=False;
           if (!can_open)
            { ff_msg=F_NO_OPEN;
              goto ff_error;
            }
           set_data(bd.f.End_of_fold,exfilename,False);
           write_fold(exfilename,bd.f.Start_of_fold,(FILE*)0);
           if (bd.f.Start_of_fold->x.fold.data != bd.f.End_of_fold)
              delete_list(bd.f.Start_of_fold->x.fold.data, bd.f.End_of_fold->prec);
           bd.f.Start_of_fold->x.fold.data = bd.f.End_of_fold;
           bd.f.End_of_fold->prec = bd.f.Start_of_fold;
           set_linetyp(*bd.f.Start_of_fold,START_FILED);
           break;
         }
         /*}}}  */
        case START_FILED:
         /*{{{  unfile*/
         { boolean oldview;
           unsigned char f_buff[_POSIX_PATH_MAX+1];
           struct lg_dumb lang_dump;
           
           save_lang(&lang_dump);
           oldview=bd.m.read_only;
           pre_open_fold(bd.f.current);
           ustrcpy(f_buff,get_data(bd.f.End_of_fold));
           home_expand((char*)f_buff);
           set_data(bd.f.End_of_fold,f_buff,False);
           if (bd.f.Start_of_fold->next == bd.f.End_of_fold)
               insert_file(bd.f.End_of_fold,
                           bd.f.Start_of_fold,
                           bd.f.End_of_fold,
                           False,
                           bd.f.real_head,
                           (boolean*)0,
                           (boolean*)0,
                           read_pipe);
           close_fold_at(bd.f.current);
           reset_lang(&lang_dump);
           bd.m.read_only=oldview;
           break;
         }
         /*}}}  */
      }
     bd.f.cur_line_typ=get_linetyp(*bd.f.current);
     write_dsp_line(bd.f.current, bd.scr.cursor.h);
     return;
   }
ff_error:
  message(get_msg(ff_msg,newfilename));
  try_unchange();
  return;
}
/*}}}  */
/*{{{  attach_file*/
public void attach_file(void)
{
  ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
  switch (bd.f.cur_line_typ)
   { case START_FOLD:
      { if (normal_att(&(bd.f.current->x.fold),False))
         { check_fold(bd.f.current);
           if (bd.f.Start_of_fold->x.fold.data == bd.f.End_of_fold)
            { unsigned char filename[_POSIX_PATH_MAX+1];

              cut_filename(filename,get_data(bd.f.Start_of_fold));
              home_expand((char*)filename);
              if (access((char *)filename,R_OK)==-1)
                 if
                  /*{{{  can get dirname(current-file)/name*/
                  (    bd.f.real_tail!=bd.f.real_head
                    && join_fd(filename,get_data(bd.f.real_tail))
                  )
                  /*}}}  */
                  /*{{{  test if existing*/
                    if (access((char *)filename,R_OK) == -1)
                       goto attach_cant_open;
                    else
                     { warn_message(get_msg(F_ADD_PATH,filename));
                       set_data(bd.f.Start_of_fold,filename,False);
                     }
                  /*}}}  */
                 else
                  /*{{{  cannot open file*/
                  { attach_cant_open:

                    message
                     ( get_msg
                        ( F_F_FAILED,
                          get_data(bd.f.Start_of_fold))
                     );
                    return;
                  }
                  /*}}}  */
              set_data(bd.f.End_of_fold,get_data(bd.f.Start_of_fold),False);
              set_linetyp(*bd.f.Start_of_fold,START_FILED);
              write_dsp_line(bd.f.current, bd.scr.cursor.h);
              return;
            }
         }
        break;
      }
     case START_FILED:
        set_data(bd.f.current->x.fold.other_end,empty_text,False);
        ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check cur_linetyp");
        set_linetyp(*bd.f.current,bd.f.cur_line_typ=START_FOLD);
        bd.f.current->x.fold.UU.U1.type = DEFAULT_TYPE;
        bd.f.current->x.fold.UU.U1.contents = TEXT_CONTENTS;
        write_dsp_line(bd.f.current, bd.scr.cursor.h);
        return;
     default:
        break;
   }
  try_unchange();
}
/*}}}  */
/*{{{  filter_op*/
/*{{{  filter_line*/
private void filter_line(boolean text,unsigned char *filter)
{ unsigned char tmp_file[_POSIX_PATH_MAX+1];
  FILE *read_pipe;

  /*{{{  write line to file*/
  tmpnam((char*)tmp_file);
  if (text)
   /*{{{  fold the textline*/
   { bd.scr.cursor.w=bd.f.current->indent+1;
     start_make_fold(False);
     bd.f.cur_line_typ=get_linetyp(*bd.f.current);
     move_down();
     bd.f.cur_line_typ=get_linetyp(*bd.f.current);
     make_fold();
     bd.f.cur_line_typ=get_linetyp(*bd.f.current);
     if (!((bd.f.cur_line_typ&START_FOLD) && bd.m.select_mode==no_selection))
      /*{{{  error return*/
      { f_l_failed:

        msg_message(M_FAILED);
        return;
      }
      /*}}}  */
   }
   /*}}}  */
  file_fold(tmp_file,(FILE*)0);
  /*}}}  */
  if (!test_linetyp(*bd.f.current,START_FILED))
   /*{{{  error return*/
   { f_l_unfold:

     if (text) unfold();
     unlink((char*)tmp_file);
     goto f_l_failed;
   }
   /*}}}  */
  /*{{{  read file back again*/
  ustrcat(filter,one_space);
  ustrcat(filter,tmp_file);
  force_sh=ocl_var[var_force_sh].v;
  if (!(read_pipe=open_shell((char*)filter,"r")))
   /*{{{  error return*/
   { f_l_unfile:

     file_fold((unsigned char*)0,(FILE*)0);
     goto f_l_unfold;
   }
   /*}}}  */
  file_fold((unsigned char*)0,read_pipe);
  if ((ocl_var[var_ocl_arg].v=close_shell(read_pipe))<0)
     err_message(M_CLOSE_FAILED,M_PSTR);
  if (test_linetyp(*bd.f.current,START_FILED))
   /*{{{  error return*/
     goto f_l_unfile;
   /*}}}  */
  if (text)
     unfold();
  /*}}}  */
  unlink((char*)tmp_file);
  return;
}
/*}}}  */

public void filter_op(boolean full)
 { boolean text;
   unsigned char filter[LINELEN+_POSIX_PATH_MAX+1];

   /*{{{  check errors*/
   if (bd.m.dialect.typ==F_C_TDS)
    { msg_message(M_NOT_IF_TDS);
      goto unchange_return;
    }
   else if (bd.m.dir_edit)
    { msg_message(M_DIR_EDIT);
      goto unchange_return;
    }
   text=False;
   if (!full)
    { ori_assert(bd.f.cur_line_typ==get_linetyp(*bd.f.current),"check_cur_linetyp");
      switch (bd.f.cur_line_typ)
       { case NOT_FOLD:
            text=True;
         case START_FOLD:
            break;
         default:
            goto unchange_return;
       }
    }
   /*}}}  */
   /*{{{  get filter command*/
   s_readprompt
    ( filter,
      (unsigned char*)(full?"filter-buffer":"line-filter"),
      LINELEN,
      shell_history
    );
   if (!filter[0] || aborted)
      goto unchange_return;
   /*}}}  */
   if (full)
    { int line_number;
      int scr_level;

      ocl_screen_off();
      /*{{{  store position data and create single fold text*/
      line_number=cur_line_no();
      scr_level=bd.scr.cursor.h;
      find_element(1,1);
      bd.scr.cursor.w=1;
      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
      start_make_fold(False);
      skip_to(bd.f.tail);
      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
      make_fold();
      bd.f.cur_line_typ=get_linetyp(*bd.f.current);
      /*}}}  */
      if (test_linetyp(*bd.f.current,START_FOLD) && bd.m.select_mode==no_selection)
       { filter_line(False,filter);
         /*{{{  restore position*/
         bd.f.cur_line_typ=get_linetyp(*bd.f.current);
         unfold();
         find_element(line_number,scr_level);
         /*}}}  */
       }
      ocl_screen_on();
      restore(1);
    }
   else
      filter_line(text,filter);
   return;

 unchange_return:
   try_unchange();
 }
/*}}}  */
/*{{{  pipe_from_command*/
public void pipe_from_command(void)
{
  /*{{{  variables*/
  unsigned char command[_POSIX_PATH_MAX+1];
  FILE *pipein;
  struct lg_dumb lang_dump;
  /*}}}  */

  save_lang(&lang_dump);
  /*{{{  errors*/
  if (bd.m.dialect.typ==F_C_TDS)
   { msg_message(M_NOT_IF_TDS);
     goto unchange_return;
   }
  /*}}}  */
  /*{{{  open pipe*/
  s_readprompt(command,(unsigned char*)"pipe-from-command",LINELEN, shell_history);
  if (*command=='\0' || aborted)
     goto unchange_return;
  put_vars();
  force_sh=ocl_var[var_force_sh].v;
  if (!(pipein=open_shell((char*)command,"r")))
   { err_message(M_CANTOPEN,M_PSTR);
     goto unchange_return;
   }
  /*}}}  */
  msg_message(M_READING);
  insert_file((element *)0,bd.f.current->prec,bd.f.current,False,bd.f.real_head,(boolean*)0,(boolean*)0,pipein);
  reset_lang(&lang_dump);
  if ((ocl_var[var_ocl_arg].v=close_shell(pipein))<0)
    err_message(M_CLOSE_FAILED,M_PSTR);
  else
    msg_message(M_READ);
  return;

unchange_return:
  try_unchange();
}
/*}}}  */
/*{{{  pipe_to_command*/
public void pipe_to_command(void)
{
  /*{{{  variables*/
  unsigned char command[_POSIX_PATH_MAX+1];
  FILE *pipeout;
  change_status ch=bd.m.file_changed_status;
  /*}}}  */

  if (bd.f.tail!=bd.f.real_tail)
     msg_message(M_NO_TOP);
  else if (bd.m.dialect.typ==F_C_TDS)
     msg_message(M_NOT_IF_TDS);
  else
   {
     /*{{{  open pipe*/
     s_readprompt(command,(unsigned char*)"pipe-to-command",LINELEN, shell_history);
     if (*command=='\0' || aborted) return;
     put_vars();
     force_sh=ocl_var[var_force_sh].v;
     if (!(pipeout=open_shell((char*)command,"w")))
      { err_message(M_CANTWRITE,M_PSTR);
        return;
      }
     /*}}}  */
     msg_message(M_WRITING);
     total_save(pipeout);
     /*{{{  maybe reset cf-Flag*/
     if (ch!=unchanged_file) {
       bd.m.file_changed_status=ch;
       title_op(CHGTITLE);
     }
     /*}}}  */
     if ((ocl_var[var_ocl_arg].v=close_shell(pipeout))<0)
        err_message(M_CLOSE_FAILED,M_PSTR);
     else
        msg_message(M_WRITTEN);
   }
}
/*}}}  */
/*{{{  dump_file*/
public char *dump_file(void)
{ char *name;

  name=0;
  if
   (    (bd.m.file_changed_status!=unchanged_file)
     && (!bd.m.dir_edit)
     && (bd.f.real_tail!=bd.f.real_head)
#ifdef OS_NULL_DEVICE
     && ustrcmp(get_data(bd.f.real_tail),(unsigned char*)OS_NULL_DEVICE)
#endif
     && (name=tmpnam((char*)0))
   )
   { no_fold_out=False;
     write_fold((unsigned char*)name,bd.f.real_head->next,(FILE*)0);
     CHMOD_PRIVATE(name);
   }
  return(name);
}
/*}}}  */
/*{{{  save_file*/
public void save_file(boolean const to_top)
{
  msgtyp m;

  if (bd.m.file_changed_status==unchanged_file)
     m=M_NO_CHANGE;
  else if (bd.m.dir_edit)
     m=M_DIR_EDIT;
  else if (bd.f.tail != bd.f.real_tail && !to_top)
     m=M_NO_TOP;
  else
   { total_save((FILE*)0);
     if (!bd.f.count_comment_line)
        title_op(CHGXY);
     bd.f.count_comment_line=True;
     return;
   }
  msg_message(m);
}
/*}}}  */
/*{{{  auto_write*/
#ifdef AUTOSAVE_FILE
   public boolean autosave_done=False;
#endif

public void auto_write(void)
{
  if (bd.m.file_changed_status!=unchanged_file)
   { msgtyp m;

     if (bd.m.dir_edit)
        m=M_DIR_EDIT;
     else if (bd.f.tail == bd.f.real_tail)
      /*{{{  save*/
      {
#       ifdef AUTOSAVE_FILE
           write_fold(AUTOSAVE_FILE, bd.f.real_head->next, (FILE*)0);
           autosave_done=True;
#       else
           total_save((FILE*)0);
#       endif
        m=M_AUTO_SAVED;
      }
      /*}}}  */
     else
        m=M_NO_TOP_AUTO_SAVE;
     msg_message(m);
   }
}
/*}}}  */
/*{{{  add_edit_file*/
public int add_edit_file(char const * const name,int line,boolean no_cmd_line)
{
  if (name)
   { if (name[0])
      /*{{{  add additional entry*/
      { edit_file_buffer *x=file_ring;

        /*{{{  search in list*/
        do
         { if (x->filename && !strcmp(name,x->filename))
            { current_ring_file=x;
              goto line_update;
            }
           x=x->next;
         }
        while (x!=file_ring);
        /*}}}  */
        /*{{{  add entry*/
        { if (!(x=ori_malloc(sizeof(edit_file_buffer))))
             exit_origami(r_mem_full,M_NO_MEMORY);
          x->next=file_ring->next;
          x->filename=file_ring->filename;
          file_ring->next=x;
          /*{{{  set filename*/
          if (no_cmd_line)
           { if (!(file_ring->filename=ori_malloc(strlen(name)+1)))
                exit_origami(r_mem_full,M_NO_MEMORY);
             strcpy((char*)file_ring->filename,name);
           }
          else
           { cmd_last=file_ring;
             file_ring->filename=name;
           }
          /*}}}  */
          file_ring->last_line=1;
          current_ring_file=file_ring;
          file_ring=x;
          ring_size++;
        }
        /*}}}  */
      }
      /*}}}  */
     else
        current_ring_file = file_ring;
   }
  line_update:
  if (current_ring_file && line >=0)
     current_ring_file->last_line=line;
  if (current_ring_file && name && name[0])
   { edit_file_buffer *x=file_ring;
     int i=0;

     while (x!=current_ring_file) { x=x->next;i++; }
     return(i);
   }
  else
     return(0);
}
/*}}}  */
/*{{{  fileno2name*/
public unsigned char const *fileno2name(int no)
{ edit_file_buffer *x;

  if (!(x=file_ring) || no<0)
     return(0);
  while (no--)
     x=x->next;
  return((unsigned char*)x->filename);
}
/*}}}  */
/*{{{  gen_arg_list*/
public void gen_arg_list(element *hd,element *tl)
{ edit_file_buffer *s;
  element *x, *y, *last;

  /*{{{  read list of argument file*/
  s=file_ring;
  set_data(hd->next,(unsigned char *)STR_EDT_FILE,False);
  set_0_data(tl);
  bd.f.current=hd->next;
  last=hd->next;
  do
   /*{{{  append a line*/
   { if (s->filename)
      {
        /*{{{  line*/
        y=proc_new_element();
        set_linetyp(*y,START_FILED);
        y->x.fold.close_line=DEF_CURSOR_LINE;
        y->x.fold.UU.U1.type=DEFAULT_TYPE;
        y->x.fold.UU.U1.contents=TEXT_CONTENTS;
        y->indent=0;
        y->x.fold.UU.U1.indent=0;
        set_data(y,(unsigned char *)s->filename,False);
        /*}}}  */
        /*{{{  close the fold*/
        x=proc_new_element();
        set_linetyp(*x,END_FOLD);
        x->x.fold.other_end=y;
        x->prec=y;
        y->x.fold.data=x;
        y->x.fold.other_end=x;
        set_data(x,(unsigned char *)s->filename,False);
        /*}}}  */
        join_links(last,y);
        join_links(y,bd.f.tail);
        last=y;
        if (s==current_ring_file) bd.f.current=y;
        if (s==cmd_last && s->next!=file_ring)
         /*{{{  insert a empty line*/
         { x=proc_new_element();
           join_links(last,x);
           join_links(x,bd.f.tail);
           last=x;
         }
         /*}}}  */
      }
     s=s->next;
   }
   /*}}}  */
  while (s!=file_ring);
  current_ring_file=file_ring;
  /*}}}  */
  /*{{{  modes*/
  bd.m.dir_edit=True;
  bd.m.file_changed_status=unchanged_file;
  title_op(CHGTITLE);
  /*}}}  */
  restore_element(DEF_CURSOR_LINE);
  bd.m.dialect.typ = F_C_NONE;
  title_op(CHGTITLE);
# ifdef WINDOW_TITLE_CHANGE
     wt_buff_id= -1;
# endif
}
/*}}}  */
/*{{{  open_arg_list*/
public void open_arg_list(void)
{ element *x;

  add_edit_file((char*)0,cur_line_no(),False);
  /*{{{  prepare open file*/
  if (bd.f.real_head && bd.f.real_tail) delete_list(bd.f.real_head, bd.f.real_tail);
  /*}}}  */
  /*{{{  create empty file*/
  bd.f.head=proc_new_element();
  bd.f.head->prec = 0;
  bd.f.tail=proc_new_element();
  bd.f.tail->next = 0;
  x=proc_new_element();
  join_links(bd.f.head, x);
  join_links(x, bd.f.tail);
  set_linetyp(*x,START_ENTER_FILED);
  x->x.fold.other_end = bd.f.tail;
  bd.f.tail->x.fold.other_end = x;
  set_linetyp(*bd.f.tail,END_FOLD);
  bd.f.real_head = bd.f.head;
  bd.f.real_tail = bd.f.tail;
  if (!bd.m.user_view) bd.m.read_only=False;
  /*}}}  */
  bd.f.entered=0;
  gen_arg_list(bd.f.real_head,bd.f.real_tail);
  bd.e.file_no=add_edit_file((char*)get_data(bd.f.real_tail),cur_line_no(),True);
# ifdef WINDOW_TITLE_CHANGE
     wt_buff_id= -1;
# endif
  title_op(CHGXY);
  call_number_macro(auto_macro);
  warn_mult_edit();
}
/*}}}  */
/*{{{  open_file*/
public void open_file(boolean const ignore_changed)
{
  unsigned char name[_POSIX_PATH_MAX+1];

  add_edit_file((char*)0,cur_line_no(),False);
  if
   (   !ignore_changed
    && bd.m.file_changed_status!=unchanged_file
    && yes(get_msg(M_CHANGED_SAVE))
   )
   { total_save((FILE*)0);
     if (bd.m.file_changed_status!=unchanged_file) return;
   }
  if (aborted)
     return;
  if (!filearg)
   { filearg=name;
     fileprompt(name);
   }
  if (aborted)
     return;
  bd.e.file_no=add_edit_file((char*)filearg,-1,True);
  if (!bd.m.user_view) bd.m.read_only=False;
  delete_list(bd.f.real_head, bd.f.real_tail);
  bd.f.entered=0;
  create_list();
# ifdef WINDOW_TITLE_CHANGE
     wt_buff_id= -1;
# endif
  restore_element(DEF_CURSOR_LINE);
  bd.m.file_changed_status=unchanged_file;
  title_op(CHGXY);
  call_number_macro(auto_macro);
  warn_mult_edit();
}
/*}}}  */
/*{{{  next_file*/
private void next_file(int of, boolean ignore_changed)
{ edit_file_buffer *x=file_ring,*cur=current_ring_file;

  /*{{{  shift next*/
  while (of>0)
   { of--;
     while (x!=cur) x=x->next;
     cur=x->next;
   }
  /*}}}  */
  /*{{{  shift previous*/
  while (of<0)
   { of++;
     while (x->next!=cur) x=x->next;
     cur=x;
   }
  /*}}}  */
  filearg=(unsigned char*)cur->filename;
  if
   (    !ignore_changed
     && bd.m.file_changed_status!=unchanged_file
     && yes(get_msg(M_CHANGED_SAVE))
   )
   { total_save((FILE*)0);
     if (bd.m.file_changed_status!=unchanged_file) return;
    }
  if (aborted) return;
  if (filearg) open_file(ignore_changed); else open_arg_list();
  if (current_ring_file)
     find_element(current_ring_file->last_line,DEF_CURSOR_LINE);
}
/*}}}  */
/*{{{  open_list_file*/
public void open_list_file(void)
{ int i;
  boolean ask;
  unsigned char name[16];

  ask=ocl_var[var_mod_beh].v==0;
  if (!ask)
     i=ocl_var[var_mod_beh].v-1;
  if (bd.m.file_changed_status!=unchanged_file && yes(get_msg(M_CHANGED_SAVE)))
   { total_save((FILE*)0);
     if (bd.m.file_changed_status!=unchanged_file) return;
   }
  if (aborted)
     return;
  if (ask)
   { s_readprompt(name,get_msg(M_FILEPO),15,misc_history);
     if (aborted)
        return;
     i=atoi((char*)name);
   }
  if (i<0)
    i=ring_size-1;
  else if (i>=ring_size)
     i=0;
  next_file(i-bd.e.file_no,True);
}
/*}}}  */
/*{{{  enter_list_file*/
public void enter_list_file(void)
{ int i;
  unsigned char name[16];
  unsigned char const *s;

  s_readprompt(name,get_msg(M_FILEPO),15,misc_history);
  if (aborted) return;
  i=atoi((char*)name);
  if (i<0 || i>ring_size || !(s=fileno2name(i)) || !*s)
     s=(unsigned char*)empty_text;
  enter_fold(s);
}
/*}}}  */
/*{{{  write_file*/
public void write_file(void)
{
  if (bd.f.tail == bd.f.real_tail)
   { unsigned char newfilename[_POSIX_PATH_MAX+1];

     fileprompt(newfilename);
     if (*newfilename != '\0' && !aborted)
      { if ((bd.m.dialect.typ != F_C_TDS) && yes(get_msg(M_LIST)))
           no_fold_out=True;
        if (!aborted)
           write_fold(newfilename, bd.f.real_head->next,(FILE*)0);
        no_fold_out=False;
      }
   }
  else
     msg_message(M_NO_TOP);
}
/*}}}  */
