mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC 0/2] kconfig: Add fzf fuzzy search for config options
@ 2024-03-27 14:25 Markus Schneider-Pargmann
  2024-03-27 14:25 ` [RFC 1/2] kconfig: Add helpallconfig Markus Schneider-Pargmann
  2024-03-27 14:25 ` [RFC 2/2] scripts: Add fzfconfig helper script Markus Schneider-Pargmann
  0 siblings, 2 replies; 3+ messages in thread
From: Markus Schneider-Pargmann @ 2024-03-27 14:25 UTC (permalink / raw)
  To: Masahiro Yamada, Markus Schneider-Pargmann; +Cc: linux-kernel, linux-kbuild

Hi,

These two patches are introducing a way to use fzf with the kernel
config options.

Using 'make fzfconfig' opens a list of all config options and their
state in the currently used configuration file. A preview is provided
for the currently selected config option in the list, showing the
original Kconfig snippet. Using Enter opens make menuconfig for the
selected option.

I reused the existing helpnewconfig command as it contains all the
information necessary and extended it to display all options using
helpallconfig. Using a wrapper script, that does simple parsing, the
view is transformed into a line based representation that is usable by
fzf.

I used this helper for some time now and it seems to work quite good for
me, though there may be cornercases for symbols etc. where it doesn't
work. I chose to use helpnewconfig/helpallconfig as it seems to be just
a small modification on the existing codebase to achieve fzf support.

Best
Markus

Markus Schneider-Pargmann (2):
  kconfig: Add helpallconfig
  scripts: Add fzfconfig helper script

 scripts/fzfconfig        | 112 +++++++++++++++++++++++++++++++++++++++
 scripts/kconfig/Makefile |   8 ++-
 scripts/kconfig/conf.c   |  17 ++++--
 3 files changed, 132 insertions(+), 5 deletions(-)
 create mode 100755 scripts/fzfconfig

-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [RFC 1/2] kconfig: Add helpallconfig
  2024-03-27 14:25 [RFC 0/2] kconfig: Add fzf fuzzy search for config options Markus Schneider-Pargmann
@ 2024-03-27 14:25 ` Markus Schneider-Pargmann
  2024-03-27 14:25 ` [RFC 2/2] scripts: Add fzfconfig helper script Markus Schneider-Pargmann
  1 sibling, 0 replies; 3+ messages in thread
From: Markus Schneider-Pargmann @ 2024-03-27 14:25 UTC (permalink / raw)
  To: Masahiro Yamada, Markus Schneider-Pargmann; +Cc: linux-kernel, linux-kbuild

To support a possible fzf driven kconfig script, all config symbols need
to be printed. As helpnewconfig already provides a very similar list,
this patch extends that functionality to print all config symbols with a
new command called helpallconfig.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---
 scripts/kconfig/Makefile |  4 +++-
 scripts/kconfig/conf.c   | 17 +++++++++++++----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index ea1bf3b3dbde..87df82c03afb 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -77,7 +77,8 @@ localyesconfig localmodconfig: $(obj)/conf
 #  deprecated for external use
 simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
 	alldefconfig randconfig listnewconfig olddefconfig syncconfig \
-	helpnewconfig yes2modconfig mod2yesconfig mod2noconfig
+	helpallconfig helpnewconfig yes2modconfig mod2yesconfig \
+	mod2noconfig
 
 PHONY += $(simple-targets)
 
@@ -147,6 +148,7 @@ help:
 	@echo  '  mod2yesconfig	  - Change answers from mod to yes if possible'
 	@echo  '  mod2noconfig	  - Change answers from mod to no if possible'
 	@echo  '  listnewconfig   - List new options'
+	@echo  '  helpallconfig   - List all options and help text'
 	@echo  '  helpnewconfig   - List new options and help text'
 	@echo  '  olddefconfig	  - Same as oldconfig but sets new symbols to their'
 	@echo  '                    default value without prompting'
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index b5730061872b..3abc5f6b3a27 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -32,6 +32,7 @@ enum input_mode {
 	defconfig,
 	savedefconfig,
 	listnewconfig,
+	helpallconfig,
 	helpnewconfig,
 	olddefconfig,
 	yes2modconfig,
@@ -633,13 +634,14 @@ static void check_conf(struct menu *menu)
 	struct symbol *sym;
 	struct menu *child;
 
-	if (!menu_is_visible(menu))
+	if (input_mode != helpallconfig && !menu_is_visible(menu))
 		return;
 
 	sym = menu->sym;
-	if (sym && !sym_has_value(sym) &&
-	    (sym_is_changeable(sym) ||
-	     (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
+	if (input_mode == helpallconfig ||
+	    (sym && !sym_has_value(sym) &&
+	     (sym_is_changeable(sym) ||
+	      (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)))) {
 
 		switch (input_mode) {
 		case listnewconfig:
@@ -647,6 +649,7 @@ static void check_conf(struct menu *menu)
 				print_symbol_for_listconfig(sym);
 			break;
 		case helpnewconfig:
+		case helpallconfig:
 			printf("-----\n");
 			print_help(menu);
 			printf("-----\n");
@@ -678,6 +681,7 @@ static const struct option long_opts[] = {
 	{"alldefconfig",  no_argument,       &input_mode_opt, alldefconfig},
 	{"randconfig",    no_argument,       &input_mode_opt, randconfig},
 	{"listnewconfig", no_argument,       &input_mode_opt, listnewconfig},
+	{"helpallconfig", no_argument,       &input_mode_opt, helpallconfig},
 	{"helpnewconfig", no_argument,       &input_mode_opt, helpnewconfig},
 	{"olddefconfig",  no_argument,       &input_mode_opt, olddefconfig},
 	{"yes2modconfig", no_argument,       &input_mode_opt, yes2modconfig},
@@ -696,6 +700,7 @@ static void conf_usage(const char *progname)
 	printf("\n");
 	printf("Mode options:\n");
 	printf("  --listnewconfig         List new options\n");
+	printf("  --helpallconfig         List all options and help text\n");
 	printf("  --helpnewconfig         List new options and help text\n");
 	printf("  --oldaskconfig          Start a new configuration using a line-oriented program\n");
 	printf("  --oldconfig             Update a configuration using a provided .config as base\n");
@@ -783,6 +788,7 @@ int main(int ac, char **av)
 	case oldaskconfig:
 	case oldconfig:
 	case listnewconfig:
+	case helpallconfig:
 	case helpnewconfig:
 	case olddefconfig:
 	case yes2modconfig:
@@ -888,6 +894,9 @@ int main(int ac, char **av)
 			check_conf(&rootmenu);
 		} while (conf_cnt);
 		break;
+	case helpallconfig:
+		check_conf(&rootmenu);
+		break;
 	case olddefconfig:
 	default:
 		break;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [RFC 2/2] scripts: Add fzfconfig helper script
  2024-03-27 14:25 [RFC 0/2] kconfig: Add fzf fuzzy search for config options Markus Schneider-Pargmann
  2024-03-27 14:25 ` [RFC 1/2] kconfig: Add helpallconfig Markus Schneider-Pargmann
@ 2024-03-27 14:25 ` Markus Schneider-Pargmann
  1 sibling, 0 replies; 3+ messages in thread
From: Markus Schneider-Pargmann @ 2024-03-27 14:25 UTC (permalink / raw)
  To: Masahiro Yamada, Markus Schneider-Pargmann; +Cc: linux-kernel, linux-kbuild

Add a script to present all config options in fzf. This allows to fuzzy
search in all config options and their help texts. It also displays the
configuration state in the list. A preview window shows the actual
Kconfig snippet for the config option.

Using 'Enter' in the displayed list will open 'make menuconfig' and
automatically execute a search for the selected symbol. After that the
user can use the menuconfig to change the option or do other things.
After exiting menuconfig the fzf list is refreshed and you can continue
navigating the list from the point where you entered menuconfig.

Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---
 scripts/fzfconfig        | 112 +++++++++++++++++++++++++++++++++++++++
 scripts/kconfig/Makefile |   4 ++
 2 files changed, 116 insertions(+)
 create mode 100755 scripts/fzfconfig

diff --git a/scripts/fzfconfig b/scripts/fzfconfig
new file mode 100755
index 000000000000..48f9590c1031
--- /dev/null
+++ b/scripts/fzfconfig
@@ -0,0 +1,112 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Author: Markus Schneider-Pargmann <msp@baylibre.com>
+#
+# List all config options inside of fzf and offer an easy option to jump to the
+# option in menuconfig
+
+config_script="scripts/config --file $KCONFIG_CONFIG"
+
+history_file="$HOME/.cache/kconfig_fzf.hist"
+
+kconfig_fzf_clenup_on_exit() {
+  rm -f "$menucfgpipe"
+}
+
+kconfig_fzf_oneline_config_items() {
+  make helpallconfig | \
+    grep -vE '^(Type  :|  Depends on:|  Visible if:|Selects:|Selected by|CONFIG_)' | \
+    sed 's/^  Prompt: \(.*\)$/1111111111\11111111111/g' | \
+    tr '\n' ' ' | \
+    sed 's/----- -----/\n/g' | \
+    sed 's/\(^ *\|-----\)//g' | \
+    sed 's/  */ /g' | \
+    sed 's/^\(.*\)1111111111\(.*\)1111111111\(.*\)/\t\2:\1\3/g' | \
+    sed 's/^\([^\t].*\)$/\t:\1/g' | \
+    sed 's/^\(.*\)Symbol: \([^ ]*\) \[\([^]]\{1,40\}\)[^]]*\].*Defined at \([^:]*\):\([0-9]*\) .*$/\4:\5\t:\2\3:\1/g' | \
+    grep -E '^.*:[0-9]*	:.*=.*:'
+}
+
+kconfig_fzf_make_menuconfig() {
+  menucfgpipe="$(mktemp --dry-run)"
+  trap kconfig_fzf_clenup_on_exit EXIT
+  mkfifo "$menucfgpipe"
+
+  make menuconfig < "$menucfgpipe" &
+  menuconfigpid=$!
+
+  echo "/^${1}\$" > "$menucfgpipe"
+
+  cat > "$menucfgpipe" < /dev/stdin &
+  redirectpid=$!
+
+  wait $menuconfigpid
+  kill $redirectpid
+}
+
+kconfig_fzf_get_catcmd() {
+  for cmd in bat batcat
+  do
+    if which $cmd > /dev/null
+    then
+      echo $cmd \
+        --paging=never \
+        --force-colorization \
+        --highlight-line {2}
+      return
+    fi
+  done
+  echo 'echo -e "+----------\n| "File: {1}:{2}"\n+----------"; cat --number'
+  exit 0
+}
+
+kconfig_fzf_command() {
+  menuconfig_action="execute(bash -c \"source $0;"' kconfig_fzf_make_menuconfig \$(echo {3} | cut -d '=' -f 1)")'
+  reload_action="reload(bash -c 'source $0; kconfig_fzf_oneline_config_items')"
+  catcmd="$(kconfig_fzf_get_catcmd)"
+
+  kconfig_fzf_oneline_config_items | column --table --separator '	' | \
+    env SHELL=/bin/bash \
+    fzf \
+      --history="$history_file" \
+      --tiebreak=begin \
+      --delimiter=: \
+      --nth=.. \
+      --with-nth=3,4 \
+      --preview "$catcmd"' \
+        "${srctree:-.}/"{1}' \
+      --preview-window 'right,90,+{2}-5,~3' \
+      --bind "ctrl-r:${reload_action}" \
+      --bind "ctrl-g:execute(echo \"'{}'\"; read)" \
+      --bind "enter:${menuconfig_action}+${reload_action}" \
+      --header 'enter: Open in menuconfig, ctrl-r: Reload, esc: Exit'
+    if [ "$?" -eq 130 ]
+    then
+      return 0
+    fi
+    return "$ret"
+}
+
+if [ "$#" -gt "0" ]
+then
+  echo "USAGE: $0"
+  echo ""
+  echo "Show all kconfig symbols in fzf and open selected item on enter in make menuconfig."
+  echo ""
+  echo "You can fuzzy search in these data fields: <KCONFIG_FILE>:<LINENO>:<CONFIG_SYMBOL>=<VALUE>:<PROMPT>:<HELP>."
+  echo "Not all fields are visible but the search is still done."
+  echo "A preview of the Kconfig file is shown on the right side."
+  echo ""
+  echo "Key bindings:"
+  echo "  Enter : Open symbol in make menuconfig"
+  echo "  CTRL-r: Reload config symbols"
+  echo "  Escape: Exit"
+  exit 0
+fi
+
+(return 0 2>/dev/null) && kconfig_fzf_sourced=1
+if [ "$kconfig_fzf_sourced" != "1" ]
+then
+  kconfig_fzf_command
+fi
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 87df82c03afb..1f47b9ae9786 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -124,6 +124,10 @@ testconfig: $(obj)/conf
 	$(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
 clean-files += tests/.cache
 
+PHONY += fzfconfig
+fzfconfig:
+	$(srctree)/scripts/fzfconfig
+
 # Help text used by make help
 help:
 	@echo  'Configuration targets:'
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-03-27 14:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-27 14:25 [RFC 0/2] kconfig: Add fzf fuzzy search for config options Markus Schneider-Pargmann
2024-03-27 14:25 ` [RFC 1/2] kconfig: Add helpallconfig Markus Schneider-Pargmann
2024-03-27 14:25 ` [RFC 2/2] scripts: Add fzfconfig helper script Markus Schneider-Pargmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®