Skip to content

Commit 290b887

Browse files
ychinchrisbra
authored andcommitted
patch 9.0.1991: no cmdline completion for setting the font
Problem: no cmdline completion for setting the font Solution: enable it on Win32 and GTK builds Add guifont cmdline completion (for Windows and GTK) For Windows, auto-complete will only suggest monospace fonts as that's the only types allowed. Will also suggest font options after the colon, including suggesting the current font size for convenience, and misc charset and quality options like `cANSI` and `qCLEARTYPE`. For GTK, auto-complete will suggest only monospace fonts for `guifont` but will include all fonts for `guifontwide`. The completion code doesn't currently suggest the current font size, as the GTK guifont format does not have a clear delimiter (':' for other platforms). closes: #13264 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Yee Cheng Chin <[email protected]>
1 parent ea746f9 commit 290b887

9 files changed

Lines changed: 362 additions & 9 deletions

File tree

src/gui_gtk_x11.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5315,6 +5315,62 @@ gui_mch_free_font(GuiFont font)
53155315
pango_font_description_free(font);
53165316
}
53175317

5318+
/*
5319+
* Cmdline expansion for setting 'guifont' / 'guifontwide'. Will enumerate
5320+
* through all fonts for completion. When setting 'guifont' it will only show
5321+
* monospace fonts as it's unlikely other fonts would be useful.
5322+
*/
5323+
void
5324+
gui_mch_expand_font(optexpand_T *args, void *param, int (*add_match)(char_u *val))
5325+
{
5326+
PangoFontFamily **font_families = NULL;
5327+
int n_families = 0;
5328+
int wide = *(int *)param;
5329+
5330+
if (args->oe_include_orig_val && *args->oe_opt_value == NUL && !wide)
5331+
{
5332+
// If guifont is empty, and we want to fill in the orig value, suggest
5333+
// the default so the user can modify it.
5334+
if (add_match((char_u *)DEFAULT_FONT) != OK)
5335+
return;
5336+
}
5337+
5338+
pango_context_list_families(
5339+
gui.text_context,
5340+
&font_families,
5341+
&n_families);
5342+
5343+
for (int i = 0; i < n_families; i++)
5344+
{
5345+
if (!wide && !pango_font_family_is_monospace(font_families[i]))
5346+
continue;
5347+
5348+
const char* fam_name = pango_font_family_get_name(font_families[i]);
5349+
if (input_conv.vc_type != CONV_NONE)
5350+
{
5351+
char_u *buf = string_convert(&input_conv, (char_u*)fam_name, NULL);
5352+
if (buf != NULL)
5353+
{
5354+
if (add_match(buf) != OK)
5355+
{
5356+
vim_free(buf);
5357+
break;
5358+
}
5359+
vim_free(buf);
5360+
}
5361+
else
5362+
break;
5363+
}
5364+
else
5365+
{
5366+
if (add_match((char_u *)fam_name) != OK)
5367+
break;
5368+
}
5369+
}
5370+
5371+
g_free(font_families);
5372+
}
5373+
53185374
/*
53195375
* Return the Pixel value (color) for the given color name.
53205376
*

src/optiondefs.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,9 +1164,13 @@ static struct vimoption options[] =
11641164
{(char_u *)NULL, (char_u *)0L}
11651165
#endif
11661166
SCTX_INIT},
1167-
{"guifont", "gfn", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP,
1167+
{"guifont", "gfn", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP
1168+
#if !defined(FEAT_GUI_GTK)
1169+
|P_COLON
1170+
#endif
1171+
,
11681172
#ifdef FEAT_GUI
1169-
(char_u *)&p_guifont, PV_NONE, did_set_guifont, NULL,
1173+
(char_u *)&p_guifont, PV_NONE, did_set_guifont, expand_set_guifont,
11701174
{(char_u *)"", (char_u *)0L}
11711175
#else
11721176
(char_u *)NULL, PV_NONE, NULL, NULL,
@@ -1183,10 +1187,14 @@ static struct vimoption options[] =
11831187
{(char_u *)NULL, (char_u *)0L}
11841188
#endif
11851189
SCTX_INIT},
1186-
{"guifontwide", "gfw", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP,
1190+
{"guifontwide", "gfw", P_STRING|P_VI_DEF|P_RCLR|P_ONECOMMA|P_NODUP
1191+
#if !defined(FEAT_GUI_GTK)
1192+
|P_COLON
1193+
#endif
1194+
,
11871195
#if defined(FEAT_GUI)
11881196
(char_u *)&p_guifontwide, PV_NONE,
1189-
did_set_guifontwide, NULL,
1197+
did_set_guifontwide, expand_set_guifont,
11901198
{(char_u *)"", (char_u *)0L}
11911199
#else
11921200
(char_u *)NULL, PV_NONE, NULL, NULL,

src/optionstr.c

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,8 @@ did_set_option_listflag(char_u *val, char_u *flags, char *errbuf)
731731
}
732732

733733
/*
734-
* Expand an option that accepts a list of string values.
734+
* Expand an option that accepts a list of fixed string values with known
735+
* number of items.
735736
*/
736737
static int
737738
expand_set_opt_string(
@@ -801,10 +802,11 @@ static char_u *set_opt_callback_orig_option = NULL;
801802
static char_u *((*set_opt_callback_func)(expand_T *, int));
802803

803804
/*
804-
* Callback used by expand_set_opt_generic to also include the original value.
805+
* Callback used by expand_set_opt_generic to also include the original value
806+
* as the first item.
805807
*/
806808
static char_u *
807-
expand_set_opt_callback(expand_T *xp, int idx)
809+
expand_set_opt_generic_cb(expand_T *xp, int idx)
808810
{
809811
if (idx == 0)
810812
{
@@ -817,7 +819,8 @@ expand_set_opt_callback(expand_T *xp, int idx)
817819
}
818820

819821
/*
820-
* Expand an option with a callback that iterates through a list of possible names.
822+
* Expand an option with a callback that iterates through a list of possible
823+
* names using an index.
821824
*/
822825
static int
823826
expand_set_opt_generic(
@@ -838,14 +841,103 @@ expand_set_opt_generic(
838841
args->oe_regmatch,
839842
matches,
840843
numMatches,
841-
expand_set_opt_callback,
844+
expand_set_opt_generic_cb,
842845
FALSE);
843846

844847
set_opt_callback_orig_option = NULL;
845848
set_opt_callback_func = NULL;
846849
return ret;
847850
}
848851

852+
static garray_T *expand_cb_ga;
853+
static optexpand_T *expand_cb_args;
854+
855+
/*
856+
* Callback provided to a function in expand_set_opt_callback. Will perform
857+
* regex matching against the value and add to the list.
858+
*
859+
* Returns OK usually. Returns FAIL if it failed to allocate memory, and the
860+
* caller should terminate the enumeration.
861+
*/
862+
static int
863+
expand_set_opt_callback_cb(char_u *val)
864+
{
865+
regmatch_T *regmatch = expand_cb_args->oe_regmatch;
866+
expand_T *xp = expand_cb_args->oe_xp;
867+
garray_T *ga = expand_cb_ga;
868+
char_u *str;
869+
870+
if (val == NULL || *val == NUL)
871+
return OK;
872+
873+
if (xp->xp_pattern[0] != NUL &&
874+
!vim_regexec(regmatch, val, (colnr_T)0))
875+
return OK;
876+
877+
str = vim_strsave_escaped(val, (char_u *)" \t\\");
878+
879+
if (str == NULL)
880+
return FAIL;
881+
882+
if (ga_grow(ga, 1) == FAIL)
883+
{
884+
vim_free(str);
885+
return FAIL;
886+
}
887+
888+
((char_u **)ga->ga_data)[ga->ga_len] = str;
889+
++ga->ga_len;
890+
return OK;
891+
}
892+
893+
/*
894+
* Expand an option with a provided function that takes a callback. The
895+
* function will enumerate through all options and call the callback to add it
896+
* to the list.
897+
*
898+
* "func" is the enumerator function that will generate the list of options.
899+
* "func_params" is a single parameter that will be passed to func.
900+
*/
901+
static int
902+
expand_set_opt_callback(
903+
optexpand_T *args,
904+
void (*func)(optexpand_T *, void* params, int (*cb)(char_u *val)),
905+
void *func_params,
906+
int *numMatches,
907+
char_u ***matches)
908+
{
909+
garray_T ga;
910+
int include_orig_val = args->oe_include_orig_val;
911+
char_u *option_val = args->oe_opt_value;
912+
913+
ga_init2(&ga, sizeof(char *), 30);
914+
915+
if (include_orig_val && *option_val != NUL)
916+
{
917+
char_u *p = vim_strsave(option_val);
918+
if (p == NULL)
919+
return FAIL;
920+
if (ga_grow(&ga, 1) == FAIL)
921+
{
922+
vim_free(p);
923+
return FAIL;
924+
}
925+
((char_u **)ga.ga_data)[ga.ga_len] = p;
926+
++ga.ga_len;
927+
}
928+
929+
expand_cb_ga = &ga;
930+
expand_cb_args = args;
931+
932+
func(args, func_params, expand_set_opt_callback_cb);
933+
934+
expand_cb_ga = NULL;
935+
expand_cb_args = NULL;
936+
937+
*matches = ga.ga_data;
938+
*numMatches = ga.ga_len;
939+
return OK;
940+
}
849941

850942
/*
851943
* Expand an option which is a list of flags.
@@ -2237,6 +2329,27 @@ did_set_guifont(optset_T *args UNUSED)
22372329
return errmsg;
22382330
}
22392331

2332+
/*
2333+
* Expand the 'guifont' option. Only when GUI is being used. Each platform has
2334+
* specific behaviors.
2335+
*/
2336+
int
2337+
expand_set_guifont(optexpand_T *args, int *numMatches, char_u ***matches)
2338+
{
2339+
if (!gui.in_use)
2340+
return FAIL;
2341+
2342+
# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_GTK)
2343+
char_u **varp = (char_u **)args->oe_varp;
2344+
int wide = (varp == &p_guifontwide);
2345+
2346+
return expand_set_opt_callback(
2347+
args, gui_mch_expand_font, &wide, numMatches, matches);
2348+
# else
2349+
return FAIL;
2350+
# endif
2351+
}
2352+
22402353
# if defined(FEAT_XFONTSET) || defined(PROTO)
22412354
/*
22422355
* The 'guifontset' option is changed.

0 commit comments

Comments
 (0)