programme de téléavertisseur comme moins, capable de répéter les N premières lignes

15

Existe-t-il un moyen de faire lessrépéter la première ligne du programme (ou les 2 premières lignes) sur chaque page affichée?

Y a-t-il un autre programme de téléavertisseur qui peut le faire?

Ce serait une application de tueur pour la navigation dans les tables de base de données, pensez mysqlou psqlou gqlplus...

Pour ceux d'entre vous qui ne comprennent pas l'idée, voir la capture d'écran en bas de cette page . Je veux répéter la ligne d'en-tête + la barre ascii horizontale.

filiprem
la source
Oh boy, qui demande une extension à moins, comme un point Freeze Pane. Par exemple, --freeze-pane 10,2 conserverait 1 ligne d'en-têtes de colonne et 10 colonnes d'en-tête de ligne. Le défilement horizontal et vertical conserverait respectivement les en-têtes de ligne et de colonne. Ce serait vraiment cool à utiliser pour un pager psql (merlinmoncure.blogspot.com/2007/10/better-psql-with-less.html)
Gunther Schadow

Réponses:

12

Il existe une solution utilisant Vim.

Tout d'abord, nous avons besoin d'une macro Vim, qui fera la plupart du travail, je l'enregistre dans ~/.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()

Deuxièmement, pour émuler un pager, j'ai besoin d'appeler vim pour qu'il:

  • lire l'entrée standard
  • mais si l'argument est donné en ligne de commande, lisez tout ce qui vient là
  • travailler en mode lecture seule
  • ignorer tous les scripts d'initialisation, mais exécuter à la place la macro Less définie ci-dessus

J'ai mis cela ensemble comme script d'aide dans ~/bin/vimpager:

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

Troisièmement, je dois remplacer la variable d'environnement $ PAGER, mais uniquement pour psql (ajouter ceci à mon ~/.bash_aliases):

if which vimpager &>/dev/null; then
  alias psql='PAGER=vimpager psql';
fi
filiprem
la source
C'est adorable, je l'ai essayé. Maintenant, ce serait bien si on pouvait également ajouter des en-têtes de ligne, au lieu de ces numéros de ligne.
Gunther Schadow
4

Avez-vous essayé le mode SQL dans Emacs / XEmacs?

Ce n'est certainement pas aussi simple à utiliser que moreou less, mais il fait ce que vous demandez, en laissant une ligne d'en-tête tout en faisant défiler les résultats verticalement et horizontalement.

bsd
la source
Merci, je ne connais pas Emacs mais ça a l'air intéressant. J'aurais finalement besoin d'un script shell qui: démarrer emacs, y exécuter psql (avec les paramètres de connexion donnés), activer le mode sql et faire ce que je veux (toujours geler les 2 premières lignes lorsqu'il y a des résultats de requête plus grands que la taille de l'écran) . des indices à ce sujet?
filiprem
3

Cela emprunte très fortement à la réponse acceptée, mais ajoute ...

  • Défilement plus rapide
  • Impossible de faire défiler accidentellement dans l'en-tête
  • Mise en évidence de la syntaxe (certains crédits appartiennent ici )
    • Nombres positifs / négatifs, dates, heures, NULLVrai / Faux (et T / F, O / N, Oui / Non)
    • Numéros de ligne, si vous les avez devant un caractère de pipe.
  • Texte d'aide
  • Prise en charge du Vim inclus avec Git pour Windows
  • Ne menacez pas de mettre à jour la vue si le tampon stdin change

Certaines portions devront peut-être être modifiées pour votre sortie spécifique, car je ne les utilise pas psql. J'ai également des fonctions d'assistance légèrement différentes pour mes besoins, mais elles sont similaires à celles de la réponse acceptée.

Exemple d'entrée

  | 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 |

Code

" :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()
Michael - Où est Clay Shirky
la source
2

Vous pouvez utiliser plusieurs «régions» dans 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

Il vous suffit ensuite de définir la variable d'environnement $ FILE:

$ FILE=$HOME/.bash_profile screen -mc screenrc.sql
Arcege
la source
1
c'est presque ce que je voulais, mais (a) la fenêtre du haut ne défile pas à droite, donc elle est inutile pour les tables larges
filiprem
Je ne sais pas ce que vous entendez par «inutile pour les tables larges»; screen peut s'étendre à la taille du terminal (s'il n'exécute pas la fitcommande screen). J'avais pensé que vous ne vouliez pas que le haut défile. Lorsque je l'ai testé moi-même, les deux fenêtres défilent comme elles le devraient. Le haut fait défiler deux lignes (1-2, 3-4, 5-6, etc.) et le bas défile selon les besoins. Quel est le comportement que vous voyez /
Arcege
0

Vous pouvez ajouter un nombre avant le «avant» et il fera défiler N lignes, pas une longueur complète. Donc, si votre fenêtre de terminal est de 40 lignes, tapez 38fpour commencer à faire défiler seulement 38 lignes, en laissant les 2 dernières lignes de la dernière «page». Depuis la page de manuel:

   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.
Arcege
la source
1
Je dois garder premier , et non dernières lignes de N. Comme "figer les N premières lignes" dans la feuille de calcul Google.
filiprem
Ah désolé. Je ne sais pas si un utilitaire qui ferait ça. Ensuite, ce que je suggère est: utilisez screenou tmuxpour créer deux volets, redimensionnez la première à deux lignes ( resize 2) puis exécutez less, dans le deuxième volet, exécutez lessnormalement. Vous pouvez configurer cela comme un script avec un fichier .screenrc spécifique. Voir autre réponse.
Arcege