<commit_before>
(define-library (led eval)
   (import
      (owl toplevel)
      (owl parse)
      (owl readline)
      (only (owl sys) isatty)
      (led log)
      (led buffer)
      (led extra)
      (led parse)
      (led env)
      (only (led system) led-path->runes)
      (only (led subprocess) start-repl)
      (only (led render) render-content))

   (export
      led-eval   ;; buff env exp -> buff' env' | #f env' (with error message)
      led-eval-runes
      led-repl   ;; maybe move elsewhere later

      push-undo
      pop-undo

      dirty?    ;; env -> bool, is the buffer dirty (has unsaved changes)
      )

   (begin

      ;; env name -> (data -> data)
      (define (led-eval-call env name)
         (find-extra name))

      (define (led-eval-position buff env exp)
         (if (number? exp)
            exp
            (begin
               (log "unknown position " exp)
               #f)))

      (define (push-undo env delta)
         (pipe env
            (put 'redo null) ;; destroy future of alternative past
            (put 'undo (cons delta (get env 'undo null)))))

      ;; use the undo stack as a marker of last saved status
      (define (mark-saved env)
         (put env 'saved (get env 'undo null)))

      (define (dirty? env)
         (not (equal?
            (get env 'undo null)
            (get env 'saved null))))

      (define (pop-undo env)
         (let ((stack (get env 'undo null)))
            (if (null? stack)
               (values env #false)
               (values
                  (pipe env
                     (put 'undo (cdr stack))
                     (put 'redo (cons (car stack) (get env 'redo null))))
                  (car stack)))))

      (define (pop-redo env)
         (let ((stack (get env 'redo null)))
            (if (null? stack)
               (values env #false)
               (values
                  (pipe env
                     (put 'redo (cdr stack))
                     (put 'undo (cons (car stack) (get env 'undo null))))
                  (car stack)))))

      (define (led-eval buff env exp)
         (log "led-eval " exp)
         (tuple-case exp
            ((left) ;; usually keyboard h, move left by one character on current line
               ;; convert to match ui-left
               (lets ((bp (seek-delta buff -1)))
                  (if (and bp (not (eq? #\newline (buffer-char bp))))
                     (values bp env)
                     (values buff env))))
            ((write-buffer target)
               (lets ((path (or target (get env 'path)))
                      (fd (and path (open-output-file path))))
                  (log "Writing buffer to " path)
                  (if fd
                     (let ((data (buffer->bytes buff)))
                        (if (write-bytes fd data)
                           (values buff
                              (set-status-text
                                 (pipe env
                                    (mark-saved)
                                    (put 'path path))
                                 (str "Wrote " (length data) "b to " path ".")))
                           (values #f
                              (set-status-text env (str "Failed to write to " path ".")))))<commit_msg>closing output file descriptor after saving buffer<commit_after>
(define-library (led eval)
   (import
      (owl toplevel)
      (owl parse)
      (owl readline)
      (only (owl sys) isatty)
      (led log)
      (led buffer)
      (led extra)
      (led parse)
      (led env)
      (only (led system) led-path->runes)
      (only (led subprocess) start-repl)
      (only (led render) render-content))

   (export
      led-eval   ;; buff env exp -> buff' env' | #f env' (with error message)
      led-eval-runes
      led-repl   ;; maybe move elsewhere later

      push-undo
      pop-undo

      dirty?    ;; env -> bool, is the buffer dirty (has unsaved changes)
      )

   (begin

      ;; env name -> (data -> data)
      (define (led-eval-call env name)
         (find-extra name))

      (define (led-eval-position buff env exp)
         (if (number? exp)
            exp
            (begin
               (log "unknown position " exp)
               #f)))

      (define (push-undo env delta)
         (pipe env
            (put 'redo null) ;; destroy future of alternative past
            (put 'undo (cons delta (get env 'undo null)))))

      ;; use the undo stack as a marker of last saved status
      (define (mark-saved env)
         (put env 'saved (get env 'undo null)))

      (define (dirty? env)
         (not (equal?
            (get env 'undo null)
            (get env 'saved null))))

      (define (pop-undo env)
         (let ((stack (get env 'undo null)))
            (if (null? stack)
               (values env #false)
               (values
                  (pipe env
                     (put 'undo (cdr stack))
                     (put 'redo (cons (car stack) (get env 'redo null))))
                  (car stack)))))

      (define (pop-redo env)
         (let ((stack (get env 'redo null)))
            (if (null? stack)
               (values env #false)
               (values
                  (pipe env
                     (put 'redo (cdr stack))
                     (put 'undo (cons (car stack) (get env 'undo null))))
                  (car stack)))))

      (define (led-eval buff env exp)
         (log "led-eval " exp)
         (tuple-case exp
            ((left) ;; usually keyboard h, move left by one character on current line
               ;; convert to match ui-left
               (lets ((bp (seek-delta buff -1)))
                  (if (and bp (not (eq? #\newline (buffer-char bp))))
                     (values bp env)
                     (values buff env))))
            ((write-buffer target)
               (lets ((path (or target (get env 'path)))
                      (fd (and path (open-output-file path))))
                  (log "Writing buffer to " path)
                  (if fd
                     (let ((data (buffer->bytes buff)))
                        (if (write-bytes fd data)
                           (begin
                              (close-port fd)
                              (values buff
                                 (set-status-text
                                    (pipe env
                                       (mark-saved)
                                       (put 'path path))
                                    (str "Wrote " (length data) "b to " path "."))))
                           (values #f
                              (set-status-text env (str "Failed to write to " path ".")))))
{'fraction_non_alphanumeric': 0.11356135613561356, 'fraction_numerical': 0.00030003000300030005, 'mean_word_length': 1.1759138381201044, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '561283', 'n_tokens_mistral': 1834, 'n_tokens_neox': 1732, 'n_words': 639}