#+HUGO_BASE_DIR: ../ #+SEQ_TODO: TODO DRAFT DONE #+PROPERTY: header-args :eval no * Blog Ideas * Emacs :@emacs: ** Elisp :elisp: *** DONE Do Ediff as I mean :ediff: :PROPERTIES: :EXPORT_FILE_NAME: do-ediff-as-i-mean :EXPORT_DATE: 2015-03-09T17:31:45-04:00 :END: *Update (2017/09/19)* Updated =modi/ediff-dwim= to the latest revision in my config. ----- In almost all of my =ediff= use cases, I would have windows open side-by-side in a frame, and then I would want to do a diff between the two using =ediff-buffers=. But emacs doesn't know that I obviously want to diff those two side-by-side buffers! So it always asks me to select the buffers to be diffed. The same problem is when using =ediff-files= too. So I came up with the following helper function to pick the correct =ediff= command. #+HUGO: more #+BEGIN_SRC emacs-lisp (defun modi/ediff-dwim () "Do ediff as I mean. If a region is active, call `ediff-regions-wordwise'. Else if the frame has 2 windows with identical major modes, - Do `ediff-files' if the buffers are associated to files and the buffers have not been modified. - Do `ediff-buffers' otherwise. Else if the current is a file buffer with a VC backend, call `vc-ediff' Else call `ediff-buffers'." (interactive) (let* ((num-win (safe-length (window-list))) (bufa (get-buffer (buffer-name))) (filea (buffer-file-name bufa)) (modea (with-current-buffer bufa major-mode)) bufb fileb modeb) (save-excursion (other-window 1) (setq bufb (get-buffer (buffer-name))) (setq fileb (buffer-file-name bufb)) (setq modeb (with-current-buffer bufb major-mode))) (cond ;; If a region is selected ((region-active-p) (call-interactively #'ediff-regions-wordwise)) ;; Else if 2 windows with same major modes ((and (= 2 num-win) (eq modea modeb)) (if ;; If either of the buffers is not associated to a file, ;; or if either of the buffers is modified (or (null filea) (null fileb) (buffer-modified-p bufa) (buffer-modified-p bufb)) (progn (message "Running (ediff-buffers \"%s\" \"%s\") .." bufa bufb) (ediff-buffers bufa bufb)) (progn (message "Running (ediff-files \"%s\" \"%s\") .." filea fileb) (ediff-files filea fileb)))) ;; Else if file in current buffer has a vc backend ((and filea (vc-registered filea)) (call-interactively #'vc-ediff)) ;; Else call `ediff-buffers' (t (call-interactively #'ediff-buffers))))) #+END_SRC [[https://github.com/search?utf8=%E2%9C%93&q=user:kaushalmodi+extension:el++"defun+modi/ediff-dwim"&type=Code][Find this function in my emacs config]]. ----- My favorite =ediff= settings are: #+BEGIN_SRC emacs-lisp ;; No separate frame for ediff control buffer (setq ediff-window-setup-function #'ediff-setup-windows-plain) ;; Split windows horizontally in ediff (instead of vertically) (setq ediff-split-window-function #'split-window-horizontally) #+END_SRC ** Org :@org: *** DONE Building Org Development version :development: :PROPERTIES: :EXPORT_FILE_NAME: building-org-development-version :EXPORT_DATE: 2017-07-22 :END: I am assuming that you already know what Org or [[http://orgmode.org/][org-mode]] is and that's why you are here. You would want to build Org from its development branch ([[http://orgmode.org/cgit.cgi/org-mode.git/log/][=master= branch]]) to get the latest and greatest goodies /plus/ bug fixes! Go through the [[http://orgmode.org/cgit.cgi/org-mode.git/tree/etc/ORG-NEWS][=ORG-NEWS=]] file to read about the new features. If you like what you see there, here are the steps for installing the development version of Org. #+HUGO: more **** Clone the Org repo #+BEGIN_SRC shell git clone http://orgmode.org/org-mode.git #+END_SRC /Unfortunately Org repo is not hosted on =https=./ **** Build Setup 1. Copy =/mk/default.mk= to =/local.mk= 2. Tweak =local.mk= ***** Customizing =local.mk= Here are few variables that you might like to change in the =local.mk=: - =prefix= :: Org installation directory #+BEGIN_SRC makefile prefix = /dir/where/you/want/to/install/org # Default: /usr/share #+END_SRC The =.el= files will go to =$(prefix)/emacs/site-lisp/org= by default. If you'd like to change that, change the =lispdir= variable. - =infodir= :: Org Info installation directory. I like to keep the Info file for development version of Org in a separate directory. #+BEGIN_SRC makefile infodir = $(prefix)/org/info # Default: $(prefix)/info #+END_SRC - =ORG_MAKE_DOC= :: Types of Org documentation you'd like to build by default. Below enables generation of the Info and PDF Org manuals and the Org reference cards (in PDF too). #+BEGIN_SRC makefile # Define below you only need info documentation, the default includes html and pdf ORG_MAKE_DOC = info pdf card # html #+END_SRC - =ORG_ADD_CONTRIB= :: Packages from the =contrib/= directory that you'd like to build along with Org. Below are the ones on my /must-have/ list. #+BEGIN_SRC makefile # Define if you want to include some (or all) files from contrib/lisp # just the filename please (no path prefix, no .el suffix), maybe with globbing # org-eldoc - Headline breadcrumb trail in minibuffer # ox-extra - Allow ignoring just the heading, but still export the body of those headings # org-mime - Convert org buffer to htmlized format for email ORG_ADD_CONTRIB = org-eldoc ox-extra org-mime #+END_SRC **** Build #+BEGIN_SRC shell make autoloads make make install #+END_SRC Type =make help= for help on the Org =Makefile=. Type =make helpall= to get a detailed help, or see the [[http://orgmode.org/worg/dev/org-build-system.html][Org build system help]]. **** Set the correct paths in your emacs config 1. Remove the default Org version that ships with Emacs from the =load-path=. Do the same if you have Org installed via Melpa/Org Elpa too (the latest stable versions). 2. Remove the older Org Info directory references too from =Info-directory-list=. 3. Update the =load-path= and =Info-directory-list= variables with values based on the =lispdir= and =infodir= variables above. Below snippet of code does all that -- Make sure this code is executed *after* you do =(package-initialize)=, but *before* you =require= the =org= package. #+BEGIN_SRC emacs-lisp (defvar modi/org-version-select 'dev "Variable to choose the version of Org to be loaded. Valid values are `dev', `elpa' and `emacs'. When set to `dev', the development version of Org built locally is loaded. When set to `elpa', Org is installed and loaded from Org Elpa. When set to `emacs', the Org version shipped with Emacs is used. The value is defaulted to `elpa' as few things in this config need Org version to be at least 9.x.") (defvar modi/default-lisp-directory "/your/emacs/share/dir/version/lisp/" "Directory containing lisp files for the Emacs installation. This value must match the path to the lisp/ directory of your Emacs installation. If Emacs is installed using --prefix=\"${PREFIX_DIR}\" this value would typically be \"${PREFIX_DIR}/share/emacs//lisp/\".") (defvar org-dev-lisp-directory "/value/of/lispdir/in/local.mk" "Directory containing lisp files for dev version of Org. This value must match the `lispdir' variable in the Org local.mk. By default the value is \"$prefix/emacs/site-lisp/org\", where `prefix' must match that in local.mk too.") (defvar org-dev-info-directory "/value/of/infodir/in/local.mk" "Directory containing Info manual file for dev version of Org. This value must match the `infodir' variable in the Org local.mk.") (with-eval-after-load 'package ;; If `modi/org-version-select' is *not* `emacs', remove the Emacs version of Org ;; from the `load-path'. (unless (eq modi/org-version-select 'emacs) ;; Remove Org that ships with Emacs from the `load-path'. (dolist (path load-path) (when (string-match-p (expand-file-name "org" modi/default-lisp-directory) path) (setq load-path (delete path load-path))))) ;; If `modi/org-version-select' is *not* `elpa', remove the Elpa ;; version of Org from the `load-path'. (unless (eq modi/org-version-select 'elpa) (dolist (org-elpa-install-path (directory-files-recursively ;Requires emacs 25+ package-user-dir "\\`org\\(-plus-contrib\\)*-[0-9.]+\\'" :include-directories)) (setq load-path (delete org-elpa-install-path load-path)) ;; Also ensure that the associated path is removed from Info ;; search list. (setq Info-directory-list (delete org-elpa-install-path Info-directory-list)))) (if (eq modi/org-version-select 'dev) ;; It's possible that `org-dev-info-directory' is set to an ;; unconventional value, in which case, it will not be automatically ;; added to `Info-directory-alist'. So to ensure that the correct Org ;; Info is used, add this variable to `Info-directory-alist' manually. (add-to-list 'Info-directory-list org-dev-info-directory) ;; If `modi/org-version-select' is *not* `dev', remove the development ;; version of Org from the `load-path'. (dolist (path load-path) (when (string= org-dev-lisp-directory path) (setq load-path (delete path load-path)))) (with-eval-after-load 'info ;; Also ensure that the associated path is removed from Info search list. (setq Info-directory-list (delete org-dev-info-directory Info-directory-list))))) #+END_SRC To simplify the "before you =require= the =org= package" part, if using the [[https://github.com/jwiegley/use-package][=use-package=]], above code would go in /HERE/: #+BEGIN_SRC emacs-lisp (use-package org :preface ) #+END_SRC *Note*: Remember that you need to correctly set the values of these 3 variables in the above snippet: - =modi/default-lisp-directory= - =org-dev-lisp-directory= - =org-dev-info-directory= ***** Related Emacs package manager customization (Bonus Points) You can refer to my [[https://github.com/kaushalmodi/.emacs.d/blob/master/setup-packages.el][=setup-packages.el=]] to see how to fine-tune the Emacs package manager setup to work well with the development version of Org. - Prevent adding Org Elpa to =package-archives=. - Prevent auto-installation of the older versions of Org triggered by package-dependency checks. - Even if you install Org from (M)Elpa, do not prompt to upgrade it (as you would be rocking the shiniest and newest version of Org from its =master= branch from now on! :smile:). /Search for =modi/org-version-select= in there./ **** Testing that the right Org got loaded 1. *Restart Emacs* (/Don't be lazy -- do it./) 2. =M-x org-version= -- That should show something like this in the echo area: #+BEGIN_EXAMPLE Org mode version 9.0.9 (release_9.0.9-648-gc56021 @ /home/kmodi/usr_local/apps/6/emacs/master/share/emacs/site-lisp/org/) #+END_EXAMPLE This message format is broken down as: #+BEGIN_EXAMPLE Org mode version (release_-???-g @ /emacs/site-lisp/org/) #+END_EXAMPLE If the =GIT-HASH= and =PREFIX= match to your expectations, congratulations! Else, please let me know in comments if I can help you. **** Future Org development version updates 1. Below will do =git pull= and build Org. #+BEGIN_SRC shell make update #+END_SRC 2. Restart Emacs. * COMMENT Local Variables :ARCHIVE: # Local Variables: # fill-column: 70 # eval: (auto-fill-mode 1) # org-refile-targets: nil # eval: (add-hook 'after-save-hook #'org-hugo-export-subtree-to-md-after-save :append :local) # org-hugo-footer: "\n\n[//]: # \"Exported with love from a post written in Org mode\"\n[//]: # \"- https://github.com/kaushalmodi/ox-hugo\"" # End: