Function: combobulate--place-node-or-text

combobulate--place-node-or-text is a natively compiled function defined in combobulate-manipulation.el.

Signature

(combobulate--place-node-or-text POSITION NODE-OR-TEXT &optional MODE NO-TRAILING-NEWLINE)

Documentation

Place NODE-OR-TEXT at POSITION.

NODE-OR-TEXT must be a valid node or a string.

If NODE-OR-TEXT is a NODE, then its first-line indentation is calculated first and the text indented properly relative to POSITION.

If NODE-OR-TEXT is a string, then all indentation must be handled by the caller. The string is inserted at POSITION.

If MODE is non-nil, then it must be either newline or inline. Where newline forces the placement of NODE-OR-TEXT on a new line. If MODE is inline then it is places inline alongside other nodes around POSITION.

If NO-TRAILING-NEWLINE is non-nil, then no trailing newline is inserted after NODE-OR-TEXT.

Source Code

;; Defined in /nix/store/b5fvrwzi3zvkabyzx0in6gw1cj963z46-emacs-packages-deps/share/emacs/site-lisp/combobulate-manipulation.el
(defun combobulate--place-node-or-text (position node-or-text &optional mode no-trailing-newline)
  "Place NODE-OR-TEXT at POSITION.

NODE-OR-TEXT must be a valid node or a string.

If NODE-OR-TEXT is a NODE, then its first-line indentation is
calculated first and the text indented properly relative to
POSITION.

If NODE-OR-TEXT is a string, then all indentation must be handled
by the caller. The string is inserted at POSITION.

If MODE is non-nil, then it must be either `newline' or
`inline'. Where `newline' forces the placement of NODE-OR-TEXT on
a new line. If MODE is `inline' then it is places inline
alongside other nodes around POSITION.

If NO-TRAILING-NEWLINE is non-nil, then no trailing newline is inserted
after NODE-OR-TEXT."
  (let* ((col (save-excursion (goto-char position)
                              (current-column)))
         (node-text)
         (newline-insert (and (or (eq mode 'newline) (null mode))
                              (combobulate-before-point-blank-p position))))
    (cond
     ((stringp node-or-text)
      (setq node-text (combobulate-indent-string
                       node-or-text
                       :first-line-amount col
                       :first-line-operation 'absolute
                       :rest-lines-amount 'relative)))
     ((or (combobulate-node-p node-or-text)
          (combobulate-proxy-node-p node-or-text))
      (let ((sequence-separator
             ;; attempt to guess the sequence separator, almost always
             ;; an anonymous node, that (usually!) follows nodes --
             ;; think array/list separators; semicolons after
             ;; expressions, etc. -- and ensure it is appended to the
             ;; cloned text. This is of course not the proper way to
             ;; do this: the `xxx-grammar.json' files contain the
             ;; rules for sequences and the character to use. This is
             ;; merely the 90% solution that works for most, but not
             ;; all, instances.
             (save-excursion
               (combobulate--goto-node node-or-text t)
               (when-let ((node-after (condition-case nil
                                          (combobulate-node-on (point) (1+ (point)) nil nil)
                                        (error nil))))
                 (cond
                  ;; named nodes get no sequence separator
                  ((combobulate-node-named-p node-after) "")
                  ((and (combobulate-node-anonymous-p node-after)
                        (member (combobulate-node-text node-after)
                                (combobulate-read plausible-separators)))
                   (combobulate-node-text node-after))
                  (t "")))))
            (node-col (save-excursion
                        (combobulate--goto-node node-or-text)
                        (current-indentation))))
        (setq node-text (if newline-insert
                            (combobulate-indent-string
                             ;; the first line may not include all of its
                             ;; indentation because the node extents won't
                             ;; include it. This fixes it so it does.
                             (combobulate-indent-string-first-line
                              (concat (combobulate-node-text node-or-text) sequence-separator)
                              node-col)
                             :first-line-amount (- col node-col)
                             :first-line-operation 'add)
                          (concat (combobulate-node-text node-or-text) sequence-separator)))))
     (t (error "Cannot place node or text `%s'" node-or-text)))
    (goto-char position)
    ;; If a node has nothing but whitespace preceding it, then it's a
    ;; "newline-delimited" node. Newline-delimited nodes are regular
    ;; nodes that exist, usually, on a line of their own. That is on
    ;; contrast to inline-delimited nodes that are placed to the left
    ;; or right on a line with other nodes.
    (if newline-insert
        ;; newline-delimited node
        (progn
          (unless no-trailing-newline (split-line 0))
          (combobulate--refactor-insert-copied-values
           (list (string-trim-right node-text))))
      ;; inline-delimited node
      (save-excursion
        (insert node-text)
        (just-one-space 0)
        (unless (looking-at "\\s-")
          (insert " "))))))