Script Library: 1238 scripts
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Archive version of: pager.r ... version: 1 ... btiffin 1-Mar-2008

Amendment note: new script || Publicly available? Yes

REBOL [
    Title: "Simple pager"
    File: %pager.r    Version: 0.9.1    Date: 08-Feb-2008
    Author: "Brian Tiffin"   Rights: "Copyright 2008, Brian Tiffin"
    Purpose: {
        A more less page pager; 
        support b, r, /, ?, >, <, q and /options [rows: cols: num: eof:]
    }
    Comment: {Not perfect, but functional}
    History: [
        08-Feb-2008 0.0.1 'btiffin "First cut"
        14-Feb-2008 0.9.0 'btiffin "Added clear screen"
        29-Feb-2008 0.9.1 'btiffin "Added Search, capture"
    ]
    Library: [
        level: 'intermediate
        platform: 'all    type: [tool function]   domain: [files text]
        tested-under: [1.3.2.3.1 Win98]    see-also: none    support: none
        license: 'mit
    ]
]
more: less: page: pager: func ["supports b, <, >, w, /, ?, q while paging" 
    intake "input data or filename"
    /options "rows: cols: integer!, eof: num: logic!" electives [block!]
    /cap "input becomes block to evaluate and capture prin/t]"
    /n /num "shortcut (and override) for /options [num: on]"
    /local data line con ch cnt opts stay getkey keys input
        pad pre0 sea str tmp pos backlines slice reported
        capture captured sys-print sys-prin print-out prin-out
][
    input: func [/local val] [ ; input normally adds to console history
        any [
            empty? val: pick system/ports/input 1
            remove system/console/history
        ]
        val
    ]
    sys-print: get in system/words 'print  sys-prin: get in system/words 'prin
    print-out: func [value][append captured reform [reduce value newline]]
    prin-out:  func [value][append captured reform value]
    capture: func [flag [logic!]][
        either flag [
            captured: copy ""  set 'print :print-out  set 'prin :prin-out
        ][
            set 'print :sys-print  set 'prin  :sys-prin
        ]
    ]
    con: open/binary/no-wait [scheme: 'console]
    getkey: does [
        until [all [found? wait/all [con 00:00:00.01] ch: copy con]]
    ]
    prin "^(1B)[7n"  ;; get rows and cols of console
    str: to string! copy con
    opts: make object! [
        eof: true    num: false  rows: 24  cols: 80
        rows: attempt [to integer! copy/part next next str find str ";"]
        cols: attempt [to integer! copy/part next find str ";" find str "R"]
    ]
    reported: opts/cols ; for end-of-terminal newline control
    if options [opts: construct/with electives opts]
    if num [opts/num: on]
    percent: does [
        any [
            all [zero? length? data  "0%"]
            rejoin [index? back data " / " length? head data " "
              round multiply divide index? back data
              length? head data 100 "%"]
        ]
    ]
    either cap [
        if error? try [capture on  do intake  capture off] [
            set 'print :sys-print  set 'prin :sys-prin
        ]
        data: parse/all captured "^/"
    ][
	    data: switch/default type?/word intake [
	        word! [
	            if error? try [
	                capture on  help :intake
	                prin newline  source :intake  capture off
	            ][set 'print :sys-print  set 'prin :sys-prin]
	            parse/all captured "^/"
	        ]
	        file! [read/lines intake]
	        url! [read/lines intake]
	        string! [parse/all intake "^/"]
	        block! [parse/all mold/only new-line/all intake on "^/"]
	        object! [parse/all mold intake "^/"]
	    ][parse/all mold intake "^/"]
    ]
    
    str: pos: none  tmp: copy ""  ; supporting search
    pre0: head insert/dup copy "" "0" length? form length? data
    pad: func [n] [ 
        join join copy/part pre0 subtract length? pre0 length? form n n " "
    ]
    ;; reformat data into opts/cols sized pieces with optional line nums
    slice: func [incoming [block!] /local line outgoing] [
        outgoing: copy []
        while [not tail? incoming] [
            line: pick incoming 1
            replace/all line tab "    "
            replace/all line backspace "."
            if opts/num [insert head line pad index? incoming]
            until [
                insert tail outgoing copy/part line opts/cols
                line: skip line opts/cols
                tail? line
            ]
            incoming: next incoming
        ]
        outgoing
    ]
    data: slice data
    if empty? data [prin "--empty--" exit]
    backlines: func [lines [integer!] /pages] [
        data: skip data negate either pages [
            subtract multiply opts/rows lines lines
        ][
            subtract add opts/rows lines 1
        ]
    ]
    keys: [
        case [
	        ; q - quit
	        find charset ["qQ"] ch [close con  prin newline  exit]
	        ;find [#{51} #{71}] ch [close con  prin newline exit]
	        ; b - back page #{42} #{62}
	        find charset ["bB"] ch [backlines/pages 2]
	        ; up arrow, backspace - up one line
	        find [#{08} #{1B5B41}] ch [backlines 1]
	        ; down arrow, enter - down one line
	        find [#{0D} #{1B5B42}] ch [
	            data: skip data 1  backlines/pages 1
	        ]
	        ; < - top  #{3C}
	        find charset ["<"] ch [data: head data]
	        ; > - bottom #{3E}
	        find charset [">"] ch [data: tail data  backlines/pages 1]
	        ; w - refresh  wee-fresh [#{57} #{77}]
	        find charset ["wW"] ch [backlines/pages 1]
	        ; /, f - forward find [#{2F} #{46} #{66} #{4E} #{6E}]
	        find charset ["/fFnN"] ch [
	            unless all [not empty? tmp  find charset ["nN"] ch] [
	                prin " Forward:" tmp: input
	            ]
	            unless empty? tmp [str: tmp]
	            backlines/pages 1
	            pos: data  sea: next data  found: false
	            while [all [not tail? sea  not found]] [
	                if find sea/1 str [data: sea  found: true]
	                sea: next sea
	            ]
	            unless found [data: pos] true
	        ]
	        ; ?, r - find reverse [#{3F} #{52} #{72} #{50} #{70}]
	        find charset ["?rRpP"] ch [
	            unless all [not empty? tmp  find charset ["pP"] ch] [
	                prin " Backwards:" tmp: input
	            ]
	            unless empty? tmp [str: tmp]
	            backlines/pages 1
	            pos: data  sea: back data  found: false
	            until [
	                if find sea/1 str [data: sea  found: true]
	                any [head? sea  found  not sea: back sea]
	            ]
	            unless found [data: pos] true       
	        ]
	        ; g - go
	        find charset ["gG"] ch [
	            prin " Line: " tmp: input
	            data: skip head data
	              any [attempt [to integer! tmp] index? data]
	            backlines/pages 1
	        ] 
	        ; digit - skip n 1-9
	        find charset [#"1" - #"9"] ch [
	            data: skip data to integer! to string! ch
	            backlines/pages 1
	        ] 
	        ; h - help [#{48} #{68}]
	        find charset ["hH"] ch [
	            prin "^(1B)[J"
	            print "Welcome to pager - Up down and all around"
	            print ["Supports:"]
	            print [tab "q - quit"]
	            print [tab "h - this help"]
	            print [tab "w - refresh (weefresh)"]
	            print [tab "b - back a page"]
	            print [tab "> - bottom"]
	            print [tab "< - top"]
	            print [tab "g - goto line"]
	            print [tab "f or / - find forward"]
	            print [tab tab "n for next"]
	            print [tab "r or ? - find reverse"]
	            print [tab tab "p for previous"]
	            print [tab "up-arrow or backspace - back one line"]
	            print [tab "down-arrow or enter - forward one line"]
	            print [tab "digit - forward n lines"]
	            print ["Command options:"]
	            print [tab "rows: and cols:  to set rows and columns"]
	            print [tab "num: on to display line numbers"]
	            print [tab "eof: false to not wait at end of file"]
	            print ["Displaying" index? data "of" length? head data]
	            print ["Evals:" stats/evals "Mem:" stats]
	            getkey  backlines/pages 1
	            true
	        ]
        ]
    ]
    stay: true
    while [stay] [
        cnt: 1  prin "^(1B)[J"  ;; clear screen
        until [
            line: first data
            data: next data
            prin line
            unless equal? length? line reported [prin newline]
            cnt: add cnt 1
            if greater-or-equal? cnt opts/rows [
                if tail? data [break]
                prin ["--more--" percent]
                getkey  do keys
                cnt: 1  prin "^(1B)[J"
            ]
            tail? data
        ]
        either opts/eof [
            prin ["--eof--" index? back data "/" length? head data] getkey
            stay: to logic! do keys
        ][
            stay: false
        ]
    ]
    close con  prin newline exit
]
Notes