2012-08-04 5 views
20

Che problema può verificarsi se la funzione goto-line viene utilizzata in un programma elisp non interattivo? La sua docstring dà un avvertimento dicendo che:Perché "goto-line" in Emacs solo per uso interattivo?

Questa funzione è solitamente la cosa sbagliata da utilizzare in un programma Lisp. Che probabilmente si desidera invece è qualcosa di simile:

(goto-char (point-min)) (forward-line (1- N)) 

Inoltre, quando cerco di byte-compile-file mio file di inizializzazione compreso goto-line, ottengo un avvertimento sgradevole come questo, ancora una volta:

.emacs:170:19:Warning: `goto-line' used from Lisp code 
That command is designed for interactive use only 

Is usare goto-line in un programma non interattivo davvero così pericoloso? In correlazione, perché è preferibile la soluzione forward-line suggerita?

+0

Non sai come goto-line non funzionerebbe in modo interattivo, passa a una riga nel buffer corrente –

+0

@JonLin È possibile trovare un esempio che utilizza in modo non interattivo 'goto-line' in [EmacsWiki: AUCTeX] (http://emacswiki.org/emacs/AUCTeX#toc20):' th-evince-sync'. – dkim

+0

event_jr ha risposto alla domanda come posta, ma ancora * perché * stai cercando di farlo? Potrebbe esserci un modo migliore per realizzare ciò che vuoi veramente. Inoltre, vorrei sottolineare che se il buffer è stato ristretto andando a una certa linea probabilmente non sta andando a fare quello che pensi che sia. – scottfrazer

risposta

29

In primo luogo, questo impedisce ai programmatori di Elisp di cadere in cattive abitudini - scrivendo codice inefficiente in un numero di riga. Ad esempio, anziché utilizzare (forward-line 1) calcolare il numero di riga corrente, incrementare e utilizzare goto-line.

Dalla lista this mailing articolo:

In poche parole, il motivo per cui goto-line non deve essere un comando di frequente utilizzato è che normalmente non c'è alcun motivo per voler ottenere per la linea numero N a meno hai un programma che ti ha detto che c'è qualcosa di interessante su quella linea .

secondo luogo, goto-line manipola ambiente utente in aggiunta al movimento punto (cioè push-mark). Per uso non interattivo, questo potrebbe non essere quello che vuoi . D'altra parte, se dopo aver considerato tutto questo, credi goto-line è esattamente quello che ti serve, poi basta chiamare in questo modo:

(defun foo() 
    (interactive) 
    (with-no-warnings 
    (goto-line N))) 

E non avrà nessuna avvisi del compilatore.

+1

+1 per aver menzionato la manipolazione del punto. –

+0

"normalmente non c'è motivo di voler arrivare al numero di riga N a meno che tu non abbia un programma che ti dice che c'è qualcosa di interessante su quella linea" - cosa succede se il tuo programma (o codice elisp) ha calcolato che c'è davvero qualcosa di interessante su quella linea ? Quindi la raccomandazione di sottrarre la linea corrente da quella linea e utilizzare invece la linea diretta? (Facile, ma solo per essere sicuro.) – ShreevatsaR

6

in aggiunta a quanto detto:

"goto-line" finalmente ricorre onto "(forward-line (1- line)", che in effetti fa il lavoro Tutta delle 43 linee di ". goto-line "comando del corpo con uso interattivo.Per esempio considerare un argomento possibilmente universale.

Quando si scrive un programma o quando lo si esegue, il computer è in uno stato diverso rispetto a una chiamata interattiva. stato usando "forward-line" direttamente

+1

La parte '(interatt-arg-descriptor)' che si occupa di uso interattivo sembra essere saltata quando 'goto-line' viene chiamato dai programmi Lisp. Da [il manuale di riferimento] (http://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Interactive.html#index-interactive-1253), "Un comando può essere chiamato da programmi Lisp come qualsiasi altra funzione, ma poi il chiamante fornisce gli argomenti e _arg-descrittore_ non ha alcun effetto. " – dkim

+0

@dkim Anche il codice oltre il calcolo dell'argomento riguarda l'uso interattivo: c'è ancora un segno di spunta, commutatore su buffer e simili. –