Skip to content

Instantly share code, notes, and snippets.

@lionel-rowe
Last active February 12, 2026 17:03
Show Gist options
  • Select an option

  • Save lionel-rowe/472d3de7738494746e5015d31220b748 to your computer and use it in GitHub Desktop.

Select an option

Save lionel-rowe/472d3de7738494746e5015d31220b748 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Revert GitHub PR Title Truncation
// @namespace https://github.com/lionel-rowe/
// @version 0.4
// @description Revert GitHub PR Title Truncation
// @author https://github.com/lionel-rowe/
// @match https://github.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
// @grant none
// @run-at document-start
// ==/UserScript==
// https://github.com/orgs/community/discussions/12450
// @ts-check
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/** @typedef {{ title: string, body: string }} Content */
const ELLIPSIS = '…'
new MutationObserver(untruncate).observe(
document.documentElement,
{ childList: true, subtree: true },
)
untruncate()
function untruncate() {
if (!location.pathname.includes('/compare/')) return
const $title = document.querySelector('[name="pull_request[title]"]')
const $body = document.querySelector('[name="pull_request[body]"]')
if (!$title?.checkVisibility() || !$body?.checkVisibility()) return
if (!($title instanceof HTMLInputElement) || !($body instanceof HTMLTextAreaElement)) {
throw new TypeError('Unexpected element types')
}
reflow($title, $body)
}
/**
* @param {HTMLInputElement} $title
* @param {HTMLTextAreaElement} $body
*/
function reflow($title, $body) {
const result = getReflowed({ title: $title.value, body: $body.value })
if (result == null) return
$title.value = result.title
$body.value = result.body
}
/**
* @param {Content} content
* @returns {Content | null}
*/
function getReflowed({ title, body }) {
if (title.endsWith(ELLIPSIS) && body.startsWith(ELLIPSIS)) {
const m = /\n\s*/.exec(body)
const first = body.slice(0, m?.index ?? undefined)
const rest = m == null ? '' : body.slice(m.index + m[0].length)
return {
title: title.slice(0, -ELLIPSIS.length) + first.slice(ELLIPSIS.length),
body: rest,
}
}
return null
}
@lionel-rowe
Copy link
Author

Title gets wrong when a PR tempate is used

  • $title.value = $title.value.slice(0, -ellipsis.length) + $body.value.slice(ellipsis.length)

  • $title.value = $title.value.slice(0, -ellipsis.length) + first.slice(ellipsis.length)

Thanks @StefanMich ! Updated with that fix and a couple of other changes.

@orestesgaolin
Copy link

In my case I had to change

// @match        https://github.com/*/compare/*

to

// @match        https://github.com/**/compare/*

@lionel-rowe
Copy link
Author

In my case I had to change
...

Thanks @orestesgaolin ! I've updated the script to run on @match https://github.com/*, along with some other changes. That's necessary because most navigations on GitHub don't cause full-page refresh, thus the initially matched URL might be something completely different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment