ace.define("ace/keyboard/sublime", ["require", "exports", "module", "ace/keyboard/hash_handler"], function (require, exports, module) {
  "use strict";

  var HashHandler = require("../keyboard/hash_handler").HashHandler;

  function moveBySubWords(editor, direction, extend) {
    var selection = editor.selection;
    var row = selection.lead.row;
    var column = selection.lead.column;
    var line = editor.session.getLine(row);

    if (!line[column + direction]) {
      var method = (extend ? "selectWord" : "moveCursorShortWord") + (direction == 1 ? "Right" : "Left");
      return editor.selection[method]();
    }

    if (direction == -1) column--;

    while (line[column]) {
      var type = getType(line[column]) + getType(line[column + direction]);
      column += direction;

      if (direction == 1) {
        if (type == "WW" && getType(line[column + 1]) == "w") break;
      } else {
        if (type == "wW") {
          if (getType(line[column - 1]) == "W") {
            column -= 1;
            break;
          } else {
            continue;
          }
        }

        if (type == "Ww") break;
      }

      if (/w[s_oW]|_[sWo]|o[s_wW]|s[W]|W[so]/.test(type)) break;
    }

    if (direction == -1) column++;
    if (extend) editor.selection.moveCursorTo(row, column);else editor.selection.moveTo(row, column);

    function getType(x) {
      if (!x) return "-";
      if (/\s/.test(x)) return "s";
      if (x == "_") return "_";
      if (x.toUpperCase() == x && x.toLowerCase() != x) return "W";
      if (x.toUpperCase() != x && x.toLowerCase() == x) return "w";
      return "o";
    }
  }

  exports.handler = new HashHandler();
  exports.handler.addCommands([{
    name: "find_all_under",
    exec: function exec(editor) {
      if (editor.selection.isEmpty()) editor.selection.selectWord();
      editor.findAll();
    },
    readOnly: true
  }, {
    name: "find_under",
    exec: function exec(editor) {
      if (editor.selection.isEmpty()) editor.selection.selectWord();
      editor.findNext();
    },
    readOnly: true
  }, {
    name: "find_under_prev",
    exec: function exec(editor) {
      if (editor.selection.isEmpty()) editor.selection.selectWord();
      editor.findPrevious();
    },
    readOnly: true
  }, {
    name: "find_under_expand",
    exec: function exec(editor) {
      editor.selectMore(1, false, true);
    },
    scrollIntoView: "animate",
    readOnly: true
  }, {
    name: "find_under_expand_skip",
    exec: function exec(editor) {
      editor.selectMore(1, true, true);
    },
    scrollIntoView: "animate",
    readOnly: true
  }, {
    name: "delete_to_hard_bol",
    exec: function exec(editor) {
      var pos = editor.selection.getCursor();
      editor.session.remove({
        start: {
          row: pos.row,
          column: 0
        },
        end: pos
      });
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor"
  }, {
    name: "delete_to_hard_eol",
    exec: function exec(editor) {
      var pos = editor.selection.getCursor();
      editor.session.remove({
        start: pos,
        end: {
          row: pos.row,
          column: Infinity
        }
      });
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor"
  }, {
    name: "moveToWordStartLeft",
    exec: function exec(editor) {
      editor.selection.moveCursorLongWordLeft();
      editor.clearSelection();
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor"
  }, {
    name: "moveToWordEndRight",
    exec: function exec(editor) {
      editor.selection.moveCursorLongWordRight();
      editor.clearSelection();
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor"
  }, {
    name: "selectToWordStartLeft",
    exec: function exec(editor) {
      var sel = editor.selection;
      sel.$moveSelection(sel.moveCursorLongWordLeft);
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor"
  }, {
    name: "selectToWordEndRight",
    exec: function exec(editor) {
      var sel = editor.selection;
      sel.$moveSelection(sel.moveCursorLongWordRight);
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor"
  }, {
    name: "selectSubWordRight",
    exec: function exec(editor) {
      moveBySubWords(editor, 1, true);
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor",
    readOnly: true
  }, {
    name: "selectSubWordLeft",
    exec: function exec(editor) {
      moveBySubWords(editor, -1, true);
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor",
    readOnly: true
  }, {
    name: "moveSubWordRight",
    exec: function exec(editor) {
      moveBySubWords(editor, 1);
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor",
    readOnly: true
  }, {
    name: "moveSubWordLeft",
    exec: function exec(editor) {
      moveBySubWords(editor, -1);
    },
    multiSelectAction: "forEach",
    scrollIntoView: "cursor",
    readOnly: true
  }]);
  [{
    bindKey: {
      mac: "cmd-k cmd-backspace|cmd-backspace",
      win: "ctrl-shift-backspace|ctrl-k ctrl-backspace"
    },
    name: "removetolinestarthard"
  }, {
    bindKey: {
      mac: "cmd-k cmd-k|cmd-delete|ctrl-k",
      win: "ctrl-shift-delete|ctrl-k ctrl-k"
    },
    name: "removetolineendhard"
  }, {
    bindKey: {
      mac: "cmd-shift-d",
      win: "ctrl-shift-d"
    },
    name: "duplicateSelection"
  }, {
    bindKey: {
      mac: "cmd-l",
      win: "ctrl-l"
    },
    name: "expandtoline"
  }, {
    bindKey: {
      mac: "cmd-shift-a",
      win: "ctrl-shift-a"
    },
    name: "expandSelection",
    args: {
      to: "tag"
    }
  }, {
    bindKey: {
      mac: "cmd-shift-j",
      win: "ctrl-shift-j"
    },
    name: "expandSelection",
    args: {
      to: "indentation"
    }
  }, {
    bindKey: {
      mac: "ctrl-shift-m",
      win: "ctrl-shift-m"
    },
    name: "expandSelection",
    args: {
      to: "brackets"
    }
  }, {
    bindKey: {
      mac: "cmd-shift-space",
      win: "ctrl-shift-space"
    },
    name: "expandSelection",
    args: {
      to: "scope"
    }
  }, {
    bindKey: {
      mac: "ctrl-cmd-g",
      win: "alt-f3"
    },
    name: "find_all_under"
  }, {
    bindKey: {
      mac: "alt-cmd-g",
      win: "ctrl-f3"
    },
    name: "find_under"
  }, {
    bindKey: {
      mac: "shift-alt-cmd-g",
      win: "ctrl-shift-f3"
    },
    name: "find_under_prev"
  }, {
    bindKey: {
      mac: "cmd-g",
      win: "f3"
    },
    name: "findnext"
  }, {
    bindKey: {
      mac: "shift-cmd-g",
      win: "shift-f3"
    },
    name: "findprevious"
  }, {
    bindKey: {
      mac: "cmd-d",
      win: "ctrl-d"
    },
    name: "find_under_expand"
  }, {
    bindKey: {
      mac: "cmd-k cmd-d",
      win: "ctrl-k ctrl-d"
    },
    name: "find_under_expand_skip"
  }, {
    bindKey: {
      mac: "cmd-alt-[",
      win: "ctrl-shift-["
    },
    name: "toggleFoldWidget"
  }, {
    bindKey: {
      mac: "cmd-alt-]",
      win: "ctrl-shift-]"
    },
    name: "unfold"
  }, {
    bindKey: {
      mac: "cmd-k cmd-0|cmd-k cmd-j",
      win: "ctrl-k ctrl-0|ctrl-k ctrl-j"
    },
    name: "unfoldall"
  }, {
    bindKey: {
      mac: "cmd-k cmd-1",
      win: "ctrl-k ctrl-1"
    },
    name: "foldOther",
    args: {
      level: 1
    }
  }, {
    bindKey: {
      win: "ctrl-left",
      mac: "alt-left"
    },
    name: "moveToWordStartLeft"
  }, {
    bindKey: {
      win: "ctrl-right",
      mac: "alt-right"
    },
    name: "moveToWordEndRight"
  }, {
    bindKey: {
      win: "ctrl-shift-left",
      mac: "alt-shift-left"
    },
    name: "selectToWordStartLeft"
  }, {
    bindKey: {
      win: "ctrl-shift-right",
      mac: "alt-shift-right"
    },
    name: "selectToWordEndRight"
  }, {
    bindKey: {
      mac: "ctrl-alt-shift-right|ctrl-shift-right",
      win: "alt-shift-right"
    },
    name: "selectSubWordRight"
  }, {
    bindKey: {
      mac: "ctrl-alt-shift-left|ctrl-shift-left",
      win: "alt-shift-left"
    },
    name: "selectSubWordLeft"
  }, {
    bindKey: {
      mac: "ctrl-alt-right|ctrl-right",
      win: "alt-right"
    },
    name: "moveSubWordRight"
  }, {
    bindKey: {
      mac: "ctrl-alt-left|ctrl-left",
      win: "alt-left"
    },
    name: "moveSubWordLeft"
  }, {
    bindKey: {
      mac: "ctrl-m",
      win: "ctrl-m"
    },
    name: "jumptomatching",
    args: {
      to: "brackets"
    }
  }, {
    bindKey: {
      mac: "ctrl-f6",
      win: "ctrl-f6"
    },
    name: "goToNextError"
  }, {
    bindKey: {
      mac: "ctrl-shift-f6",
      win: "ctrl-shift-f6"
    },
    name: "goToPreviousError"
  }, {
    bindKey: {
      mac: "ctrl-o"
    },
    name: "splitline"
  }, {
    bindKey: {
      mac: "ctrl-shift-w",
      win: "alt-shift-w"
    },
    name: "surrowndWithTag"
  }, {
    bindKey: {
      mac: "cmd-alt-.",
      win: "alt-."
    },
    name: "close_tag"
  }, {
    bindKey: {
      mac: "cmd-j",
      win: "ctrl-j"
    },
    name: "joinlines"
  }, {
    bindKey: {
      mac: "ctrl--",
      win: "alt--"
    },
    name: "jumpBack"
  }, {
    bindKey: {
      mac: "ctrl-shift--",
      win: "alt-shift--"
    },
    name: "jumpForward"
  }, {
    bindKey: {
      mac: "cmd-k cmd-l",
      win: "ctrl-k ctrl-l"
    },
    name: "tolowercase"
  }, {
    bindKey: {
      mac: "cmd-k cmd-u",
      win: "ctrl-k ctrl-u"
    },
    name: "touppercase"
  }, {
    bindKey: {
      mac: "cmd-shift-v",
      win: "ctrl-shift-v"
    },
    name: "paste_and_indent"
  }, {
    bindKey: {
      mac: "cmd-k cmd-v|cmd-alt-v",
      win: "ctrl-k ctrl-v"
    },
    name: "paste_from_history"
  }, {
    bindKey: {
      mac: "cmd-shift-enter",
      win: "ctrl-shift-enter"
    },
    name: "addLineBefore"
  }, {
    bindKey: {
      mac: "cmd-enter",
      win: "ctrl-enter"
    },
    name: "addLineAfter"
  }, {
    bindKey: {
      mac: "ctrl-shift-k",
      win: "ctrl-shift-k"
    },
    name: "removeline"
  }, {
    bindKey: {
      mac: "ctrl-alt-up",
      win: "ctrl-up"
    },
    name: "scrollup"
  }, {
    bindKey: {
      mac: "ctrl-alt-down",
      win: "ctrl-down"
    },
    name: "scrolldown"
  }, {
    bindKey: {
      mac: "cmd-a",
      win: "ctrl-a"
    },
    name: "selectall"
  }, {
    bindKey: {
      linux: "alt-shift-down",
      mac: "ctrl-shift-down",
      win: "ctrl-alt-down"
    },
    name: "addCursorBelow"
  }, {
    bindKey: {
      linux: "alt-shift-up",
      mac: "ctrl-shift-up",
      win: "ctrl-alt-up"
    },
    name: "addCursorAbove"
  }, {
    bindKey: {
      mac: "cmd-k cmd-c|ctrl-l",
      win: "ctrl-k ctrl-c"
    },
    name: "centerselection"
  }, {
    bindKey: {
      mac: "f5",
      win: "f9"
    },
    name: "sortlines"
  }, {
    bindKey: {
      mac: "ctrl-f5",
      win: "ctrl-f9"
    },
    name: "sortlines",
    args: {
      caseSensitive: true
    }
  }, {
    bindKey: {
      mac: "cmd-shift-l",
      win: "ctrl-shift-l"
    },
    name: "splitSelectionIntoLines"
  }, {
    bindKey: {
      mac: "ctrl-cmd-down",
      win: "ctrl-shift-down"
    },
    name: "movelinesdown"
  }, {
    bindKey: {
      mac: "ctrl-cmd-up",
      win: "ctrl-shift-up"
    },
    name: "movelinesup"
  }, {
    bindKey: {
      mac: "alt-down",
      win: "alt-down"
    },
    name: "modifyNumberDown"
  }, {
    bindKey: {
      mac: "alt-up",
      win: "alt-up"
    },
    name: "modifyNumberUp"
  }, {
    bindKey: {
      mac: "cmd-/",
      win: "ctrl-/"
    },
    name: "togglecomment"
  }, {
    bindKey: {
      mac: "cmd-alt-/",
      win: "ctrl-shift-/"
    },
    name: "toggleBlockComment"
  }, {
    bindKey: {
      linux: "ctrl-alt-q",
      mac: "ctrl-q",
      win: "ctrl-q"
    },
    name: "togglerecording"
  }, {
    bindKey: {
      linux: "ctrl-alt-shift-q",
      mac: "ctrl-shift-q",
      win: "ctrl-shift-q"
    },
    name: "replaymacro"
  }, {
    bindKey: {
      mac: "ctrl-t",
      win: "ctrl-t"
    },
    name: "transpose"
  }].forEach(function (binding) {
    var command = exports.handler.commands[binding.name];
    if (command) command.bindKey = binding.bindKey;
    exports.handler.bindKey(binding.bindKey, command || binding.name);
  });
});

(function () {
  ace.require(["ace/keyboard/sublime"], function (m) {
    if (typeof module == "object" && typeof exports == "object" && module) {
      module.exports = m;
    }
  });
})();