Steve Losh avatar Steve Losh committed d9b936c

Initial commit (MIT License).

Comments (0)

Files changed (3)

+Copyright (C) 2011 by Steve Losh
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this
+software and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be included in all copies
+or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
+A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+keymando-vim
+============
+
+This Keymando plugin adds a Vim-like editing mode everywhere (with a few apps
+excluded).  To try it out, open TextEdit and play with it.
+
+It's still pretty rough at the moment -- most edge cases aren't handled properly.
+Pasting in particular is not properly working yet.
+
+Current Features
+----------------
+
+Keymando-vim has several modes, each with their own bindings (just like Vim).
+
+**Note:** until keymando-vim hits 1.0.0 everything is subject to change in lots of
+backwards-incompatible ways.  Use it at your own risk.
+
+### Any Mode
+
+    <M-Esc> - Toggle keymando-vim off and on.  Requires `growlnotify` for alerts.
+
+### Insert Mode
+
+    <Esc> - Switch to normal mode.
+    <C-[> - Switch to normal mode.
+
+### Normal Mode
+
+    h/j/k/l - Left/down/up/right.
+
+    w - Move one word forward.
+    b - Move one word back.
+    e - Move to the next "end of word".
+    0 - Move to the beginning of the line.
+
+    i - Enter insert mode here.
+    a - Enter insert mode after the character to the right of the cursor.
+    A - Move to the end of the line and enter insert mode.
+    I - Move to the beginning of the line and enter insert mode.
+    o - Add a new line below this one and enter insert mode in it.
+    O - Add a new line above this one and enter insert mode in it.
+
+    d<text object> - Delete the given text object.
+    c<text object> - Delete the given text object.
+
+    dd - Delete the current line.
+    cc - Remove all text on the current line and enter insert mode in it.
+
+    p - Paste the cut line after the current one.
+    P - Paste the cut line before the current one.
+
+    u     - Undo.
+    <C-r> - Redo.
+
+    x - Delete the character to the right of the cursor.
+    s - Delete the character to the right of the cursor and enter insert mode.
+
+### Text Objects
+
+    w - From the cursor to next "word beginning".
+    b - From the cursor backwards to the previous "word beginning".
+class Vim < Plugin
+  @oldmode = 'n'
+  @mode = 'n'
+  @maps = {}
+
+  class << self; attr_accessor :mode, :maps, :oldmode; end
+
+  def before
+  end
+
+  def fire(key)
+      fn = Vim.maps[Vim.mode][key]
+      if fn
+          fn.call()
+      else
+          send(key)
+      end
+  end
+
+  def tomode(m)
+      oldmap = Vim.maps[Vim.mode]
+      newmap = Vim.maps[m]
+
+      oldmap.keys.each do |k|
+          #unmap k
+      end
+
+      newmap.keys.each do |k|
+          #map(k, lambda { self.fire(k) })
+      end
+  end
+
+  def toggle()
+      if Vim.mode == 'disabled'
+          Vim.mode = Vim.oldmode
+          system '/usr/local/bin/growlnotify -m "" -a Keymando Vim mode enabled.'
+      else
+          Vim.oldmode = Vim.mode
+          Vim.mode = 'disabled'
+          system '/usr/local/bin/growlnotify -m "" -a Keymando Vim mode disabled.'
+      end
+  end
+
+  def after
+      except /iTerm/, /MacVim/, /Firefox/, /PeepOpen/, /Quicksilver/, /1Password/ do
+          Vim.maps['disabled'] = {}
+          Vim.maps['n'] = {
+              'h' => lambda { send("<Left>") },
+              'j' => lambda { send("<Down>") },
+              'k' => lambda { send("<Up>") },
+              'l' => lambda { send("<Right>") },
+
+              'w' => lambda { send("<Alt-Right><Alt-Right><Alt-Left>") },
+              'b' => lambda { send("<Alt-Left>") },
+              'e' => lambda { send("<Alt-Right>") },
+              '0' => lambda { send("<Cmd-Left>") },
+
+              'i' => lambda { Vim.mode = 'i' },
+              'a' => lambda { Vim.mode = 'i'; send("<Right>") },
+              'A' => lambda { Vim.mode = 'i'; send("<Ctrl-e>") },
+              'I' => lambda { Vim.mode = 'i'; send("<Ctrl-a>") },
+              'o' => lambda { Vim.mode = 'i'; send("<Cmd-Right><Return>") },
+              'O' => lambda { Vim.mode = 'i'; send("<Cmd-Left><Return><Up>") },
+
+              'd' => lambda { Vim.mode = 'od' },
+              'c' => lambda { Vim.mode = 'oc' },
+
+              'p' => lambda { send("<Cmd-Left><Down><Cmd-v>") },
+              'P' => lambda { send("<Cmd-Left><Cmd-v>") },
+
+              'u' => lambda { send("<Cmd-z>") },
+              '<Ctrl-R>' => lambda { send("<Shift-Cmd-z>") },
+
+              'x' => lambda { send("<Shift-Right><Cmd-x>") },
+              's' => lambda { send("<Shift-Right><Cmd-x>"); Vim.mode = 'i' },
+
+              '<Escape>' => lambda { send("<Escape>") },
+          }
+          Vim.maps['i'] = {
+              '<Ctrl-[>' => lambda { Vim.mode = 'n' },
+              '<Escape>' => lambda { Vim.mode = 'n' },
+          }
+          Vim.maps['od'] = {
+              'w'  => lambda { send("<Shift-Alt-Right><Cmd-x>"); Vim.mode = 'n' },
+              'b'  => lambda { send("<Shift-Alt-Left><Cmd-x>"); Vim.mode = 'n' },
+              'd'  => lambda { send("<Cmd-Left><Shift-Down><Cmd-x>"); Vim.mode = 'n' },
+
+              #'iw' => lambda { send("<Alt-Right><Shift-Alt-Left><Delete>"); Vim.mode = 'n' },
+
+              '<Escape>' => lambda { Vim.mode = 'n' },
+          }
+          Vim.maps['oc'] = {
+              'w' => lambda { send("<Shift-Alt-Right><Cmd-x>"); Vim.mode = 'i' },
+              'b'  => lambda { send("<Shift-Alt-Left><Cmd-x>"); Vim.mode = 'i' },
+              'c' => lambda { send("<Cmd-Left><Shift-Down><Cmd-x><Return><Up>"); Vim.mode = 'i' },
+
+              #'iw' => lambda { send("<Alt-Right><Shift-Alt-Left><Delete>"); Vim.mode = 'i' },
+
+              '<Escape>' => lambda { Vim.mode = 'n' },
+          }
+
+          keys = Vim.maps.values.reduce([]) do |l, m|
+              l = l + m.keys
+          end
+          keys.uniq.each do |k|
+              map(k, lambda { self.fire(k) })
+          end
+      end
+
+      map "<Alt-Escape>", lambda { self.toggle }
+  end
+end
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.