19

Since I am using org-mode to track my todo list in emacs, I like the iPhone app: MobileOrg, with it, I can access my todo list all day.

But here's the problem:

I have to manually org-mobile-push my changes from local file to mobile phone through dropbox, and org-mobile-pull the changes made by phone back.

How to make that automatically? Like adding some recipes in dotemacs file.

user1087032
  • 755
  • 1
  • 6
  • 8
  • Isn't this a duplicate of http://stackoverflow.com/questions/4217599/hooking-some-emacs-events-to-improve-org-mode-mobileorg-integration ? – Adam Spiers Mar 01 '12 at 17:12
  • Actually, it is, although the way the question is phrased I would not have recognized it on sight. – gimpf Jul 13 '13 at 18:18
  • Is `(run-with-timer 0 (* 5 60) 'org-mobile-pull)` good for the automatic pulling(/pushing)? – Dror Dec 19 '14 at 23:18

7 Answers7

22

Add these two lines to dot emacs file:

(add-hook 'after-init-hook 'org-mobile-pull)
(add-hook 'kill-emacs-hook 'org-mobile-push) 

With them, it automatically pulls the changes on emacs startup, and pushes the changes before emacs exits.

-- Update

If you never exit your Emacs, this solution might not work for you. So, another solution using idle timer

;; moble sync
(defvar org-mobile-sync-timer nil)
(defvar org-mobile-sync-idle-secs (* 60 10))
(defun org-mobile-sync ()
  (interactive)
  (org-mobile-pull)
  (org-mobile-push))
(defun org-mobile-sync-enable ()
  "enable mobile org idle sync"
  (interactive)
  (setq org-mobile-sync-timer
        (run-with-idle-timer org-mobile-sync-idle-secs t
                             'org-mobile-sync)));
(defun org-mobile-sync-disable ()
  "disable mobile org idle sync"
  (interactive)
  (cancel-timer org-mobile-sync-timer))
(org-mobile-sync-enable)

I just found out it is same as below answer, so, if you prefer the idle timer solution, please upvote tkf's answer.

Community
  • 1
  • 1
Chris Zheng
  • 1,509
  • 1
  • 15
  • 20
  • Arguably, if you are killing and restarting your Emacs often enough for this to be actually practical, you are doing something wrong. A solution based on a save hook or idle timer should be preferable. – Peter Eisentraut Nov 15 '12 at 17:09
  • What I wrote is a way to do this simply, yes, idle timer is better, but need more scripts, I'll edit this answer to add idle timer solution, which I am using now. – Chris Zheng Nov 16 '12 at 02:46
16

I have something like this in my Emacs setting to do push and pull when I am away from computer.

(defvar my-org-mobile-sync-timer nil)

(defvar my-org-mobile-sync-secs (* 60 20))

(defun my-org-mobile-sync-pull-and-push ()
  (org-mobile-pull)
  (org-mobile-push)
  (when (fboundp 'sauron-add-event)
    (sauron-add-event 'my 3 "Called org-mobile-pull and org-mobile-push")))

(defun my-org-mobile-sync-start ()
  "Start automated `org-mobile-push'"
  (interactive)
  (setq my-org-mobile-sync-timer
        (run-with-idle-timer my-org-mobile-sync-secs t
                             'my-org-mobile-sync-pull-and-push)))

(defun my-org-mobile-sync-stop ()
  "Stop automated `org-mobile-push'"
  (interactive)
  (cancel-timer my-org-mobile-sync-timer))

(my-org-mobile-sync-start)

Alternative is to put the following in cron job (I found this here https://github.com/matburt/mobileorg-android/wiki/Scripting/):

emacs --batch --load ~/.emacs --eval "(org-mobile-pull)" --eval "(org-mobile-push)"
tkf
  • 2,990
  • 18
  • 32
  • I'm assuming the 60 is if emacs is idle for 60 seconds and then the 20 seconds is to run every 20 seconds thereafter. Is this correct?? If not, please let me know. Thanks a lot. – J Spen Jun 11 '12 at 13:09
  • No. my-org-mobile-sync-secs stores 1200, meaning that Emacs does pull/push if it is idle 20 minutes. It does nothing after if it stays in idle. If it reenters to idle state (you do some editing after leaving Emacs in idle more than 20 minutes, first pull/push occurs, you stop editing, and then 20 minutes elapse), it will do another pull/push again. – tkf Jun 13 '12 at 15:25
2

This code is taken from http://kenmankoff.com/2012/08/17/emacs-org-mode-and-mobileorg-auto-sync/, with a couple of details changed. You need to configure the variables in the beginning. This code will

  • Check every 30s whether MobileOrg has synced, and if so

    • Pull from MobileOrg.
    • Push to MobileOrg.

      This is necessary to update the agenda views in MobileOrg. With this behavior, you can be away from your computer, update some things in MobileOrg, sync, wait 30 seconds, sync again, and your mobile agenda view will be updated.

  • Whenever an org file is saved
    • Check whether the saved org file is supposed to be synced with MobileOrg, and if so
      • Wait for the user to become idle
      • Push to MobileOrg

Code for your .emacs file:

(require 'org-mobile)
;; Configure these two variables
(setq org-mobile-inbox-for-pull "~/Dropbox/org/mobile.org" 
      org-mobile-directory "~/Dropbox/MobileOrg")
(require 'gnus-async) 
;; Define a timer variable
(defvar org-mobile-push-timer nil
  "Timer that `org-mobile-push-timer' used to reschedule itself, or nil.")
;; Push to mobile when the idle timer runs out
(defun org-mobile-push-with-delay (secs)
   (when org-mobile-push-timer
    (cancel-timer org-mobile-push-timer))
  (setq org-mobile-push-timer
        (run-with-idle-timer
         (* 1 secs) nil 'org-mobile-push)))
;; After saving files, start an idle timer after which we are going to push 
(add-hook 'after-save-hook 
 (lambda () 
   (if (or (eq major-mode 'org-mode) (eq major-mode 'org-agenda-mode))
     (dolist (file (org-mobile-files-alist))
       (if (string= (expand-file-name (car file)) (buffer-file-name))
           (org-mobile-push-with-delay 10))))))
;; watch mobileorg.org for changes, and then call org-mobile-pull
(defun org-mobile-install-monitor (file secs)
  (run-with-timer
   0 secs
   (lambda (f p)
     (unless (< p (second (time-since (elt (file-attributes f) 5))))
       (org-mobile-pull)
       (org-mobile-push)))
   file secs))
(defvar monitor-timer (org-mobile-install-monitor (concat org-mobile-directory "/mobileorg.org") 30)
  "Check if file changed every 30 s.")
senf78
  • 1,297
  • 2
  • 8
  • 4
  • Be aware that with this setup, MobileOrg sync causes pull, pull causes push, and push causes save. This should generally not be a problem, but could if for example your workflow includes reverting buffers (which it shouldn't). – senf78 Jul 11 '15 at 22:55
1

As a side solution, similar to Sandeep C's

;; for Emacs 24.3.1 insert next line
(require 'cl)  
;; automatically org-mobile-push on save of a file
(add-hook 
 'after-save-hook 
 (lambda ()
   (let (
         (org-filenames (mapcar 'file-name-nondirectory (directory-files org-directory))) ; list of org file names (not paths)
         (filename (file-name-nondirectory buffer-file-name)) ; list of the buffers filename (not path)
         )
     (if (find filename org-filenames :test #'string=)
         (org-mobile-push)        
       )
     )
   )
)
Community
  • 1
  • 1
Carlos López-Camey
  • 2,504
  • 1
  • 17
  • 20
1

I use this elisp code from gist on my init.el and it works pretty well, except it doesn't have org-mobile-pull built in.

tatsuhirosatou
  • 25,149
  • 14
  • 39
  • 40
  • This post http://kenmankoff.com/2012/08/17/emacs-org-mode-and-mobileorg-auto-sync/ also includes the part for pulling – xji May 04 '15 at 09:50
1

you can also push right after saving a note, like this:

(add-hook 
  'after-save-hook 
  (lambda () 
     (if (string= buffer-file-name "<path to my notes.org>") 
        (org-mobile-push)
     )
  ))
Sandeep Chayapathi
  • 1,490
  • 2
  • 13
  • 31
0

I opted to simply push when saving, so I added this to my emacs init file:

(defun org-mobile-push-on-save ()
  "Used in `after-save-hook'."
  (when (memq this-command '(save-buffer save-some-buffers))
    (org-mobile-push)))

(add-hook 'org-mode-hook
          (lambda ()
            (add-hook 'after-save-hook 'org-mobile-push-on-save nil 'make-local)))

In a nutshell, it adds an after-save-hook to org-mode buffers.

More info on the code:

For auto-pull, a timer as in other answers is probably a good way.

Community
  • 1
  • 1
felideon
  • 1,361
  • 1
  • 12
  • 21