Skip to content

Instantly share code, notes, and snippets.

@JordanMartinez
Created November 21, 2018 16:35
Show Gist options
  • Save JordanMartinez/f540b0c75232f1c7ac611e61b86651af to your computer and use it in GitHub Desktop.
Save JordanMartinez/f540b0c75232f1c7ac611e61b86651af to your computer and use it in GitHub Desktop.
Philosophy of Text Editor

Problems to solve

Model of Editor

  • a definition for what a docuemnt is
    • Sequence of Paragraphs
      • non-newline-ending-pars
        • PlainText - sequence of strings (paragraphs)
        • RichText - sequence of styled segments
      • newline-ending pars
        • singlePar
    • Sequence of Entities
      • ClassedText - sequence of entities that determine how to be rendered (paragraphs, lines, segments, etc.)
        • parser-based design using a tree-structure
          • syntax highlighting
          • changes allowed/not allowed at some position
  • changes
    • can a change be done at position X?
    • what kind of changes can be done
      • only invertable changes?
        • if yes: undo/redo supported
        • if no:
          • undo/redo not supported
          • undo/redo supported, but must forget undo history since can't undo the change
      • content-based:
        • insertion
        • deletion
        • replacement
      • caret-based: (code is simplified if caret is modeled same way as selection where caret/anchor == same)
        • moveByChars left/right amount
        • moveToPos position
        • drop anchor and moveby left/right amount
        • drop anchor and move to position
      • selection-based:
        • change to caret
        • move caret/anchor/leftmost/rightmost ByChars left/right amount collapse/no-collapse
        • move caret/anchor/leftmost/rightmost to position collapse/no-collapse
        • shiftBoth ByChars left/right amount
    • how should a change be modeled
      • store previous & next states:
        • Comparison
          • Pros: accurate & easy
          • Cons: memory inefficient
      • store change that, when applied to old, produces new:
        • Comparison
          • Pros: memory efficient
          • Cons: requires syncing
        • How should a changes sync?
          • update content
          • update positions
          • update viewport
    • can changes be merged?
      • if so, what is a valid merge?
        • time-based: merge if within a given time period or not
        • source-based: merge if initiated by one, some or all: user, programmer
        • content-based:
          • merge two consecutive insertions by making one change that inserts both at once
          • merge two consecutive deletions by making one change that deletes both at once
          • merge two consecutive replacements by making one change that deletes both and inserts both at once
        • position-based:
          • TODO
          • merge two consecutive caret movements by
          • merge two
  • positions within the document
    • What types of positions can be in a document?
      • caret
      • selection
      • decoration (range with info)
    • how many positions can be in a document?
      • none & 0 decorations - static (regular non-editable HTML)
      • none + 0..n decorations - readonly (dynamic non-editable HTML)
      • 1 c/s + 0..n decorations - editable (dynamic editable HTML)
      • multiple c/s + 0..n decorations - refactorable
    • how should a position be modeled in the document?
      • Coordinate System used
        • position stored outside of document
          • 1D position (0 .. lengthOfDoc)
          • 2D position ( (0 .. lastParIdx) (0 .. lastColPos of par))
        • position stored within document
          • cursor-based position
            • supports only 1 position
          • find-by-path-based position (root -> (node -> ...) leaf)
            • supports multple positions
      • Specific types
        • caret: 1 position
        • selection: 2 positions
        • decorations: 2 positions + arbitrary data

View / Viewport

  • Translating between Coordinate Systems
    • where did a screen position occur in a document?
      • screen x-y coordinate -> viewport left-top-scaleX-scaleY-scrollX-scrollY coordinate -> documentPosition
    • where does a document position appear on the screen?
      • docuemntPosition -> viewport left-top-scaleX-scaleY-scrollX-scrollY coordinate -> screen x-y coordinate
    • where does a screen position appear in viewport?
      • viewport left-top-scaleX-scaleY-scrollX-scrollY coordinate -> screen x-y coordinate
    • where does a viewport position appear on screen?
      • screen x-y coordinate -> viewport left-top-scaleX-scaleY-scrollX-scrollY coordinate
  • Scrolling
    • What is a scroll?
      • Input: mouse-wheel / touch-based / scrollbar-based
      • Direction: X / Y / Both
      • Inertia:
        • on or not?
        • how much to scale the scroll?
  • Rendering
    • What is rendering
      • a function that maps a model of some content to a view of it
        • view could be editable or read-only
        • different functions could generate different views of same content
          • markdown writer & renderer
          • regular one (for me) & debug one (for figuring out where it's positioning things...)
    • What is folding
      • temporarily rendering some content with a placeholder image / span
    • What types of folding
      • Block/Paragraph folding
        • only top-level entities (e.g. paragraphs) can be folded
      • Range folding
        • range from X to Y is folded
          • allows possibility of making content that appears on two separate lines appear on the same line
    • How could something be rendered
      • types of rendering
        • separate rendering
          • render the content, then the caret/selection/decorations, then the scrollbars (if needed)
            • Pro/Con
              • Pros:
                • easiest?
              • Cons:
                • assumes grid-like viewport (rows = paragraphs, columns = characters)
                  • adding images would significantly complicate this issue
        • sequential rendering
          • render content & c/s/d as one entity, then the scrollbars (if needed)
            • Pro/Con
              • Pros:
                • enable inverting the color of selected text
              • Cons:
                • might not be that 'fast'
                • assumes content can be split
        • hybrid
          • store content and selection boundary separately in leaf
      • Viewport options
        • [not useful] no viewport; use overflow value
          • no overflow
            • content goes beyond layout: bad
          • clipped
            • content clipped & can't access it unless implement scrolling of some sort (basically need to implement a viewport at that point...)
          • auto
            • content clipped & can scroll, but no API to translate screen position into document position
        • viewport-based
          • any anchor cell + offset + fill viewport
            • layout anchor at offset, continue below until empty, continue above until empty
            • line height = fixed
            • fill 'extra space' if have content for that
              • this part makes this problematic!
          • top anchor cell + offset + fill below viewport until empty
            • layout anchor at offset and continue laying out below
            • line height = fixed
            • simulate "extra space" at bottom of area and at top of area
            • how would one prevent 'extra space'?
              • if top == 0, then offset > 0
              • if top == (lastViewportIdx), then offset < 0
              • No, enable TopAnchor and BottomAnchor positions, which determine the layout direction
                • Note: this also takes care of "gravity" idea from Flowless
                • However, calculation would need to be aware of possibility of anchor-referent flipping
          • top anchor & offset + range based
            • line height = dynamic (depends on total number in range)
            • layout top at offset, and layout remaining lines, distributing available viewport height evenly
            • scaling vertically would be easier...?
              • Only my code would benefit from this approach
        • Scrollbars
          • what are they
            • represent the amount of content being viewed (the block) and where in the document (the track)
            • enable fine-tune scrolling (as opposed to wheel-based scrolling)
          • Scroll bar options
            • always
              • easiest but takes up 'real estate'
            • never
              • easiest but fine-tune behavior needs to be provided in some other way
            • as needed
              • general idea:
                • calc if need y & x
                • if both, do both
                • if one then...
                  • if Y/X causes X/Y to be too short, do both
                  • otherwise, just do Y/X
                • else do neither
            • appear when hover
              • hidden by default but appear 'over' the content
              • appearing
                • fade in/out when hover over their section
                  • opacity increases gradually based on mouse distance from the scroll bar
                • there or not based on whether mouse is over section
              • Issues
                • touch can't 'hover' (though I guess tapping the screen would work...)
                • unexpected behavior: click at end, and end up clicking on track, not content, which causes a unexpected scroll
  • Events
    • Context-based (may be a part of a sequence and requires other info)
      • General Idea: Context Start Trigger -> input -> Context End Trigger
      • Possible State Conditions
        • continue if X-chars has been inputted
        • continue if X-mouse events has occurred
        • continue if X-time has passed
        • continue is X-process has started/is-ongoing/finished (HTTP request, file save, etc.)
        • continue without condition (primitive context)
      • Specific Details
        • Context Start Trigger
          • current state fits some context
        • Input
          • 1 or more events (mouse, keyboard, time, etc.)
        • Context End Trigger
          • current state meets some condition
    • Specific Contexts
      • main caret is
        • a caret and
          • user
            • clicks mouse:
              • move caret to that position
            • presses a "regular" key:
              • insert content
              • delete content
              • move caret to new position
          • programmer
            • uses API to do something
              • do that something
        • is a selection and
          • user
            • shift is
              • not pressed & clicks mouse:
                • move caret to that position & collapse selection
              • pressed & clicks mouse
                • move caret to new position, changing selection
            • presses a "regular" key:
              • delete selection & insert content
              • delete selection
              • move caret to new position, changing selection
            • starts to drag mouse:
              • not over the selection
                • but stops without movement
                  • move caret to that position & collapse selection
                • and continues dragging mouse
                  • move caret to new position, changing selection
                  • and stops dragging mouse
                    • move caret to new position, changing selection (might already be here, so irrelevant)
              • over the selection
                • but stops without movement
                  • move caret to that position & collapse selection
                • and continues dragging mouse
                  • and 1st time dragging
                    • generate move image
                    • change selection to decoration
                    • move caret to where mouse is
                  • and n-time dragging
                    • move caret to where mouse is
                  • and stops dragging mouse
                    • delete old selection & its content
                    • insert old content at where caret is
                    • add selection from caret's start position to end of insertion
          • programmer
            • uses API to do something
              • do that something
  • MouseEvents
    • what kind of event has occurred?
      • mouse clicked & click count is 1/2/3/4/n
      • mouse drag started & inside/not-inside selection
      • mouse being dragged & not-dragging/dragging a selection & mouse inside/outside editor
      • mouse finished drag & was not-dragging/dragging a selection
  • KeyboardEvent
    • What kind of keyboard events should be listened to?
      • Primitive (doesn't require any other info besides event)
        • navigation
          • arrow keys: up/down/left/right
          • home/end keys
          • page up/down keys
        • edits
          • Special edits
            • whitespace
              • tab
              • space
              • enter
            • deletion
              • delete
              • backspace
          • Latin-based
            • alphabet + numbers + symbols
          • IME-based
            • Asian languages
        • behaviors:
          • Ctrl/Shift/Alt/Meta stuff
          • FN-based stuff
          • F[1-12] based stuff
          • context-menu stuff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment