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

Paginate help output? #314

Open
ttscoff opened this issue Jan 19, 2022 · 3 comments
Open

Paginate help output? #314

ttscoff opened this issue Jan 19, 2022 · 3 comments

Comments

@ttscoff
Copy link

ttscoff commented Jan 19, 2022

Some of my subcommand help screens have gotten quite large between long_desc, flags/options and multiple examples. I have a pager built into my little app and I'm wondering if there's a way I could hook the help command to direct output through the pager so it works more the way that git help (or even man) does instead of requiring the user to scroll back up to see the first options.

@ttscoff
Copy link
Author

ttscoff commented Jan 22, 2022

I monkey patched it for now, but if there's a more elegant way, I'd love to hear. If it's not already an option and I missed it, might be nice to have the ability to pipe the help command output as needed.

@davetron5000
Copy link
Owner

Hmm, yeah this seems like a good feature, but I'm not sure exactly how to achieve this. Can you share what you did?

The only thing I can think of is to have gli replace itself with gli «args» | $PAGER somehow

@ttscoff
Copy link
Author

ttscoff commented Jan 23, 2022

I just did a very dirty monkey patch over the whole show_help function and changed the puts command to my built-in pagination function.

module GLI
  module Commands
    # Help Command Monkeypatch for paginated output
    class Help < Command
      def show_help(global_options,options,arguments,out,error)
        Doing::Pager.paginate = true

        command_finder = HelpModules::CommandFinder.new(@app,arguments,error)
        if options[:c]
          help_output = HelpModules::HelpCompletionFormat.new(@app,command_finder,arguments).format
          out.puts help_output unless help_output.nil?
        elsif arguments.empty? || options[:c]
          Doing::Pager.page HelpModules::GlobalHelpFormat.new(@app,@sorter,@text_wrapping_class).format
        else
          name = arguments.shift
          command = command_finder.find_command(name)
          unless command.nil?
            Doing::Pager.page HelpModules::CommandHelpFormat.new(
              command,
              @app,
              @sorter,
              @synopsis_formatter_class,
              @text_wrapping_class).format
          end
        end
      end
    end
  end
end

My pagination routine just detects the appropriate pager for the system based on GIT_PAGER, PAGER, and a cascade of potential executables (bat, less, more). If it finds a usable one, it uses IO.pipe to send text to it. Happy to share it, but I'm just bad enough at Ruby to by shy about it :).

What I'd be interested in is just a block like on_error, but on_help do |help_text| that received the formatted help output and let you do what you wanted to with it, defaulting to puts if it returns true. And if help -c was run than the block would be skipped. I'm probably not thinking through the complexities or possibilities, though.

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