Exemple #1
0
/// Redraw the popup menu, using "pum_first" and "pum_selected".
void pum_redraw(void)
{
  int row = pum_row;
  int col;
  int attr_norm = highlight_attr[HLF_PNI];
  int attr_select = highlight_attr[HLF_PSI];
  int attr_scroll = highlight_attr[HLF_PSB];
  int attr_thumb = highlight_attr[HLF_PST];
  int attr;
  int i;
  int idx;
  char_u *s;
  char_u *p = NULL;
  int totwidth, width, w;
  int thumb_pos = 0;
  int thumb_heigth = 1;
  int round;
  int n;

  // Never display more than we have
  if (pum_first > pum_size - pum_height) {
    pum_first = pum_size - pum_height;
  }

  if (pum_scrollbar) {
    thumb_heigth = pum_height * pum_height / pum_size;
    if (thumb_heigth == 0) {
      thumb_heigth = 1;
    }
    thumb_pos = (pum_first * (pum_height - thumb_heigth)
                 + (pum_size - pum_height) / 2)
                / (pum_size - pum_height);
  }

  for (i = 0; i < pum_height; ++i) {
    idx = i + pum_first;
    attr = (idx == pum_selected) ? attr_select : attr_norm;

    // prepend a space if there is room
    if (curwin->w_p_rl) {
      if (pum_col < curwin->w_wincol + curwin->w_width - 1) {
        screen_putchar(' ', row, pum_col + 1, attr);
      }
    } else if (pum_col > 0) {
      screen_putchar(' ', row, pum_col - 1, attr);
    }

    // Display each entry, use two spaces for a Tab.
    // Do this 3 times: For the main text, kind and extra info
    col = pum_col;
    totwidth = 0;

    for (round = 1; round <= 3; ++round) {
      width = 0;
      s = NULL;

      switch (round) {
        case 1:
          p = pum_array[idx].pum_text;
          break;

        case 2:
          p = pum_array[idx].pum_kind;
          break;

        case 3:
          p = pum_array[idx].pum_extra;
          break;
      }

      if (p != NULL) {
        for (;; mb_ptr_adv(p)) {
          if (s == NULL) {
            s = p;
          }
          w = ptr2cells(p);

          if ((*p == NUL) || (*p == TAB) || (totwidth + w > pum_width)) {
            // Display the text that fits or comes before a Tab.
            // First convert it to printable characters.
            char_u *st;
            int saved = *p;

            *p = NUL;
            st = transstr(s);
            *p = saved;

            if (curwin->w_p_rl) {
              char_u *rt = reverse_text(st);
              char_u *rt_start = rt;
              int size = vim_strsize(rt);

              if (size > pum_width) {
                do {
                  size -= has_mbyte ? (*mb_ptr2cells)(rt) : 1;
                  mb_ptr_adv(rt);
                } while (size > pum_width);

                if (size < pum_width) {
                  // Most left character requires 2-cells but only 1 cell
                  // is available on screen.  Put a '<' on the left of the 
                  // pum item
                  *(--rt) = '<';
                  size++;
                }
              }
              screen_puts_len(rt, (int)STRLEN(rt), row, col - size + 1,
                              attr);
              free(rt_start);
              free(st);

              col -= width;
            } else {
              if (st != NULL) {
                screen_puts_len(st, (int)STRLEN(st), row, col, attr);
                free(st);
              }
              col += width;
            }

            if (*p != TAB) {
              break;
            }

            // Display two spaces for a Tab.
            if (curwin->w_p_rl) {
              screen_puts_len((char_u *)"  ", 2, row, col - 1, attr);
              col -= 2;
            } else {
              screen_puts_len((char_u *)"  ", 2, row, col, attr);
              col += 2;
            }
            totwidth += 2;
            // start text at next char
            s = NULL;
            width = 0;
          } else {
            width += w;
          }
        }
      }

      if (round > 1) {
        n = pum_kind_width + 1;
      } else {
        n = 1;
      }

      // Stop when there is nothing more to display.
      if ((round == 3)
          || ((round == 2)
              && (pum_array[idx].pum_extra == NULL))
          || ((round == 1)
              && (pum_array[idx].pum_kind == NULL)
              && (pum_array[idx].pum_extra == NULL))
          || (pum_base_width + n >= pum_width)) {
        break;
      }

      if (curwin->w_p_rl) {
        screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
                    col + 1, ' ', ' ', attr);
        col = pum_col - pum_base_width - n + 1;
      } else {
        screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
                    ' ', ' ', attr);
        col = pum_col + pum_base_width + n;
      }
      totwidth = pum_base_width + n;
    }

    if (curwin->w_p_rl) {
      screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ', ' ',
                  attr);
    } else {
      screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
    }

    if (pum_scrollbar > 0) {
      if (curwin->w_p_rl) {
        screen_putchar(' ', row, pum_col - pum_width,
                       i >= thumb_pos && i < thumb_pos + thumb_heigth
                       ? attr_thumb : attr_scroll);
      } else {
        screen_putchar(' ', row, pum_col + pum_width,
                       i >= thumb_pos && i < thumb_pos + thumb_heigth
                       ? attr_thumb : attr_scroll);
      }
    }
    row++;
  }
}
Exemple #2
0
/*
 * Redraw the popup menu, using "pum_first" and "pum_selected".
 */
void pum_redraw(void)          {
    int row = pum_row;
    int col;
    int attr_norm = highlight_attr[HLF_PNI];
    int attr_select = highlight_attr[HLF_PSI];
    int attr_scroll = highlight_attr[HLF_PSB];
    int attr_thumb = highlight_attr[HLF_PST];
    int attr;
    int i;
    int idx;
    char_u      *s;
    char_u      *p = NULL;
    int totwidth, width, w;
    int thumb_pos = 0;
    int thumb_heigth = 1;
    int round;
    int n;

    /* Never display more than we have */
    if (pum_first > pum_size - pum_height)
        pum_first = pum_size - pum_height;

    if (pum_scrollbar) {
        thumb_heigth = pum_height * pum_height / pum_size;
        if (thumb_heigth == 0)
            thumb_heigth = 1;
        thumb_pos = (pum_first * (pum_height - thumb_heigth)
                     + (pum_size - pum_height) / 2)
                    / (pum_size - pum_height);
    }

    for (i = 0; i < pum_height; ++i) {
        idx = i + pum_first;
        attr = (idx == pum_selected) ? attr_select : attr_norm;

        /* prepend a space if there is room */
        if (curwin->w_p_rl) {
            if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1)
                screen_putchar(' ', row, pum_col + 1, attr);
        } else if (pum_col > 0)
            screen_putchar(' ', row, pum_col - 1, attr);

        /* Display each entry, use two spaces for a Tab.
         * Do this 3 times: For the main text, kind and extra info */
        col = pum_col;
        totwidth = 0;
        for (round = 1; round <= 3; ++round) {
            width = 0;
            s = NULL;
            switch (round) {
            case 1:
                p = pum_array[idx].pum_text;
                break;
            case 2:
                p = pum_array[idx].pum_kind;
                break;
            case 3:
                p = pum_array[idx].pum_extra;
                break;
            }
            if (p != NULL)
                for (;; mb_ptr_adv(p)) {
                    if (s == NULL)
                        s = p;
                    w = ptr2cells(p);
                    if (*p == NUL || *p == TAB || totwidth + w > pum_width) {
                        /* Display the text that fits or comes before a Tab.
                         * First convert it to printable characters. */
                        char_u  *st;
                        int saved = *p;

                        *p = NUL;
                        st = transstr(s);
                        *p = saved;
                        if (curwin->w_p_rl) {
                            if (st != NULL) {
                                char_u  *rt = reverse_text(st);

                                if (rt != NULL) {
                                    char_u      *rt_start = rt;
                                    int size;

                                    size = vim_strsize(rt);
                                    if (size > pum_width) {
                                        do {
                                            size -= has_mbyte
                                                    ? (*mb_ptr2cells)(rt) : 1;
                                            mb_ptr_adv(rt);
                                        } while (size > pum_width);

                                        if (size < pum_width) {
                                            /* Most left character requires
                                             * 2-cells but only 1 cell is
                                             * available on screen.  Put a
                                             * '<' on the left of the pum
                                             * item */
                                            *(--rt) = '<';
                                            size++;
                                        }
                                    }
                                    screen_puts_len(rt, (int)STRLEN(rt),
                                                    row, col - size + 1, attr);
                                    vim_free(rt_start);
                                }
                                vim_free(st);
                            }
                            col -= width;
                        } else   {
                            if (st != NULL) {
                                screen_puts_len(st, (int)STRLEN(st), row, col,
                                                attr);
                                vim_free(st);
                            }
                            col += width;
                        }

                        if (*p != TAB)
                            break;

                        /* Display two spaces for a Tab. */
                        if (curwin->w_p_rl) {
                            screen_puts_len((char_u *)"  ", 2, row, col - 1,
                                            attr);
                            col -= 2;
                        } else   {
                            screen_puts_len((char_u *)"  ", 2, row, col, attr);
                            col += 2;
                        }
                        totwidth += 2;
                        s = NULL;                       /* start text at next char */
                        width = 0;
                    } else
                        width += w;
                }

            if (round > 1)
                n = pum_kind_width + 1;
            else
                n = 1;

            /* Stop when there is nothing more to display. */
            if (round == 3
                    || (round == 2 && pum_array[idx].pum_extra == NULL)
                    || (round == 1 && pum_array[idx].pum_kind == NULL
                        && pum_array[idx].pum_extra == NULL)
                    || pum_base_width + n >= pum_width)
                break;
            if (curwin->w_p_rl) {
                screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
                            col + 1, ' ', ' ', attr);
                col = pum_col - pum_base_width - n + 1;
            } else   {
                screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
                            ' ', ' ', attr);
                col = pum_col + pum_base_width + n;
            }
            totwidth = pum_base_width + n;
        }

        if (curwin->w_p_rl)
            screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ',
                        ' ', attr);
        else
            screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ',
                        attr);
        if (pum_scrollbar > 0) {
            if (curwin->w_p_rl)
                screen_putchar(' ', row, pum_col - pum_width,
                               i >= thumb_pos && i < thumb_pos + thumb_heigth
                               ? attr_thumb : attr_scroll);
            else
                screen_putchar(' ', row, pum_col + pum_width,
                               i >= thumb_pos && i < thumb_pos + thumb_heigth
                               ? attr_thumb : attr_scroll);
        }

        ++row;
    }
}