Skip to content

Instantly share code, notes, and snippets.

@Metaxal
Last active September 10, 2023 09:41
Show Gist options
  • Save Metaxal/2628c2d4909cee135e5f6dd8254602a0 to your computer and use it in GitHub Desktop.
Save Metaxal/2628c2d4909cee135e5f6dd8254602a0 to your computer and use it in GitHub Desktop.
remove trailing spaces on save
#lang racket/base
;;; Author: Laurent Orseau https://github.com/Metaxal
;;; License: [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) or
;;; [MIT license](http://opensource.org/licenses/MIT) at your option.
(require quickscript
racket/string
racket/class)
(define (text-only-editor? ed)
(not (send ed find-next-non-string-snip #f)))
(define-hook on-save-file
#:help-string "Remove trailing spaces on save"
;; save-filename : target file path to save the file to.
;; filename : file path of the editor.
(λ (#:editor ed #:save-filename save-filename #:file filename)
(when (and
;; Check this is not a backup save, as there's an quick but annoying flicker that can
;; happen seemingly randomly otherwise.
(or (not filename) ; first-time save
(equal? save-filename filename))
;; Ensure that the editor is text only, otherwise non-string snips will be replaced
;; with "."
(text-only-editor? ed))
(define pos (send ed get-start-position))
(define ln (send ed position-line pos))
(define pos-in-line (- pos (send ed line-start-position ln)))
(define str (send ed get-text))
(define new-str (regexp-replace* #px" +\n" str "\n")) ; WARNING: eol may differ on platforms?
;; I think the docs for Flattened Text mention that "\n" is used to separate lines in text%
(unless (string=? str new-str) ; avoid modifying the buffer if nothing to do. Seems inefficient
;; Start an edit sequence so we can undo everything at once.
;; Ideally this sequence would be appended to the last user sequence so that a user
;; undo actually undoes the last user do, but I don't know how to do that.
(send ed begin-edit-sequence)
(send ed insert new-str 0 (send ed last-position))
(define new-pos (min (+ (send ed line-start-position ln) pos-in-line)
(send ed line-end-position ln)))
;; Restore cursor position on the same line
(send ed set-position new-pos)
(send ed end-edit-sequence)))))
(module url2script-info racket/base
(provide filename url)
(define filename "remove-trailing-spaces.rkt")
(define url "https://gist.github.com/Metaxal/2628c2d4909cee135e5f6dd8254602a0"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment