Shougo / ddu.vim

Dark deno-powered UI framework for Vim/NeoVim
MIT License
295 stars 24 forks source link

Window focus does not move in kind action that returns `ActionFlags.RefreshItems` or `ActionFlags.Persist` #47

Closed tennashi closed 1 year ago

tennashi commented 1 year ago

Warning: I will close the issue without the minimal init.vim and the reproduction instructions.

Problems summary

Window focus does not move when executing term_start() in kind action that returns ActionFlags.RefreshItems or ActionFlags.Persist.

Works as expected for kind actions that return ActionFlags.None or ActionFlags.Redraw.

Expected

Focus is moved to the window opened by term_start().

Environment Information

Provide a minimal init.vim/vimrc without plugin managers (Required!)

" Your minimal init.vim/vimrc
set runtimepath+=~/path/to/ddu.vim/
set runtimepath+=~/path/to/ddu-ui-ff/
set runtimepath+=~/path/to/test_kind/

type Params = Record<never, never>;

export class Kind extends BaseKind { actions: Record< string, (args: ActionArguments) => Promise

= { test: async (args: ActionArguments): Promise => { await term_start(args.denops, ["ls", "-la"]);

  return ActionFlags.RefreshItems;
},

};

params(): Params { return {}; } }


* `~/path/to/test_kind/denops@ddu-sources/test.ts`
```typescript
import { BaseSource, Item } from "https://deno.land/x/ddu_vim@v2.3.0/types.ts";
import { GatherArguments } from "https://deno.land/x/ddu_vim@v2.3.0/base/source.ts";

type Params = Record<never, never>;

export class Source extends BaseSource<Params> {
  kind = "test";

  gather(_args: GatherArguments<Params>): ReadableStream<Item<never>[]> {
    return new ReadableStream({
      start(controler) {
        controler.enqueue([{
          word: "test",
        }]);
        controler.close();
      },
    });
  }

  params(): Params {
    return {};
  }
}

How to reproduce the problem from neovim/Vim startup (Required!)

  1. :call ddu#start({'ui': 'ff', 'sources': [{'name': 'test'}]})
  2. :call ddu#ui#ff#do_action('itemAction', {'name': 'test'})

Screenshot (if possible)

Upload the log messages by :redir and :message (if errored)

Shougo commented 1 year ago

OK. I have changed the behavior.

But it is experimental. I may restore the behavior.

tennashi commented 1 year ago

@Shougo I've confirmed that it works, thanks! However, even kind actions that don't invoke window creation always move the focus outside ddu. Maybe it would be better to have another flag like ActionFlags.RestoreCursor.

Shougo commented 1 year ago

Please describe the example. I will check it later.

tennashi commented 1 year ago

type Params = Record<never, never>;

export class Kind extends BaseKind { actions: Record< string, (args: ActionArguments) => Promise

= { test: async (args: ActionArguments): Promise => { await term_start(args.denops, ["ls", "-la"]);

  return ActionFlags.RefreshItems;
},
test2: async (args: ActionArguments<Params>): Promise<ActionFlags> => {
  return ActionFlags.RefreshItems;
},

};

params(): Params { return {}; } }


The current behavior moves the focus outside ddu when action `test2` is executed.
The expected behavior is that the focus moves only when the focus is intentionally moved outside ddu in the action.
Since it may be difficult to distinguish whether intentional or not in the ddu, I thought it would be sufficient if we could specify this explicitly in the action:

* `~/path/to/test_kind/denops/@ddu-kinds/test.ts`
```ts
import {
  ActionArguments,
  ActionFlags,
  BaseKind,
} from "https://deno.land/x/ddu_vim@v2.3.0/types.ts";
import { term_start } from "https://deno.land/x/denops_std@v4.0.0/function/vim/mod.ts";

type Params = Record<never, never>;

export class Kind extends BaseKind<Params> {
  actions: Record<
    string,
    (args: ActionArguments<Params>) => Promise<ActionFlags>
  > = {
    test: async (args: ActionArguments<Params>): Promise<ActionFlags> => {
      await term_start(args.denops, ["ls", "-la"]);

      return ActionFlags.RefreshItems & ActionFlags.RestoreCursor; // current behavior
    },
    test2: async (args: ActionArguments<Params>): Promise<ActionFlags> => {
      return ActionFlags.RefreshItems; // version "12633f6dea1019dbe4d02970a0a197ce84057c6e" behavior
    },
  };

  params(): Params {
    return {};
  }
}
Shougo commented 1 year ago

return ActionFlags.RefreshItems | ActionFlags.RestoreCursor; // current behavior

Shougo commented 1 year ago

I have added RestoreCursor.