diff mbox series

[RFC,2/2] scripts: Add fzfconfig helper script

Message ID 20240327142544.1728286-3-msp@baylibre.com (mailing list archive)
State New
Headers show
Series kconfig: Add fzf fuzzy search for config options | expand

Commit Message

Markus Schneider-Pargmann March 27, 2024, 2:25 p.m. UTC
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 mbox series

Patch

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:'