--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -96,9 +96,25 @@
 //config:	depends on FEATURE_LESS_DASHCMD
 //config:	help
 //config:	  Enables "-N" command.
+//config:
+//config:config FEATURE_LESS_RAW
+//config:	bool "Enable -R ('raw control characters')"
+//config:	default y
+//config:	depends on FEATURE_LESS_DASHCMD
+//config:	help
+//config:	This is essential for less applet to work with tools that use colors
+//config:	and paging, such as git, systemd tools or nmcli.
+//config:
+//config:config FEATURE_LESS_ENV
+//config:	bool "Take options from $LESS environment variable"
+//config:	default y
+//config:	depends on FEATURE_LESS_DASHCMD
+//config:	help
+//config:	This is essential for less applet to work with tools that use colors
+//config:	and paging, such as git, systemd tools or nmcli.
 
 //usage:#define less_trivial_usage
-//usage:       "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~I?] [FILE]..."
+//usage:       "[-E" IF_FEATURE_LESS_FLAGS("Mm") "N" IF_FEATURE_LESS_RAW("R") "h~I?] [FILE]..."
 //usage:#define less_full_usage "\n\n"
 //usage:       "View FILE (or stdin) one screenful at a time\n"
 //usage:     "\n	-E	Quit once the end of a file is reached"
@@ -108,6 +124,9 @@
 //usage:	)
 //usage:     "\n	-N	Prefix line number to each line"
 //usage:     "\n	-I	Ignore case in all searches"
+//usage:	IF_FEATURE_LESS_RAW(
+//usage:     "\n	-R	Remove color escape codes in input"
+//usage:	)
 //usage:     "\n	-~	Suppress ~s displayed past EOF"
 
 #include <sched.h>  /* sched_yield() */
@@ -143,6 +162,7 @@ enum {
 	FLAG_TILDE = 1 << 4,
 	FLAG_I = 1 << 5,
 	FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_DASHCMD,
+	FLAG_R = (1 << 7) * ENABLE_FEATURE_LESS_RAW,
 /* hijack command line options variable for internal state vars */
 	LESS_STATE_MATCH_BACKWARDS = 1 << 15,
 };
@@ -186,6 +206,9 @@ struct globals {
 	regex_t pattern;
 	smallint pattern_valid;
 #endif
+#if ENABLE_FEATURE_LESS_RAW
+	smallint in_escape;
+#endif
 #if ENABLE_FEATURE_LESS_ASK_TERMINAL
 	smallint winsize_err;
 #endif
@@ -458,6 +481,26 @@ static void read_lines(void)
 				*--p = '\0';
 				continue;
 			}
+#if ENABLE_FEATURE_LESS_RAW
+			if (option_mask32 & FLAG_R) {
+				if (c == '\033')
+					goto discard;
+				if (G.in_escape) {
+					if (isdigit(c)
+					 || c == '['
+					 || c == ';'
+					 || c == 'm'
+					) {
+ discard:
+						G.in_escape = (c != 'm');
+						readpos++;
+						continue;
+					}
+					/* Hmm, unexpected end of "ESC [ N ; N m" sequence */
+					G.in_escape = 0;
+				}
+			}
+#endif
 			{
 				size_t new_last_line_pos = last_line_pos + 1;
 				if (c == '\t') {
@@ -1613,12 +1656,34 @@ int less_main(int argc, char **argv)
 	/* TODO: -x: do not interpret backspace, -xx: tab also */
 	/* -xxx: newline also */
 	/* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */
-	getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S"));
+	getopt32(argv, "EMmN~I"
+		IF_FEATURE_LESS_DASHCMD("S")
+		IF_FEATURE_LESS_RAW("R")
+	);
 	argc -= optind;
 	argv += optind;
 	num_files = argc;
 	files = argv;
 
+	/* Tools typically pass LESS="FRSXMK".
+	 * The options we don't understand are ignored. */
+	if (ENABLE_FEATURE_LESS_ENV) {
+		char *c = getenv("LESS");
+		if (c) while (*c) switch (*c++) {
+		case 'M':
+			option_mask32 |= FLAG_M;
+			break;
+		case 'R':
+			option_mask32 |= FLAG_R;
+			break;
+		case 'S':
+			option_mask32 |= FLAG_S;
+			break;
+		default:
+			break;
+		}
+	}
+
 	/* Another popular pager, most, detects when stdout
 	 * is not a tty and turns into cat. This makes sense. */
 	if (!isatty(STDOUT_FILENO))
