Code Monkey home page Code Monkey logo

grugru's Introduction

https://raw.githubusercontent.com/ROCKTAKEY/images/4524403fbcdd9abe6d88197eddb1c4d241046e72/grugru.png https://img.shields.io/github/tag/ROCKTAKEY/grugru.svg?style=flat-square https://img.shields.io/github/license/ROCKTAKEY/grugru.svg?style=flat-square https://img.shields.io/github/actions/workflow/status/ROCKTAKEY/grugru/CI.yml.svg?style=flat-square https://img.shields.io/codecov/c/github/ROCKTAKEY/grugru/master.svg?style=flat-square https://melpa.org/packages/grugru-badge.svg

Grugru: Rotate text at point.

With this package, you can rotate things at point.

https://raw.githubusercontent.com/ROCKTAKEY/images/7baf9507a8fb9c20eda7395be1c9d91d0ae61c51/emacs-lisp-mode.gif Fig. 1 demo on emacs-lisp-mode

https://raw.githubusercontent.com/ROCKTAKEY/images/35e323db33f4da1545c289f2741782c4ac04968b/c++-mode.gif Fig. 2 demo on c++-mode

https://raw.githubusercontent.com/ROCKTAKEY/images/698f33489645a6e7b0c29d879771dbb15fa3fcd9/grugru-define-local.gif Fig. 3 Use grugru-define-local interactively

How to Use?

You can interactively use the function grugru. This function rotate the thing at point if assigned. You can assign rotated things with grugru-define-on-major-mode, grugru-define-on-local-major-mode, and grugru-define-local. If you use grugru, you should assign grugru to 1 stroke key like C-;, or M-g.

(global-set-key (kbd "C-;") #'grugru)   ; Or other key.

If you want use default grugru, eval grugru-default-setup. In the other words, add to your init.el:

(grugru-default-setup)

If you want grugru to highlight gurgruable thing, add to your init.el:

(grugru-highlight-mode)

If you want to change default action at point, you can use grugru-edit, with which you can edit grugrus at point interactively. The change edited by this function is saved in grugru-edit-save-file, and loaded by run grugru-edit-load. So to load the change, you can write on init.el after (grugru-default-setup):

(grugru-edit-load)

If you want to use ivy or ido as completing-read, set grugru-edit-completing-function. Or, you can use grugru-redefine-\* or grugru-remove-\* for non-interactive editing of default setup.

Examples

;; Define grugru on major-mode.
(grugru-define-on-major-mode 'c-mode 'symbol '("unsigned" "signed"))
(grugru-define-on-major-mode 'c-mode 'word '("get" "set"))
;; Now, you can toggle unsigned <=> signed and get <=> set
;; by running the command grugru in c-mode.

;; You can pass a list of symbol major-mode instead of one.
(grugru-define-on-major-mode '(java-mode c++-mode) 'word '("get" "set"))

;; Define grugru on current major-mode.
;; Same as (grugru-define-on-major-mode major-mode 'symbol '("red" "green" "yellow"))
;; This should be run in some hook or function,
;; because major-mode is not confirmed if in init.el.
(add-hook 'c-mode-common-hook
 (lambda ()
  (grugru-define-on-local-major-mode 'symbol '("red" "green" "yellow"))))

;; Define grugru on local. Should be defined in some hook or function,
;; because it is saved buffer local.
(add-hook 'text-mode-hook
          (lambda ()
           (grugru-define-local 'word '("is" "was"))
           (grugru-define-local 'word '("I" "my" "me" "mine"))))

;; Define grugru globally. This is applied in all buffers.
(grugru-define-global 'symbol '("yes" "no"))

;; Define grugru keeping case:
(grugru-define-global 'symbol (grugru-metagenerator-keep-case '("yes" "no")))

;; If you want grugru to define grugru defaultly keeping case:
(customize-set-variable 'grugru-strings-metagenerator #'grugru-metagenerator-simple)

;; You can use function instead of list of strings.
(grugru-define-on-major-mode
 'c-mode 'symbol
 ;; Optional argument `rev' is flag for backward rotation.
 ;; If the second argument `rev' is ignoreable (for example, rotate two strings),
 ;; you can just use the function receiving only 1 argument.
 (lambda (arg &optional rev)
   (if rev
       ;; backward
       (cond
        ((string-match "a\\(.*\\)b" arg)
         ;; Rotate axyzb to cxyzd
         (concat "c" (match-string 1 arg) "d"))
        ((string-match "b\\(.*\\)c" arg)
         ;; Rotate bxyzc to axyzb
         (concat "a" (match-string 1 arg) "b"))
        ((string-match "c\\(.*\\)d" arg)
         ;; Rotate cxyzd to bxyzc
         (concat "b" (match-string 1 arg) "c")))
     ;; forward
     (cond
      ((string-match "a\\(.*\\)b" arg)
       ;; Rotate axyzb to bxyzc
       (concat "b" (match-string 1 arg) "c"))
      ((string-match "b\\(.*\\)c" arg)
       ;; Rotate bxyzc to cxyzd
       (concat "c" (match-string 1 arg) "d"))
      ((string-match "c\\(.*\\)d" arg)
       ;; Rotate cxyzd to axyzb
       (concat "a" (match-string 1 arg) "b"))))))

;; You can indicate which position is valid to grugru in strings.
;; The function can return not only string but also cons cell (BOUNDS . STRING).
;; BOUNDS is a list of cons cell (BEG . END), which is pair of numbers indicating
;; range valid to rotate.
(defun grugru-default@emacs-lisp+nth!aref (str)
  "Return STR exchanged `nth' and `aref' with argument permutation."
  (cond
   ((string-match "^(\\_<\\(nth\\)\\_>" str)
    (cons
     (cons (match-beginning 1) (match-end 1))
     ;; This function permutate arguments on Lisp.
     (grugru-utils-lisp-exchange-args
     (replace-match "aref" nil nil str 1)
     '(2 1))))
   ((string-match "^(\\_<\\(aref\\)\\_>" str)
    (cons
     (cons (match-beginning 1) (match-end 1))
     (grugru-utils-lisp-exchange-args
     (replace-match "nth" nil nil str 1)
     '(2 1))))))

;; You can also write like:
(grugru-define-multiple
 (fundamental-mode
  . ((word . ("aaa" "bbb" "ccc"))
     ;; (symbol "xxx" "yyy" "zzz") is same as below.
     ;; You can use both.
     (symbol . ("xxx" "yyy" "zzz"))
     (word . ("abc" "def" "ghi"))))
  (word . ("aaaa" "bbbb" "cccc"))
  (symbol . ("xxxx" "yyyyy" "zzzzz"))
  (word . ("abcd" "defd" "ghid")))
;; or
(grugru-define-multiple
 (fundamental-mode
   (word "aaa" "bbb" "ccc")
   (symbol "xxx" "yyy" "zzz")
   (word "abc" "def" "ghi"))
  (word "aaaa" "bbbb" "cccc")
  (symbol "xxxx" "yyyyy" "zzzzz")
  (word "abcd" "defd" "ghid"))

;; Above two examples are both expanded to:
(progn
  (progn
     (grugru-define-on-major-mode 'fundamental-mode 'word '("aaa" "bbb" "ccc"))
     (grugru-define-on-major-mode 'fundamental-mode 'symbol '("xxx" "yyy" "zzz"))
     (grugru-define-on-major-mode 'fundamental-mode 'word '("abc" "def" "ghi")))
   (grugru-define-global 'word '("aaaa" "bbbb" "cccc"))
   (grugru-define-global 'symbol '("xxxx" "yyyyy" "zzzzz"))
   (grugru-define-global 'word '("abcd" "defd" "ghid")))


;; You can define function which rotate pre-specified texts.
;; For example, three-state can rotate only 2 tuples,
;; ("water" "ice" "vapor") and ("solid" "liquid" "gas"),
;; not any other tuples defined by grugru-define-global and so on.
(grugru-define-function three-state ()
 "Docstring. This is optional."
 (symbol . ("water" "ice" "vapor"))
 (symbol . ("solid" "liquid" "gas")))
;; If you want to find the functions defined by `grugru-define-function'
;; with `describe-function', execute this:
(grugru-find-function-integration-mode +1)

Interactive Functions

grugru

This function rotates text at point. Rotated text is defined by grugru-define-* functions. If prefix argument is passed, repeatedly executed. Negative prefix arguments means backward rotation. Also, grugru-backward can be used for backward rotation.

grugru-select

This function replace text at point. You can select grugru and string replaced to.

You can assign completing function to grugru-completing-function.

grugru-edit

This function edits grugru at point defined by default.

First, select grugru from grugrus available at point. Then, edit the list in minibuffer.

The change is saved to file grugru-edit-save-file if it is not local one. You can assign completing function to grugru-completing-function.

Functions Defining grugru

(grugru-define-global GETTER STRINGS-OR-FUNCTION)

Define global grugru with GETTER and STRINGS-OR-FUNCTION.

GETTER is a function, or a symbol which is alias defined in grugru-getter-alist. GETTER also can be positive or negative number, which means the number of characters after point. By default, symbol, word, char is available. If it is a function, it should return cons cell (begin . end) which express things at point, and with no argument.

STRINGS-OR-FUNCTION is list of string or function.

List of string: If it includes string gotten by GETTER, the things gotten by GETTER is replaced to next string.

Function: It is passed things gotten by GETTER, and should return string to replace the things to.

You can use like:

;; Replace "yes" at point, to "no".
;; Or replace "no" at point, to "yes".
(grugru-define-global 'symbol '("yes" "no"))

(grugru-define-on-major-mode MAJOR GETTER STRINGS-OR-FUNCTION)

Define major-mode local grugru with GETTER and STRINGS-OR-FUNCTION.

Same as grugru-define-global, but grugru defined with this is applied only in buffer on MAJOR major-mode. MAJOR can be list of major-modes.

;; Replace "yes" at point, to "no", or replace "no" at point, to "yes",
;; only in lisp-interaction-mode.
(grugru-define-on-major-mode lisp-interaction-mode 'symbol '("yes" "no"))

(grugru-define-local GETTER STRINGS-OR-FUNCTION)

Define buffer-local grugru with GETTER and STRINGS-OR-FUNCTION.

Same as grugru-define-global, but grugru defined with this is applied only in buffer where eval this expression.

;; This should be used in hook or others.
;; Because this definition is buffer-local.
(add-hook 'text-mode-hook
           (lambda ()
            (grugru-define-local 'word '("is" "was"))
            (grugru-define-local 'word '("I" "my" "me" "mine"))))

Also, you can run it interactively (though cannot set STRINGS-OR-FUNCTION to a function). On interactive usage, by default, GETTER is the length of car of STRINGS-OR-FUNCTION, and STRINGS-OR-FUNCTION is a list which has 2 elements, constructed interactively. With prefix argument, you can select GETTER and length of STRINGS-OR-FUNCTION. Default GETTER is set by grugru-local-interactively-default-getter.

(grugru-define-multiple &rest CLAUSES)

This function define multiple grugru.

Each CLAUSE is:

  • (GETTER . STRINGS-OR-FUNCTION): means (grugru-define-global GETTER STRINGS-OR-FUNCTION).
  • (MAJOR (GETTER . STRINGS-OR-FUNCTION)...): means (grugru-define-on-major-mode MAJOR GETTER STRINGS-OR-FUNCTION)....
  • List of above.
(grugru-define-multiple
 (fundamental-mode
  . ((word . ("aaa" "bbb" "ccc"))
     ;; (symbol "xxx" "yyy" "zzz") is same as below.
     ;; You can use both.
     (symbol . ("xxx" "yyy" "zzz"))
     (word . ("abc" "def" "ghi"))))
  (word . ("aaaa" "bbbb" "cccc"))
  (symbol . ("xxxx" "yyyyy" "zzzzz"))
  (word . ("abcd" "defd" "ghid")))
;; or
(grugru-define-multiple
 (fundamental-mode
   (word "aaa" "bbb" "ccc")
   (symbol "xxx" "yyy" "zzz")
   (word "abc" "def" "ghi"))
  (word "aaaa" "bbbb" "cccc")
  (symbol "xxxx" "yyyyy" "zzzzz")
  (word "abcd" "defd" "ghid"))

;; Above two examples are both expanded to:
(progn
  (progn
     (grugru-define-on-major-mode 'fundamental-mode 'word '("aaa" "bbb" "ccc"))
     (grugru-define-on-major-mode 'fundamental-mode 'symbol '("xxx" "yyy" "zzz"))
     (grugru-define-on-major-mode 'fundamental-mode 'word '("abc" "def" "ghi")))
   (grugru-define-global 'word '("aaaa" "bbbb" "cccc"))
   (grugru-define-global 'symbol '("xxxx" "yyyyy" "zzzzz"))
   (grugru-define-global 'word '("abcd" "defd" "ghid")))

(grugru-define-function NAME () &optional DOCSTRING &rest BODY)

Define function which can roate only grugru defined by BODY. Each element of BODY is (GETTER . STRINGS-OR-FUNCTION), which meaning is same as grugru-define-* functions.

;; The function `three-state' rotate like "water"=>"ice"=>"vapor"=>"water",
;; or "solid"=>"liquid"=>"gas"=>"solid".
(grugru-define-function three-state ()
 "Docstring. This is optional."
 (symbol . ("water" "ice" "vapor"))
 (symbol . ("solid" "liquid" "gas")))

;; This sentense do NOT affect to the function `three-state'.
(grugru-define-global 'symbol '("yes" "no"))

Utilities to define grugru

(grugru-utils-lisp-exchange-args LIST-STRING PERMUTATION)

Permute argument of sexp read from LIST-STRING according to PERMUTATION.

For example, (grugru-utils-lisp-exchange-args \"(nth 1 '(x y z))\" '(2 1)) returns (nth '(x y z) 1). Newlines and whitespaces are also kept.

This function is defined for user to define the function for grugru which rotate not only fuction’s name but also arguments’ order.

Usage

(defun grugru-rotate-nth-aref (str)
  (cond
   ((string-match "^(\\(\\_<nth\\_>\\)" str) ;match to "(nth"
    (grugru-utils-lisp-exchange-args
     (replace-match "aref" nil nil str 1) ;replace function's name to "aref"
     '(2 1)))                             ;exchange arguments' order
   ((string-match "^(\\(\\_<aref\\_>\\)" str) ;match to "(aref"
    (grugru-utils-lisp-exchange-args
     (replace-match "nth" nil nil str 1) ;replace function's name to "nth"
     '(2 1)))))                          ;exchange arguments' order
(grugru-define-on-major-mode
 'emacs-lisp-mode
 'list
 #'grugru-rotate-nth-aref)

;; Then,
(nth 3 '(foo bar))
;; is rotated to:
(aref '(foo bar) 3)

Custom Variables

grugru-getter-alist

Alist of getter.

Each key (car) of element is a symbol, which is regarded as GETTER.

Each value (cdr) of element is a function or sexp. It should return things at point.

grugru-edit-save-file

The name of file saved the information by grugru-edit. Default value is “~/.emacs.d/.grugru”.

grugru-completing-function

Completing function. Default value is completing-read. If you would like to use ivy or ido, write:

;; For ivy:
(setq grugru-completing-function #'ivy-completing-read)
;; For ido:
(setq grugru-completing-function #'ido-completing-read)

grugru-select-function-generate-number

This variable have how many strings are generated from function in STRINGS-OR-FUNCTION, on grugru-select.

grugru-local-interactively-default-getter

Indicate default getter on interactive usage of grugru-define-local. 0 means If 0, gets number from first string, otherwise it should be symbol in grugru-getter-alist or a function which gets things at point.

grugru-point-after-rotate

Where the point is after rotation by grugru.

  • as-is means keeping first position.
  • beginning means beginning of rotated things.
  • end means end of rotated things.

grugru-indent-after-rotate

Indent rotated text after grugru or not. Indent happens only if text after rotation has a newline.

(grugru-define-local 'list '("(abc def)" "(ghi\njkl)"))
;; If `grugru-indent-after-rotate' is nil,
(abc def)
;; is rotated to:
(ghi
jkl)

;; If `grugru-indent-after-rotate' is t,
(abc def)
;; is rotated to:
(ghi
 jkl)

grugru-strings-metagenerator

Function which generates default generator from strings on grugru-define-*. The function should recieve STRINGS, list of string, as one argument, and return function. Returned function should recieve one or two argument(s), string STRING as first one, boolean REVERSE as second one.

STRING means current string. Returned function (generator) returns string next to STRING. If REVERSE is non-nil, it returns previous one instead.

leaf-keyword :grugru

You can use :grugru keyword on leaf.el, if you use leaf-keywords.el.

By default, leaf--name is used as major-mode. Or you can write major-mode obviously.

(leaf lisp-mode
 :grugru
 (symbol "nil" "t")
 (emacs-lisp-mode
  (word "add" "remove"))
 ...)
;; The section of `:grugru' means:
(grugru-define-multiple
 (lisp-mode
  (symbol "nil" "t"))
 (emacs-lisp-mode
  (word "add" "remove")))

License

This package is licensed by GPLv3. See LICENSE.

grugru's People

Contributors

conao3 avatar rocktakey avatar syohex avatar takaxp avatar terlar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

grugru's Issues

Increase / decrease numbers

Hello,

I wanted to add the ability to increase / decrease numbers. Coming from vim I'm used to "C-a" and "C-x" to increment / decrement numbers, which I used with some plugin (like boole) to make it works on other things (toggling true / false…).

Now your package does the second part very well but didn't work on numbers.

I gave it a try and this is what I came up with, keep in mind I'm very new to elisp (and would gladly take any advice on how to makes this better).

(defun +grugru--getter-number ()
  "Get beginning/end of number at point.

   We have to first get the word at point and make sure it's only a number so
   we are not modifying a number inside a word. Otherwise we would be
   increasing things like types (=f32=)."
  (if (string-match-p "^-?\\(?:[0-9]*[.]\\)?[0-9]+$" (thing-at-point 'word))
      (bounds-of-thing-at-point 'number)))

(add-to-list 'grugru-getter-alist '(number . +grugru--getter-number))

(grugru-define-global
 'number
 (lambda (arg &optional rev)
   (let ((num (string-to-number arg)))
          (number-to-string (if rev (- num 1) (+ num 1)))))

I'm probably missing edge cases, the big one was to avoid matching numbers inside words.

Now I don't know if it's something you want to support but I thought it might at least be useful to someone. If you don't want a PR maybe you can add it to the readme or add a wiki section with examples.

Regexp support

Like this:
regexp=>to-string

(grugru-define 'symbol
  '(("regexp" . "to-string")
     ("regexp2" . "to-string2")))
;; regexp=>regeto-string
(grugru-define 'symbol
  '((("\\(re\\)ge\\(xp\\)" 2) . "to-string")
     ("regexp2" . "to-string2")))
;; regexp=>regere
(grugru-define 'symbol
  '((("\\(re\\)ge\\(xp\\)" 2) . "\1")
     ("regexp2" . "to-string2")))

Adding a hook

If a hook is implemented in grugru that will be called after rotating, it may very useful. For me, I'd like to use the hook to call save-buffer to reduce my key typing.

Rotate backwards

If there are several candidates it would be nice to be able to rotate backwards as well as forwards.

Is this currently possible?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.