programma cercapersone come less, in grado di ripetere le prime N righe


15

Esiste un modo per far lessripetere il programma alla prima riga (o alle prime 2 righe) su ogni pagina visualizzata?

Esiste un altro programma di cercapersone che può farlo?

Questa sarebbe un'app killer per la navigazione nella tabella del database, pensa mysqlo psqlo gqlplus...

Per quelli di voi che non hanno idea, vedere lo screenshot in fondo a questa pagina . Voglio ripetere la riga di intestazione + barra ASCII orizzontale.


Oh ragazzo, questo richiede un'estensione a meno, come un punto Freeze Pane. Ad esempio --freeze-riquadro 10,2 manterrà 1 riga di intestazioni di colonna e 10 righe di riga. Lo scorrimento orizzontale e verticale preserverebbe rispettivamente le intestazioni di riga e colonna. Sarebbe davvero bello da usare per un cercapersone psql (merlinmoncure.blogspot.com/2007/10/better-psql-with-less.html)
Gunther Schadow

Risposte:


12

C'è una soluzione usando Vim.

In primo luogo, abbiamo bisogno di una macro Vim, che farà la maggior parte del lavoro, lo salvo in ~/.vim/plugin/less.vim:

" :Less
" turn vim into a pager for psql aligned results 
fun! Less()
  set nocompatible
  set nowrap
  set scrollopt=hor
  set scrollbind
  set number
  execute 'above split'
  " resize upper window to one line; two lines are not needed because vim adds separating line
  execute 'resize 1'
  " switch to lower window and scroll 2 lines down 
  wincmd j
  execute 'norm! 2^E'
  " hide statusline in lower window
  set laststatus=0
  " hide contents of upper statusline. editor note: do not remove trailing spaces in next line!
  set statusline=\  
  " arrows do scrolling instead of moving
  nmap ^[OC zL
  nmap ^[OB ^E
  nmap ^[OD zH
  nmap ^[OA ^Y
  nmap <Space> <PageDown>
  " faster quit (I tend to forget about the upper panel)
  nmap q :qa^M
  nmap Q :qa^M
endfun
command! -nargs=0 Less call Less()

In secondo luogo, per emulare un cercapersone, ho bisogno di invocare VIM in modo che:

  • leggere input standard
  • ma se l'argomento è dato dalla riga di comando, leggi qualunque cosa vi arrivi
  • funziona in modalità di sola lettura
  • salta tutti gli script init, ma esegui invece meno macro definita sopra

Ho messo questo insieme come script helper in ~/bin/vimpager:

#!/bin/bash
what=-
test "$@" && what="$@"
exec vim -u NONE -R -S ~/.vim/plugin/less.vim -c Less $what

In terzo luogo, ho bisogno di sostituire la variabile di ambiente $ PAGER, ma solo per psql (aggiungilo al mio ~/.bash_aliases):

if which vimpager &>/dev/null; then
  alias psql='PAGER=vimpager psql';
fi

Questo è adorabile, l'ho provato. Ora sarebbe bello se si potessero aggiungere anche le intestazioni di riga, anziché questi numeri di riga.
Gunther Schadow

4

Hai provato la modalità SQL in Emacs / XEmacs?

Certamente non è così semplice da usare come moreo less, ma fa quello che chiedi, lasciando una riga di intestazione mentre scorri i risultati in verticale e in orizzontale.


Grazie, non conosco Emacs ma sembra interessante. Avrei eventualmente bisogno di uno script di shell che avrebbe: avviare emacs, eseguire lì psql, (con i parametri di connessione forniti), abilitare la modalità sql e fare quello che voglio (bloccare sempre le prime 2 righe quando ci sono risultati di query più grandi della dimensione dello schermo) . qualche suggerimento al riguardo?
filiprem,

3

Questo prende in prestito molto dalla risposta accettata, ma aggiunge ...

  • Scorrimento più veloce
  • Impossibile scorrere accidentalmente nell'intestazione
  • Evidenziazione della sintassi (parte del credito appartiene qui )
    • Numeri, date, orari positivi / negativi NULL, Vero / Falso (e T / F, S / N, Sì / No)
    • Numeri di riga, se li hai prima di un carattere pipe.
  • Testo guida
  • Supporto per Vim incluso in Git per Windows
  • Non minacciare di aggiornare la vista se il buffer stdin cambia

Potrebbe essere necessario modificare alcune parti per l'output specifico, poiché non lo uso psql. Ho anche funzioni di supporto leggermente diverse per i miei scopi, ma sono simili a quelle della risposta accettata.

Input di esempio

  | ID |   First   |     Last     | Member | Balance |
--+----+-----------+--------------+--------+---------+
 1|  4 | Tom       | Hanks        | False  |    0.00 |
 2| 12 | Susan     | Patterson    | True   |   10.00 |
 3| 23 | Harriet   | Langford-Wat | False  |    0.00 |
 4|  8 | Jerry     |     NULL     | True   | -382.94 |
[… More rows …]
10| 87 | Horace    | Weaver       | False  |   47.52 |

Codice

" :HeadPager
" Turn vim into a pager with a header row
" Adapted from /unix//a/27840/143088
fun! HeadPager()
    " If you didn't get three lines, shortcut out
    if line('$') < 3
        set nocompatible
        nmap <silent> q :qa!<c-M>
        nmap <silent> Q :qa!<c-M>
        return
    endif

    set noswapfile
    set nocompatible
    set nowrap
    set scrollopt=hor
    set scrollbind

    " Hide statusline in lower window
    set laststatus=0
    " Explain mapped chars in status line.
    set statusline=\ \ \ Q\ to\ quit\.\ Arrows\ or\ mousewheel\ to\ scroll\.\ \(Vim\ commands\ work\,\ too\.\)

    " Delete/copy header lines
    silent execute '1,2d'

    " Split screen with new buffer (opens at top)
    execute 'new'

    " Switch to upper split
    wincmd k

    " Paste the header over the blank line
    execute 'norm! Vp'

    " Header highlighting
    syn match Pipe "|"
    hi def Pipe ctermfg=blue
    syn match Any /[^|]\+/
    hi def Any ctermfg=yellow

    " Switch back to lower split for scrolling
    wincmd j

    " Set lower split height to maximum
    execute "norm! \<c-W>_"

    " Syntax highlighting
    syn cluster CellContents contains=None
    syn match Pipe "|" contained nextgroup=@CellContents skipwhite
    hi def Pipe ctermfg=blue

    " Start with newline or |. End right before next | or EOL
    syn region Cell start=/\v(^|\|)\s*/ end=/\v(\||$)\@=/ contains=LineNumber,Pipe

    syn match NumPos /\v\+?\d+(,?\d{3})*\.?\d*\ze *(\||$)\@=/ contained
    syn match NumNeg   /\v-\d+(,?\d{3})*\.?\d*\ze *(\||$)\@=/ contained
    syn match NumZero         /\v[+-]?0+\.?0*\ze *(\||$)\@=/  contained
    hi def NumPos ctermfg=cyan
    hi def NumNeg ctermfg=red
    hi def NumZero ctermfg=NONE
    syn cluster CellContents add=NumPos,NumNeg,NumZero

    syn match DateVal /\v\d{4}-\d{2}-\d{2}/ contained nextgroup=TimeVal skipwhite
    syn match TimeVal /\v\d{1,2}:\d{2}(:\d{2})?(\.\d+)?(Z| ?\c[AP]M)?\ze *(\||$)\@=/ contained
    hi def DateVal ctermfg=magenta
    hi def TimeVal ctermfg=magenta
    syn cluster CellContents add=DateVal,TimeVal

    syn match TrueVal /\v\c(t(rue)?|y(es)?)\ze *(\||$)\@=/ contained
    syn match FalseVal /\v\c(f(alse)?|no?)\ze *(\||$)\@=/ contained
    hi def TrueVal ctermfg=green
    hi def FalseVal ctermfg=red
    syn match NullVal /\v\cnull?\ze *(\||$)\@=/ contained
    hi def NullVal ctermbg=gray ctermfg=black
    syn cluster CellContents add=TrueVal,FalseVal,NullVal

    syn match LineNumber /^ *\d\+/ contained
    hi def LineNumber ctermfg=yellow

    " Arrows do scrolling instead of moving
    nmap <silent> <Up> 3<c-Y>
    nmap <silent> <Down> 3<c-E>
    nmap <silent> <Left> zH
    nmap <silent> <Right> zL
    nmap <Space> <PageDown>
    " Faster quit (I tend to forget about the upper panel)
    nmap <silent> q :qa!<c-M>
    nmap <silent> Q :qa!<c-M>

    " Ignore external updates to the buffer
    autocmd! FileChangedShell */fd/*
    autocmd! FileChangedRO */fd/*
endfun
command! -nargs=0 HeadPager call HeadPager()

2

È possibile utilizzare più "regioni" in screen:

$ cat screenrc.sql
escape ^aa  # adjust as needed
bind q quit # to quickly exit
screen 0 less ${FILE}
screen 1 less ${FILE}
split  # create two regions
focus top # starting with the top region
resize 4  # make it four lines (one for screen line, one for less prompt)
select 0  # display window 0
focus bottom  # in the bottom region
select 1  # display window 1 and focus here

Quindi devi solo impostare la variabile d'ambiente $ FILE:

$ FILE=$HOME/.bash_profile screen -mc screenrc.sql

1
questo è quasi quello che volevo, ma (a) la finestra in alto non scorre a destra, quindi è inutile per i tavoli larghi
filiprem,

Non sono sicuro di cosa intendi per "inutile per tavoli ampi"; lo schermo può espandersi fino alle dimensioni del terminale (se non esegue il fitcomando schermo). Avevo pensato che non volevi che la parte superiore scorresse. Quando l'ho provato da solo, entrambe le finestre scorrono come dovrebbero. La parte superiore scorre due righe (1-2, 3-4, 5-6, ecc.) E la parte inferiore scorre secondo necessità. Qual è il comportamento che stai osservando /
Arcege il

0

Puoi aggiungere un numero prima di "avanti" e scorrerà N righe, non una lunghezza intera. Quindi, se la finestra del terminale è di 40 righe, digita 38fper iniziare a scorrere solo 38 righe, lasciando le ultime 2 righe dall'ultima "pagina". Dalla manpage:

   SPACE or ^V or f or ^F
          Scroll forward N  lines,  default  one  window  (see  option  -z
          below).   If  N  is  more  than  the screen size, only the final
          screenful is displayed.  Warning: some systems use ^V as a  spe‐
          cial literalization character.

   z      Like  SPACE,  but  if  N is specified, it becomes the new window
          size.

   b or ^B or ESC-v
          Scroll backward N lines,  default  one  window  (see  option  -z
          below).   If  N  is  more  than  the screen size, only the final
          screenful is displayed.

1
Devo mantenere la prima , non le ultime N righe. Come "congelare le prime N righe" nel foglio di calcolo di Google.
filiprem,

Mi dispiace. Non so se un'utilità che lo farebbe. Quindi quello che suggerisco è: utilizzare screeno tmuxper creare due riquadri, ridimensionare la prima a due righe ( resize 2) e quindi eseguire less, nel secondo riquadro, eseguire lessnormalmente. Puoi configurarlo come uno script con un file .screenrc specifico. Vedi risposta alternativa.
Arcege,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.