Esempio n. 1
0
void listdigraphs(void)
{
  digr_T *dp;

  msg_putchar('\n');

  dp = digraphdefault;

  for (int i = 0; dp->char1 != NUL && !got_int; ++i) {
    digr_T tmp;

    // May need to convert the result to 'encoding'.
    tmp.char1 = dp->char1;
    tmp.char2 = dp->char2;
    tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);

    if ((tmp.result != 0)
        && (tmp.result != tmp.char2)
        && (has_mbyte || (tmp.result <= 255))) {
      printdigraph(&tmp);
    }
    dp++;
    os_breakcheck();
  }

  dp = (digr_T *)user_digraphs.ga_data;
  for (int i = 0; i < user_digraphs.ga_len && !got_int; ++i) {
    printdigraph(dp);
    os_breakcheck();
    dp++;
  }
  // clear screen, because some digraphs may be wrong, in which case we messed
  // up ScreenLines
  must_redraw = CLEAR;
}
Esempio n. 2
0
/*
 * print the changelist
 */
void ex_changes(exarg_T *eap)
{
  int i;
  char_u      *name;

  /* Highlight title */
  MSG_PUTS_TITLE(_("\nchange line  col text"));

  for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) {
    if (curbuf->b_changelist[i].mark.lnum != 0) {
      msg_putchar('\n');
      if (got_int)
        break;
      sprintf((char *)IObuff, "%c %3d %5ld %4d ",
          i == curwin->w_changelistidx ? '>' : ' ',
          i > curwin->w_changelistidx ? i - curwin->w_changelistidx
          : curwin->w_changelistidx - i,
          (long)curbuf->b_changelist[i].mark.lnum,
          curbuf->b_changelist[i].mark.col);
      msg_outtrans(IObuff);
      name = mark_line(&curbuf->b_changelist[i].mark, 17);
      msg_outtrans_attr(name, hl_attr(HLF_D));
      xfree(name);
      os_breakcheck();
    }
    ui_flush();
  }
  if (curwin->w_changelistidx == curbuf->b_changelistlen)
    MSG_PUTS("\n>");
}
Esempio n. 3
0
/*
 * print the jumplist
 */
void ex_jumps(exarg_T *eap)
{
  int i;
  char_u      *name;

  cleanup_jumplist();
  /* Highlight title */
  MSG_PUTS_TITLE(_("\n jump line  col file/text"));
  for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i) {
    if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
      if (curwin->w_jumplist[i].fmark.fnum == 0)
        fname2fnum(&curwin->w_jumplist[i]);
      name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
      if (name == NULL)             /* file name not available */
        continue;

      msg_putchar('\n');
      if (got_int) {
        xfree(name);
        break;
      }
      sprintf((char *)IObuff, "%c %2d %5ld %4d ",
          i == curwin->w_jumplistidx ? '>' : ' ',
          i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
          : curwin->w_jumplistidx - i,
          curwin->w_jumplist[i].fmark.mark.lnum,
          curwin->w_jumplist[i].fmark.mark.col);
      msg_outtrans(IObuff);
      msg_outtrans_attr(name,
          curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
          ? hl_attr(HLF_D) : 0);
      xfree(name);
      os_breakcheck();
    }
    ui_flush();
  }
  if (curwin->w_jumplistidx == curwin->w_jumplistlen)
    MSG_PUTS("\n>");
}
Esempio n. 4
0
/*
 * Find a file in a search context.
 * The search context was created with vim_findfile_init() above.
 * Return a pointer to an allocated file name or NULL if nothing found.
 * To get all matching files call this function until you get NULL.
 *
 * If the passed search_context is NULL, NULL is returned.
 *
 * The search algorithm is depth first. To change this replace the
 * stack with a list (don't forget to leave partly searched directories on the
 * top of the list).
 */
char_u *vim_findfile(void *search_ctx_arg)
{
  char_u      *file_path;
  char_u      *rest_of_wildcards;
  char_u      *path_end = NULL;
  ff_stack_T  *stackp;
  size_t len;
  char_u      *p;
  char_u      *suf;
  ff_search_ctx_T *search_ctx;

  if (search_ctx_arg == NULL)
    return NULL;

  search_ctx = (ff_search_ctx_T *)search_ctx_arg;

  /*
   * filepath is used as buffer for various actions and as the storage to
   * return a found filename.
   */
  file_path = xmalloc(MAXPATHL);

  /* store the end of the start dir -- needed for upward search */
  if (search_ctx->ffsc_start_dir != NULL)
    path_end = &search_ctx->ffsc_start_dir[
      STRLEN(search_ctx->ffsc_start_dir)];

  /* upward search loop */
  for (;; ) {
    /* downward search loop */
    for (;; ) {
      /* check if user user wants to stop the search*/
      os_breakcheck();
      if (got_int)
        break;

      /* get directory to work on from stack */
      stackp = ff_pop(search_ctx);
      if (stackp == NULL)
        break;

      /*
       * TODO: decide if we leave this test in
       *
       * GOOD: don't search a directory(-tree) twice.
       * BAD:  - check linked list for every new directory entered.
       *       - check for double files also done below
       *
       * Here we check if we already searched this directory.
       * We already searched a directory if:
       * 1) The directory is the same.
       * 2) We would use the same wildcard string.
       *
       * Good if you have links on same directory via several ways
       *  or you have selfreferences in directories (e.g. SuSE Linux 6.3:
       *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
       *
       * This check is only needed for directories we work on for the
       * first time (hence stackp->ff_filearray == NULL)
       */
      if (stackp->ffs_filearray == NULL
          && ff_check_visited(&search_ctx->ffsc_dir_visited_list
              ->ffvl_visited_list,
              stackp->ffs_fix_path
              , stackp->ffs_wc_path
              ) == FAIL) {
#ifdef FF_VERBOSE
        if (p_verbose >= 5) {
          verbose_enter_scroll();
          smsg("Already Searched: %s (%s)",
               stackp->ffs_fix_path, stackp->ffs_wc_path);
          msg_puts("\n");  // don't overwrite this either
          verbose_leave_scroll();
        }
#endif
        ff_free_stack_element(stackp);
        continue;
      }
#ifdef FF_VERBOSE
      else if (p_verbose >= 5) {
        verbose_enter_scroll();
        smsg("Searching: %s (%s)",
             stackp->ffs_fix_path, stackp->ffs_wc_path);
        msg_puts("\n");  // don't overwrite this either
        verbose_leave_scroll();
      }
#endif

      /* check depth */
      if (stackp->ffs_level <= 0) {
        ff_free_stack_element(stackp);
        continue;
      }

      file_path[0] = NUL;

      /*
       * If no filearray till now expand wildcards
       * The function expand_wildcards() can handle an array of paths
       * and all possible expands are returned in one array. We use this
       * to handle the expansion of '**' into an empty string.
       */
      if (stackp->ffs_filearray == NULL) {
        char_u *dirptrs[2];

        /* we use filepath to build the path expand_wildcards() should
         * expand.
         */
        dirptrs[0] = file_path;
        dirptrs[1] = NULL;

        /* if we have a start dir copy it in */
        if (!vim_isAbsName(stackp->ffs_fix_path)
            && search_ctx->ffsc_start_dir) {
          STRCPY(file_path, search_ctx->ffsc_start_dir);
          add_pathsep((char *)file_path);
        }

        /* append the fix part of the search path */
        STRCAT(file_path, stackp->ffs_fix_path);
        add_pathsep((char *)file_path);

        rest_of_wildcards = stackp->ffs_wc_path;
        if (*rest_of_wildcards != NUL) {
          len = STRLEN(file_path);
          if (STRNCMP(rest_of_wildcards, "**", 2) == 0) {
            /* pointer to the restrict byte
             * The restrict byte is not a character!
             */
            p = rest_of_wildcards + 2;

            if (*p > 0) {
              (*p)--;
              file_path[len++] = '*';
            }

            if (*p == 0) {
              /* remove '**<numb> from wildcards */
              STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
            } else
              rest_of_wildcards += 3;

            if (stackp->ffs_star_star_empty == 0) {
              /* if not done before, expand '**' to empty */
              stackp->ffs_star_star_empty = 1;
              dirptrs[1] = stackp->ffs_fix_path;
            }
          }

          /*
           * Here we copy until the next path separator or the end of
           * the path. If we stop at a path separator, there is
           * still something else left. This is handled below by
           * pushing every directory returned from expand_wildcards()
           * on the stack again for further search.
           */
          while (*rest_of_wildcards
                 && !vim_ispathsep(*rest_of_wildcards))
            file_path[len++] = *rest_of_wildcards++;

          file_path[len] = NUL;
          if (vim_ispathsep(*rest_of_wildcards))
            rest_of_wildcards++;
        }

        /*
         * Expand wildcards like "*" and "$VAR".
         * If the path is a URL don't try this.
         */
        if (path_with_url((char *)dirptrs[0])) {
          stackp->ffs_filearray = xmalloc(sizeof(char *));
          stackp->ffs_filearray[0] = vim_strsave(dirptrs[0]);
          stackp->ffs_filearray_size = 1;
        } else
          /* Add EW_NOTWILD because the expanded path may contain
           * wildcard characters that are to be taken literally.
           * This is a bit of a hack. */
          expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
              &stackp->ffs_filearray_size,
              &stackp->ffs_filearray,
              EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);

        stackp->ffs_filearray_cur = 0;
        stackp->ffs_stage = 0;
      } else
        rest_of_wildcards = &stackp->ffs_wc_path[
          STRLEN(stackp->ffs_wc_path)];

      if (stackp->ffs_stage == 0) {
        /* this is the first time we work on this directory */
        if (*rest_of_wildcards == NUL) {
          /*
           * We don't have further wildcards to expand, so we have to
           * check for the final file now.
           */
          for (int i = stackp->ffs_filearray_cur;
               i < stackp->ffs_filearray_size; ++i) {
            if (!path_with_url((char *)stackp->ffs_filearray[i])
                && !os_isdir(stackp->ffs_filearray[i]))
              continue;                 /* not a directory */

            /* prepare the filename to be checked for existence
             * below */
            STRCPY(file_path, stackp->ffs_filearray[i]);
            add_pathsep((char *)file_path);
            STRCAT(file_path, search_ctx->ffsc_file_to_search);

            /*
             * Try without extra suffix and then with suffixes
             * from 'suffixesadd'.
             */
            len = STRLEN(file_path);
            if (search_ctx->ffsc_tagfile)
              suf = (char_u *)"";
            else
              suf = curbuf->b_p_sua;
            for (;; ) {
              /* if file exists and we didn't already find it */
              if ((path_with_url((char *)file_path)
                   || (os_path_exists(file_path)
                       && (search_ctx->ffsc_find_what
                           == FINDFILE_BOTH
                           || ((search_ctx->ffsc_find_what
                                == FINDFILE_DIR)
                               == os_isdir(file_path)))))
#ifndef FF_VERBOSE
                  && (ff_check_visited(
                          &search_ctx->ffsc_visited_list->ffvl_visited_list,
                          file_path
                          , (char_u *)""
                          ) == OK)
#endif
                  ) {
#ifdef FF_VERBOSE
                if (ff_check_visited(
                        &search_ctx->ffsc_visited_list->ffvl_visited_list,
                        file_path
                        , (char_u *)""
                        ) == FAIL) {
                  if (p_verbose >= 5) {
                    verbose_enter_scroll();
                    smsg("Already: %s", file_path);
                    msg_puts("\n");  // don't overwrite this either
                    verbose_leave_scroll();
                  }
                  continue;
                }
#endif

                /* push dir to examine rest of subdirs later */
                assert(i < UCHAR_MAX - 1);
                stackp->ffs_filearray_cur = (char_u)(i + 1);
                ff_push(search_ctx, stackp);

                if (!path_with_url((char *)file_path))
                  simplify_filename(file_path);
                if (os_dirname(ff_expand_buffer, MAXPATHL)
                    == OK) {
                  p = path_shorten_fname(file_path,
                      ff_expand_buffer);
                  if (p != NULL)
                    STRMOVE(file_path, p);
                }
#ifdef FF_VERBOSE
                if (p_verbose >= 5) {
                  verbose_enter_scroll();
                  smsg("HIT: %s", file_path);
                  msg_puts("\n");  // don't overwrite this either
                  verbose_leave_scroll();
                }
#endif
                return file_path;
              }

              /* Not found or found already, try next suffix. */
              if (*suf == NUL)
                break;
              assert(MAXPATHL >= len);
              copy_option_part(&suf, file_path + len,
                  MAXPATHL - len, ",");
            }
          }
        } else {
          /*
           * still wildcards left, push the directories for further
           * search
           */
          for (int i = stackp->ffs_filearray_cur;
               i < stackp->ffs_filearray_size; ++i) {
            if (!os_isdir(stackp->ffs_filearray[i]))
              continue;                 /* not a directory */

            ff_push(search_ctx,
                ff_create_stack_element(
                    stackp->ffs_filearray[i],
                    rest_of_wildcards,
                    stackp->ffs_level - 1, 0));
          }
        }
        stackp->ffs_filearray_cur = 0;
        stackp->ffs_stage = 1;
      }

      /*
       * if wildcards contains '**' we have to descent till we reach the
       * leaves of the directory tree.
       */
      if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0) {
        for (int i = stackp->ffs_filearray_cur;
             i < stackp->ffs_filearray_size; ++i) {
          if (fnamecmp(stackp->ffs_filearray[i],
                  stackp->ffs_fix_path) == 0)
            continue;             /* don't repush same directory */
          if (!os_isdir(stackp->ffs_filearray[i]))
            continue;               /* not a directory */
          ff_push(search_ctx,
              ff_create_stack_element(stackp->ffs_filearray[i],
                  stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
        }
      }

      /* we are done with the current directory */
      ff_free_stack_element(stackp);

    }

    /* If we reached this, we didn't find anything downwards.
     * Let's check if we should do an upward search.
     */
    if (search_ctx->ffsc_start_dir
        && search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
      ff_stack_T  *sptr;

      /* is the last starting directory in the stop list? */
      if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
              (int)(path_end - search_ctx->ffsc_start_dir),
              search_ctx->ffsc_stopdirs_v) == TRUE)
        break;

      /* cut of last dir */
      while (path_end > search_ctx->ffsc_start_dir
             && vim_ispathsep(*path_end))
        path_end--;
      while (path_end > search_ctx->ffsc_start_dir
             && !vim_ispathsep(path_end[-1]))
        path_end--;
      *path_end = 0;
      path_end--;

      if (*search_ctx->ffsc_start_dir == 0)
        break;

      STRCPY(file_path, search_ctx->ffsc_start_dir);
      add_pathsep((char *)file_path);
      STRCAT(file_path, search_ctx->ffsc_fix_path);

      /* create a new stack entry */
      sptr = ff_create_stack_element(file_path,
          search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
      ff_push(search_ctx, sptr);
    } else
      break;
  }

  xfree(file_path);
  return NULL;
}