Emacs: Comment stockez-vous le dernier paramètre fourni par l'utilisateur par défaut?
Question
Je suis en train d’écrire une fonction interactive dont je voudrais me rappeler le dernier argument fourni par l’utilisateur et l’utiliser par défaut.
(defun run-rake (param)
(interactive "sTask: ")
(shell-command (format "rake %s" task)))
La première fois que la fonction est invoquée, je souhaite qu'elle se souvienne de l'argument fourni par l'utilisateur afin qu'il puisse simplement appuyer sur la touche Entrée et qu'il utilisera la valeur fournie la fois précédente.
Je n'arrive pas à trouver cela dans la documentation. Comment procédez-vous dans elisp?
La solution
Vous pouvez voir comment la commande compile
effectue cela. Affichez le texte d'aide pour la commande de compilation avec Compiler C-h f
, déplacez le curseur sur le nom du fichier contenant la fonction, puis appuyez sur RETURN
. Cela fera apparaître le fichier source pour compiler
.
En gros, il existe une variable dynamique / globale commande de compilation
contenant la dernière commande de compilation. Emacs est un système mono-utilisateur, mono-thread, il n'y a donc vraiment pas besoin de beaucoup plus. N'oubliez pas non plus qu'Elisp est une très vieille école Lisp et que les variables ont une portée dynamique (pile d'appels) et non lexicale. Dans ce type de système, il est naturel de:
(let ((compile-command "gcc -o foo foo.c frobnicate.c"))
...
(compile)
...)
En parlant de la commande compiler
, avez-vous essayé de l'utiliser au lieu de votre propre run-rake
?
Autres conseils
read-from-minibuffer
est ce que vous voulez utiliser. Il a une place pour une variable d’historique.
Voici un exemple de code:
(defvar run-rake-history nil "History for run-rake")
(defun run-rake (cmd)
(interactive (list (read-from-minibuffer "Task: " (car run-rake-history) nil nil 'run-rake-history)))
(shell-command (format "rake %s " cmd)))
Évidemment, adaptez-vous à vos besoins. 'Run-rake-history est simplement une variable utilisée pour stocker l'historique de cette invocation de' read-from-minibuffer. Une autre option consisterait à utiliser 'achèvement-lecture - mais cela suppose que vous disposiez d'une liste de choix que vous souhaitez limiter à l'utilisateur (ce qui n'est généralement pas le cas pour les commandes similaires à un shell).
J'ai compris comment faire cela manuellement en utilisant un defvar (global), mais cela ressemble au genre de chose qui devrait déjà être fournie par la bibliothèque principale (un peu comme le paramètre make du schéma). Cela semble être plus de code et plus de manuel qu'il ne devrait l'être:
(defvar *editconf-ruby-run-rake-last-rake-task* nil)
(defun editconf-ruby-run-rake-last-rake-task (&optional new-val)
(when new-val
(setf *editconf-ruby-run-rake-last-rake-task* new-val))
*editconf-ruby-run-rake-last-rake-task*)
(defun editconf-ruby-run-rake (task-name)
"Execute rake `task-name'. See
`krb-ruby-get-rakefile-path-for-current-buffer' for how the
Rakefile is located.."
(interactive
(let* ((rakefile (krb-ruby-get-rakefile-path-for-current-buffer))
(rake-tasks (krb-ruby-get-rake-tasks rakefile))
(default-task (or (editconf-ruby-run-rake-last-rake-task)
(editconf-ruby-run-rake-last-rake-task (car rake-tasks)))))
(list
(read-string (format "Task [%s|%s]: "
rake-tasks
default-task)
nil nil default-task))))
(editconf-ruby-run-rake-last-rake-task task-name)
(let ((cmd (format "cd %s; rake %s"
(krb-lisp-strip-path-suffix rakefile 1)
task-name)))
(message "editconf-ruby-run-rake: cmd='%s'" cmd)
(shell-command cmd)))