bling / fzf.el

A front-end for fzf
GNU General Public License v3.0
369 stars 50 forks source link

How can I pass arguments? #1

Open khalidchawtany opened 9 years ago

khalidchawtany commented 9 years ago

Note: I am using spacemacs with evil

How can I pass args to fzf so that I can enable C-j and C-k to select items as in NeoVim or terminal?

In spacemacs the screen is not rendered properly (as can be seen in the screenshot). I wonder if passing --colors arg could solve this or it is caused by some spacemacs config?

screen shot 2015-10-02 at 21 50 07

I am new to emacs, sorry If I am asking something obvious :)

bling commented 9 years ago

c-j and c-k work out of the box for me, no additional config is needed. in any case, have a look at fzf/args; it'll let you customize the arguments to pass to fzf. as for spacemacs, i'm have no idea. it bundles a lot of stuff so it could be anything. see if you can reproduce the problem with a plain emacs with no packages first.

bling commented 9 years ago

also, what version of emacs are you running?

khalidchawtany commented 9 years ago

Sorry for the very obvious question. I found out how to pass args to fzf. However, it breaks fzf and the window does not show up anymore. I have passed these args as can be seen in the screenshot:

screen shot 2015-10-06 at 07 47 54

Then I found out if I move to the elements above using the arrow key then I can move down using ctrl-j. So, it seems that ctrl-k is overridden somewhere. The describe key function tells me that ctrl-k is used:

C-k runs the command term-send-raw, which is an interactive compiled Lisp
function in `term.el'.

As for the version, I tried both of the following and the results are the same:

GNU Emacs 24.5.1 (x86_64-apple-darwin14.5.0, Carbon Version 157 AppKit 1348.17)
of 2015-09-28 on MacBook-Pro.local

GNU Emacs 25.0.50.1 (x86_64-apple-darwin15.0.0, NS appkit-1404.11 Version 10.11 (Build 15A284))
of 2015-10-03

If I use terminal Emacs (Not the gui) then fzf is rendered properly with the same config. However, ctrl-k still does not work.

I know that this is related to spacemacs config but I cannot get rid of it as I am a vim user and I don't know how to do anything without evil mode and other configs provided by spacemacs. However, i will dig into it once I know a little bit more about elisp and how it integrates with emacs.

Feel free to close this as currently I am not able to work with plain emacs with no packages.

avli commented 8 years ago

@bling I can confirm the fzf output is not rendered properly sometimes. But I believe something is wrong with different color themes support. For example, with the default color theme everything works, but try, for example, deeper-blue theme from standard Emacs collection and fzf output will become unreadable.

Update: resizing *fzf* buffer size fixes the issue...

Update 2: After experimenting with different UI settings I think boxed mode-line causes the artifacts like on picture above. @khalidchawtany, please, try M-x customize-face RET mode-line and ensure there are no options like box, underline or overline. I think it's Emacs rendering bug rather than issue with fzf plugin.

khalidchawtany commented 8 years ago

There is Box option. I unchecked the check box and then applied and saved. After saving I checked again and found out that the Box option is still checked ! I have no idea what could be checking it again :(

avli commented 8 years ago

@khalidchawtany I'm afraid Emacs colour theme reenable the box when been loaded and overwrites your customisations. I think, the most obvious way to fix the issue is to edit theme itself.

MaryHal commented 8 years ago

It's possible to remap a face in a single buffer using face-remap-add-relative. For example,

(defadvice fzf/start (after normalize-fzf-mode-line activate)
  (face-remap-add-relative 'mode-line '(:box nil))

will remove the box portion of the mode-line face in only the fzf buffer.

bling commented 8 years ago

PR #2 was just merged, which will correctly handle spaces in the args. setting fzf/args to -x --color=no might fix this for some of you. with colors off fzf uses underlining instead.

avli commented 8 years ago

@sanford1 Good point, thank you! Unfortunately this trick doesn't fix issue with term/fzf. I believe, the issue is somewhere deeper in Emacs core.

khalidchawtany commented 8 years ago

@sanford1 Thank you, the defadvice solved the rendering issue for me. @avli Indeed the issue was caused by that BOX option, thank for your help. @bling feel free to close this :+1:

MaryHal commented 8 years ago

@avli Could you describe your problem with more detail? I've found two things:

(defun disable-scroll-margin ()
  (setq-local scroll-margin 0))
(add-hook 'term-mode-hook #'disable-scroll-margin)
avli commented 8 years ago

@sanford1 I've just discovered your suggestion about defadvice works for me when the only fzf argument is -x. But setting -x --color=no breaks the output.

bling commented 8 years ago

since fzf always creates a new window (and uses a custom modeline) the fix for this should be part of the package.

so basically we have to turn off scroll margins and fancy modelines?

avli commented 8 years ago

Correct me if I wrong, but I believe it's Emacs or Emacs term bug not fzf. Probably, it would be wiser to write bug report to Emacs developers?

MaryHal commented 8 years ago

@avli I can't reproduce your problem. fzf.el seems to work fine for me even when using -x --color=no.

@bling What distorts the fzf window is when the mode-line has a strange height (e.g. padding the mode-line with :box). I'm not sure why though. Running fzf in ansi-term works perfectly. Even though using face-remap-add-relative works for the most part, it seems like modifying the mode-line face to a fixed height is side-stepping the real issue. It should do for now though, as fzf.el would be unusable otherwise.

I've also discovered a bug when using face-remap-add-relative, but it might be hard to reproduce. My color theme has a few faces that inherit from the mode-line and these faces appeared to get persistent modifications by face-remap-add-relative too (only sometimes though). It seemed like it was a problem when I made a selection when fzf was still indexing. I tried to fix it by actually undoing face-remap-add-relative when the fzf process/term process ends, although I'm not too sure how well it works:

(let ((fzf/mode-line-face-cookie nil))
  (defadvice fzf/start (after normalize-fzf-mode-line activate)
    (setq fzf/mode-line-face-cookie (face-remap-add-relative 'mode-line '(:box nil))))

  (defadvice fzf/after-term-handle-exit (before undo-fzf-mode-line-change activate)
    (face-remap-remove-relative fzf/mode-line-face-cookie))
  )

Strangely enough, I tried fzf.el (with a modifed mode-line) with unicode filenames that caused differing row heights and it worked well enough, aside from a similar scroll-off issue as with scroll-margin.

romanodesouza commented 8 years ago

@khalidchawtany, any news about the ctrl bindings issue on spacemacs? I solved it enabling Emacs mode after entering in term mode.

(add-hook 'term-mode-hook 'evil-emacs-state)

Although it's not the best solution, it works.

khalidchawtany commented 8 years ago

@romanoaugusto88, unfortunately I have given up :(

jmromer commented 8 years ago

Hiding the modeline altogether did the trick for me:

(defadvice fzf/start (after normalize-fzf-mode-line activate)
  "Hide the modeline so FZF will render properly."
  (setq mode-line-format nil))
sandric commented 8 years ago

Wasn't this issue resolved? Looks like I have tried all the variants, here's my fzf-related config in init.el:

(use-package fzf
  :ensure t
  :config (progn
            (add-to-list 'load-path "~/.fzf/bin/fzf")

            (defadvice fzf/start (after normalize-fzf-mode-line activate)
              (face-remap-add-relative 'mode-line '(:box nil)))

            (defun disable-scroll-margin ()
              (setq-local scroll-margin 0))
            (add-hook 'term-mode-hook #'disable-scroll-margin)

            (defadvice fzf/start (after normalize-fzf-mode-line activate)
              "Hide the modeline so FZF will render properly."
              (setq mode-line-format nil))))

I tried this with only -x and with -x --color=no, tried to disable my theme, tried to run fzf in ansi-term - the same result, the rendering gets broken somehow.. I also successfully tried @bling gist for fzf in helm, the only problem with it is that looks like it is not updated until it finished searching and its unable to see live updates on search results, and from beginning it is not showing all file names but is blank.

sandric commented 8 years ago

Ok, looks like I figured out the problem in my case - maybe it will be helpful somebody with similar setup. My issue was somehow related to tabbar - when I disabled it now everything works perfectly. I also tried to move window down - I was thinking maybe it have to do something with tabbar which is also at top applying this commit - didn't helped.

jmromer commented 8 years ago

My issue was somehow related to tabbar - when I disabled it now everything works perfectly.

I just experienced this too. Disabling evil-tabs fixed it for me.

sandric commented 8 years ago

Sorry, I just realized - I ment not the built one tabbar, but tabbar.el

ghost commented 7 years ago

Unfortunately none of these work. I am using the latest Develop version of Spacemacs, in emacs 25.1.1.

My config has EVERY suggested workaround in it:

  (setq fzf/args "-x --color=no")

  (defadvice fzf/start (after normalize-fzf-mode-line activate)
    (face-remap-add-relative 'mode-line '(:box nil)))

  (defun disable-scroll-margin ()
    (setq-local scroll-margin 0))
  (add-hook 'term-mode-hook #'disable-scroll-margin)

  (defadvice fzf/start (after normalize-fzf-mode-line activate)
    "Hide the modeline so FZF will render properly."
    (setq mode-line-format nil))

The fzf output is still a garbled mess:

screen shot 2016-12-10 at 17 05 57

I give up. Going back to trying native Spacemacs methods instead.

ghost commented 7 years ago

Note: If you are in a projectile project (any file under a path with a .git or similar svn folder, or contains an empty .projectile file somewhere in its path to mark it as a project), then you can press <SPC p f> to do a fuzzy find exactly like fzf. This shortcut is built into Spacemacs and runs "projectile-find-file", which is super efficient. Only works for projects and all files contained under the project path, but probably good enough for most people here?

And if you aren't in a project, you can manually press <SPC SPC> find-name-dired, then give it a path to search from (use ~/ to return to home folder), and then a "find" utility pattern such as "*.cpp". You then just use regular dired commands (press ? to see the help) on the results such as Enter to open the file or "d" to mark one or more files for deletion and "x" to xpunge (finalize deletion).

I highly recommend adding this to your user-config in dotspacemacs:

(evil-leader/set-key "f F" 'find-name-dired)

Now you can do:

<SPC f f> = regular non-recursive, fuzzy helm search <SPC f F> = dired recursive, find-pattern based search (works even if not in a project) <SPC p f> = projectile recursive, fuzzy search (best and fastest way to search in projects)

ghost commented 7 years ago

@jkrmr @khalidchawtany @avli @sanford1 @romanoaugusto88 @sandric

Pinging everyone who mentioned Spacemacs. Check my solution in the previous comment. It may be all you need. I have given up on using fzf in Spacemacs since there are multiple better/similar natively built-in methods to achieve the same thing (without having to spawn a separate process and without having to deal with all the fzf rendering issues). From now on I only use fzf in regular terminal windows when I am not in Spacemacs. :-)

jmromer commented 7 years ago

to do a fuzzy find exactly like fzf.

Not quite exactly like fzf. Performance feels significantly worse with projectile-find-file on large projects and the fuzzy-matching is not as good. (I think grizzl helps with the latter, but I'm not sure -- the main value-add of fzf for me is its speed.) That nothing (afaik) with fzf's speed yet exists for emacs is a bummer.

ghost commented 7 years ago

@jkrmr Probably true about the performance. Fzf is native C. Projectile is Emacs-lisp.

But there's seemingly no way to fix the garbled fzf text in Emacs 25.x right now, so I don't think we have much choice.

sandric commented 7 years ago

@SteveJobzniak you can try to run fzf with --margin 1,0 param - it helped me. Looks like bottom margin needs to be set in order cursor not to move up.

ghost commented 7 years ago

@sandric: Wow that kicks ass, thank you so much! Now I have 4 methods to find files, and fzf is a great one. I was able to drop ALL of the other settings I listed above. The ONLY thing I needed is this:

(setq fzf/args "-x --color bw --margin 1,0")
(evil-leader/set-key "f z" 'fzf)
(evil-leader/set-key "f Z" 'fzf-directory)

There was no more need to hide the modeline (the helpful "FZF [current dir]" line at the bottom).

If anyone wonders (like me) what margin does, it's moving the > prompt (typing prompt) in fzf. And --margin 1,0 is telling it to move it 1 line upwards vertically (and 0 means completely left-aligned horizontally). This setting means that there's an empty line after the fzf prompt. That was enough to prevent Emacs from getting confused about cursor position and to stop corrupting the display!

Note that black and white via --color bw may be the best choice if you frequently change between light and dark themes in Emacs. It handles that perfectly. The other modes stupidly output a background color (black or white) which makes fzf super ugly when you change theme color. And often unreadable, in case the foreground and background are mapped to something awful on that theme. But hey, at least fzf in colorless mode is great too. The underlines look good.

Oh and the keybinds: <SPC f z> for fuzzy in current directory, <SPC f Z> for fuzzy in a directory of your choice.

And many people seem confused about how to kill an ongoing fzf inside Emacs, if you regret starting a search. Easy. What do you do in a terminal to cleanly kill something? You hit Ctrl-c. What do you do in Emacs to send Ctrl-c to a terminal process? You press <Ctrl-c Ctrl-c> and it will kill fzf cleanly and make the emacs terminal buffer close itself.

ghost commented 7 years ago

@jkrmr Oh and you will definitely want to check out my previous comment. Enjoy :) Thanks again @sandric! Great to have multiple fast methods of finding files now! Fzf is definitely the BEST one of them all! Really happy to have it working now thanks to you!

ghost commented 7 years ago

@bling Perhaps you want to consider making changing the default args to -x --margin 1,0 so that this issue is fixed by default. Spacemacs is getting super popular and soon there won't be anymore regular Emacs users haha. ;-) And it only adds 1 blank line at the bottom of fzf's window, which is a super cheap price to pay for fixing this major bug and making fzf.el work perfectly.

Maybe even throw in --color bw to avoid theme color issues by default. Users can remove that option manually if they really want to. Fzf looks like completely unreadable trash on about 50% of all themes (meaning you can't even see the name of the selected file)... unless you disable all colors.

sandric commented 7 years ago

I actually was thinking to make ivy counsel function for fzf, but I havent figured out best way to do that.

ghost commented 7 years ago

@sandric I still managed to get fzf to break and become garbled a few times (not sure how to trigger the problem though, since it's rare now). It makes fzf a bit annoying. But I'll keep it around for certain cases when I have to search large trees that contain so many files that I need its speed. Luckily I found a general-purpose replacement which is better integrated into Spacemacs/Emacs:

helm-find:

  ;; Bind <SPC f /> to use Helm's own recursive find-based search.
  ;; The main point of this is its perfect Helm integration, but it only refeshes
  ;; when the "find" command finishes executing, so fzf beats it for large trees.
  (defun my/helm-find () (interactive) (setq current-prefix-arg '(4)) (call-interactively 'helm-find))
  (evil-leader/set-key "f /" 'my/helm-find)

It asks you for a directory (default to current file's dir) and then a space-separated list of find patterns (which will be AND'ed together). It provides live results like fzf, but is slower to update since it runs synchronously due to Emacs single-threaded engine pausing on the execution of the find-command.