/* * Duplicate the menu item text and then process to see if a mnemonic key * and/or accelerator text has been identified. * Returns a pointer to allocated memory, or NULL for failure. * If mnemonic != NULL, *mnemonic is set to the character after the first '&'. * If actext != NULL, *actext is set to the text after the first TAB. */ static char_u *menu_text(char_u *str, int *mnemonic, char_u **actext) { char_u *p; char_u *text; /* Locate accelerator text, after the first TAB */ p = vim_strchr(str, TAB); if (p != NULL) { if (actext != NULL) *actext = vim_strsave(p + 1); text = vim_strnsave(str, (int)(p - str)); } else text = vim_strsave(str); /* Find mnemonic characters "&a" and reduce "&&" to "&". */ for (p = text; p != NULL; ) { p = vim_strchr(p, '&'); if (p != NULL) { if (p[1] == NUL) /* trailing "&" */ break; if (mnemonic != NULL && p[1] != '&') *mnemonic = p[1]; STRMOVE(p, p + 1); p = p + 1; } } return text; }
/* * Initialise vim to use the font with the given name. Return FAIL if the font * could not be loaded, OK otherwise. */ int gui_mch_init_font(char_u *font_name, int fontset) { vimjs_init_font((char*)font_name); gui.char_width = vimjs_get_char_width(); gui.char_height = vimjs_get_char_height(); gui.char_ascent = gui.char_height; char_u buf[100]; gui.norm_font = vim_strsave(font_name); vim_strncpy(buf, "bold ", 99); // should report 1 less to vim_strncpy vim_strcat(buf, font_name, 100); gui.bold_font = vim_strsave(buf); vim_strncpy(buf, "italic ", 99); // should report 1 less to vim_strncpy vim_strcat(buf, font_name, 100); gui.ital_font = vim_strsave(buf); vim_strncpy(buf, "bold italic ", 99); // should report 1 less to vim_strncpy vim_strcat(buf, font_name, 100); gui.boldital_font = vim_strsave(buf); int w,h; w = vimjs_get_window_width(); h = vimjs_get_window_height(); gui_resize_shell(w, h); return OK; }
static int get_x11_icon(int test_only) { if (!test_only) { if (STRNCMP(T_NAME, "builtin_", 8) == 0) oldicon = vim_strsave(T_NAME + 8); else oldicon = vim_strsave(T_NAME); } return FALSE; }
// Initialize users garray and fill it with os usernames. // Return Ok for success, FAIL for failure. int os_get_usernames(garray_T *users) { if (users == NULL) { return FALSE; } ga_init(users, sizeof(char *), 20); # if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) char *user; struct passwd *pw; setpwent(); while ((pw = getpwent()) != NULL) { // pw->pw_name shouldn't be NULL but just in case... if (pw->pw_name != NULL) { if (ga_grow(users, 1) == FAIL) { return FAIL; } user = (char *)vim_strsave((char_u*)pw->pw_name); if (user == NULL) { return FAIL; } ((char **)(users->ga_data))[users->ga_len++] = user; } } endpwent(); # endif return OK; }
/* * Add a number or string entry to dictionary "d". * When "str" is NULL use number "nr", otherwise use "str". * Returns FAIL when out of memory and when key already exists. */ int dict_add_nr_str( dict_T *d, char *key, varnumber_T nr, char_u *str) { dictitem_T *item; item = dictitem_alloc((char_u *)key); if (item == NULL) return FAIL; item->di_tv.v_lock = 0; if (str == NULL) { item->di_tv.v_type = VAR_NUMBER; item->di_tv.vval.v_number = nr; } else { item->di_tv.v_type = VAR_STRING; item->di_tv.vval.v_string = vim_strsave(str); } if (dict_add(d, item) == FAIL) { dictitem_free(item); return FAIL; } return OK; }
/* * External interface */ static void DoPy3Command(exarg_T *eap, const char *cmd) { #if defined(MACOS) && !defined(MACOS_X_UNIX) GrafPtr oldPort; #endif #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) char *saved_locale; #endif #if defined(MACOS) && !defined(MACOS_X_UNIX) GetPort(&oldPort); /* Check if the Python library is available */ if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress) goto theend; #endif if (Python3_Init()) goto theend; RangeStart = eap->line1; RangeEnd = eap->line2; Python_Release_Vim(); /* leave vim */ #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) /* Python only works properly when the LC_NUMERIC locale is "C". */ saved_locale = setlocale(LC_NUMERIC, NULL); if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0) saved_locale = NULL; else { /* Need to make a copy, value may change when setting new locale. */ saved_locale = (char *)vim_strsave((char_u *)saved_locale); (void)setlocale(LC_NUMERIC, "C"); } #endif pygilstate = PyGILState_Ensure(); PyRun_SimpleString((char *)(cmd)); PyGILState_Release(pygilstate); #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) if (saved_locale != NULL) { (void)setlocale(LC_NUMERIC, saved_locale); vim_free(saved_locale); } #endif Python_Lock_Vim(); /* enter vim */ PythonIO_Flush(); #if defined(MACOS) && !defined(MACOS_X_UNIX) SetPort(oldPort); #endif theend: return; /* keeps lint happy */ }
/* * Return the name of font "font" in allocated memory. * Don't know how to get the actual name, thus use the provided name. */ char_u * gui_mch_get_fontname(GuiFont font, char_u *name) { if (font != NOFONT) { return vim_strsave((char_u*)font); } return NULL; }
/* * maintains the list of already visited files and dirs * returns FAIL if the given file/dir is already in the list * returns OK if it is newly added */ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path) { ff_visited_T *vp; bool url = false; FileInfo file_info; // For a URL we only compare the name, otherwise we compare the // device/inode. if (path_with_url(fname)) { STRLCPY(ff_expand_buffer, fname, MAXPATHL); url = true; } else { ff_expand_buffer[0] = NUL; if (!os_get_file_info((char *)fname, &file_info)) { return FAIL; } } /* check against list of already visited files */ for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) { if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0) || (!url && vp->ffv_dev_valid && vp->ffv_dev == file_info.stat.st_dev && vp->ffv_ino == file_info.stat.st_ino)) { /* are the wildcard parts equal */ if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE) /* already visited */ return FAIL; } } /* * New file/dir. Add it to the list of visited files/dirs. */ vp = xmalloc(sizeof(ff_visited_T) + STRLEN(ff_expand_buffer)); if (!url) { vp->ffv_dev_valid = TRUE; vp->ffv_ino = file_info.stat.st_ino; vp->ffv_dev = file_info.stat.st_dev; vp->ffv_fname[0] = NUL; } else { vp->ffv_dev_valid = FALSE; STRCPY(vp->ffv_fname, ff_expand_buffer); } if (wc_path != NULL) vp->ffv_wc_path = vim_strsave(wc_path); else vp->ffv_wc_path = NULL; vp->ffv_next = *visited_list; *visited_list = vp; return OK; }
/* * Get a font structure for highlighting. */ GuiFont gui_mch_get_font(char_u *name, int giveErrorIfMissing) { if(vimjs_check_font((char*)name)) return (char*)vim_strsave(name); if (giveErrorIfMissing) EMSG2(_(e_font), name); return NOFONT; }
/** * Get the name of the given font */ char_u * gui_mch_get_fontname(GuiFont font, char_u *name) { if (font == NULL || name == NULL) { return NULL; } char_u *s = vim_strsave( name ); return s; }
/* * maintains the list of already visited files and dirs * returns FAIL if the given file/dir is already in the list * returns OK if it is newly added */ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path) { ff_visited_T *vp; bool url = false; FileID file_id; // For an URL we only compare the name, otherwise we compare the // device/inode. if (path_with_url((char *)fname)) { STRLCPY(ff_expand_buffer, fname, MAXPATHL); url = true; } else { ff_expand_buffer[0] = NUL; if (!os_fileid((char *)fname, &file_id)) { return FAIL; } } /* check against list of already visited files */ for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) { if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0) || (!url && vp->file_id_valid && os_fileid_equal(&(vp->file_id), &file_id))) { // are the wildcard parts equal if (ff_wc_equal(vp->ffv_wc_path, wc_path)) { // already visited return FAIL; } } } /* * New file/dir. Add it to the list of visited files/dirs. */ vp = xmalloc(sizeof(ff_visited_T) + STRLEN(ff_expand_buffer)); if (!url) { vp->file_id_valid = true; vp->file_id = file_id; vp->ffv_fname[0] = NUL; } else { vp->file_id_valid = false; STRCPY(vp->ffv_fname, ff_expand_buffer); } if (wc_path != NULL) vp->ffv_wc_path = vim_strsave(wc_path); else vp->ffv_wc_path = NULL; vp->ffv_next = *visited_list; *visited_list = vp; return OK; }
/* * Duplicate the menu item text and then process to see if a mnemonic key * and/or accelerator text has been identified. * Returns a pointer to allocated memory, or NULL for failure. * If mnemonic != NULL, *mnemonic is set to the character after the first '&'. * If actext != NULL, *actext is set to the text after the first TAB. */ static char_u *menu_text(char_u *str, int *mnemonic, char_u **actext) { char_u *p; char_u *text; /* Locate accelerator text, after the first TAB */ p = vim_strchr(str, TAB); if (p != NULL) { if (actext != NULL) *actext = vim_strsave(p + 1); text = vim_strnsave(str, (int)(p - str)); } else text = vim_strsave(str); /* Find mnemonic characters "&a" and reduce "&&" to "&". */ for (p = text; p != NULL; ) { p = vim_strchr(p, '&'); if (p != NULL) { if (p[1] == NUL) /* trailing "&" */ break; if (mnemonic != NULL && p[1] != '&') #if !defined(__MVS__) || defined(MOTIF390_MNEMONIC_FIXED) *mnemonic = p[1]; #else { /* * Well there is a bug in the Motif libraries on OS390 Unix. * The mnemonic keys needs to be converted to ASCII values * first. * This behavior has been seen in 2.8 and 2.9. */ char c = p[1]; __etoa_l(&c, 1); *mnemonic = c; } #endif STRMOVE(p, p + 1); p = p + 1; } } return text; }
/* * Encode "val" into a JSON format string. * The result is added to "gap" * Returns FAIL on failure and makes gap->ga_data empty. */ static int json_encode_gap(garray_T *gap, typval_T *val, int options) { if (json_encode_item(gap, val, get_copyID(), options) == FAIL) { ga_clear(gap); gap->ga_data = vim_strsave((char_u *)""); return FAIL; } return OK; }
/* converts lua value at 'pos' to typval 'tv' */ static void luaV_totypval (lua_State *L, int pos, typval_T *tv) { switch(lua_type(L, pos)) { case LUA_TBOOLEAN: tv->v_type = VAR_SPECIAL; tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos); break; case LUA_TSTRING: tv->v_type = VAR_STRING; tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos)); break; case LUA_TNUMBER: #ifdef FEAT_FLOAT tv->v_type = VAR_FLOAT; tv->vval.v_float = (float_T) lua_tonumber(L, pos); #else tv->v_type = VAR_NUMBER; tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos); #endif break; case LUA_TUSERDATA: { void *p = lua_touserdata(L, pos); if (lua_getmetatable(L, pos)) /* has metatable? */ { /* check list */ luaV_getfield(L, LUAVIM_LIST); if (lua_rawequal(L, -1, -2)) { tv->v_type = VAR_LIST; tv->vval.v_list = *((luaV_List *) p); ++tv->vval.v_list->lv_refcount; lua_pop(L, 2); /* MTs */ return; } /* check dict */ luaV_getfield(L, LUAVIM_DICT); if (lua_rawequal(L, -1, -3)) { tv->v_type = VAR_DICT; tv->vval.v_dict = *((luaV_Dict *) p); ++tv->vval.v_dict->dv_refcount; lua_pop(L, 3); /* MTs */ return; } lua_pop(L, 3); /* MTs */ } break; } default: tv->v_type = VAR_NUMBER; tv->vval.v_number = 0; } }
/* * ":menutrans". * This function is also defined without the +multi_lang feature, in which * case the commands are ignored. */ void ex_menutranslate(exarg_T *eap) { char_u *arg = eap->arg; menutrans_T *tp; char_u *from, *from_noamp, *to; if (menutrans_ga.ga_itemsize == 0) ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5); /* * ":menutrans clear": clear all translations. */ if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) { tp = (menutrans_T *)menutrans_ga.ga_data; for (int i = 0; i < menutrans_ga.ga_len; ++i) { free(tp[i].from); free(tp[i].from_noamp); free(tp[i].to); } ga_clear(&menutrans_ga); /* Delete all "menutrans_" global variables. */ del_menutrans_vars(); } else { /* ":menutrans from to": add translation */ from = arg; arg = menu_skip_part(arg); to = skipwhite(arg); *arg = NUL; arg = menu_skip_part(to); if (arg == to) EMSG(_(e_invarg)); else { ga_grow(&menutrans_ga, 1); tp = (menutrans_T *)menutrans_ga.ga_data; from = vim_strsave(from); from_noamp = menu_text(from, NULL, NULL); to = vim_strnsave(to, (int)(arg - to)); if (from_noamp != NULL) { menu_translate_tab_and_shift(from); menu_translate_tab_and_shift(to); menu_unescape_name(from); menu_unescape_name(to); tp[menutrans_ga.ga_len].from = from; tp[menutrans_ga.ga_len].from_noamp = from_noamp; tp[menutrans_ga.ga_len].to = to; ++menutrans_ga.ga_len; } else { free(from); free(from_noamp); free(to); } } } }
/* * Copy the jumplist from window "from" to window "to". */ void copy_jumplist(win_T *from, win_T *to) { int i; for (i = 0; i < from->w_jumplistlen; ++i) { to->w_jumplist[i] = from->w_jumplist[i]; if (from->w_jumplist[i].fname != NULL) to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname); } to->w_jumplistlen = from->w_jumplistlen; to->w_jumplistidx = from->w_jumplistidx; }
/* * Returns the already visited list for the given filename. If none is found it * allocates a new one. */ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_list_hdr_T **list_headp) { ff_visited_list_hdr_T *retptr = NULL; /* check if a visited list for the given filename exists */ if (*list_headp != NULL) { retptr = *list_headp; while (retptr != NULL) { if (fnamecmp(filename, retptr->ffvl_filename) == 0) { #ifdef FF_VERBOSE if (p_verbose >= 5) { verbose_enter_scroll(); smsg((char_u *)"ff_get_visited_list: FOUND list for %s", filename); /* don't overwrite this either */ msg_puts((char_u *)"\n"); verbose_leave_scroll(); } #endif return retptr; } retptr = retptr->ffvl_next; } } #ifdef FF_VERBOSE if (p_verbose >= 5) { verbose_enter_scroll(); smsg((char_u *)"ff_get_visited_list: new list for %s", filename); /* don't overwrite this either */ msg_puts((char_u *)"\n"); verbose_leave_scroll(); } #endif /* * if we reach this we didn't find a list and we have to allocate new list */ retptr = (ff_visited_list_hdr_T*)alloc((unsigned)sizeof(*retptr)); if (retptr == NULL) return NULL; retptr->ffvl_visited_list = NULL; retptr->ffvl_filename = vim_strsave(filename); if (retptr->ffvl_filename == NULL) { vim_free(retptr); return NULL; } retptr->ffvl_next = *list_headp; *list_headp = retptr; return retptr; }
/* * Encode "val" into a JSON format string. * The result is in allocated memory. * The result is empty when encoding fails. * "options" can be JSON_JS or zero; */ char_u * json_encode(typval_T *val, int options) { garray_T ga; /* Store bytes in the growarray. */ ga_init2(&ga, 1, 4000); if (json_encode_item(&ga, val, get_copyID(), options) == FAIL) { vim_free(ga.ga_data); return vim_strsave((char_u *)""); } return ga.ga_data; }
/* * Get a string item from a dictionary. * When "save" is TRUE allocate memory for it. * Returns NULL if the entry doesn't exist or out of memory. */ char_u * get_dict_string(dict_T *d, char_u *key, int save) { dictitem_T *di; char_u *s; di = dict_find(d, key, -1); if (di == NULL) return NULL; s = get_tv_string(&di->di_tv); if (save && s != NULL) s = vim_strsave(s); return s; }
/* * Allocate a new sign */ static sign_T * alloc_new_sign(char_u *name) { sign_T *sp; sign_T *lp; int start = next_sign_typenr; // Allocate a new sign. sp = (sign_T *)alloc_clear_id((unsigned)sizeof(sign_T), aid_sign_define_by_name); if (sp == NULL) return NULL; // Check that next_sign_typenr is not already being used. // This only happens after wrapping around. Hopefully // another one got deleted and we can use its number. for (lp = first_sign; lp != NULL; ) { if (lp->sn_typenr == next_sign_typenr) { ++next_sign_typenr; if (next_sign_typenr == MAX_TYPENR) next_sign_typenr = 1; if (next_sign_typenr == start) { vim_free(sp); emsg(_("E612: Too many signs defined")); return NULL; } lp = first_sign; // start all over continue; } lp = lp->sn_next; } sp->sn_typenr = next_sign_typenr; if (++next_sign_typenr == MAX_TYPENR) next_sign_typenr = 1; // wrap around sp->sn_name = vim_strsave(name); if (sp->sn_name == NULL) // out of memory { vim_free(sp); return NULL; } return sp; }
/* * Initialize the icon information for a new sign */ static void sign_define_init_icon(sign_T *sp, char_u *icon) { vim_free(sp->sn_icon); sp->sn_icon = vim_strsave(icon); backslash_halve(sp->sn_icon); # ifdef FEAT_SIGN_ICONS if (gui.in_use) { out_flush(); if (sp->sn_image != NULL) gui_mch_destroy_sign(sp->sn_image); sp->sn_image = gui_mch_register_sign(sp->sn_icon); } # endif }
// Returns the user directory for the given username. // The caller has to free() the returned string. // If the username is not found, NULL is returned. char *os_get_user_directory(const char *name) { #if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H) struct passwd *pw; if (name == NULL) { return NULL; } pw = getpwnam(name); if (pw != NULL) { // save the string from the static passwd entry into malloced memory char *user_directory = (char *)vim_strsave((char_u *)pw->pw_dir); return user_directory; } #endif return NULL; }
/* * Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy. */ vimmenu_T *gui_find_menu(char_u *path_name) { vimmenu_T *menu = NULL; char_u *name; char_u *saved_name; char_u *p; menu = root_menu; saved_name = vim_strsave(path_name); name = saved_name; while (*name) { /* find the end of one dot-separated name and put a NUL at the dot */ p = menu_name_skip(name); while (menu != NULL) { if (menu_name_equal(name, menu)) { if (menu->children == NULL) { /* found a menu item instead of a sub-menu */ if (*p == NUL) EMSG(_("E336: Menu path must lead to a sub-menu")); else EMSG(_(e_notsubmenu)); menu = NULL; goto theend; } if (*p == NUL) /* found a full match */ goto theend; break; } menu = menu->next; } if (menu == NULL) /* didn't find it */ break; /* Found a match, search the sub-menu. */ menu = menu->children; name = p; } if (menu == NULL) EMSG(_("E337: Menu not found - check menu names")); theend: free(saved_name); return menu; }
/* * Show the mapping associated with a menu item or hierarchy in a sub-menu. */ static int show_menus(char_u *path_name, int modes) { char_u *p; char_u *name; vimmenu_T *menu; vimmenu_T *parent = NULL; menu = root_menu; name = path_name = vim_strsave(path_name); /* First, find the (sub)menu with the given name */ while (*name) { p = menu_name_skip(name); while (menu != NULL) { if (menu_name_equal(name, menu)) { /* Found menu */ if (*p != NUL && menu->children == NULL) { EMSG(_(e_notsubmenu)); free(path_name); return FAIL; } else if ((menu->modes & modes) == 0x0) { EMSG(_(e_othermode)); free(path_name); return FAIL; } break; } menu = menu->next; } if (menu == NULL) { EMSG2(_(e_nomenu), name); free(path_name); return FAIL; } name = p; parent = menu; menu = menu->children; } free(path_name); /* Now we have found the matching menu, and we list the mappings */ /* Highlight title */ MSG_PUTS_TITLE(_("\n--- Menus ---")); show_menus_recursive(parent, modes, 0); return OK; }
/* * Make a copy of "str" and append it as an item to list "l". * When "len" >= 0 use "str[len]". * Returns FAIL when out of memory. */ int list_append_string(list_T *l, char_u *str, int len) { listitem_T *li = listitem_alloc(); if (li == NULL) return FAIL; list_append(l, li); li->li_tv.v_type = VAR_STRING; li->li_tv.v_lock = 0; if (str == NULL) li->li_tv.vval.v_string = NULL; else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) : vim_strsave(str))) == NULL) return FAIL; return OK; }
int serverSetName(char_u *name) { HWND hwnd = 0; hwnd = findServer(name); if (hwnd != 0) return FALSE; /* Remember the name */ serverName = vim_strsave(name); /* Update the message window title */ SetWindowText(message_window, (char *)name); return TRUE; }
void init_homedir(void) { // In case we are called a second time. xfree(homedir); homedir = NULL; const char *var = os_getenv("HOME"); #ifdef WIN32 // Typically, $HOME is not defined on Windows, unless the user has // specifically defined it for Vim's sake. However, on Windows NT // platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for // each user. Try constructing $HOME from these. if (var == NULL) { const char *homedrive = os_getenv("HOMEDRIVE"); const char *homepath = os_getenv("HOMEPATH"); if (homepath == NULL) { homepath = "\\"; } if (homedrive != NULL && strlen(homedrive) + strlen(homepath) < MAXPATHL) { snprintf(os_buf, MAXPATHL, "%s%s", homedrive, homepath); if (os_buf[0] != NUL) { var = os_buf; vim_setenv("HOME", os_buf); } } } #endif if (var != NULL) { #ifdef UNIX // Change to the directory and get the actual path. This resolves // links. Don't do it when we can't return. if (os_dirname((char_u *)os_buf, MAXPATHL) == OK && os_chdir(os_buf) == 0) { if (!os_chdir(var) && os_dirname(IObuff, IOSIZE) == OK) { var = (char *)IObuff; } if (os_chdir(os_buf) != 0) { EMSG(_(e_prev_dir)); } } #endif homedir = vim_strsave((char_u *)var); } }
/* * ":menutrans". * This function is also defined without the +multi_lang feature, in which * case the commands are ignored. */ void ex_menutranslate(exarg_T *eap) { char_u *arg = eap->arg; char_u *from, *from_noamp, *to; if (menutrans_ga.ga_itemsize == 0) ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5); /* * ":menutrans clear": clear all translations. */ if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) { GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS); /* Delete all "menutrans_" global variables. */ del_menutrans_vars(); } else { /* ":menutrans from to": add translation */ from = arg; arg = menu_skip_part(arg); to = skipwhite(arg); *arg = NUL; arg = menu_skip_part(to); if (arg == to) EMSG(_(e_invarg)); else { from = vim_strsave(from); from_noamp = menu_text(from, NULL, NULL); to = vim_strnsave(to, (int)(arg - to)); if (from_noamp != NULL) { menu_translate_tab_and_shift(from); menu_translate_tab_and_shift(to); menu_unescape_name(from); menu_unescape_name(to); menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga); tp->from = from; tp->from_noamp = from_noamp; tp->to = to; } else { free(from); free(to); } } } }
/* * Return the line at mark "mp". Truncate to fit in window. * The returned string has been allocated. */ static char_u *mark_line(pos_T *mp, int lead_len) { char_u *s, *p; int len; if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) return vim_strsave((char_u *)"-invalid-"); s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (int)Columns); /* Truncate the line to fit it in the window */ len = 0; for (p = s; *p != NUL; mb_ptr_adv(p)) { len += ptr2cells(p); if (len >= Columns - lead_len) break; } *p = NUL; return s; }
/* * Terminal version of a balloon, uses the popup menu code. */ void ui_post_balloon(char_u *mesg, list_T *list) { ui_remove_balloon(); if (mesg == NULL && list == NULL) return; if (list != NULL) { listitem_T *li; int idx; balloon_arraysize = list->lv_len; balloon_array = (pumitem_T *)alloc_clear( (unsigned)sizeof(pumitem_T) * list->lv_len); if (balloon_array == NULL) return; for (idx = 0, li = list->lv_first; li != NULL; li = li->li_next, ++idx) { char_u *text = get_tv_string_chk(&li->li_tv); balloon_array[idx].pum_text = vim_strsave( text == NULL ? (char_u *)"" : text); } } else balloon_arraysize = split_message(mesg, &balloon_array); if (balloon_arraysize > 0) { pum_array = balloon_array; pum_size = balloon_arraysize; pum_compute_size(); pum_scrollbar = 0; pum_height = balloon_arraysize; pum_position_at_mouse(BALLOON_MIN_WIDTH); pum_selected = -1; pum_first = 0; pum_redraw(); } }