Suggerimenti per giocare a golf a Vim


32

Di recente mi sono reso conto di come Vim grande per il golf, specialmente per la . Inoltre, secondo meta vim è almeno un "linguaggio di programmazione" perfettamente accettabile, per lo scopo di questo sito.

Quali consigli generali hai per giocare a golf a Vim? Sto cercando idee che possano essere applicate a problemi di code-golf e che siano anche in qualche modo specifiche per Vim (es. "Rimuovere i commenti" non è una risposta).

Si prega di inviare un suggerimento per risposta.


4
Questa è una domanda di suggerimenti particolarmente utile perché "Suggerimenti per giocare a golf in VIM" e "Suggerimenti per utilizzare Vim in modo efficiente come editor di testo" sono sostanzialmente la stessa cosa.
DLosc,

Risposte:


15

Prestare attenzione alle varianti maiuscole dei comandi comuni. Questo può banalmente salvare una sequenza di tasti in molti contesti. Per esempio:

A = $a
C = c$
D = d$
I = ^i
S = cc
X = dh
Y = yy

Un altro è quello di utilizzare al Gposto di gg, ma solo se si utilizza un conteggio! Ad esempio, senza un conteggio, si ggsposta all'inizio e si Gsposta alla fine. Tuttavia, con un conteggio, entrambi si spostano sulla riga specificata, quindi 5Gè più breve di ma equivalente a 5gg .

Un altro è da usare Hal posto di gg, ma è importante notare che questo funziona solo se puoi garantire che qualsiasi input non occuperà più del numero predefinito di righe (credo che sia 24, ma può variare).


1
Se una sfida è in particolare quella dell'editor golf (e quindi di solito viene segnata da sequenze di tasti), anche una lettera maiuscola è composta da due sequenze di tasti (così è $, almeno così Ce Dsalverebbe qualcosa).
Martin Ender,

1
Qualcosa di cui non sono chiaro quando si calcola con i tasti premuti è se le lettere consecutive che richiedono il tasto Maiusc contano il tasto Maiusc solo una volta per gruppo, poiché è possibile (almeno per scopi pratici) tenerlo premuto mentre si premono gli altri tasti.
Alex A.

6
@AlexA. Personalmente, penso che i modificatori non dovrebbero contare. Forse abbiamo bisogno di un meta post su questo ...
DJMcMayhem

Ge ggnon sono equivalenti. Il primo va alla fine del buffer e il secondo all'inizio.
Giordania,

@Jordan Questo è un buon punto. Volevo dire che sono uguali quando viene dato un conteggio, ad esempio 5Gè equivalente a 5gg. Aggiungerò qualche dettaglio in più su questo punto.
DJMcMayhem

11

Ogni volta che un comando fallisce, emetterà un rumore negativo, che annullerà la macro corrente. Puoi (ab) usarlo per creare una forma grezza di loop. Ad esempio, se si desidera ripetere i tasti <foobar>finché il buffer non contiene meno di 3 righe. Tu puoi fare

qq<foobar>3G``@qq

che significa:

qq                 'Start recording in register q
  <foobar>         'Keystrokes
          3G       'Go to line 3. If line 3 doesn't exist, this is effectively a "break" statement.
            ``     'Jump back to previous cursor location
              @q   'Call macro q
                q  'Stop recording

È importante notare che se lo si sta verificando in una sessione di vim, @qpotrebbero verificarsi effetti collaterali indesiderati, poiché le macro vengono caricate da .vim_profile. Puoi aggirare questo in un paio di modi diversi. Probabilmente la soluzione migliore è lanciare vim

vim -i NONE

Puoi anche eliminare il tuo .viminfo.

Se hai già avviato vim, puoi digitare

qqq

all'inizio azzerare la macro.

Altre condizioni con cui è possibile sostituire il 3G sono

f<char>    'Jump to first occurence of <char>. Also see F, t and T

o

<number>|  'Go to the <number>'th character on the current line.

8

Ci sono versioni più abbreviate di ex comandi che pensi. Ad esempio, probabilmente già sapevi che :globalpuò essere abbreviato:g , ma sapevi che :nnoremapè equivalente a :nn?

È una buona idea eseguire :h :footutti gli ex comandi che stai usando nella tua risposta per vedere se c'è una versione più breve.


6
:%s/\n//g

è sempre equivalente a

:%s/\n//

che sembra essere anche equivalente a

:%s/\n

abbastanza sorprendentemente. (In generale, senza alcun flag, l'ultima barra in :sun'espressione non è mai necessaria.)


2
Questo funziona per newline, ma non funziona per nessun personaggio che potrebbe apparire più di una volta in una riga. Ad esempio :%s/xnon rimuove ogni occorrenza di x, ma solo la prima su ogni riga.
DJMcMayhem

1
Puoi anche usare :&&per ripetere un comando sostitutivo e i suoi flag.
DJMcMayhem

6

Supponiamo che tu sia in modalità inserimento e desideri eseguire un singolo comando in modalità normale. Potresti scrivere così:

isome_text<esc><foobar>gisome_more_text

Non farlo in questo modo. Invece, usa <C-o>, che esegue un singolo comando normale, quindi torna immediatamente alla modalità di inserimento.

isome_text<C-o><foobar>some_more_text

Nemmeno io penso che quegli spazi siano necessari
Funds Lawsuit Monica

@QPaysTaxes Hai ragione, non lo sono. Ho pensato che lo avrebbe reso più leggibile. Lo modificherò.
DJMcMayhem

Non hai bisogno di un <CR>dopo <foobar>per inviare il comando?
Fondi Monica's Lawsuit

@QPaysTaxes Solo se si tratta di un comando ex o di una ricerca. (Eg qualsiasi comando a partire da un :, /o ?)
DJMcMayhem

Oh mio Dio. Ho confuso il comando e le modalità normali. Fantastico: D
Fondo Monica's Lawsuit

5

Esistono tre operatori "cambia caso",

gu    "Convert to lowercase
gU    "Convert to uppercase
g~    "Toggle case

Poiché questi sono operatori, prendono un movimento, quindi per convertire il carattere corrente in minuscolo si userebbe

gul

Ecco dove arriva il trucco divertente. :) Se vuoi cambiare il caso di un singolo carattere o della riga corrente, è un byte più breve in modalità visiva. Ad esempio gulè equivalente a

vu

E gu_(_ è la riga corrente) è equivalente a

Vu

Questo trucco non funziona per v?attivare / disattivare , perché attiva una ricerca all'indietro in modalità visiva (proprio come v/ma muovendosi nella direzione opposta) quindi è necessariovg? invece. Tuttavia, ecco dove è possibile utilizzare l' ~operatore, per salvare ancora più byte! (Grazie @Doorknob per averlo segnalato)

Puoi vedere questo trucco in azione sulla mia risposta vim qui e sulla risposta V equivalente su e post.


1
Non dimenticare ~, che alterna il caso del personaggio sotto il cursore e lo sposta a destra!
Maniglia della porta

5

L'alfabeto in 10 sequenze di tasti

Tutto il merito di questa tecnica va a Lynn, che per primo l'ha usata in questa risposta . Lo sto scrivendo qui per i posteri.

Utilizzare i seguenti dieci tasti per strappare l'alfabeto minuscolo:

:h<_␍jjYZZ

(Dove un ritorno a capo, ovvero il tasto Invio.)

Spiegazione

:h<_␍apre la sezione di aiuto v_b_<_example(un esempio di selezione visuale a blocchi), che contiene il testo abcdefghijklmnopqrstuvwyxz. jjYsi sposta su quella linea e la strattona, quindi ZZchiude la finestra di aiuto.


4

Conosci i tuoi registri

Non "aYè sempre necessario strappare o eliminare il testo in un registro specifico (ad es. ) Per utilizzarlo in un secondo momento. Vim ha diversi registri che vengono automaticamente popolati con i soggetti di vari comandi. Digita :help registersper vederli tutti, ma ecco alcune note particolari:

  • Registro senza nome: ""- L'ultimo testo che è stato strappato o eliminato.

  • Registro numerato "0: l'ultimo testo che è stato strappato.

  • Registri numerati "1- "9- L'ultimo testo che è stato eliminato a meno che non fosse inferiore a una riga. Ogni volta che "1viene riempito, i contenuti precedenti vengono spostati in"2 e così via.

  • Piccolo registro di eliminazione: "-- L'ultimo testo più corto di una riga che è stata eliminata.

  • Ultimo testo inserito: ".

In particolare, le "-e "1registri possono essere utili insieme, consentendo di eliminare un testo con ad esempio ddnel "1registro ed eliminare qualche altro testo con Din "-(ovviamente, la semantica non sono identici, ma spesso non hanno bisogno di essere ).

Tutti i registri possono essere un po 'difficili da tenere traccia, ma puoi vedere il contenuto di tutti i tuoi registri in qualsiasi momento digitando :registers.


3

Questo è emerso in chat in precedenza, quindi ho pensato di poterlo pubblicare come un suggerimento completo.

<C-a>e <C-x>incrementare e decrementare il numero successivo sulla riga. Questa è una funzione estremamente utile per alcuni semplici calcoli, ma consente anche un piccolo trucco accurato.

Diciamo che è necessario passare al numero successivo. Ad esempio, dobbiamo cambiare

I need 2 spell better

a

I need to spell better

Il modo ovvio è saltare al 2, quindi fare:

sto                "Synonymous with 'clto'

Dal momento che questo è più breve di

:s/2/to<cr>

Esistono molti modi diversi per passare al 2. Ad esempio,

/2<cr>
ww 
2w
ee
2e
8|
f2

Così come molti altri modi.

Questi sono tutti 2 (o più) tasti. Tuttavia, poiché <C-a>e <C-x>non solo incrementare / decrementare i numeri, ma anche passare al numero successivo, possiamo togliere un byte con

<C-a>sto

3

Movimenti golfisti

Spesso se stai lavorando con un blocco di testo (specialmente nelle sfide ), dovrai passare al primo o all'ultimo carattere nel buffer. Ge ggsono abbastanza buoni, ma ci sono alcune cose fastidiose. Ad esempio, per ottenere l'ultimo personaggio, è necessario G$e ggnon ti inserirà necessariamente nella prima colonna se c'è spazio bianco iniziale. Ecco alcuni movimenti più piacevoli, sebbene si noti che funzionano solo se il testo non ha linee vuote nel mezzo:

  • Primo carattere del buffer: {è migliore di gg0. Se ci sono linee vuote nel mezzo del testo, puoi anche usare ciò goche ti porta al primo carattere nel buffer, non importa quale.

  • Ultimo carattere del buffer: }è migliore diG$

Funzionano anche come argomento per un operatore, ma si noti che sono movimenti saggi del personaggio, non movimenti saggia!


Hè più golfoso digg
Kritixi Lithos il

@KritixiLithos tranne che Hnon è affidabile. Il comportamento dipende dalla dimensione della finestra visibile e da dove ci si trova nel buffer. (Rimappato in V per evitare questa confusione)
DJMcMayhem

2

Esegui calcoli con il registro delle espressioni

È possibile eseguire calcoli sia in modalità normale che in modalità inserimento.

Modalità normale

In modalità normale, se si digita @= il cursore si sposta sulla riga di comando, dove è possibile immettere qualsiasi espressione. Quando si preme invio, il risultato dell'espressione verrà eseguito come comandi in modalità normale.

Ad esempio, supponiamo di voler andare alla colonna centrale della riga corrente. La chiamata di funzione col('$')restituisce il numero di colonne nella riga, quindi possiamo ottenere ciò digitando quanto segue:

@=col('$')/2<CR>|

Quando premi Invio, il cursore ritorna sul buffer e vim attende un operatore (come |) come se tu avessi appena inserito un numero. In alternativa, avresti potuto inserire questo:

@=col('$')/2.'|'

... ma ovviamente sono più byte.

Modalità di inserimento

Puoi usare il registro delle espressioni anche in modalità insert, premendo <Ctrl-r>=invece di @=. Funziona allo stesso modo in modalità normale, tranne per il fatto che il risultato dell'espressione immessa verrà eseguito in modalità inserimento. Ad esempio, se hai digitato<Ctrl-r>=col('$')<CR> , il numero di colonne nella riga corrente verrebbe inserito nel cursore come se lo avessi digitato.

Per ulteriori informazioni sul registro delle espressioni, digitare :help "=.

Riutilizzo delle espressioni

L'ultima espressione è stato utilizzato viene memorizzato nel registro l'espressione, "=. Digitando @=<CR>in modalità normale o <Ctrl-r>=<CR>in modalità inserimento si valuterà di nuovo l'espressione, permettendoti di usarli in modo molto simile alle macro.

Fare calcoli nelle sostituzioni

È possibile valutare le espressioni anche quando si effettuano sostituzioni di espressioni regolari. Tutto quello che devi fare è iniziare la sostituzione con \=. Ad esempio, supponiamo di voler numerare le righe in questo file:

foo
bar
baz

La chiamata di funzione line('.')restituisce il numero di linea corrente, quindi il lavoro è semplice. Inserendo questo:

:s/^/\=line('.').' '/g<CR>

... produce il risultato desiderato:

1 foo
2 bar
3 baz

Per utilizzare i gruppi acquisiti in una tale espressione è possibile utilizzare la submatch()funzione, dove ad esempio submatch(0)è equivalente a \0una sostituzione ordinaria, submatch(1)è equivalente a \1, ecc. Questo purtroppo consuma molte sequenze di tasti.

Per ulteriori informazioni sulla sostituzione delle espressioni, digitare :help sub-replace-expression.


Per il tuo ultimo esempio ci sono modi più brevi. Ad esempio i1 <esc>bqqywjPb<C-a>@qq@qè una soluzione in modalità normale pura che è più corta di 5 byte. E se sei su Unix, potresti persino farlo :%!nl. Ancora buoni consigli però!
DJMcMayhem

1
Il mio obiettivo era dimostrare come utilizzare la funzione, non come numerare le linee con il minor numero di tasti.
Giordania,

1

È possibile modificare direttamente il testo di una macro, che può essere significativamente più breve di un condizionale contorto. Ad esempio, supponiamo che tu voglia incollare qualcosa n volte, dove n è l'input dell'utente. Prima ho provato a fare questo:

qq/[1-9]<enter><c-x>``p@qq@q

Spiegazione:

qq                             #Start Recording
  /[1-9]<enter>                #Search for a number that isn't 0.
                <c-x>          #Decrement that number
                     ``p       #jump back to your previous location and paste.
                        @q     #Recursive call to macro 'q'
                          q@q  #Stop recording, and run the macro

Si tratta di 18 sequenze di tasti e un modo davvero brutto per farlo. Invece, vai alla posizione di quel numero e fai questo:

Ap<esc>"qdd@q

Spiegazione:

Ap<esc>                 #Append a 'p' to the end of the current line.
       "qdd             #Delete the current line into register q
           @q           #Run macro q.

Si tratta di 9 battiture, un enorme miglioramento.

Modificare:

Ancora più breve è eseguire la macro per il tuo numero e quindi digitare il comando. Per esempio:

"qdd@qp

Spiegazione:

"qdd         #Delete the current line into register q
    @q       #Run register q
      p      #Paste

7 tasti.


1
1. Usa D, no dd. 2. Se il comando non prevede registri, è possibile renderlo ancora più breve. Ad esempio, se si desidera ripetere il carattere xtutte le volte che il numero sotto il cursore, anziché"qD@qix<esc> utilizzare D@"ix<esc>.
Maniglia della porta
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.