Text editor: syntax highlighting + line numbers on by default
The most common use of the text editor seems to be for scripting. Having line numbers and syntax highlighting enabled by default seems sensible. Syntax highlighting is now enabled by default, but is automatically disabled when the datablock has a non-highlighted extension. Highlighting is enabled for filenames like: - Text - Text.001 - somefile.py and is automatically disabled when the datablock has an extension for which Blender has no syntax highlighter registered. Reviewers: billreynish, campbellbarton Subscribers: brecht, billreynish Differential Revision: https://developer.blender.org/D5472
This commit is contained in:
parent
72eb70f933
commit
05417b2220
|
@ -50,7 +50,11 @@ class TEXT_HT_header(Header):
|
|||
row = layout.row(align=True)
|
||||
row.prop(st, "show_line_numbers", text="")
|
||||
row.prop(st, "show_word_wrap", text="")
|
||||
row.prop(st, "show_syntax_highlight", text="")
|
||||
|
||||
is_syntax_highlight_supported = st.is_syntax_highlight_supported()
|
||||
syntax = row.row(align=True)
|
||||
syntax.active = is_syntax_highlight_supported
|
||||
syntax.prop(st, "show_syntax_highlight", text="")
|
||||
|
||||
if text:
|
||||
is_osl = text.name.endswith((".osl", ".osl"))
|
||||
|
@ -65,6 +69,7 @@ class TEXT_HT_header(Header):
|
|||
row.prop(text, "use_module")
|
||||
|
||||
row = layout.row()
|
||||
row.active = is_syntax_highlight_supported
|
||||
row.operator("text.run_script")
|
||||
|
||||
|
||||
|
@ -226,7 +231,9 @@ class TEXT_MT_view(Menu):
|
|||
|
||||
layout.prop(st, "show_line_numbers")
|
||||
layout.prop(st, "show_word_wrap")
|
||||
layout.prop(st, "show_syntax_highlight")
|
||||
syntax = layout.column()
|
||||
syntax.active = st.is_syntax_highlight_supported()
|
||||
syntax.prop(st, "show_syntax_highlight")
|
||||
layout.prop(st, "show_line_highlight")
|
||||
|
||||
layout.separator()
|
||||
|
|
|
@ -42,6 +42,8 @@ void BLI_split_dirfile(
|
|||
const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen);
|
||||
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen);
|
||||
void BLI_split_file_part(const char *string, char *file, const size_t filelen);
|
||||
const char *BLI_path_extension(const char *filepath) ATTR_NONNULL();
|
||||
|
||||
void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file)
|
||||
ATTR_NONNULL();
|
||||
void BLI_join_dirfile(char *__restrict string,
|
||||
|
|
|
@ -38,6 +38,7 @@ struct ListBase;
|
|||
typedef bool (*UniquenameCheckCallback)(void *arg, const char *name);
|
||||
|
||||
size_t BLI_split_name_num(char *left, int *nr, const char *name, const char delim);
|
||||
bool BLI_string_is_decimal(const char *string) ATTR_NONNULL();
|
||||
|
||||
void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len);
|
||||
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len);
|
||||
|
|
|
@ -1684,6 +1684,24 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen)
|
|||
BLI_split_dirfile(string, NULL, file, 0, filelen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the last extension (e.g. the position of the last period).
|
||||
* Returns NULL if there is no extension.
|
||||
*/
|
||||
const char *BLI_path_extension(const char *filepath)
|
||||
{
|
||||
const char *extension = strrchr(filepath, '.');
|
||||
if (extension == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (BLI_first_slash(extension) != NULL) {
|
||||
/* There is a path separator in the extension, so the '.' was found in a
|
||||
* directory component and not in the filename. */
|
||||
return NULL;
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a filename to a dir, ensuring slash separates.
|
||||
*/
|
||||
|
|
|
@ -82,6 +82,21 @@ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char deli
|
|||
return name_len;
|
||||
}
|
||||
|
||||
bool BLI_string_is_decimal(const char *string)
|
||||
{
|
||||
if (*string == '\0') {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Keep iterating over the string until a non-digit is found. */
|
||||
while (isdigit(*string)) {
|
||||
string++;
|
||||
}
|
||||
|
||||
/* If the non-digit we found is the terminating \0, everything was digits. */
|
||||
return *string == '\0';
|
||||
}
|
||||
|
||||
static bool is_char_sep(const char c)
|
||||
{
|
||||
return ELEM(c, '.', ' ', '-', '_');
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
struct ARegion;
|
||||
struct bContext;
|
||||
struct SpaceText;
|
||||
struct Text;
|
||||
struct UndoStep;
|
||||
struct UndoType;
|
||||
|
||||
|
@ -40,4 +41,7 @@ void ED_text_undosys_type(struct UndoType *ut);
|
|||
|
||||
struct UndoStep *ED_text_undo_push_init(struct bContext *C);
|
||||
|
||||
/* text_format.c */
|
||||
bool ED_text_is_syntax_highlight_supported(struct Text *text);
|
||||
|
||||
#endif /* __ED_TEXT_H__ */
|
||||
|
|
|
@ -63,6 +63,8 @@ static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
|
|||
stext->lheight = 12;
|
||||
stext->tabnumber = 4;
|
||||
stext->margin_column = 80;
|
||||
stext->showsyntax = true;
|
||||
stext->showlinenrs = true;
|
||||
|
||||
/* header */
|
||||
ar = MEM_callocN(sizeof(ARegion), "header for text");
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct TextDrawContext {
|
|||
int font_id;
|
||||
int cwidth;
|
||||
int lheight_dpi;
|
||||
bool syntax_highlight;
|
||||
} TextDrawContext;
|
||||
|
||||
static void text_draw_context_init(const SpaceText *st, TextDrawContext *tdc)
|
||||
|
@ -61,6 +62,7 @@ static void text_draw_context_init(const SpaceText *st, TextDrawContext *tdc)
|
|||
tdc->font_id = blf_mono_font;
|
||||
tdc->cwidth = 0;
|
||||
tdc->lheight_dpi = st->lheight_dpi;
|
||||
tdc->syntax_highlight = st->showsyntax && ED_text_is_syntax_highlight_supported(st->text);
|
||||
}
|
||||
|
||||
static void text_font_begin(const TextDrawContext *tdc)
|
||||
|
@ -418,7 +420,7 @@ static int text_draw_wrapped(const SpaceText *st,
|
|||
const char *format,
|
||||
int skip)
|
||||
{
|
||||
const bool use_syntax = (st->showsyntax && format);
|
||||
const bool use_syntax = (tdc->syntax_highlight && format);
|
||||
FlattenString fs;
|
||||
int basex, lines;
|
||||
int i, wrap, end, max, columns, padding; /* column */
|
||||
|
@ -514,7 +516,7 @@ static void text_draw(const SpaceText *st,
|
|||
int y,
|
||||
const char *format)
|
||||
{
|
||||
const bool use_syntax = (st->showsyntax && format);
|
||||
const bool use_syntax = (tdc->syntax_highlight && format);
|
||||
FlattenString fs;
|
||||
int columns, size, n, w = 0, padding, amount = 0;
|
||||
const char *in = NULL;
|
||||
|
@ -1383,8 +1385,8 @@ static void draw_brackets(const SpaceText *st, const TextDrawContext *tdc, ARegi
|
|||
|
||||
char ch;
|
||||
|
||||
// showsyntax must be on or else the format string will be null
|
||||
if (!text->curl || !st->showsyntax) {
|
||||
// syntax_highlight must be on or else the format string will be null
|
||||
if (!text->curl || !tdc->syntax_highlight) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1576,7 +1578,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
|||
tmp = text->lines.first;
|
||||
lineno = 0;
|
||||
for (i = 0; i < st->top && tmp; i++) {
|
||||
if (st->showsyntax && !tmp->format) {
|
||||
if (tdc.syntax_highlight && !tmp->format) {
|
||||
tft->format_line(st, tmp, false);
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1633,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
|||
UI_FontThemeColor(tdc.font_id, TH_TEXT);
|
||||
|
||||
for (i = 0; y > clip_min_y && i < st->viewlines && tmp; i++, tmp = tmp->next) {
|
||||
if (st->showsyntax && !tmp->format) {
|
||||
if (tdc.syntax_highlight && !tmp->format) {
|
||||
tft->format_line(st, tmp, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "DNA_text_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "ED_text.h"
|
||||
|
||||
#include "text_format.h"
|
||||
|
||||
/****************** flatten string **********************/
|
||||
|
@ -224,3 +227,38 @@ TextFormatType *ED_text_format_get(Text *text)
|
|||
return tft_lb.first;
|
||||
}
|
||||
}
|
||||
|
||||
bool ED_text_is_syntax_highlight_supported(Text *text)
|
||||
{
|
||||
if (text == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TextFormatType *tft;
|
||||
|
||||
const char *text_ext = BLI_path_extension(text->id.name + 2);
|
||||
if (text_ext == NULL) {
|
||||
/* Extensionless datablocks are considered highlightable as Python. */
|
||||
return true;
|
||||
}
|
||||
text_ext++; /* skip the '.' */
|
||||
if (BLI_string_is_decimal(text_ext)) {
|
||||
/* "Text.001" is treated as extensionless, and thus highlightable. */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check all text formats in the static list */
|
||||
for (tft = tft_lb.first; tft; tft = tft->next) {
|
||||
/* All formats should have an ext, but just in case */
|
||||
const char **ext;
|
||||
for (ext = tft->ext; *ext; ext++) {
|
||||
/* If extension matches text name, return the matching tft */
|
||||
if (BLI_strcasecmp(text_ext, *ext) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The filename has a non-numerical extension that we could not highlight. */
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "BKE_studiolight.h"
|
||||
#include "BKE_sequencer.h"
|
||||
|
||||
#include "ED_text.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
|
@ -1504,6 +1506,11 @@ static void rna_SpaceTextEditor_text_set(PointerRNA *ptr,
|
|||
WM_main_add_notifier(NC_TEXT | NA_SELECTED, st->text);
|
||||
}
|
||||
|
||||
static bool rna_SpaceTextEditor_text_is_syntax_highlight_supported(struct SpaceText *space)
|
||||
{
|
||||
return ED_text_is_syntax_highlight_supported(space->text);
|
||||
}
|
||||
|
||||
static void rna_SpaceTextEditor_updateEdited(Main *UNUSED(bmain),
|
||||
Scene *UNUSED(scene),
|
||||
PointerRNA *ptr)
|
||||
|
@ -4539,6 +4546,7 @@ static void rna_def_space_text(BlenderRNA *brna)
|
|||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
FunctionRNA *func;
|
||||
|
||||
srna = RNA_def_struct(brna, "SpaceTextEditor", "Space");
|
||||
RNA_def_struct_sdna(srna, "SpaceText");
|
||||
|
@ -4568,6 +4576,15 @@ static void rna_def_space_text(BlenderRNA *brna)
|
|||
RNA_def_property_ui_icon(prop, ICON_LINENUMBERS_ON, 0);
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL);
|
||||
|
||||
func = RNA_def_function(srna,
|
||||
"is_syntax_highlight_supported",
|
||||
"rna_SpaceTextEditor_text_is_syntax_highlight_supported");
|
||||
RNA_def_function_return(func,
|
||||
RNA_def_boolean(func, "is_syntax_highlight_supported", false, "", ""));
|
||||
RNA_def_function_ui_description(func,
|
||||
"Returns True if the editor supports syntax highlighting "
|
||||
"for the current text datablock");
|
||||
|
||||
prop = RNA_def_property(srna, "show_syntax_highlight", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "showsyntax", 0);
|
||||
RNA_def_property_ui_text(prop, "Syntax Highlight", "Syntax highlight for scripting");
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "BKE_text.h"
|
||||
|
||||
#include "ED_text.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "ED_text.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "rna_internal.h" /* own include */
|
||||
|
@ -59,6 +61,14 @@ void RNA_api_text(StructRNA *srna)
|
|||
func, "write text at the cursor location and advance to the end of the text block");
|
||||
parm = RNA_def_string(func, "text", "Text", 0, "", "New text for this data-block");
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
|
||||
func = RNA_def_function(
|
||||
srna, "is_syntax_highlight_supported", "ED_text_is_syntax_highlight_supported");
|
||||
RNA_def_function_return(func,
|
||||
RNA_def_boolean(func, "is_syntax_highlight_supported", false, "", ""));
|
||||
RNA_def_function_ui_description(func,
|
||||
"Returns True if the editor supports syntax highlighting "
|
||||
"for the current text datablock");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -618,3 +618,18 @@ TEST(path_util, PathFrameGet)
|
|||
PATH_FRAME_GET("", -1, -1, false);
|
||||
}
|
||||
#undef PATH_FRAME_GET
|
||||
|
||||
|
||||
/* BLI_path_extension */
|
||||
TEST(path_util, PathExtension)
|
||||
{
|
||||
EXPECT_EQ(NULL, BLI_path_extension("some.def/file"));
|
||||
EXPECT_EQ(NULL, BLI_path_extension("Text"));
|
||||
EXPECT_EQ(NULL, BLI_path_extension("Text…001"));
|
||||
|
||||
EXPECT_STREQ(".", BLI_path_extension("some/file."));
|
||||
EXPECT_STREQ(".gz", BLI_path_extension("some/file.tar.gz"));
|
||||
EXPECT_STREQ(".abc", BLI_path_extension("some.def/file.abc"));
|
||||
EXPECT_STREQ(".abc", BLI_path_extension("C:\\some.def\\file.abc"));
|
||||
EXPECT_STREQ(".001", BLI_path_extension("Text.001"));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ extern "C" {
|
|||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
}
|
||||
|
||||
using std::initializer_list;
|
||||
|
@ -588,3 +589,23 @@ TEST(string, StringStrncasestr)
|
|||
res = BLI_strncasestr(str_test0, "not there", 9);
|
||||
EXPECT_EQ(res, (void *)NULL);
|
||||
}
|
||||
|
||||
|
||||
/* BLI_string_is_decimal */
|
||||
TEST(string, StrIsDecimal)
|
||||
{
|
||||
EXPECT_FALSE(BLI_string_is_decimal(""));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("je moeder"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("je møder"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("Agent 327"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("Agent\000327"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("\000327"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("0x16"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("16.4"));
|
||||
EXPECT_FALSE(BLI_string_is_decimal("-1"));
|
||||
|
||||
EXPECT_TRUE(BLI_string_is_decimal("0"));
|
||||
EXPECT_TRUE(BLI_string_is_decimal("1"));
|
||||
EXPECT_TRUE(BLI_string_is_decimal("001"));
|
||||
EXPECT_TRUE(BLI_string_is_decimal("11342908713948713498745980171334059871345098713405981734"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue