2
\$\begingroup\$

I have function that processes text and returns it in altered state. Result of the processing is a property list with following properties of interest:

  • :success - t if processing finished correctly
  • :text - complete changed text
  • :changedLines: list of changed lines as 2 element vectors [number-of-line line-text] (numbers are zero-based)
  • :cursorX - position of cursor on the current line
  • :error - description of the problem in case processing failed to succeed

This is a final version of the code:

(defun parinfer-mode--insert-result (result)
  "Put results of running parinfer in current buffer
If cursor is right after a newline and next character is a closing curly brace, result is ignored
All lines that were changed are replaced, then cursor is set toa new position"
  (let ((inhibit-modification-hooks t))
    (cl-macrolet ((-char-before (point) `(or (char-before ,point) -1))
                  (-char-after (point) `(or (char-after ,point) -1))
                  (sv (arg) `(symbol-value ,arg)))
      (cl-labels ((replace-line (index new-line posvar)
                                (forward-line (- index (sv posvar)))
                                (let ((beg (point))
                                      (end (progn (move-end-of-line 1) (point))))
                                  (insert new-line)
                                  (delete-region beg end))
                                (set posvar index)))
        (if (plist-get result :success)
            (if (not (and (= (-char-before (point)) 10)
                          (= (-char-after (point)) 41)))
                (let* ((old-line (line-number-at-pos))
                       (new-lines (plist-get result :changedLines))
                       (new-line-point (plist-get result :cursorX))
                       (cur-line old-line))
                  (mapc (lambda (elem)
                          (replace-line (1+ (aref elem 0))
                                        (aref elem 1)
                                        'cur-line))
                        new-lines)
                  (forward-line (- old-line cur-line))
                  (forward-char new-line-point)))
        (message "Parinfer did not succeed: %s" (plist-get result :error)))))))

This is previous version of the code:

(defun parinfer-mode--insert-result (result)
  (let ((inhibit-modification-hooks t))
    (cl-macrolet ((-char-before (point) `(or (char-before ,point) -1))
                  (-char-after (point) `(or (char-after ,point) -1)))
      (if (plist-get result :success)
          (if (not (and (= (-char-before (point)) 10)
                        (= (-char-after (point)) 41)))
              (let ((old-buffer (current-buffer))
                    (old-point (point)))
                (with-temp-buffer
                  (insert (plist-get result :text))
                  (copy-to-buffer old-buffer (point-min) (point-max)))
                (goto-char old-point)))
        (message "Parinfer did not succeed: %s" (plist-get result :error))))))

I am having doubts first approach is better then second, because it has longer and harder-to-understand code. Also, i am not clear on whether replacing code line-by-line is actually faster then switching buffer contents.

\$\endgroup\$

Your Answer

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

Browse other questions tagged or ask your own question.