Emacs vs Sublime Text on Salesforce development

  |   Source

Our client decided to move their legacy system to a cloud platform called salesforce.com. So I got a chance to investigate how to deploy code to the salesforce server inside Emacs and Sublime Text.

Salesforce provides a migration tool to deploy everything from the scratch which takes about 2 minutes. Basically makes it impossbile to be integrated with text editors.

Luckily, there is Force.com CLI which can upload single file in a few seconds. Both Sublime Text and Emacs use this tool.

Sublime Text

You need install sublime text plugin mavensmate. After installation, you need click Login menu at least once. Then when you save the code file, it's automatically deployed to the server.

For some reason, the logged in session will timeout after a couple minutes. So you need re-login. Sometimes deployment will fail, you could click the Fetch menu and fill in the component name into the popup window to confirm the fetch. Fetching will re-activate upload ability.

Mavensmate is actually just GUI wrapper of Force.com CLI,

  • When you click login, the command force login is executed
  • When saving file, force aura push or force push is executed
  • When fetching, force fetch is executed


In Sublime Text I have to re-login and fetch from time to time. That get me distracted. I prefer executing only one commmand to upload the file in editing. That command should be always successful.

My solution is to combine "login/fetch/push" commnands into one liner which is stored in a file local variable compile-command. So when I execute M-x compile, the commands "login/fetch/push" in compile-command will all be executed sequentially. So I don't need care about login and fetch things any more.

Here is my setup,

(defun my-setup-develop-environment ()
  (let (ffip-project-root)
    (setq ffip-project-root "~/projects/my-salesforce-project1")

    (when (memq major-mode '(web-mode js-mode js2-mode))
      (setq-local compile-command
                   ;; lightning controller javascript file
                   ((string-match "Controller\.js$" (buffer-file-name))
                    (format "force login -i=test -u=username@salesforce.com -p=password1; cd %s && cp %s %s && force fetch -t Aura -n %s -d %s && mv %s %s && force aura push -f %s"
                            (buffer-file-name) (concat (buffer-file-name) ".bak")
                            (replace-regexp-in-string "Controller" "" (file-name-base (buffer-file-name)))
                            (concat (buffer-file-name) ".bak") (buffer-file-name)
                   ;; ant build
                   ((string-match "build\.xml$" (buffer-file-name))
                    (format "cd %s && ant deployCode" ffip-project-root))
                   ;; lightning html view
                   ((string-match "\.cmp$" (buffer-file-name))
                    (format "force login -i=test -u=username@salesforce.com -p=password1; cd %s && force aura push -f %s"
                   ;; other salesforce pages
                    (format "force login -i=test -u=username@salesforce.com -p=password1; cd %s && force push -f %s"

;; I use web-mode for html/xml
(add-hook 'web-mode-hook 'my-setup-develop-environment)
;; I use js2-mode for javascript
(add-hook 'js2-mode-hook 'my-setup-develop-environment)
Comments powered by Disqus