MCPcopy
hub / github.com/desktop/desktop / wrapRichTextCommitMessage

Function wrapRichTextCommitMessage

app/src/lib/wrap-rich-text-commit-message.ts:34–107  ·  view source on GitHub ↗
(
  summaryText: string,
  bodyText: string,
  tokenizer: Tokenizer,
  maxSummaryLength = MaxSummaryLength
)

Source from the content-addressed store, hash-verified

32 * maxSummaryLength + 1 long when rendered.
33 */
34export function wrapRichTextCommitMessage(
35 summaryText: string,
36 bodyText: string,
37 tokenizer: Tokenizer,
38 maxSummaryLength = MaxSummaryLength
39): { summary: ReadonlyArray<TokenResult>; body: ReadonlyArray<TokenResult> } {
40 const tokens = tokenizer.tokenize(summaryText.trimRight())
41
42 const summary = new Array<TokenResult>()
43 const overflow = new Array<TokenResult>()
44
45 let remainder = maxSummaryLength
46
47 for (const token of tokens) {
48 // An emoji token like ":white_square_button: would still only take
49 // up a little bit more space than a regular character when rendered
50 // as an image, we take that into consideration here with an approximation
51 // that an emoji is twice as wide as a normal character.
52 const charCount = token.kind === TokenType.Emoji ? 2 : token.text.length
53
54 if (remainder <= 0) {
55 // There's no room left in the summary, everything needs to
56 // go into the overflow
57 overflow.push(token)
58 } else if (remainder >= charCount) {
59 // The token fits without us having to think about wrapping!
60 summary.push(token)
61 remainder -= charCount
62 } else {
63 // There's not enough room to include the token in its entirety,
64 // we've got to make a decision between hard wrapping or pushing
65 // to overflow.
66 if (token.kind === TokenType.Text) {
67 // We always hard-wrap text, it'd be nice if we could attempt
68 // to break at word boundaries in the future but that's too
69 // complex for now.
70 summary.push(text(token.text.substring(0, remainder)))
71 overflow.push(text(token.text.substring(remainder)))
72 } else if (token.kind === TokenType.Emoji) {
73 // Can't hard-wrap inside an emoji
74 overflow.push(token)
75 } else if (token.kind === TokenType.Link) {
76 // Hard wrapping an issue link is confusing so we treat them
77 // as atomic. For all other links (@mentions or https://...)
78 // We want at least the first couple of characters of the link
79 // text showing otherwise we'll end up with weird links like "h"
80 // or "@"
81 if (!token.text.startsWith('#') && remainder > 5) {
82 summary.push(link(token.text.substring(0, remainder), token.text))
83 overflow.push(link(token.text.substring(remainder), token.text))
84 } else {
85 overflow.push(token)
86 }
87 } else {
88 return assertNever(token, `Unknown token type`)
89 }
90
91 remainder = 0

Callers 2

wrapFunction · 0.90
createStateFunction · 0.90

Calls 6

assertNeverFunction · 0.90
textFunction · 0.85
linkFunction · 0.85
ellipsisFunction · 0.85
tokenizeMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected