コード例 #1
0
ファイル: popupmnu.c プロジェクト: pthrasher/neovim
/*
 * Set the index of the currently selected item.  The menu will scroll when
 * necessary.  When "n" is out of range don't scroll.
 * This may be repeated when the preview window is used:
 * "repeat" == 0: open preview window normally
 * "repeat" == 1: open preview window but don't set the size
 * "repeat" == 2: don't open preview window
 * Returns TRUE when the window was resized and the location of the popup menu
 * must be recomputed.
 */
static int pum_set_selected(int n, int repeat)
{
    int resized = FALSE;
    int context = pum_height / 2;

    pum_selected = n;

    if (pum_selected >= 0 && pum_selected < pum_size) {
        if (pum_first > pum_selected - 4) {
            /* scroll down; when we did a jump it's probably a PageUp then
             * scroll a whole page */
            if (pum_first > pum_selected - 2) {
                pum_first -= pum_height - 2;
                if (pum_first < 0)
                    pum_first = 0;
                else if (pum_first > pum_selected)
                    pum_first = pum_selected;
            } else
                pum_first = pum_selected;
        } else if (pum_first < pum_selected - pum_height + 5)   {
            /* scroll up; when we did a jump it's probably a PageDown then
             * scroll a whole page */
            if (pum_first < pum_selected - pum_height + 1 + 2) {
                pum_first += pum_height - 2;
                if (pum_first < pum_selected - pum_height + 1)
                    pum_first = pum_selected - pum_height + 1;
            } else
                pum_first = pum_selected - pum_height + 1;
        }

        /* Give a few lines of context when possible. */
        if (context > 3)
            context = 3;
        if (pum_height > 2) {
            if (pum_first > pum_selected - context) {
                /* scroll down */
                pum_first = pum_selected - context;
                if (pum_first < 0)
                    pum_first = 0;
            } else if (pum_first < pum_selected + context - pum_height + 1)   {
                /* scroll up */
                pum_first = pum_selected + context - pum_height + 1;
            }
        }

        /*
         * Show extra info in the preview window if there is something and
         * 'completeopt' contains "preview".
         * Skip this when tried twice already.
         * Skip this also when there is not much room.
         * NOTE: Be very careful not to sync undo!
         */
        if (pum_array[pum_selected].pum_info != NULL
                && Rows > 10
                && repeat <= 1
                && vim_strchr(p_cot, 'p') != NULL) {
            win_T       *curwin_save = curwin;
            int res = OK;

            /* Open a preview window.  3 lines by default.  Prefer
             * 'previewheight' if set and smaller. */
            g_do_tagpreview = 3;
            if (p_pvh > 0 && p_pvh < g_do_tagpreview)
                g_do_tagpreview = p_pvh;
            resized = prepare_tagpreview(FALSE);
            g_do_tagpreview = 0;

            if (curwin->w_p_pvw) {
                if (curbuf->b_fname == NULL
                        && curbuf->b_p_bt[0] == 'n' && curbuf->b_p_bt[2] == 'f'
                        && curbuf->b_p_bh[0] == 'w') {
                    /* Already a "wipeout" buffer, make it empty. */
                    while (!bufempty())
                        ml_delete((linenr_T)1, FALSE);
                } else   {
                    /* Don't want to sync undo in the current buffer. */
                    ++no_u_sync;
                    res = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, 0, NULL);
                    --no_u_sync;
                    if (res == OK) {
                        /* Edit a new, empty buffer. Set options for a "wipeout"
                         * buffer. */
                        set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
                        set_option_value((char_u *)"bt", 0L,
                                         (char_u *)"nofile", OPT_LOCAL);
                        set_option_value((char_u *)"bh", 0L,
                                         (char_u *)"wipe", OPT_LOCAL);
                        set_option_value((char_u *)"diff", 0L,
                                         NULL, OPT_LOCAL);
                    }
                }
                if (res == OK) {
                    char_u      *p, *e;
                    linenr_T lnum = 0;

                    for (p = pum_array[pum_selected].pum_info; *p != NUL; ) {
                        e = vim_strchr(p, '\n');
                        if (e == NULL) {
                            ml_append(lnum++, p, 0, FALSE);
                            break;
                        } else   {
                            *e = NUL;
                            ml_append(lnum++, p, (int)(e - p + 1), FALSE);
                            *e = '\n';
                            p = e + 1;
                        }
                    }

                    /* Increase the height of the preview window to show the
                     * text, but no more than 'previewheight' lines. */
                    if (repeat == 0) {
                        if (lnum > p_pvh)
                            lnum = p_pvh;
                        if (curwin->w_height < lnum) {
                            win_setheight((int)lnum);
                            resized = TRUE;
                        }
                    }

                    curbuf->b_changed = 0;
                    curbuf->b_p_ma = FALSE;
                    curwin->w_cursor.lnum = 1;
                    curwin->w_cursor.col = 0;

                    if (curwin != curwin_save && win_valid(curwin_save)) {
                        /* Return cursor to where we were */
                        validate_cursor();
                        redraw_later(SOME_VALID);

                        /* When the preview window was resized we need to
                         * update the view on the buffer.  Only go back to
                         * the window when needed, otherwise it will always be
                         * redraw. */
                        if (resized) {
                            win_enter(curwin_save, TRUE);
                            update_topline();
                        }

                        /* Update the screen before drawing the popup menu.
                         * Enable updating the status lines. */
                        pum_do_redraw = TRUE;
                        update_screen(0);
                        pum_do_redraw = FALSE;

                        if (!resized && win_valid(curwin_save))
                            win_enter(curwin_save, TRUE);

                        /* May need to update the screen again when there are
                         * autocommands involved. */
                        pum_do_redraw = TRUE;
                        update_screen(0);
                        pum_do_redraw = FALSE;
                    }
                }
            }
        }
    }

    if (!resized)
        pum_redraw();

    return resized;
}
コード例 #2
0
ファイル: popupmnu.c プロジェクト: EricR86/neovim
/// Set the index of the currently selected item.  The menu will scroll when
/// necessary.  When "n" is out of range don't scroll.
/// This may be repeated when the preview window is used:
/// "repeat" == 0: open preview window normally
/// "repeat" == 1: open preview window but don't set the size
/// "repeat" == 2: don't open preview window
///
/// @param n
/// @param repeat
///
/// @returns TRUE when the window was resized and the location of the popup
/// menu must be recomputed.
static int pum_set_selected(int n, int repeat)
{
  int resized = FALSE;
  int context = pum_height / 2;

  pum_selected = n;

  if ((pum_selected >= 0) && (pum_selected < pum_size)) {
    if (pum_first > pum_selected - 4) {
      // scroll down; when we did a jump it's probably a PageUp then
      // scroll a whole page
      if (pum_first > pum_selected - 2) {
        pum_first -= pum_height - 2;
        if (pum_first < 0) {
          pum_first = 0;
        } else if (pum_first > pum_selected) {
          pum_first = pum_selected;
        }
      } else {
        pum_first = pum_selected;
      }
    } else if (pum_first < pum_selected - pum_height + 5) {
      // scroll up; when we did a jump it's probably a PageDown then
      // scroll a whole page
      if (pum_first < pum_selected - pum_height + 1 + 2) {
        pum_first += pum_height - 2;
        if (pum_first < pum_selected - pum_height + 1) {
          pum_first = pum_selected - pum_height + 1;
        }
      } else {
        pum_first = pum_selected - pum_height + 1;
      }
    }

    // Give a few lines of context when possible.
    if (context > 3) {
      context = 3;
    }

    if (pum_height > 2) {
      if (pum_first > pum_selected - context) {
        // scroll down
        pum_first = pum_selected - context;

        if (pum_first < 0) {
          pum_first = 0;
        }
      } else if (pum_first < pum_selected + context - pum_height + 1) {
        // scroll up
        pum_first = pum_selected + context - pum_height + 1;
      }
    }

    // Show extra info in the preview window if there is something and
    // 'completeopt' contains "preview".
    // Skip this when tried twice already.
    // Skip this also when there is not much room.
    // NOTE: Be very careful not to sync undo!
    if ((pum_array[pum_selected].pum_info != NULL)
        && (Rows > 10)
        && (repeat <= 1)
        && (vim_strchr(p_cot, 'p') != NULL)) {
      win_T *curwin_save = curwin;
      int res = OK;

      // Open a preview window.  3 lines by default.  Prefer
      // 'previewheight' if set and smaller.
      g_do_tagpreview = 3;

      if ((p_pvh > 0) && (p_pvh < g_do_tagpreview)) {
        g_do_tagpreview = (int)p_pvh;
      }
      RedrawingDisabled++;
      // Prevent undo sync here, if an autocommand syncs undo weird
      // things can happen to the undo tree.
      no_u_sync++;
      resized = prepare_tagpreview(false);
      no_u_sync--;
      RedrawingDisabled--;
      g_do_tagpreview = 0;

      if (curwin->w_p_pvw) {
        if (!resized
            && (curbuf->b_nwindows == 1)
            && (curbuf->b_fname == NULL)
            && (curbuf->b_p_bt[0] == 'n')
            && (curbuf->b_p_bt[2] == 'f')
            && (curbuf->b_p_bh[0] == 'w')) {
          // Already a "wipeout" buffer, make it empty.
          while (!bufempty()) {
            ml_delete((linenr_T)1, FALSE);
          }
        } else {
          // Don't want to sync undo in the current buffer.
          no_u_sync++;
          res = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, 0, NULL);
          no_u_sync--;

          if (res == OK) {
            // Edit a new, empty buffer. Set options for a "wipeout"
            // buffer.
            set_option_value("swf", 0L, NULL, OPT_LOCAL);
            set_option_value("bt", 0L, "nofile", OPT_LOCAL);
            set_option_value("bh", 0L, "wipe", OPT_LOCAL);
            set_option_value("diff", 0L, NULL, OPT_LOCAL);
          }
        }

        if (res == OK) {
          char_u *p, *e;
          linenr_T lnum = 0;

          for (p = pum_array[pum_selected].pum_info; *p != NUL;) {
            e = vim_strchr(p, '\n');
            if (e == NULL) {
              ml_append(lnum++, p, 0, FALSE);
              break;
            } else {
              *e = NUL;
              ml_append(lnum++, p, (int)(e - p + 1), FALSE);
              *e = '\n';
              p = e + 1;
            }
          }

          // Increase the height of the preview window to show the
          // text, but no more than 'previewheight' lines.
          if (repeat == 0) {
            if (lnum > p_pvh) {
              lnum = p_pvh;
            }

            if (curwin->w_height < lnum) {
              win_setheight((int)lnum);
              resized = TRUE;
            }
          }

          curbuf->b_changed = false;
          curbuf->b_p_ma = FALSE;
          curwin->w_cursor.lnum = 1;
          curwin->w_cursor.col = 0;

          if ((curwin != curwin_save) && win_valid(curwin_save)) {
            // When the first completion is done and the preview
            // window is not resized, skip the preview window's
            // status line redrawing.
            if (ins_compl_active() && !resized) {
              curwin->w_redr_status = FALSE;
            }

            // Return cursor to where we were
            validate_cursor();
            redraw_later(SOME_VALID);

            // When the preview window was resized we need to
            // update the view on the buffer.  Only go back to
            // the window when needed, otherwise it will always be
            // redraw.
            if (resized) {
              no_u_sync++;
              win_enter(curwin_save, true);
              no_u_sync--;
              update_topline();
            }

            // Update the screen before drawing the popup menu.
            // Enable updating the status lines.
            pum_is_visible = false;
            update_screen(0);
            pum_is_visible = true;

            if (!resized && win_valid(curwin_save)) {
              no_u_sync++;
              win_enter(curwin_save, true);
              no_u_sync--;
            }

            // May need to update the screen again when there are
            // autocommands involved.
            pum_is_visible = false;
            update_screen(0);
            pum_is_visible = true;
          }
        }
      }
    }
  }

  if (!resized) {
    pum_redraw();
  }

  return resized;
}
コード例 #3
0
ファイル: screen.c プロジェクト: kindy/vim0
void
cursupdate()
{
        LPTR *p;
        int inc, c, nlines;
        int i;
        int didinc;

        if (bufempty()) {                /* special case - file is empty */
                *Topchar  = *Filemem;
                *Curschar = *Filemem;
        } else if ( LINEOF(Curschar) < LINEOF(Topchar) ) {
                nlines = cntllines(Curschar,Topchar);
                /* if the cursor is above the top of */
                /* the screen, put it at the top of the screen.. */
                *Topchar = *Curschar;
                Topchar->index = 0;
                /* ... and, if we weren't very close to begin with, */
                /* we scroll so that the line is close to the middle. */
                if ( nlines > Rows/3 ) {
                        for (i=0, p = Topchar; i < Rows/3 ;i++, *Topchar = *p)
                                if ((p = prevline(p)) == NULL)
                                        break;
                } else
                        s_ins(0, nlines-1);
                updatescreen();
        }
        else if (LINEOF(Curschar) >= LINEOF(Botchar)) {
                nlines = cntllines(Botchar,Curschar);
                /* If the cursor is off the bottom of the screen, */
                /* put it at the top of the screen.. */
                /* ... and back up */
                if ( nlines > Rows/3 ) {
                        p = Curschar;
                        for (i=0; i < (2*Rows)/3 ;i++)
                                if ((p = prevline(p)) == NULL)
                                        break;
                        *Topchar = *p;
                } else {
                        scrollup(nlines);
                }
                updatescreen();
        }

        Cursrow = Curscol = Cursvcol = 0;
        for ( p=Topchar; p->linep != Curschar->linep ;p = nextline(p) )
                Cursrow += plines(p);

        Cline_row = Cursrow;
        Cline_size = plines(p);

        for (i=0; i <= Curschar->index ;i++) {
                c = Curschar->linep->s[i];
                /* A tab gets expanded, depending on the current column */
                if ( c == TAB && !P(P_LS) )
                        inc = P(P_TS) - (Curscol % P(P_TS));
                else
                        inc = chars[(unsigned)(c & 0xff)].ch_size;
                Curscol += inc;
                Cursvcol += inc;
                if ( Curscol >= Columns ) {
                        Curscol -= Columns;
                        Cursrow++;
                        didinc = TRUE;
                }
                else
                        didinc = FALSE;
        }
        if (didinc)
                Cursrow--;

        if (c == TAB && State == NORMAL && !P(P_LS)) {
                Curscol--;
                Cursvcol--;
        } else {
                Curscol -= inc;
                Cursvcol -= inc;
        }
        if (Curscol < 0)
                Curscol += Columns;

        if (set_want_col) {
                Curswant = Cursvcol;
                set_want_col = FALSE;
        }
}