diff --git a/channel_completion.go b/channel_completion.go index c62cd5e..6579cd9 100644 --- a/channel_completion.go +++ b/channel_completion.go @@ -17,17 +17,19 @@ func completionUserEntry(s state.Store, u discord.User, g *discord.Guild) cchat. m, err := s.Member(g.ID, u.ID) if err == nil { return cchat.CompletionEntry{ - Raw: u.Mention(), - Text: RenderMemberName(*m, *g), - IconURL: u.AvatarURL(), + Raw: u.Mention(), + Text: RenderMemberName(*m, *g), + Secondary: text.Rich{Content: u.Username + "#" + u.Discriminator}, + IconURL: u.AvatarURL(), } } } return cchat.CompletionEntry{ - Raw: u.Mention(), - Text: text.Rich{Content: u.Username}, - IconURL: u.AvatarURL(), + Raw: u.Mention(), + Text: text.Rich{Content: u.Username}, + Secondary: text.Rich{Content: u.Username + "#" + u.Discriminator}, + IconURL: u.AvatarURL(), } } @@ -73,9 +75,10 @@ func (ch *Channel) completeMentions(word string) (entries []cchat.CompletionEntr for _, u := range c.DMRecipients { if startsWith(match, u.Username) { entries = append(entries, cchat.CompletionEntry{ - Raw: u.Mention(), - Text: text.Rich{Content: u.Username}, - IconURL: u.AvatarURL(), + Raw: u.Mention(), + Text: text.Rich{Content: u.Username}, + Secondary: text.Rich{Content: u.Username + "#" + u.Discriminator}, + IconURL: u.AvatarURL(), }) if len(entries) >= MaxCompletion { return @@ -104,9 +107,10 @@ func (ch *Channel) completeMentions(word string) (entries []cchat.CompletionEntr for _, mem := range m { if startsWith(match, mem.User.Username, mem.Nick) { entries = append(entries, cchat.CompletionEntry{ - Raw: mem.User.Mention(), - Text: RenderMemberName(mem, *g), - IconURL: mem.User.AvatarURL(), + Raw: mem.User.Mention(), + Text: RenderMemberName(mem, *g), + Secondary: text.Rich{Content: mem.User.Username + "#" + mem.User.Discriminator}, + IconURL: mem.User.AvatarURL(), }) if len(entries) >= MaxCompletion { return @@ -178,10 +182,11 @@ func (ch *Channel) completeEmojis(word string) (entries []cchat.CompletionEntry) for _, emoji := range guild.Emojis { if startsWith(match, emoji.Name) { entries = append(entries, cchat.CompletionEntry{ - Raw: emoji.String(), - Text: text.Rich{Content: ":" + emoji.Name + ":"}, - IconURL: urlutils.Sized(emoji.EmojiURL(), 32), // small - Image: true, + Raw: emoji.String(), + Text: text.Rich{Content: ":" + emoji.Name + ":"}, + Secondary: text.Rich{Content: guild.Name}, + IconURL: urlutils.Sized(emoji.EmojiURL(), 32), // small + Image: true, }) if len(entries) >= MaxCompletion { return diff --git a/segments/embed.go b/segments/embed.go index a24c931..825ddf3 100644 --- a/segments/embed.go +++ b/segments/embed.go @@ -17,10 +17,12 @@ var imageExts = []string{".jpg", ".jpeg", ".png", ".webp", ".gif"} func (r *TextRenderer) renderEmbeds(embeds []discord.Embed, m *discord.Message, s state.Store) { for _, embed := range embeds { r.startBlock() - r.buf.WriteString("---\n") + r.buf.WriteString("---") + r.ensureBreak() r.renderEmbed(embed, m, s) + r.ensureBreak() r.buf.WriteString("---") // render prepends newline already r.endBlock() } diff --git a/segments/link.go b/segments/link.go index 0b3f4df..faa3d02 100644 --- a/segments/link.go +++ b/segments/link.go @@ -5,6 +5,11 @@ import ( "github.com/yuin/goldmark/ast" ) +// linkState is used for ast.Link segments. +type linkState struct { + linkstack []int // stack of starting integers +} + type LinkSegment struct { start, end int url string @@ -13,18 +18,31 @@ type LinkSegment struct { var _ text.Linker = (*LinkSegment)(nil) func (r *TextRenderer) link(n *ast.Link, enter bool) ast.WalkStatus { + // If we're entering the link node, then add the starting point to the stack + // and move on. if enter { - // Write the actual title. - start, end := r.write(n.Title) - - // Close the segment. - r.append(LinkSegment{ - start, - end, - string(n.Destination), - }) + r.lnks.linkstack = append(r.lnks.linkstack, r.buf.Len()) + return ast.WalkContinue } + // If there's nothing in the stack, then don't do anything. This shouldn't + // happen. + if len(r.lnks.linkstack) == 0 { + return ast.WalkContinue + } + + // We're exiting the link node. Pop the segment off the stack. + ilast := len(r.lnks.linkstack) - 1 + start := r.lnks.linkstack[ilast] + r.lnks.linkstack = r.lnks.linkstack[:ilast] + + // Close the segment on enter false. + r.append(LinkSegment{ + start, + r.buf.Len(), + string(n.Destination), + }) + return ast.WalkContinue } diff --git a/segments/md.go b/segments/md.go index 37b3e19..c8f69d9 100644 --- a/segments/md.go +++ b/segments/md.go @@ -55,6 +55,7 @@ type TextRenderer struct { src []byte segs []text.Segment inls inlineState + lnks linkState // these fields can be nil msg *discord.Message