Function: csv--jit-align
csv--jit-align is a natively compiled function defined in csv-mode.el.
Signature
(csv--jit-align BEG END)
Source Code
;; Defined in /nix/store/3gmjnyw9n226b7k7jamikx980vf8267p-emacs-packages-deps/share/emacs/site-lisp/elpa/csv-mode-1.27/csv-mode.el
(defun csv--jit-align (beg end)
(save-excursion
;; This is run with inhibit-modification-hooks set, so the overlays'
;; modification-hook doesn't work :-(
(and csv--header-line
(<= beg (overlay-end csv--header-line))
(>= end (overlay-start csv--header-line))
(csv--header-flush))
;; First, round up to a whole number of lines.
(goto-char end)
(unless (bolp) (forward-line 1) (setq end (point)))
(goto-char beg)
(unless (bolp) (forward-line 1) (setq beg (point)))
(csv--jit-unalign beg end)
(put-text-property beg end 'csv--jit t)
(pcase-let* ((`(,column-widths ,field-widths) (csv--column-widths beg end))
(changed (csv--jit-merge-columns column-widths))
(ellipsis-width (csv--ellipsis-width)))
(when changed
;; Do it after the current redisplay is over.
(run-with-timer jit-lock-context-time nil #'csv--jit-flush beg end))
;; Align fields:
(goto-char beg)
(while (< (point) end)
(unless (csv-not-looking-at-record)
(let ((w csv--jit-columns)
(widths-config csv--config-column-widths)
(column 0)) ;Desired position of left-side of this column.
(while (and w (not (eolp)))
(let* ((field-beg (point))
(width-config (pop widths-config))
(align-padding (if (bolp) 0 csv-align-padding))
(left-padding 0) (right-padding 0)
(field-width (pop field-widths))
(column-width
(min (max csv-align-min-width
(car (pop w)))
(or width-config
;; Don't apply csv-align-max-width
;; to the last field!
(if w csv-align-max-width
most-positive-fixnum))))
(x (- column-width field-width)) ; Required padding.
(truncate nil))
(csv-end-of-field)
;; beg = beginning of current field
;; end = (point) = end of current field
(when (< x 0)
(setq truncate (max column
(+ column column-width
align-padding (- ellipsis-width))))
(setq x 0))
;; Compute required padding:
(pcase csv-align-style
('left
;; Left align -- pad on the right:
(setq left-padding align-padding
right-padding x))
('right
;; Right align -- pad on the left:
(setq left-padding (+ align-padding x)))
('auto
;; Auto align -- left align text, right align numbers:
(if (string-match "\\`[-+.[:digit:]]+\\'"
(buffer-substring field-beg (point)))
;; Right align -- pad on the left:
(setq left-padding (+ align-padding x))
;; Left align -- pad on the right:
(setq left-padding align-padding
right-padding x)))
('centre
;; Centre -- pad on both left and right:
(let ((y (/ x 2))) ; truncated integer quotient
(setq left-padding (+ align-padding y)
right-padding (- x y)))))
(cond
((or (memq 'csv buffer-invisibility-spec)
;; For TSV, hidden or not doesn't make much difference,
;; but the behavior is slightly better when we "hide"
;; the TABs with a `display' property than if we add
;; before/after-strings.
(tsv--mode-p))
;; Hide separators...
;; Merge right-padding from previous field
;; with left-padding from this field:
(if (zerop column)
(when (> left-padding 0)
;; Display spaces before first field
;; by overlaying first character:
(csv--make-overlay
field-beg (1+ field-beg) nil nil nil
`(before-string ,(make-string left-padding ?\ )
csv--jit t)))
;; Display separator as spaces:
(with-silent-modifications
(put-text-property
(1- field-beg) field-beg
'display `(space :align-to
,(+ left-padding column))))))
(t ;; Do not hide separators...
(let ((overlay (csv--make-overlay field-beg (point)
nil nil t
'(csv--jit t))))
(when (> left-padding 0) ; Pad on the left.
;; Display spaces before field:
(overlay-put overlay 'before-string
(make-string left-padding ?\ )))
(unless (eolp)
(if (> right-padding 0) ; Pad on the right.
;; Display spaces after field:
(overlay-put
overlay
'after-string (make-string right-padding ?\ )))))))
(setq column (+ column column-width align-padding))
;; Do it after applying the property, so `move-to-column' can
;; take it into account.
(when truncate
(let ((trunc-pos
(save-excursion
;; ¡¡ BIG UGLY HACK !!
;; `current-column' and `move-to-column' count
;; text hidden with an ellipsis "as if" it were
;; fully visible, which is completely wrong here,
;; so circumvent this by temporarily pretending
;; that `csv-truncate' is fully invisible (which
;; isn't quite right either, but should work
;; just well enough for us here).
(let ((buffer-invisibility-spec
buffer-invisibility-spec))
(add-to-invisibility-spec 'csv-truncate)
(move-to-column truncate))
(point))))
(put-text-property trunc-pos (point)
'invisible 'csv-truncate)
(when (> (- (point) trunc-pos) 1)
;; Arrange to temporarily untruncate the string when
;; cursor moves into it.
;; FIXME: This only works if
;; `global-disable-point-adjustment' is non-nil!
;; Arguably this should be fixed by making
;; point-adjustment code pay attention to
;; cursor-sensor-functions!
(put-text-property
(1+ trunc-pos) (point)
'cursor-sensor-functions
(list #'csv-align--cursor-truncated)))))
(unless (eolp) (forward-char)) ; Skip separator.
))))
(forward-line)))
`(jit-lock-bounds ,beg . ,end)))