2023-02-27

itml2md

(sph lang scm-format)

#(library-short-description (sph lang scm-format))

sub-expression distribution algorithm nesting-proportional indentation possible transformations on code structure like sorting exports/imports/definitions command-line program and library part of #(link-c-one ("sph-lib" "start" "overview")) depends on guile-reader/ the command-line utility is part of #(link-c-one ("sph-script" "script" "overview" "project")) maturity: medium-high status: in active use, tested on all sph code often

caveats

mixed output of (quote) (unquote) and its read-syntax variants '() ,() is currently not retained. depending on the boolean config option "use-read-syntax-quote", all relevant forms get converted to one of those styles. this applies to quote/quasiquote/unquote/syntax/quasisyntax/unsyntax read syntax number notation, for example octal notation with #o, currently gets converted to decimal notation. for example #o755 becomes 493

default configuration

(define scm-format-default-config
  (ht-create-symbol
    format
    (ht-create-symbol
      indent-string (string-multiply " " 2)
      max-chars-per-line 100
      max-exprs-per-line-start 3
      max-exprs-per-line-middle 2
      max-exprs-per-line-end (inf)
      use-read-syntax-quote #f
      multiple-leading-parenthesis-spacing #t
      toplevel-vertical-spacing 1 toplevel-vertical-spacing-oneline 0)
    transform
    (ht-create-symbol
      sort-export #t
      sort-import #t sort-definitions #f separate-unexported-definitions #f)))

expression distribution

expressions between round brackets are counted and split into groups - start, middle, end they are distributed onto separate lines depending on the number of allowed expressions per line per group and the maximum allowed number of chars/columns per line vertical-spacing means newlines, and "oneline" in this context means expressions that fit completely on one line

indentation

the depth of indentation is always proportional to the depth of nesting. this is rather simple in definition and application and efficient in space usage. it is more consistent than other common styles, and the complexity and nesting of expressions can be easier to grasp

extendability

for example, custom formatters for list expressions with specific symbols as prefix can be set in the hash table "descend-prefix->format-proc" there is "ascend-prefix->format-proc" for matching expressions when going from the bottom to the top of the syntax tree. it contains no default procedures at the moment the matcher for structural syntax tree transformations is defined in (sph lang scm-format transform) and does not use a hashtable for setting procedures yet the files "lang/scm-format/format.scm" and "lang/scm-format/transform.scm" include the default expression formatters, which use (ice-9 match) to select parts of an expression and then create a string result

integration into emacs

for example with a procedure in .emacs config files that calls the scm-format command-line utility which is part of #(link-c-one ("sph-script" "script" "overview")) like so

(defun scheme-format ()
  (interactive)
  (let ((prev-point (point))) (shell-command-on-region (point-min) (point-max) "scm-format" t)
    (goto-char prev-point)))

this formats all buffer contents inside a mode hook this could be bound to a key combination

(add-hook (quote sph-scheme-mode-hook)
  (lambda () (define-key sph-scheme-mode-map (kbd "M-k") (quote scheme-format))))

(M-k here is M-b on qwerty-layouts)

#(library-documentation (sph lang scm-format))