emacs - Fine-tuning: `set-process-sentinel` | `set-process-filter` | `start-process` -
there few examples on internet involving 3 of functions @ issue in question -- i.e., set-process-sentinel
; set-process-filter
; , start-process
.
i've tried few different methods of fine-tuning the processes in effort force process number 1 (push
) finish prior commencement of process number 2 (push
). in of attempts, second process always runs , finishes before have finished entering password process number 1. process number 2 has password stored in osxkeychain
.
the first method tried magit, both synchronous , asynchronous processes. second method tried using function while . . .
search list of remotes in buffer containing said list. third attempt listed below -- uses list of remotes created @ outset of function , mapcar
s down list push
git.
any ideas on how better control process number 1 (push
) finishes prior commencement of process number 2 (push
) appreciated.
it not end of world process number 2 starts , finishes early, matter of learning how take control on emacs processes -- rather processes taking control of me.
edit (april 23, 2014): added doc-string. revised handling of buffer *remotes*
-- i.e., kill-local-variable 'git-remote-list
, erase-buffer
works correctly using with-current-buffer ...
(defvar git-remote-list nil "list of remote locations -- e.g., lawlist_remote or github_remote.") (make-variable-buffer-local 'git-remote-list) (defvar git-commit-message (format "committed -- %s" (current-time-string)) "the predetermined git commit message.") (make-variable-buffer-local 'git-commit-message) (defun my-process-filter (proc string) (when (string-match "password" string) (process-send-string proc (concat (read-passwd "password: ") "\n")))) (defun my-process-sentinel (proc string) (when (= 0 (process-exit-status proc)) (message "process `%s` has finished." proc))) (defun stage-commit-push-all () "this function following: * save current working buffer if has been modified. * gather list of remotes associated working directory git project. * stage -- `/usr/local/git/bin/git add .` * commit -- `/usr/local/git/bin/git commit -m [git-commit-message]` * push remotes: `/usr/local/git/bin/git push -v [remote] [current-branch]` obtaining current branch presently requires installation of magit." (interactive) (when (buffer-modified-p) (save-buffer)) (when (get-buffer "*remotes*") (with-current-buffer (get-buffer "*remotes*") (kill-local-variable 'git-remote-list) (erase-buffer))) (set-process-sentinel (start-process "list-remotes" "*remotes*" "/usr/local/git/bin/git" "remote" "-v") (lambda (p e) (when (= 0 (process-exit-status p)) (let* ( beg end git-remote-name) (with-current-buffer (get-buffer "*remotes*") (goto-char (point-max)) (while (re-search-backward "\(push\)" nil t) (beginning-of-line 1) (setq beg (point)) (re-search-forward "\t" nil t) (setq end (- (point) 1)) (setq git-remote-name (buffer-substring-no-properties beg end)) (setq git-remote-list (append (cons git-remote-name git-remote-list)))) )) (set-process-sentinel (start-process "stage-all" "*output*" "/usr/local/git/bin/git" "add" ".") (lambda (p e) (when (= 0 (process-exit-status p)) (set-process-sentinel (start-process "commit-all" "*output*" "/usr/local/git/bin/git" "commit" "-m" git-commit-message) (lambda (p e) (when (= 0 (process-exit-status p)) (mapcar (lambda (x) (let ((proc (start-process "push-process" "*output*" "/usr/local/git/bin/git" "push" "-v" (format "%s" x) (magit-get-current-branch)))) (set-process-filter proc 'my-process-filter) (set-process-sentinel proc 'my-process-sentinel) )) (with-current-buffer (get-buffer "*remotes*") git-remote-list) )))))))))))
the approach springs mind make each call start-process
dependent on sentinel previous process.
in essence, generate queue of things want do, trigger processing of first queue item, , let each sentinel trigger start process next queue item (if any) once own process has completed.
Comments
Post a Comment