Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to edit command line in vim / copy command line to clipboard / bind fzf-file-widget? #96

Open
MaxGyver83 opened this issue May 13, 2024 · 3 comments

Comments

@MaxGyver83
Copy link
Contributor

Thank you for implementing rc for Linux! I'm new to it and I have some questions:

Can I achieve any of the following in rc (with readline support):

Edit command line in vim

I have this in my .inputrc:

# edit command line in vim
"\ev": edit-and-execute-command

This does not work in rc because it's a bash function. I think it belongs into my .bashrc then. Could I replace edit-and-execute-command with an equivalent rc function? Would this have to be done in rc's source code?

Copy the current command line to the clipboard

I have this in my .bashrc:

copy_line_to_x_clipboard () {
  # using OSC 52
  printf "\e]52;c;%s\a" "$(printf %s "$READLINE_LINE" | openssl base64 -A)"
}
# bind to Ctrl-Shift-x
bind -x '"\C-X": copy_line_to_x_clipboard'

I have adapted this function for rc (in my .rcrc):

fn copy_line_to_x_clipboard {
	# using OSC 52
	printf '\e]52;c;%s\a' `{printf %s $READLINE_LINE | openssl base64 -A}
}

and moved the binding to C-X into my .inputrc:

"\C-X": copy_line_to_x_clipboard

But it still does not work. Is it possible at all to bind readline keystrokes to rc functions? (Maybe I just got the quotes wrong.)

Use fzf for file selection

More or less the same question: How can I migrate this bash snippet to rc?

  # CTRL-T - Paste the selected file path into the command line
  if [[ "${FZF_CTRL_T_COMMAND-x}" != "" ]]; then
    bind -m emacs-standard -x '"\C-t": fzf-file-widget'
    bind -m vi-command -x '"\C-t": fzf-file-widget'
    bind -m vi-insert -x '"\C-t": fzf-file-widget'
  fi

fzf/shell/key-bindings.bash at 07880ca4415009d7a151d262bc5ac62f8b6dc719 · junegunn/fzf

@rakitzis
Copy link
Owner

Hi, I'm looking at these questions and I don't know the answers. Readline support is ad hoc. If you send me a pull request to run shell functions from readline keystrokes, I'll review it.

@MaxGyver83
Copy link
Contributor Author

Hi Byron,

I tried adding this for bestline. But so far it does not work. These are my current local changes for rc:

diff --git a/Makefile b/Makefile
index 39966e6..a22e4f6 100644
--- a/Makefile
+++ b/Makefile
@@ -9,9 +9,9 @@ VERSION = 1.7.4
 PREFIX = /usr/local
 MANPREFIX = $(PREFIX)/share/man
 
-_CFLAGS = -Wall $(CFLAGS)
-_CPPFLAGS = -I. -I$(srcdir) -I$(PREFIX)/include $(CPPFLAGS)
-_LDFLAGS = -L$(PREFIX)/lib $(LDFLAGS)
+_CFLAGS = -Wall $(CFLAGS) -g
+_CPPFLAGS = -I/home/max/repos/bestline-dev -I. -I$(srcdir) -I$(PREFIX)/include $(CPPFLAGS)
+_LDFLAGS = -L/home/max/repos/bestline-dev -L$(PREFIX)/lib $(LDFLAGS) -g
 
 BINS = history mksignal mkstatval tripping
 HEADERS = edit.h getgroups.h input.h jbwrap.h proto.h rc.h rlimit.h stat.h \
diff --git a/builtins.c b/builtins.c
index f73cd2d..269f921 100644
--- a/builtins.c
+++ b/builtins.c
@@ -23,7 +23,7 @@
 #include "addon.c"
 #endif
 
-static void b_break(char **), b_cd(char **), b_continue(char **), b_eval(char **), b_flag(char **),
+static void b_bind(char **), b_break(char **), b_cd(char **), b_continue(char **), b_eval(char **), b_flag(char **),
 	b_exit(char **), b_newpgrp(char **), b_return(char **), b_shift(char **), b_umask(char **),
 	b_wait(char **), b_whatis(char **);
 
@@ -35,10 +35,17 @@ static void b_limit(char **);
 static void b_echo(char **);
 #endif
 
+#if EDIT == bestline
+extern void bestlineAddBinding(char **);
+#endif
+
 static struct {
 	builtin_t *p;
 	char *name;
 } builtins[] = {
+#if EDIT == bestline
+	{ b_bind,	"bind" },
+#endif
 	{ b_break,	"break" },
 	{ b_builtin,	"builtin" },
 	{ b_cd,		"cd" },
@@ -81,6 +88,8 @@ extern void funcall(char **av) {
 	Edata jreturn, star;
 	if (sigsetjmp(j.j, 1))
 		return;
+	/* char *bv = getenv("BESTLINE_LINE"); */
+	/* fprint(2, "\nBESTLINE_LINE: %s\n", bv ? bv : "UNSET"); */
 	starassign(*av, av+1, TRUE);
 	jreturn.jb = &j;
 	star.name = "*";
@@ -102,6 +111,18 @@ static void badnum(char *num) {
     set(FALSE);
 }
 
+#if EDIT == bestline
+static void b_bind(char **av) {
+	av++; // skip "bind"
+	if (*av == NULL || !streq(*av, "-x") || *(av+1) == NULL || *(av+2) == NULL) {
+		fprint(2, RC "%s\n", "usage: bind -x C-x my_func arg1 arg2");
+		set(FALSE);
+		return;
+	}
+	bestlineAddBinding(++av); // skip "-x"
+}
+#endif
+
 /* a dummy command. (exec() performs "exec" simply by not forking) */
 
 extern void b_exec(char **ignore) {
diff --git a/edit-bestline.c b/edit-bestline.c
index 74c36a9..ddf7567 100644
--- a/edit-bestline.c
+++ b/edit-bestline.c
@@ -280,6 +280,7 @@ void *edit_begin(int fd) {
 	struct cookie *c;
 
 	bestlineSetCompletionCallback(completion);
+	bestlineSetShellFunctionCallback((void (*)(const char **))funcall);
 
 	hist = varlookup("history");
 	if (hist != NULL)

Of course, bestline needs to be extended as well. Maybe I'll try to get it running with readline, first.

@MaxGyver83
Copy link
Contributor Author

Btw, I have written an article about rc: rc shell instead of bash or fish

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants