diff -ur less-487.orig/charset.c less-487/charset.c
--- less-487.orig/charset.c	2016-10-25 16:37:35.000000000 +0200
+++ less-487/charset.c	2017-04-13 00:20:05.068644203 +0200
@@ -410,6 +410,7 @@
 	LWCHAR c;
 {
 	c &= 0377;
+	if (c == 7) return FALSE;  /* FIXME hack for OSC 8, should be shown as ^G if outside of this escape sequence */
 	return (chardef[c] & IS_CONTROL_CHAR);
 }
 
diff -ur less-487.orig/cvt.c less-487/cvt.c
--- less-487.orig/cvt.c	2016-10-25 16:37:35.000000000 +0200
+++ less-487/cvt.c	2017-04-15 14:56:54.506376184 +0200
@@ -85,13 +85,32 @@
 				dst--;
 			} while (dst > odst &&
 				!IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
-		} else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
+		} else if ((ops & CVT_ANSI) && ch == ESC)
 		{
-			/* Skip to end of ANSI escape sequence. */
-			src++;  /* skip the CSI start char */
-			while (src < src_end)
-				if (!is_ansi_middle(*src++))
-					break;
+			if (src[0] == ']' && src[1] == '8' && src[2] == ';')
+			{
+				/* Skip to the end of a hyperlink. */
+				src += 3;
+				while (src < src_end)
+				{
+					if (src[0] == BEL)
+					{
+						src++;
+						break;
+					} else if (src[0] == ESC && src[1] == '\\')
+					{
+						src += 2;
+						break;
+					}
+					src++;
+				}
+			} else
+			{
+				/* Skip to end of ANSI escape sequence. */
+				while (src < src_end)
+					if (!is_ansi_middle(*src++))
+						break;
+			}
 		} else
 		{
 			/* Just copy the char to the destination buffer. */
diff -ur less-487.orig/less.h less-487/less.h
--- less-487.orig/less.h	2016-10-25 16:37:39.000000000 +0200
+++ less-487/less.h	2017-04-12 23:51:59.536649871 +0200
@@ -464,7 +464,10 @@
 #endif /* IS_EBCDIC_HOST */
 
 #define	ESC		CONTROL('[')
+#define	BEL		CONTROL('g')
 #define	CSI		((unsigned char)'\233')
+#define	ST		((unsigned char)'\234')
+#define	OSC		((unsigned char)'\235')
 #define	CHAR_END_COMMAND 0x40000000
 
 #if _OSK_MWC32
diff -ur less-487.orig/line.c less-487/line.c
--- less-487.orig/line.c	2016-10-25 16:37:36.000000000 +0200
+++ less-487/line.c	2017-04-13 01:09:37.718136458 +0200
@@ -264,17 +264,29 @@
 	while (shifted <= shift && from < curr)
 	{
 		c = linebuf[from];
-		if (ctldisp == OPT_ONPLUS && IS_CSI_START(c))
+		/* FIXME: accept C1 CSI and C1 OSC as well! */
+		if (ctldisp == OPT_ONPLUS && c == ESC)
 		{
 			/* Keep cumulative effect.  */
 			linebuf[to] = c;
 			attr[to++] = attr[from++];
-			while (from < curr && linebuf[from])
-			{
-				linebuf[to] = linebuf[from];
-				attr[to++] = attr[from];
-				if (!is_ansi_middle(linebuf[from++]))
-					break;
+			if (linebuf[from] == ']' && linebuf[from+1] == '8' && linebuf[from+2] == ';') {
+				while (from < curr && linebuf[from])
+				{
+					linebuf[to] = linebuf[from];
+					attr[to++] = attr[from++];
+					/* FIXME: accept C1 ST */
+					if (linebuf[from-1] == BEL || (linebuf[from-1] == '\\' && linebuf[from-2] == ESC))
+						break;
+				}
+			} else {
+				while (from < curr && linebuf[from])
+				{
+					linebuf[to] = linebuf[from];
+					attr[to++] = attr[from];
+					if (!is_ansi_middle(linebuf[from++]))
+						break;
+				}
 			} 
 			continue;
 		}
@@ -506,23 +518,139 @@
 
 /*
  * Are we currently within a recognized ANSI escape sequence?
+ *
+ * FIXME This code is a nightmare!
+ * Displaying a line potentially takes O(n^2) time as this function is called
+ * for each character. 
+ * Why do we walk backwards at all, rather having a state machine that knows
+ * the current state???
+ * Not to mention the if-else hell...
  */
 	static int
 in_ansi_esc_seq()
 {
-	char *p;
+	char *p, *save;
+	LWCHAR ch, ch2;
 
 	/*
-	 * Search backwards for either an ESC (which means we ARE in a seq);
+	 * Search backwards for either a CSI (which means we ARE in a seq);
 	 * or an end char (which means we're NOT in a seq).
 	 */
+
+	/* Potential lone ESC */
+	p = &linebuf[curr];
+	if (p > linebuf)
+	{
+		ch = step_char(&p, -1, linebuf);
+		if (ch == ESC)
+			return (1);
+	}
+
+	/* Search for ESC [ or a terminator character */
 	for (p = &linebuf[curr];  p > linebuf; )
 	{
-		LWCHAR ch = step_char(&p, -1, linebuf);
-		if (IS_CSI_START(ch))
+		ch = step_char(&p, -1, linebuf);
+		save = p;
+		if (ch == ESC)
 			return (1);
+		if (ch == CSI)
+			return (1);
+		else if (ch == '[' && p > linebuf)
+		{
+			ch2 = step_char(&p, -1, linebuf);
+			if (ch2 == ESC)
+				return (1);
+		}
 		if (!is_ansi_middle(ch))
 			return (0);
+		p = save;
+	}
+	return (0);
+}
+
+/*
+ * Are we currently within a hyperlink escape sequence?
+ * (Not to be confused with the the visible anchor text of the hyperlink.)
+ *
+ * FIXME This code is a nightmare!
+ * Displaying a line potentially takes O(n^2) time as this function is called
+* for each character. 
+ * Why do we walk backwards at all, rather having a state machine that knows
+ * the current state???
+ * Not to mention the if-else hell...
+ */
+	static int
+in_hyperlink_esc_seq()
+{
+	char *p, *save;
+	LWCHAR ch, ch2, ch3, ch4;
+
+	/*
+	 * Search backwards for either an OSC 8 ; (which means we ARE in a hyperlink);
+	 * or a BEL or ST (which means we're NOT in a seq).
+	 */
+
+	/* Potential prefix (ESC, ESC [ or ESC [ 8 but no semicolon yet) */
+	p = &linebuf[curr];
+	if (p > linebuf)
+	{
+		ch = step_char(&p, -1, linebuf);
+		if (ch == ESC)
+			return (1);
+		else if (ch == OSC)
+			return (1);
+		else if (ch == ']' && p > linebuf)
+		{
+			ch2 = step_char(&p, -1, linebuf);
+			if (ch2 == ESC)
+				return (1);
+		}
+		else if (ch == '8' && p > linebuf)
+		{
+			ch2 = step_char(&p, -1, linebuf);
+			if (ch2 == OSC)
+				return (1);
+			else if (ch2 == ']' && p > linebuf)
+			{
+				ch3 = step_char(&p, -1, linebuf);
+				if (ch3 == ESC)
+					return (1);
+			}
+		}
+	}
+
+	/* ESC [ 8 ; or a terminator */
+	for (p = &linebuf[curr];  p > linebuf; )
+	{
+		ch = step_char(&p, -1, linebuf);
+		save = p;
+		if (ch == BEL)
+			return (0);
+		else if (ch == ST)
+			return (0);
+		else if (ch == '\\' && p > linebuf)
+		{
+			ch2 = step_char(&p, -1, linebuf);
+			if (ch2 == ESC)
+				return (0);
+		}
+		else if (ch == ';' && p > linebuf)
+		{
+			ch2 = step_char(&p, -1, linebuf);
+			if (ch2 == '8' && p > linebuf)
+			{
+				ch3 = step_char(&p, -1, linebuf);
+				if (ch3 == OSC)
+					return (1);
+				else if (ch3 == ']' && p > linebuf)
+				{
+					ch4 = step_char(&p, -1, linebuf);
+					if (ch4 == ESC)
+						return (1);
+				}
+			}
+		}
+		p = save;
 	}
 	return (0);
 }
@@ -596,7 +724,12 @@
 	}
 #endif
 
-	if (ctldisp == OPT_ONPLUS && in_ansi_esc_seq())
+	if (ctldisp == OPT_ONPLUS && in_hyperlink_esc_seq())
+	{
+		a = AT_ANSI;
+		w = 0;
+	}
+	else if (ctldisp == OPT_ONPLUS && in_ansi_esc_seq())
 	{
 		if (!is_ansi_end(ch) && !is_ansi_middle(ch)) {
 			/* Remove whole unrecognized sequence.  */
@@ -963,7 +1096,7 @@
 		{
 			STORE_PRCHAR((char) ch, pos);
 		}
-	} else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch))
+	} else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch) && ch != 7 /* FIXME hack for OSC 8 */)
 	{
 		char *s;
 
@@ -1030,6 +1163,16 @@
 		for ( ;  *p != '\0';  p++)
 		{
 			linebuf[curr] = *p;
+			attr[curr++] = AT_ANSI;
+		}
+	}
+	if (ctldisp == OPT_ONPLUS)
+	{
+		/* Turn off hyperlink at end of line. */
+		char *p = "\033]8;;\007";
+		for ( ;  *p != '\0';  p++)
+		{
+			linebuf[curr] = *p;
 			attr[curr++] = AT_ANSI;
 		}
 	}
