2

emacs 26.1, multiple-cursor https://github.com/magnars/multiple-cursors.el

Here my custom Elisp function that add some number(by default 1) to number.

(defun increment-number-at-point(number)
  (interactive (list (read-number "Input increment number: " 1)))
  (skip-chars-backward "0-9")
  (or (looking-at "[0-9]+")
      (error "No number at point"))
  (replace-match (number-to-string (+ number (string-to-number (match-string 0))))))

(global-set-key (kbd "C-c +") 'increment-number-at-point)

Nice it's work fine. But suppose I has this json and want to add to every id the number 400. Example json:

[
  {
    "id": 0,
    "finished": 2,
    "orgn": 17
  },
  {
    "id": 1,
    "finished": 3,
    "orgn": 17
  },
  {
    "id": 2,
    "finished": 4,
    "orgn": 17
  },
  {
    "id": 3,
    "finished": 5,
    "orgn": 17
  }
]

The result must be:

[
  {
    "id": 400,
    "finished": 2,
    "orgn": 17
  },
  {
    "id": 401,
    "orgn": 17
  },
  {
    "id": 402,
    "orgn": 17
  },
  {
    "id": 403,
    "orgn": 17
  }
]

here my steps (use my custom function and multiple-cursor)

  1. enter image description here
  2. enter image description here
  3. enter image description here
  4. Use C-c + (increment-number-at-point)
  5. enter image description here
  6. Input 400 RET
  7. It's AGAIN ask me about number enter image description here
  8. So it ask my about number ON EVERY LINE. It's not good.

Is it possible to set ONLY ONCE number (400) and replace on every line automatic?

  • Would it help if you customize the variables mc/cmds-to-run-once and/or mc/always-run-for-all? I.e., If you have inadvertently added your custom function to the one once list, then manually delete that entry; if you don't want to be prompted at every cursor, then add your custom function to the run for all list. See the section of the README.MD entitled "Unknown commands": github.com/magnars/multiple-cursors.el Have a look inside the file .mc-lists.el .... – lawlist Nov 17 at 16:50
  • I added "increment-number-at-point" to file .mc-lists.el. But it not help. Again every time ask me about number for every line. – a_subscriber Nov 18 at 8:42
  • You need to read the number outside the function. Else as it gets called on each cursor you also have to input a number on each. – Hubisan Nov 18 at 9:24
  • Do you mean to remove "read-number" from my function ? – a_subscriber Nov 18 at 9:29
0

The function gets called for each cursor (if it is added to mc/always-run-for-all) and therefore the number is also read for each cursor.

To get around this you could write a wrapper that reads the number once and then runs your command for all cursors.

(defun my-mc/increment-number-at-cursors (number)
  "Increment numbers for all cursors by NUMBER."
  (interactive (list (read-number "Input increment number: " 1)))
  (mc/execute-command-for-all-cursors
   (lambda ()
     (interactive)
     (increment-number-at-point number))))
0

You could split your function into two.

  • One, which is doing the work on one single cursor (internal).
  • A second one, which is called once by the user (cmd). This function ensures, that the work is done by for every single cursor.

source code:

(defun foo--internal ()
  (interactive)
  (skip-chars-backward "0-9")
  (or (looking-at "[0-9]+")
      (error "No number at point"))
  (replace-match (number-to-string (+ number (string-to-number (match-string 0))))))

(defun foo-cmd (number)
  (interactive (list (read-number "Input increment number: " 1)))
  (if (fboundp 'mc/execute-command-for-all-cursors)
      (mc/execute-command-for-all-cursors #'foo--internal)
    (foo--internal)))

(global-set-key (kbd "C-c +") 'foo-cmd)
0

Answering the last question:

(defun add-to-number-atpt ()
  (interactive "*")
  (let* ((regexp "\"id\": \\([0-9]+\\),"))
    (while (re-search-forward regexp nil t)
      (replace-match (concat "\"id\": "(number-to-string (+ 400 (string-to-number (match-string-no-properties 1))))",")))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.