{"id":19837734,"url":"https://github.com/willghatch/emacs-repeatable-motion","last_synced_at":"2025-02-28T18:48:37.953Z","repository":{"id":31085930,"uuid":"34644960","full_name":"willghatch/emacs-repeatable-motion","owner":"willghatch","description":"Make repeatable versions of motion functions","archived":false,"fork":false,"pushed_at":"2017-08-15T19:36:50.000Z","size":27,"stargazers_count":5,"open_issues_count":1,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-11T11:15:30.916Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willghatch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-27T03:57:22.000Z","updated_at":"2022-02-09T16:45:33.000Z","dependencies_parsed_at":"2022-09-09T07:11:16.272Z","dependency_job_id":null,"html_url":"https://github.com/willghatch/emacs-repeatable-motion","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willghatch%2Femacs-repeatable-motion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willghatch%2Femacs-repeatable-motion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willghatch%2Femacs-repeatable-motion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willghatch%2Femacs-repeatable-motion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willghatch","download_url":"https://codeload.github.com/willghatch/emacs-repeatable-motion/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241202625,"owners_count":19926651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T12:15:25.558Z","updated_at":"2025-02-28T18:48:37.926Z","avatar_url":"https://github.com/willghatch.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![MELPA](http://melpa.org/packages/repeatable-motion-badge.svg)](http://melpa.org/#/repeatable-motion)\n\nrepeatable-motion.el\n====================\n\nThe rationale for this package is that it can be nice to have a somewhat obscure motion function that you call by name, or by a longer-than-normal key sequence.  But it would be nice to be able to repeat the function again with a single key.  So here's how it works:\n\n    (require 'repeatable-motion)\n\n    ;; The following will define the function \"repeatable-motion-forward-foo\",\n    ;; which will be the same as forward-foo, but will set it to be repeated.\n    (repeatable-motion-define 'forward-foo 'backward-foo)\n    ;; keyword arguments:\n    ;; :repeat (in case you want a different\n    ;;     function to be repeated, eg. repeat-isearch)\n    ;; :inclusive (whether the motion should be treated as inclusive by evil-mode)\n\n    ;; This will define two functions: repeatable-motion-fwd-foo and repeatable-motion-bkwd-foo.\n    ;; Useful for simple motions that have opposites.\n    (define-repeatable-pair 'fwd-foo 'bkwd-foo)\n\nAfter the above, you can run `M-x repeatable-fwd-foo` to go forword.  Then run `M-x repeatable-motion-forward` or `M-x repeatable-motion-backward` to repeat as much as you want.  If the original call to the repeatable motion had a prefix argument, the repeats use the same one unless another one is given (except 1...).\n\nSome common motions that I know have repeatable versions defined if the original ones are defined.  But I don't want to do any re-binds to not change peoples' workflows without their intervention.  If you think this is not a good idea, I might be convinced to change that.\n\nUse cases\n---------\n\nIf you are an Evil user, I recommend binding repeatable-motion-forward and backward to the keys you would otherwise use for evil-repeat-find-char and evil-repeat-find-char-reverse (probably ; and ,).  I find that while I want to use evil-repeat-search with other motions in between, but I only repeat a find-char if I didn't get to the one I wanted first.\n\nPersonally, I have in my evil-normal-state two keys bound to prefix commands which are full of motions (forward for one, and backward for the other).  I try not to use forward-char and use more efficient motions, but on occasion it is easier to simply repeat forward-char.  This lets me lose the single-key binding to forward-char and just use a two-key binding, but then repeat it (or anything else) with a single key.\n\nInstall\n-------\n\nRequires emacs version 24.  Install through Melpa or clone the repo on your load path and `(require 'repeatable-motion)`.\n\nConfigure\n---------\n\n- Customize `repeatable-motion-define-common-motions-p` to `nil` before loading if you don't want motions to be defined automatically.\n- Customize `repeatable-motion-definition-prefix` to whatever prefix you want for the repeatable versions.  Defaults to \"repeatable-motion-\".  The default conforms to emacs packaging standards, but frankly I recommend something short like \"rmo/\".\n- Customize `repeatable-motion-count-needed-prefix` to whatever prefix you want for versions that are repeatable only when they receive a non-1 prefix argument.  These motions will be like those provided with eg. repmo.vim.  Defaults to `nil` (meaning they won't be defined at all).  A good one may be \"rmo-c/\".\n- Customize `repeatable-motion-training-wheels-p` to `t` if you want training-wheels mode -- repeated calls to the motion will fail, and tell you to use the repeat key instead.\n- Customize `repeatable-motion-training-wheels-timeout` a number of seconds for the training-wheels restriction to wear off.\n\nExamples\n--------\n\nYou can put this in your emacs config file:\n\n```\n;; set or customize these before requiring the package for them to take effect\n;; for automatically defined movements.\n(setq repeatable-motion-definition-prefix \"rmo/\")\n(setq repeatable-motion-count-needed-prefix \"rmo-c/\")\n(require 'repeatable-motion)\n\n;; when we require evil, some common motions will be defined.\n;; Since we set the prefix to `rmo/`, we will have functions defined\n;; like `rmo/evil-next-line`, and `rmo/evil-forward-WORD-end`.\n(require 'evil)\n(define-key evil-motion-state-map \";\" 'repeatable-motion-forward)\n(define-key evil-motion-state-map \",\" 'repeatable-motion-backward)\n;; Let's make j/k be repeatable, but only when we use a prefix (eg `9j`)\n(define-key evil-motion-state-map \"j\" 'rmo-c/evil-next-line)\n(define-key evil-motion-state-map \"k\" 'rmo-c/evil-previous-line)\n;; Let's add some more common movements, but make them repeatable always\n(define-key evil-motion-state-map \"w\" 'rmo/evil-forward-word-begin)\n(define-key evil-motion-state-map \"b\" 'rmo/evil-backward-word-begin)\n\n;; Let's define a new repeatable motion and bind it\n(repeatable-motion-define-pair 'org-forward-element 'org-backward-element)\n;; Now rmo/org-forward-element and rmo/org-backward-element are both defined,\n;; as well as rmo-c/org-forward-element and rmo-c/org-backward-element.\n\n;; Let's use `h` and `l` as prefixes for motions -- `h` for backward, `l` for forward.\n(define-key evil-motion-state-map \"l\" nil)\n(define-key evil-motion-state-map \"h\" nil)\n(define-key evil-motion-state-map \"lc\" 'rmo/evil-forward-char)\n(define-key evil-motion-state-map \"hc\" 'rmo/evil-backward-char)\n(define-key evil-motion-state-map \"le\" 'rmo/org-forward-element)\n(define-key evil-motion-state-map \"he\" 'rmo/org-backward-element)\n(define-key evil-motion-state-map \"lp\" 'rmo/evil-forward-paragraph)\n(define-key evil-motion-state-map \"hp\" 'rmo/evil-backward-paragraph)\n;; etc\n\n;; Now we can type `le` to move forward one org element, then type `;` to move another.\n;; If we then type `j`, `;` still moves forward one element, since we used `rmo-c/` for j/k.\n;; If we type `5j`, ';' will repeat `5j` instead of org-forward-element.\n```\n\nTo see more examples of defining motions, as well as to see which ones are defined by default, see `repeatable-motion-common-motions.el`.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillghatch%2Femacs-repeatable-motion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillghatch%2Femacs-repeatable-motion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillghatch%2Femacs-repeatable-motion/lists"}