diff -urNad nedit-5.7~/source/preferences.c nedit-5.7/source/preferences.c
--- nedit-5.7~/source/preferences.c	2017-02-05 03:15:41.000000000 +1100
+++ nedit-5.7/source/preferences.c	2022-10-05 14:23:14.200972362 +1100
@@ -324,6 +324,11 @@
     Boolean honorSymlinks;
     int truncSubstitution;
     Boolean forceOSConversion;
+	int visibleTabStopsTab;
+	int visibleTabStopsTabReplaceFirstCharacterOnly;
+	int visibleTabStopsTabReplacementChar;
+	int visibleTabStopsSpace;
+	int visibleTabStopsSpaceReplacementChar;
 } PrefData;
 
 /* Temporary storage for preferences strings which are discarded after being
@@ -1072,7 +1077,17 @@
     {"truncSubstitution", "TruncSubstitution", PREF_ENUM, "Fail",
             &PrefData.truncSubstitution, TruncSubstitutionModes, False},
     {"honorSymlinks", "HonorSymlinks", PREF_BOOLEAN, "True",
-            &PrefData.honorSymlinks, NULL, False}
+            &PrefData.honorSymlinks, NULL, False},
+    {"visibleTabStopsTab", "visibleTabStopsTab", PREF_BOOLEAN, "False",
+    	&PrefData.visibleTabStopsTab, NULL, False},
+    {"visibleTabStopsTabReplaceFirstCharacterOnly", "visibleTabStopsTabReplaceFirstCharacterOnly", PREF_BOOLEAN, "True",
+    	&PrefData.visibleTabStopsTabReplaceFirstCharacterOnly, NULL, False},
+    {"visibleTabStopsTabReplacementChar", "visibleTabStopsTabReplacementChar", PREF_INT, "187",
+    	&PrefData.visibleTabStopsTabReplacementChar, NULL, False},
+    {"visibleTabStopsSpace", "visibleTabStopsSpace", PREF_BOOLEAN, "False",
+    	&PrefData.visibleTabStopsSpace, NULL, False},
+    {"visibleTabStopsSpaceReplacementChar", "MaxPrevOpenFiles", PREF_INT, "183",
+    	&PrefData.visibleTabStopsSpaceReplacementChar, NULL, False},
 };
 
 static XrmOptionDescRec OpTable[] = {
@@ -1333,6 +1348,8 @@
        written by an older version of NEdit, update regular expressions in
        highlight patterns to quote braces and use & instead of \0 */
     translatePrefFormats(requiresConversion, fileVer);
+	
+	BufSetVisibleSpaceCharacters(PrefData.visibleTabStopsTab, PrefData.visibleTabStopsTabReplaceFirstCharacterOnly, PrefData.visibleTabStopsTabReplacementChar, PrefData.visibleTabStopsSpace, PrefData.visibleTabStopsSpaceReplacementChar);
 }
 
 /*
diff -urNad nedit-5.7~/source/textBuf.c nedit-5.7/source/textBuf.c
--- nedit-5.7~/source/textBuf.c	2017-02-05 03:15:41.000000000 +1100
+++ nedit-5.7/source/textBuf.c	2022-10-05 14:47:24.144712278 +1100
@@ -47,6 +47,12 @@
                                    in the buffer where text might be inserted
                                    if the user is typing sequential chars) */
 
+int visibleTabStopsTab = 0;
+int visibleTabStopsTabReplaceFirstCharacterOnly = 0;
+char visibleTabStopsTabReplacementChar = '»';	/*(char)187*/
+int visibleTabStopsSpace = 0;
+char visibleTabStopsSpaceReplacementChar = '·';	/*(char)183*/
+
 static void histogramCharacters(const char *string, int length, char hist[256],
 	int init);
 static void subsChars(char *string, int length, char fromChar, char toChar);
@@ -1045,13 +1051,38 @@
         int tabDist, char nullSubsChar)
 {
     int i, nSpaces;
-    
+
+	if(visibleTabStopsSpace) {
+		/* show space characters */
+		if (c == ' ') {
+			*outStr = visibleTabStopsSpaceReplacementChar;
+			return 1;
+    	}
+	}
+	    
     /* Convert tabs to spaces */
     if (c == '\t') {
-	nSpaces = tabDist - (indent % tabDist);
-	for (i=0; i<nSpaces; i++)
-	    outStr[i] = ' ';
-	return nSpaces;
+		nSpaces = tabDist - (indent % tabDist);
+		for (i=0; i<nSpaces; i++) {
+			if(visibleTabStopsTab) {
+				/* show tab characters */
+				if(visibleTabStopsTabReplaceFirstCharacterOnly) {
+					if(i == 0) {
+						outStr[i] = visibleTabStopsTabReplacementChar;
+					}
+					else {
+						outStr[i] = ' ';
+					}
+				}
+				else {
+					outStr[i] = visibleTabStopsTabReplacementChar;
+				}
+			}
+			else {
+				outStr[i] = ' ';
+			}
+		}
+		return nSpaces;
     }
     
     /* Convert ASCII (and EBCDIC in the __MVS__ (OS/390) case) control
@@ -2578,3 +2609,13 @@
 {
     return i1 <= i2 ? i1 : i2;
 }
+
+void BufSetVisibleSpaceCharacters(int visibleTabStopsTabNew, int visibleTabStopsTabReplaceFirstCharacterOnlyNew, int visibleTabStopsTabReplacementCharNew, int visibleTabStopsSpaceNew, int visibleTabStopsSpaceReplacementCharNew)
+{
+	visibleTabStopsTab = visibleTabStopsTabNew;
+	visibleTabStopsTabReplaceFirstCharacterOnly = visibleTabStopsTabReplaceFirstCharacterOnlyNew;
+	visibleTabStopsTabReplacementChar = visibleTabStopsTabReplacementCharNew;
+	visibleTabStopsSpace = visibleTabStopsSpaceNew;
+	visibleTabStopsSpaceReplacementChar = visibleTabStopsSpaceReplacementCharNew;
+}
+
diff -urNad nedit-5.7~/source/textBuf.h nedit-5.7/source/textBuf.h
--- nedit-5.7~/source/textBuf.h	2017-02-05 03:15:41.000000000 +1100
+++ nedit-5.7/source/textBuf.h	2022-10-05 14:17:11.471593297 +1100
@@ -168,5 +168,6 @@
 int BufSubstituteNullChars(char *string, int length, textBuffer *buf);
 void BufUnsubstituteNullChars(char *string, textBuffer *buf);
 int BufCmp(textBuffer * buf, int pos, int len, const char *cmpText);
+void BufSetVisibleSpaceCharacters(int visibleTabStopsTabNew, int visibleTabStopsTabReplaceFirstCharacterOnlyNew, int visibleTabStopsTabReplacementCharNew, int visibleTabStopsSpaceNew, int visibleTabStopsSpaceReplacementCharNew);
 
 #endif /* NEDIT_TEXTBUF_H_INCLUDED */
