andreyorst / fzf.kak

FZF for Kakoune
MIT License
143 stars 33 forks source link

[Feature Request] support iterm outside of tmux #40

Closed grtlr closed 5 years ago

grtlr commented 5 years ago

The only way I got fzf.kak to work in iTerm (macOS) was using it inside a tmux session. It would be awesome to have native support for iTerm. Unfortunately, I have no idea where to start.

Currently, when I type :fzf-mode<ret>f I get the following error message: termcd option is not set. It appears that this functionality is only implemented for x11 and tmux.

Maybe we can use iTerms osascript support similar to this PR?

In the mean time, is there a way to run fzf only with a single line in the status bar of Kakoune, without opening a new buffer?

Thank you very much!

andreyorst commented 5 years ago

fzf.kak uses the termcmd option, which is set by kakoune. Currently kakoune doesn't seem to set this variable for Iterm:

https://github.com/mawww/kakoune/blob/e2f2503da45566f6527be6bd1025185319cce89e/rc/base/x11.kak#L3-L23

occivink commented 5 years ago

@andreyorst It would be preferable to use the terminal alias, which is now the canonical way of opening a new window in the user's preferred terminal emulator, and which handles arguments in a consistent way. To launch fzf in it, you can do terminal fzf fzf_arg_1 fzf_arg2 ... and the kakoune argument splitting will be forwarded to fzf cleanly

andreyorst commented 5 years ago

@occivink that's may be suitable for x11 but not suitable for tmux at any rate. Also I've had some errors with terminal.

occivink commented 5 years ago

Yeah if you want full control over tmux it makes sense to just handle it yourself, but as fallback terminal should be more flexible than using termcmd

andreyorst commented 5 years ago

but as fallback terminal should be more flexible than using termcmd

This involves complexity to current implementation, because I'm calling everything from shell expansion, not via kakoune commands. So termcmd is a more natural way. Maybe after I finish refactoring plug.kak I'll rewrite fzf.kak to be more simplistic.

andreyorst commented 5 years ago

Also, as far as I can see, using terminal doesn't solve problem with Iterm

occivink commented 5 years ago

Can you be more specific? What would be missing?

andreyorst commented 5 years ago

Sorry, I was misguided that iterm.kak doesn't set termcmd option which terminal relies on. I gave some more read to the iterm.kak and now I see why you're mention to use terminal instead of termcmd, I suppose that for now I should handle this in fzf.kak in the same way. However I see that it defaults to splitting terminal vertically, and not creating a new one which may lead to some problems because I don't handle terminal size when not in tmux.

Also, what if user will use alacritty on MacOS? Will curretn x11.kak work for him? If so, why do we need separate iterm.kak?

occivink commented 5 years ago

Also, what if user will use alacritty on MacOS?

I'm not quite sure, the x11-terminal command is actually not really reliant on x11 (it would work on wayland I think), but setsid might not be available on macOS . x11-focus is definitely x11-specific though.

If so, why do we need separate iterm.kak?

The separate iterm.kak is for handling iterm-level multiplexing: in iterm (much like in kitty) you can split a window into multiple panes or tabs, and it will all be done inside the same window.

andreyorst commented 5 years ago

The separate iterm.kak is for handling iterm-level multiplexing: in iterm (much like in kitty) you can split a window into multiple panes or tabs, and it will all be done inside the same window.

Splitting is a separate topic. I wonder why there's no termcmd for iterm, because I think it should work if alacritty works on MacOS via it.

grtlr commented 5 years ago

Maybe I can chime in. I have alacritty installed as well on my system. Natively (without tmux) fzf.kak produces the same error: termcmd option is not set. I checked my x11.kak file in /usr/local/share/kak/rc/base/ it contains the follwowing lines:

declare-option -docstring %{shell command run to spawn a new terminal
A shell command is appended to the one set in this option at runtime} \
    str termcmd %sh{
    for termcmd in 'alacritty      -e sh -c' \
                   'kitty             sh -c' \
                   'termite        -e      ' \
                   'urxvt          -e sh -c' \
                   'rxvt           -e sh -c' \
                   'xterm          -e sh -c' \
                   'roxterm        -e sh -c' \
                   'mintty         -e sh -c' \
                   'sakura         -x      ' \
                   'gnome-terminal -e      ' \
                   'xfce4-terminal -e      ' ; do
        terminal=${termcmd%% *}
        if command -v $terminal >/dev/null 2>&1; then
            printf %s\\n "$termcmd"
            exit
        fi
    done
}
andreyorst commented 5 years ago

I wonder why. What does command -v alacritty print when ran in (ba)sh?

I also wonder if there will be any difference between

if command -v alacritty >/dev/null 2>&1; then echo true; else echo false; fi

and

if [ -n "$(command -v alacritty)" ]; then echo true; else echo false; fi
occivink commented 5 years ago

@andreyorst Because termcmd is defined specifically for the creation of terminal windows in x11, and iterm is macos-specific. But more than that, with termcmd you can only support commands that take input arguments in a very specific way (i.e. not screen, not iterm, not dvtm) without writing the full support yourself

@grtlr is x11.kak autoloaded? It may not be if you created an autoload directory. If it is, what does echo %opt{termcmd} say?

grtlr commented 5 years ago

@andreyorst: It seems that alacritty installed using brew cask install alacritty (which most people would do) does not establish a command line binary for alacritty and only installs an application bundle to /Applications.

Because of this command -v alacritty and which alacritty both don't return anything.

andreyorst commented 5 years ago

@grtlr this makes sense.

But more than that, with termcmd you can only support commands that take input arguments in a very specific way (i.e. not screen, not iterm, not dvtm) without writing the full support yourself

@occivink This also applies to :terminal command. I can't use commands that contain arguments for tmux. If the terminal command supported something like -terminal-args <args> swithc, I would use it both for x11 and tmux, and it would made my life easier.

something like

#if in tmux
printf %\\n "terminal -term-args 'split-window -p 60' fzf fzfarg1 fzfarg2"
#else
printf %\\n "terminal fzf fzfarg1 fzfarg2"
occivink commented 5 years ago

Yeah, the idea of the terminal abstraction is to support the lowest common denominator feature, i.e. spawning a terminal with some program in it. The user can override the alias in order to define how they want the new terminal to open, as a pane, a new window or something else.

Exposing raw arguments would still require that you do custom handling for tmux/iterm/screen, so imo it would be preferable to expose additional commands that are more specific to certain windowing systems, for example terminal-vertical [-side SIDE] [-size SIZE] program arg1 arg2 ... terminal-horizontal [-side SIDE] [-size SIZE] program arg1 arg2 ... and then each windowing system script (tmux.kak, screen.kak) would handle these arguments as they see fit. This would give you more control over positioning without piercing through the abstraction.

andreyorst commented 5 years ago

Understood, I'll think about it.

@grtlr I'm sorry to say it, but I'm gonna leave this issue as is for now. I wan't to finish plug.kak refactoring, and after that I'll start working on this issue, and probably will rewrite fzf.kak from scratch, as I don't really like how it works.

grtlr commented 5 years ago

That sounds perfectly reasonable to me!

grtlr commented 5 years ago

@andreyorst Do you know a way to run fzf without opening a new buffer? I am thinking about fuzzy search for Kakoune only within the status line. That would be a great interim solution in my opinion. Thanks!

andreyorst commented 5 years ago

fzf isn't opened in a new buffer, it is opened in plain terminal, without opening new kakoune client untill you select the file in fzf.

fzf.kak already supports searching in the file, and it is opening new terminal with fzf for that. You can't run fzf in statusline or in prompt mode. fzf is a "full-screen" application, so it needs a full terminal to run in. Kakoune's search is already fuzzy, because it supports the same completion as insert mode completions.

andreyorst commented 5 years ago

I've started implementing this in spring-refactoring branch

And it seems to work in Kitty the way you've described: image

andreyorst commented 5 years ago

@andreyorst Do you know a way to run fzf without opening a new buffer? I am thinking about fuzzy search for Kakoune only within the status line. That would be a great interim solution in my opinion. Thanks!

maybe this:

define-command fzf %{ evaluate-commands %{
    edit -scratch *fzf*
    map buffer normal '<ret>' ': fzf-operate edit<ret>'
    execute-keys -draft -buffer '*fzf*' '%d'
    fzf-prompt
}}

define-command fzf-prompt %{
    prompt "fzf: " -on-change %{
        execute-keys -draft '%d'
        execute-keys -draft "! find . | fzf -f %val{text}<ret>"
    } nop
}

define-command fzf-operate -params 1 %{ evaluate-commands -save-regs 'a' %{
    execute-keys <a-h><a-l>"ay
    evaluate-commands %sh{
        candidate=$(printf "$kak_reg_a" | sed "s/&/&&/g")
        case $1 in
            (edit) printf "%s\n" "edit -existing %&$candidate&" ;;
            (*) printf "%s\n" "fail %{Wrong command}" ;;
        esac
    }
}}