objective-c cocoa syntax-highlighting nstextview

objective c - Resaltado de sintaxis de NSTextView



objective-c cocoa (4)

Por supuesto. Puede darle a NSTextView una NSAttributedString , y algunas de las cosas que puede hacer con la cadena atribuida es aplicar colores a ciertos subrangos de la cadena.

O puedes buscar en Google y ver que muchas personas han hecho cosas con esto antes.

Probablemente recomiendo usar OkudaKit .

Estoy trabajando en un editor de texto Cocoa que utiliza un NSTextView. ¿Es posible cambiar el color de ciertas partes del texto?


Te recomiendo que comiences por leer la página de CocoaDev sobre Sintaxis de resaltado. Mucha gente ha venido con soluciones para varios objetivos.

Si desea realizar el resaltado de sintaxis del código fuente, le sugiero que eche un vistazo al documento UKSyntaxColoredTextDocument de Uli Kusterer .


Debe agregar su controlador como el delegado del objeto NSTextStorage del NSTextView ( [textView textStorage] ) y luego implementar el método delegado ‑textStorageDidProcessEditing: Esto se llama siempre que el texto cambia.

En el método delegado, necesita obtener el objeto NSTextStorage actual de la vista de texto usando el método NSTextView de NSTextView . NSTextStorage es una subclase de NSAttributedString y contiene el contenido atribuido de la vista.

Su código debe analizar la cadena y aplicar color a los rangos de texto que le interesen. Aplicas color a un rango usando algo como esto, que aplicará un color amarillo a toda la cadena:

//get the range of the entire run of text NSRange area = NSMakeRange(0, [textStorage length]); //remove existing coloring [textStorage removeAttribute:NSForegroundColorAttributeName range:area]; //add new coloring [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor yellowColor] range:area];

Cómo analizar el texto depende de usted. NSScanner es una clase útil para usar cuando se analiza texto.

Tenga en cuenta que este método no es de ninguna manera la forma más eficiente de manejar el color de la sintaxis. Si los documentos que está editando son muy grandes, lo más probable es que desee considerar descargar el análisis a un hilo separado y / o ser inteligente con respecto a qué secciones del texto se vuelven a analizar.


La respuesta de Rob Keniger es buena, pero para alguien que busque un ejemplo más concreto, aquí hay un resaltador de sintaxis breve que escribí que debería resaltar la sintaxis de la plantilla RegEx. Quiero que sea gris, y que el personaje que sigue inmediatamente sea negro. Quiero que $ sea ​​rojo, con un carácter de dígito inmediatamente después de $ para que también sea rojo. Todo lo demás debería ser negro. Aquí está mi solución:

Hice una clase de resaltador de plantilla, con un encabezado que se parece a esto:

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate> @end

Lo inicializo en el archivo de plumilla como un objeto y lo conecto a mi controlador de vista con una salida. En awakeFromNib del controlador de vista, tengo esto (donde replacer es mi salida NSTextView y templateHighlighter es la salida para la clase anterior):

self.replacer.textStorage.delegate = self.templateHighlighter;

Y mi implementación se ve así:

- (void)textStorageDidProcessEditing:(NSNotification *)notification { NSTextStorage *textStorage = notification.object; NSString *string = textStorage.string; NSUInteger n = string.length; [textStorage removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, n)]; for (NSUInteger i = 0; i < n; i++) { unichar c = [string characterAtIndex:i]; if (c == ''//') { [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor lightGrayColor] range:NSMakeRange(i, 1)]; i++; } else if (c == ''$'') { NSUInteger l = ((i < n - 1) && isdigit([string characterAtIndex:i+1])) ? 2 : 1; [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(i, l)]; i++; } } }

Así que ahí van, un ejemplo completamente funcional. Hubo algunos detalles que me hicieron tropezar durante unos 10 minutos, como el hecho de que tienes que quitar la cadena de TextStorage para acceder a los caracteres individuales ... tal vez esto ahorre a otras personas unos minutos.