I’m happy a Vim user since 2011, when I started my vimfiles. The ergonomics of talking to your editor to make changes is amazing. And build up your skills as acquiring a new language is magical.
Recently, the need to manage tasks from different contexts makes me wonder if the so-called OrgMode is so helpful as its fandom sells.
Looking for a implementation of Org for Vim I found some projects in a Reddit thread:
- vim-orgmode
- UNMAINTAINED
- VimOrganizer
- ABANDONED
- org.vim
- Aims to provide only syntaxe highlight
- VIM Do Too
- Inpired by OrgMode to provide a, promissing, taks manager for Vim
But, they are either abandoned or, only, inspired by. Instead of a, intentionally, compatible port. Before I know if the current ports is good enough for my needs, I need to know what the original actually have.
So, this how I ended up trying to use emacs as my main editor.
This is not an Emacs Tutorial. But, a description of my attempt to learn if Org Mode worth the cost of migration from Vim. I’m not arrogant enough to think I can teach someone how to use emacs.
Vim ubiquitousity is another reason I like it so much. Any new computer is one git clone behind of my environment. Thankfully it’s not that hard to install emacs.
sudo apt install emacs git
cd ~
git clone https://github.com/acdesouza/emacs-config.git .emacs.d/
emacs
First time you open emacs it will download all, uninstalled, packages.
The default emacs from Homebrew has a very annoying random flicker. To prevent me lost my mind I followed the conorfoley suggestion to use railwaycat/homebrew-emacsmacport
brew install --cask emacs-mac
Emacs rely on GNU tools for some basic features, like directory listing. Since MacOS is not GNU-based its src_sh{ls} lacks support for src_sh{–dired} and src_sh{–group-directories-first}.
This means you need to install GNU Coreutils in MacOS. I use homebrew for that:
brew install coreutils
Brew will install it with a G, for GNU, prefix. So, you can gls instead of ls.
After some time, even emacs modes, got some updates. To make sure you’re running the latest versions once in a while update them.
- M-x list-packages :: Open emacs and list all available packages
- Wait for it updating the packages
- S-u :: Mark the new packages to update
- x :: Command the update of marked packages
I intend to describe my current workflow with emacs bindings association in its own file.
In order to provide context this is my workflow tl;dr overview:
- Read the messages in the company chat(usually, Slack) and emails looking for new tasks
- Add new discovered tasks in the To Do list.
- See the list of tasks to do
- Pick one task
- Launch the code editor and open the project directory
- Open the file to change. If more than one file is needed I vertically split and open both
- Split horizontally and open the related test above the file to change
- Make the change. Go to the terminal an run that test
- Passing: git commit
- Fail: go back to editor to fix the test
- At the end of the task close all files and start over.
I mainly work with web projects build with Ruby on Rails, HTML, JavaScript and CSS. I try to keep as vanilla as I can. But, for some projects I need things like SCSS and the ruby Slim template.
So,the whys, behind the howtos, are:
- Select one, and only one task, to prevent context switch
- See all artifacts I’m dealling with, in order to maintaing focus on the task at hand
I’m missing a way to store the new tasks and errands with minimum distraction. The Org Mode Capture seems the Dumbledore’s Pensieve. Exactly what I’m looking for.
- Shows line number and line:column position
- Hides initial message, menu, toolbar, scrollbar, and percentage position
- Stop playing hide-and-seek. Scroll only one line. And don’t wrap long lines
- Don’t ever use TAB character(ASCII byte #9). Update it to spaces
- Use 4 spaces for indentation
- Update buffer with modified files outside emacs
- I get used with Menlo, so it’s my first choice for programming
- I follow every recommendation of moving changes made by Emacs Easy Customization Tool to its own file. But, to be honest, I tried it few times. And don’t have any opinion.
- Highlight the matching parentheses when cursor is over one of then
A mode is a piece of software enhancing emacs capabilities. Enabled by the buffer content. Everyone else will call it a plugin.
These are the modes I found to support the aforementioned workflow.
- Org Mode
- The reason I’m trying emacs. For now, I’m focus in Task Management, OrgCapture, and OrgAgenda
- evil-mode
- Vim user, remember? So, I fell more comfortable to talk to the editor in order to modify the files.
- ido
- I really appreciate CtrlP. And I don’t have an opinion on Helm and Ivy. So, I starting with stock as much as I can.
- dired-sidebar
- Because, sometimes, you don’t remember the file name, but has a clue looking at the directories.
- dumb-jump
- Often I need to find a definition of a variable/method/class. This mode works as a grep backend for xref to resume my previous steps:
- grep for it in the project root.
- Copy the full path
- Paste in the open file dialog.
- projectile
- After opening the project root directory, I rarely change directory. So, having a way to scope grep and find is helpful.
- ruby-mode
- Default to emacs. I tried the Enhanced Ruby Mode. But, I could see a ruby file been painting.
- ruby-electric
- Autoclose paired syntax elements like parens, quotes, etc
- projectile-rails
- Especialization of projectile to handle rails project. Like search Model/Controller/View related to current file and alternate between code and test.
- rvm
- Point emacs to use the project’s correct ruby version and gemset. Useful for apply rubocop rules and open a rails console.
- yaml-mode
- Syntax highlight and correct indentation
- slim-mode
- Syntax highlight and correct indentation
- sass-mode
- Syntax highlight and correct indentation
- haml-mode
- Dependency of sass-mode
- web-mode
- Works for HTML, CSS, and JavaScript. Syntax highlight, correct indentation, insert tag, and matching parentheses/tags
- Help..................: C-h C-h
- Find command by key.: c
- Find command desc…: F
- Describe key..........: C-h k C-n tells you what C-n does
- Numeric Argument......: M-NUMBER <key binding>: M-5 C-o creates 5 empty lines
- Open emacs manual.....: C-h i (info)
- Display packages......: C-h p (describe-package)
- Display key bidings…: C-h b
- Describe function under cursor.,,,.: C-h f<RET>
- Find a command containing PATTERN..: C-h a <PATTERN><RET>
- Following the conventions for naming Emacs commands, here are some
words that you’ll find useful in apropos patterns. By using them in ‘C-h a’, you will also get a feel for the naming conventions.
char, line, word, sentence, paragraph, region, page, sexp, list, defun, rect, buffer, frame, window, face, file, dir, register, mode, beginning, end, forward, backward, next, previous, up, down, search, goto, kill, delete, mark, insert, yank, fill, indent, case, change, set, what, list, find, view, describe, default.
- Open file.............: C-x C-f (find-file)
- Open new buffer.......: C-x b using a new buffer name
- Switch to buffer......: C-x b (switch-to-buffer)
- Save buffer...........: C-x C-s (save-buffer)
- Close(kill) buffer....: C-x k (kill-buffer)
- Save all and close....: C-x C-c (save-buffers-kill-terminal)
- Cancel a prefix.......: C-g
- Incremental Search....: C-s <TERM>
- Backward search.......: C-r <TERM>
- RegExpe Search........: C-M-s <REGEXP>
The Xref
I’m using Dumb Jump as backend. It’s bind to gd
- Go to definition......: M-. (xref-find-definitions)
- Back from definition..: M-, (xref-pop-marker-stack)
Inside \*xref\* buffer:
- Open previous ref.....................: p OR , (xref-previous-line)
- Open next ref.........................: n OR . (xref-next-line)
- Open current ref and close \*xref\*…: TAB (xref-quit-and-goto-xref)
- Close \*xref\* buffer.................: q (xref-quit)
- Replace...............................: r pattern RET new_value // NOT WORKING
- Move to other frame…: C-x 5 o (other-frame)
- Next page.............: C-v (scroll-up)
- Previous page.........: M-v (scroll-down)
- Center page on cursor.: C-l (recenter-top-bottom)
- Split horizontal......: C-x 2 (split-window-below)
- Split vertical........: C-x 3 (split-window-right)
- Close current window..: C-x 0 (delete-window)
- Close other windows…: C-x 1 (delete-other-windows)
- Move to other window..: C-x o (other-window)
- Go to top.............: M-< (beginning-of-buffer)
- Next page.............: C-v (scroll-up)
- Center page on cursor.: C-l (recent-top-bottom)
- Previous page.........: M-v (scroll-down)
- Go to bottom..........: M-> (end-of-buffer)
- Increase font.........: C-x C-= (text-scale-adjust)
- Decrease font.........: C-x C– (text-scale-adjust)
- Go to line............: M-g g LineNumber
- Go to begin of line…: C-a (move-beginning-of-line)
- Go to end of line.....: C-e (move-end-of-line)
- Go one word forward…: M-f (forward-word)
- Go one word backward..: M-b (backward-word)
- Open file.............: C-x C-f (find-file)
- Open new buffer.......: C-x b using a new buffer name
- Save buffer...........: C-x C-s (save-buffer)
- Switch to buffer......: C-x b (switch-to-buffer)
- Close(kill) buffer....: C-x k (kill-buffer)
- Increase font.........: C-x C-=
- Decrease font.........: C-x C–
- Undo.......................: C-x u (undo)
- Yank(paste latest kill)..,.: C-y (yank)
- Rotate to previous kills.: M-y (yank-pop)
- Add new line after cursor....: C-o (open-line)
- Delete to the end of line....: C-k (kill-line)
- Delete whole line............: C-S-backspace (kill-whole-line)
- Delete word forward........: M-d (kill-word)
- Delete word backward.......: M-<DEL> (backward-kill-word)
- Kill until Char............: M-z CHAR (zap-to-char)
- M-x align-regexp RET = RET
- Align the `=` sign on a list of variables
FROM
a = 1 potato = 2 closest = 5
TO
a = 1 potato = 2 closest = 5
- Columnize hashes
- Align Ruby hashes or JSON objects
- Select text:
- Using Shift+Arrow keys
- Go to the beginning.: C-<SPC>
- Go to the ending....: C-x C-x (exchange-point-and-mark)
- Also use it to move to the beginning or end of the mark
- Cancel selecion...................: C-g
- Search and replace marked region..: M-% (query-replace)
- Kill the region...................: C-w (kill-region)
- Kill and save(cut) region.........: M-w (kill-ring-region)
- Toggle comment on region..........: \c (comment-or-uncomment-region)
- Select text:
- Go to the beginning…: C-x-<SPC> move with arrows to the end
- Insert text...........: M-x string-insert-rectangle<RET> STRING<RET>
- Replace text..........: C-x r t STRING<RET>
- Kill rectangle........: C-x r k (kill-rectangle)
- Yank killed rectangle.: C-x r y (yank-rectangle)
- Mark a word........: M-@ (mark-word)
- Mark a paragraph…: M-h (mark-paragraph)
- Mark defun.........: C-M-h (mark-defun) # Mark a function/method
- Call Command by Name..: M-x (execute-extended-command)
- To call a Command N times..: M-<times> M-x
- Previous used.........: M-p
- Next used.............: M-n
- Evaluate expression…: C-j
- Complete the word.: C-M-/ (dabbrev-completion)
- Expand the word…: M-/ (dabbrev-expand)
- Open ..................: C-x d (ido-dired)
- Open in minibuffer.....: C-x C-f (ido-find-file)
- Open in another window.: C-x 4 d (dired-other-window)
- Quit ..................: q (quit-window)
- Mark file under cursor..........: m
- Mark files with regexp..........: % m regexp<RET>
- Remove file under cursor mark…: u
- Remove all file marks...........: U
- Copy marked/file under cursor…: C
- Move marked/file under cursor…: R
- Delete marked/file under cursor.: D
- Add subdirectory................: +
Mode prefix: C-c p
- Go to project..................: C-c p p (projectile-switch-project)
- Find file in project...........: C-c p f (projectile-find-file)
- Toggle Implementation<->Test…: C-c p t (projectile-toggle-between-implementation-and-test)
- Switch to the previous project buffer..: C-c p left
- Switch to the next project buffer......: C-c p right
- Close project’s buffers................: C-c p k (projectile-kill-buffers)
Mode prefix: C-c r
- Go to view template for current controller action…: C-c r V
- Go to controller from current view..................: C-c r C
- Go to a test connected with the current resource....: C-c r T
- Open rails console..................................: C-c r r
- Open rails server...................................: C-c r R
- See web-mode-expanders, web-mode-engines-snippets
- Add Rails Scriptlet…:
/ for <%
| %> -/ for <% | %>
Emacs Org-mode - a system for note-taking and project planning
- Open/shut .....: TAB (org-cycle)
- Toggle all.....: C-u TAB
- Toggle checkbox when checkbox under cursor
- Add tags to heading when heading under cursor
- Next heading.......: C-c C-n (org-next-visible-heading)
- Previous heading…: C-c C-p (org-previous-visible-heading)
- Next same level heading.......: C-c C-f (org-forward-heading-same-level)
- Previous same level heading…: C-c C-b (org-backward-heading-same-level)
- Edit....: C-c C-l
- Open....: C-c C-o
- Back....: C-c &
* TODO Create a todo list [%]
- [ ] [/] First item of the todo list
- [ ] Think what you have todo
- [ ] Write it down
- [ ] [/] Priorization
- [ ] If can do only one thing and drop all others? It's the first item.
- [ ] Imagine you did the first item. What else?
- Add new item same level....: M-RET (org-meta-return)
- Add new item with TODO key.: M-S-RET (org-insert-todo-heading)
- Promote subtree one level..: M-S-LEFT (org-promote-subtree)
- Demote subtree one level…: M-S-RIGHT (org-demote-subtree)
- Move subtree up............: M-UP (org-move-subtree-up)
- Move subtree down..........: M-DOWN (org-move-subtree-down)
- Select subtree.............: C-c @ (org-mark-subtree) ;; Repeat to select next same level subtree
- Clone subtree..............: C-c C-x c (org-clone-subtree-with-time-shift)
- Toggle checkbox............: C-c C-c (org-toggle-checkbox)
- Add tag from TAGS list..: C-c C-c
- Add arbitrary tag.......: C-c C-q (org-set-tags-command)
- Search tags.............: C-c / (org-match-sparse-tree)
- Add a list of available properties: #+PROPERTY: PropertyName_ALL Opt1 Opt2 “Opt 3”
- Cycle through property options: S-LEFT or S-RIGHT ()
- Add a property.........: C-c C-x p (org-set-property)
- In the property DRAWER.: C-c C-c show Properies actions
- TIMESTAMP
- An appointment to that date/time
- SCHEDULE
- Something you’d like to start at a date/time
- DEADLINE
- Something you’d like to finish by a date/time
- Add a timestamp.............................: C-c . (org-time-stamp)
- Move timestamp back and forth...............: S-LEFT S-RIGHT
- Calculate total days between 2 timestamps…: C-c C-y (org-evaluate-time-range)
- Add a DEADLINE..............................: C-c C-d (org-deadline)
- Add a SCHEDULE..............................: C-c C-s (org-schedule)
- Capture .............................: C-c c (org-capture)
- Move TODO at point to another file…: C-c C-w (org-refile)
Creates a file.org_archive file with the archived TODO items https://orgmode.org/manual/Moving-subtrees.html#Moving-subtrees
- Archive a TODO in the same file…: C-c C-x A (org-archive-to-archive-sibling)
- Archive to a new file.............: C-c $ (org-archive-subtree)
- Open Archive headline.............: C-TAB (org-force-cycle-archived)
- Open agenda............: C-c a (org-agenda)
- Show next 7 days.......: a
- Go to previous week....: b (org-agenda-earlier)
- Go to current week.....: . (org-agenda-goto-today)
- Go to next week........: f (org-agenda-later)
- Change TODO status.....: t (org-agenda-todo)
- Goto TODO at point.....: TAB (org-agenda-goto)
- Postpone a heading.....: S-Right (org-agenda-do-date-later)
- Save all orgs files....: s (org-save-all-org-buffers)
- Refresh the agenda.....: r (org-agenda-redo)
- Exit agenda window.....: x (org-agenda-exit)