Skip to main content
Unfortunately, SO doesn't have syntax highlighting for `fish`, so I replace that with `shell`
Source Link
alias history "PAGER='bat -l fish' history" 
alias history "PAGER='bat -l fish' history" 
function history
  PAGER='bat -l fish' history $argv 
end
function history
  PAGER='bat -l fish' history $argv 
end
  1. use a different name for your alias

    alias hist 'PAGER="bat -l fish" history'
    
    alias hist 'PAGER="bat -l fish" history'
    
  2. Don't alias _old_history hist, but copy it instead

    functions --copy history _old_history
    alias history 'PAGER="bat -l fish" _old_history'
    
    functions --copy history _old_history
    alias history 'PAGER="bat -l fish" _old_history'
    
  3. If you don't care to keep fish's function, invoke the builtin history command in your own function

    function history
      builtin history $argv | bat -l fish
    end
    
    function history
      builtin history $argv | bat -l fish
    end
    
        case search # search the interactive command history
            test -z "$search_mode"
            and set search_mode --contains

            if isatty stdout
                set -l pager (__fish_anypager)
                and isatty stdout
                or set pager cat

                # If the user hasn't preconfigured less with the $LESS environment variable,
                # we do so to have it behave like cat if output fits on one screen.
                if not set -qx LESS
                    set -x LESS --quit-if-one-screen
                    # Also set --no-init for less < v530, see #8157.
                    if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
                        set -x LESS $LESS --no-init
                    end
                end
                not set -qx LV # ask the pager lv not to strip colors
                and set -x LV -c

                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
            else
                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
            end
        case search # search the interactive command history
            test -z "$search_mode"
            and set search_mode --contains

            if isatty stdout
                set -l pager (__fish_anypager)
                and isatty stdout
                or set pager cat

                # If the user hasn't preconfigured less with the $LESS environment variable,
                # we do so to have it behave like cat if output fits on one screen.
                if not set -qx LESS
                    set -x LESS --quit-if-one-screen
                    # Also set --no-init for less < v530, see #8157.
                    if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
                        set -x LESS $LESS --no-init
                    end
                end
                not set -qx LV # ask the pager lv not to strip colors
                and set -x LV -c

                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
            else
                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
            end
alias history "PAGER='bat -l fish' history" 
function history
  PAGER='bat -l fish' history $argv 
end
  1. use a different name for your alias

    alias hist 'PAGER="bat -l fish" history'
    
  2. Don't alias _old_history hist, but copy it instead

    functions --copy history _old_history
    alias history 'PAGER="bat -l fish" _old_history'
    
  3. If you don't care to keep fish's function, invoke the builtin history command in your own function

    function history
      builtin history $argv | bat -l fish
    end
    
        case search # search the interactive command history
            test -z "$search_mode"
            and set search_mode --contains

            if isatty stdout
                set -l pager (__fish_anypager)
                and isatty stdout
                or set pager cat

                # If the user hasn't preconfigured less with the $LESS environment variable,
                # we do so to have it behave like cat if output fits on one screen.
                if not set -qx LESS
                    set -x LESS --quit-if-one-screen
                    # Also set --no-init for less < v530, see #8157.
                    if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
                        set -x LESS $LESS --no-init
                    end
                end
                not set -qx LV # ask the pager lv not to strip colors
                and set -x LV -c

                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
            else
                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
            end
alias history "PAGER='bat -l fish' history" 
function history
  PAGER='bat -l fish' history $argv 
end
  1. use a different name for your alias

    alias hist 'PAGER="bat -l fish" history'
    
  2. Don't alias _old_history hist, but copy it instead

    functions --copy history _old_history
    alias history 'PAGER="bat -l fish" _old_history'
    
  3. If you don't care to keep fish's function, invoke the builtin history command in your own function

    function history
      builtin history $argv | bat -l fish
    end
    
        case search # search the interactive command history
            test -z "$search_mode"
            and set search_mode --contains

            if isatty stdout
                set -l pager (__fish_anypager)
                and isatty stdout
                or set pager cat

                # If the user hasn't preconfigured less with the $LESS environment variable,
                # we do so to have it behave like cat if output fits on one screen.
                if not set -qx LESS
                    set -x LESS --quit-if-one-screen
                    # Also set --no-init for less < v530, see #8157.
                    if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
                        set -x LESS $LESS --no-init
                    end
                end
                not set -qx LV # ask the pager lv not to strip colors
                and set -x LV -c

                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
            else
                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
            end
added 1579 characters in body
Source Link
glenn jackman
  • 86.6k
  • 16
  • 120
  • 173

why doesn't the builtin history support pager?

I assume the fish designers didn't think that was a core part of the history functionality. I assume they put the user-facing stuff in a function that users can override.

Here's the relevant snippet from the default history function:

        case search # search the interactive command history
            test -z "$search_mode"
            and set search_mode --contains

            if isatty stdout
                set -l pager (__fish_anypager)
                and isatty stdout
                or set pager cat

                # If the user hasn't preconfigured less with the $LESS environment variable,
                # we do so to have it behave like cat if output fits on one screen.
                if not set -qx LESS
                    set -x LESS --quit-if-one-screen
                    # Also set --no-init for less < v530, see #8157.
                    if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
                        set -x LESS $LESS --no-init
                    end
                end
                not set -qx LV # ask the pager lv not to strip colors
                and set -x LV -c

                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
            else
                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
            end

why doesn't the builtin history support pager?

I assume the fish designers didn't think that was a core part of the history functionality. I assume they put the user-facing stuff in a function that users can override.

Here's the relevant snippet from the default history function:

        case search # search the interactive command history
            test -z "$search_mode"
            and set search_mode --contains

            if isatty stdout
                set -l pager (__fish_anypager)
                and isatty stdout
                or set pager cat

                # If the user hasn't preconfigured less with the $LESS environment variable,
                # we do so to have it behave like cat if output fits on one screen.
                if not set -qx LESS
                    set -x LESS --quit-if-one-screen
                    # Also set --no-init for less < v530, see #8157.
                    if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
                        set -x LESS $LESS --no-init
                    end
                end
                not set -qx LV # ask the pager lv not to strip colors
                and set -x LV -c

                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
            else
                builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
            end
Source Link
glenn jackman
  • 86.6k
  • 16
  • 120
  • 173

Two things are happening here:

  1. fish's alias actually creates a function.
  2. fish ships with a default history function already.

So when you write

alias history "PAGER='bat -l fish' history" 

what you actually have is the recursive function

function history
  PAGER='bat -l fish' history $argv 
end

Some solutions:

  1. use a different name for your alias

    alias hist 'PAGER="bat -l fish" history'
    
  2. Don't alias _old_history hist, but copy it instead

    functions --copy history _old_history
    alias history 'PAGER="bat -l fish" _old_history'
    
  3. If you don't care to keep fish's function, invoke the builtin history command in your own function

    function history
      builtin history $argv | bat -l fish
    end